Skip to content

Commit bb2564f

Browse files
Grace Tangkhatchad
authored andcommitted
Generate entry_points.txt (#175)
Fix #175.
1 parent 3cc5b1e commit bb2564f

File tree

12 files changed

+272
-8
lines changed

12 files changed

+272
-8
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ This prototype refactoring plug-in for [Eclipse](http://eclipse.org) represents
1515

1616
Explicit entry points may be marked using the appropriate annotation found in the corresponding [annotation library][annotations].
1717

18+
Explicit entry points can also be marked using importing entry points from a txt file. Each time we run the tool, a txt file named "entry_points.txt" is generated and contained in the current directory of workspace. Then, before next time we run tool to evaluate the same project, move or copy "entry_points.txt" into project directory or workspace directory of the project. While evaluating the project, the tool will ignore the explicit entry points which are added manually and regonize the explicit entry points through the file automatically.
19+
1820
### Limitations
1921

2022
There are currently some limitations with embedded streams (i.e., streams declared as part of lambda expressions sent as arguments to intermediate stream operations). This is due to model differences between the Eclipse JDT and WALA. See [#155](https://github.com/ponder-lab/Java-8-Stream-Refactoring/issues/155) for details.

edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/StreamAnalyzer.java

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,23 @@
22

33
import static com.ibm.wala.ipa.callgraph.impl.Util.makeMainEntrypoints;
44

5+
import java.io.File;
56
import java.io.IOException;
7+
import java.nio.file.Path;
8+
import java.nio.file.Paths;
69
import java.util.Collection;
710
import java.util.HashMap;
811
import java.util.HashSet;
912
import java.util.Iterator;
1013
import java.util.Map;
14+
import java.util.Scanner;
1115
import java.util.Set;
1216
import java.util.logging.Level;
1317
import java.util.logging.Logger;
1418
import java.util.stream.Collectors;
1519

1620
import org.eclipse.core.runtime.CoreException;
21+
import org.eclipse.core.runtime.IPath;
1722
import org.eclipse.jdt.core.IJavaProject;
1823
import org.eclipse.jdt.core.dom.ASTVisitor;
1924
import org.eclipse.jdt.core.dom.IMethodBinding;
@@ -29,6 +34,7 @@
2934
import com.ibm.wala.ipa.callgraph.Entrypoint;
3035
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
3136
import com.ibm.wala.ipa.cha.ClassHierarchyException;
37+
import com.ibm.wala.ipa.cha.IClassHierarchy;
3238
import com.ibm.wala.shrikeCT.InvalidClassFileException;
3339
import com.ibm.wala.ssa.SSAOptions;
3440
import com.ibm.wala.util.CancelException;
@@ -42,6 +48,8 @@ public class StreamAnalyzer extends ASTVisitor {
4248

4349
private static final Logger LOGGER = Logger.getLogger(LoggerNames.LOGGER_NAME);
4450

51+
private static final String ENTRY_POINT_FILE = "entry_points.txt";
52+
4553
private static void addImplicitEntryPoints(Collection<Entrypoint> target, Iterable<Entrypoint> source) {
4654
for (Entrypoint implicitEntryPoint : source)
4755
if (target.add(implicitEntryPoint))
@@ -181,13 +189,22 @@ public Map<IJavaProject, Collection<Entrypoint>> analyze() throws CoreException
181189
* graph.
182190
* @return The {@link Entrypoint}s used in building the {@link CallGraph}.
183191
*/
184-
protected Collection<Entrypoint> buildCallGraph(EclipseProjectAnalysisEngine<InstanceKey> engine)
185-
throws IOException, CoreException, CallGraphBuilderCancelException, CancelException {
192+
protected Collection<Entrypoint> buildCallGraph(EclipseProjectAnalysisEngine<InstanceKey> engine) throws IOException, CoreException, CallGraphBuilderCancelException, CancelException {
186193
// if we haven't built the call graph yet.
187194
if (!this.enginesWithBuiltCallGraphsToEntrypointsUsed.keySet().contains(engine)) {
188-
// find explicit entry points.
189-
Set<Entrypoint> entryPoints = Util.findEntryPoints(engine.getClassHierarchy());
190-
entryPoints.forEach(ep -> LOGGER.info(() -> "Adding explicit entry point: " + ep));
195+
196+
Set<Entrypoint> entryPoints;
197+
// find the entry_points.txt in the project directory
198+
File entryPointFile = getEntryPointsFile(engine.getProject().getResource().getLocation(), ENTRY_POINT_FILE);
199+
if (entryPointFile != null) {
200+
// find explicit entry points from entry_points.txt
201+
entryPoints = findEntryPointsFromFile(engine.getClassHierarchy(), entryPointFile);
202+
entryPoints.forEach(ep -> LOGGER.info(() -> "Adding explicit entry point from file: " + ep));
203+
} else {
204+
// find explicit entry points.
205+
entryPoints = Util.findEntryPoints(engine.getClassHierarchy());
206+
entryPoints.forEach(ep -> LOGGER.info(() -> "Adding explicit entry point: " + ep));
207+
}
191208

192209
if (this.findImplicitEntryPoints) {
193210
// also find implicit entry points.
@@ -239,6 +256,52 @@ protected Collection<Entrypoint> buildCallGraph(EclipseProjectAnalysisEngine<Ins
239256
return this.enginesWithBuiltCallGraphsToEntrypointsUsed.get(engine);
240257
}
241258

259+
/**
260+
* Read entry_points.txt and get a set of method signatures, then, get entry
261+
* points by those signatures
262+
*
263+
* @return a set of entry points
264+
* @throws IOException
265+
*/
266+
private static Set<Entrypoint> findEntryPointsFromFile(IClassHierarchy classHierarchy, File file)
267+
throws IOException {
268+
Set<String> signatures = new HashSet<>();
269+
270+
try (Scanner scanner = new Scanner(file)) {
271+
while (scanner.hasNextLine()) {
272+
String line = scanner.nextLine();
273+
signatures.add(line);
274+
}
275+
}
276+
277+
Set<Entrypoint> entrypoints = Util.findEntryPoints(classHierarchy, signatures);
278+
return entrypoints;
279+
}
280+
281+
/**
282+
* Search entry_points.txt in project directory recursively
283+
*
284+
* @param directory:
285+
* project directory
286+
* @param fileName:
287+
* the target file
288+
* @return null: the file does not exist / file: find the file
289+
*/
290+
private static File getEntryPointsFile(IPath directory, String fileName) {
291+
// If file does not exist, find the file in upper level
292+
Path directoryPath = Paths.get(directory.toString());
293+
File file;
294+
do {
295+
file = new File(directoryPath.resolve(ENTRY_POINT_FILE).toString());
296+
directoryPath = directoryPath.getParent();
297+
} while (!file.exists() && directoryPath != null);
298+
299+
if (!file.exists())
300+
return null;
301+
else
302+
return file;
303+
}
304+
242305
public Set<Stream> getStreamSet() {
243306
return this.streamSet;
244307
}

edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/analysis/Util.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,24 @@ public static Set<Entrypoint> findEntryPoints(IClassHierarchy classHierarchy) {
264264
return result;
265265
}
266266

267+
/**
268+
* find entry points from file
269+
*/
270+
public static Set<Entrypoint> findEntryPoints(IClassHierarchy classHierarchy, Set<String> signatures) {
271+
final Set<Entrypoint> result = new HashSet<>();
272+
273+
for (IClass klass : classHierarchy)
274+
if (!(isJDKClass(klass) || isLibraryClass(klass))) {
275+
// iterate over all declared methods
276+
for (com.ibm.wala.classLoader.IMethod method : klass.getDeclaredMethods()) {
277+
if (signatures.contains(method.getSignature())) {
278+
addEntryPoint(result, method, classHierarchy);
279+
}
280+
}
281+
}
282+
return result;
283+
}
284+
267285
static Set<ITypeBinding> getAllInterfaces(ITypeBinding type) {
268286
Set<ITypeBinding> ret = new HashSet<>();
269287
ITypeBinding[] interfaces = type.getInterfaces();

edu.cuny.hunter.streamrefactoring.eval/src/edu/cuny/hunter/streamrefactoring/eval/handlers/EvaluateConvertToParallelStreamRefactoringHandler.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import java.io.FileWriter;
66
import java.io.IOException;
7+
import java.io.PrintWriter;
78
import java.util.ArrayList;
89
import java.util.Arrays;
910
import java.util.Collection;
@@ -173,6 +174,7 @@ public Object execute(ExecutionEvent event) throws ExecutionException {
173174
CSVPrinter streamExecutionModePrinter = null;
174175
CSVPrinter streamOrderingPrinter = null;
175176
CSVPrinter entryPointsPrinter = null;
177+
PrintWriter entryPointsTXTPrinter = null;
176178

177179
ConvertToParallelStreamRefactoringProcessor processor = null;
178180

@@ -231,6 +233,8 @@ public Object execute(ExecutionEvent event) throws ExecutionException {
231233
entryPointsPrinter = createCSVPrinter("entry_points.csv",
232234
new String[] { "subject", "method", "type FQN" });
233235

236+
entryPointsTXTPrinter = new PrintWriter("entry_points.txt");
237+
234238
for (IJavaProject javaProject : javaProjects) {
235239
if (!javaProject.isStructureKnown())
236240
throw new IllegalStateException(
@@ -265,6 +269,7 @@ public Object execute(ExecutionEvent event) throws ExecutionException {
265269
com.ibm.wala.classLoader.IMethod method = entryPoint.getMethod();
266270
entryPointsPrinter.printRecord(javaProject.getElementName(), method.getSignature(),
267271
method.getDeclaringClass().getName());
272+
entryPointsTXTPrinter.println(method.getSignature());
268273
}
269274

270275
// #streams.
@@ -442,6 +447,8 @@ public Object execute(ExecutionEvent event) throws ExecutionException {
442447
streamOrderingPrinter.close();
443448
if (entryPointsPrinter != null)
444449
entryPointsPrinter.close();
450+
if (entryPointsTXTPrinter != null)
451+
entryPointsTXTPrinter.close();
445452

446453
// clear cache.
447454
if (processor != null)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package p;
2+
3+
import java.util.HashSet;
4+
5+
import edu.cuny.hunter.streamrefactoring.annotations.*;
6+
7+
class A {
8+
@EntryPoint
9+
void m() {
10+
HashSet h1 = new HashSet();
11+
h1.stream().count();
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
p.A.<init>()V
2+
p.A.m()V
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package p;
2+
3+
import java.util.HashSet;
4+
5+
import edu.cuny.hunter.streamrefactoring.annotations.*;
6+
7+
class A {
8+
void m() {
9+
HashSet h1 = new HashSet();
10+
h1.stream().count();
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
q.A.<init>()V
2+
q.A.m()V
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package p;
2+
3+
import java.util.HashSet;
4+
5+
import edu.cuny.hunter.streamrefactoring.annotations.*;
6+
7+
class A {
8+
void m() {
9+
HashSet h1 = new HashSet();
10+
h1.stream().count();
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
q.A.<init>()V
2+
q.A.m()V

0 commit comments

Comments
 (0)