Skip to content

Commit 2f5f56e

Browse files
committed
Merge branch 'master' into issue_80
2 parents f8b2721 + 452e2ca commit 2f5f56e

File tree

12 files changed

+281
-10
lines changed

12 files changed

+281
-10
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,19 +2,24 @@
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.BaseStream;
1519
import java.util.stream.Collectors;
1620

1721
import org.eclipse.core.runtime.CoreException;
22+
import org.eclipse.core.runtime.IPath;
1823
import org.eclipse.jdt.core.IJavaProject;
1924
import org.eclipse.jdt.core.dom.ASTVisitor;
2025
import org.eclipse.jdt.core.dom.IMethodBinding;
@@ -30,6 +35,7 @@
3035
import com.ibm.wala.ipa.callgraph.Entrypoint;
3136
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
3237
import com.ibm.wala.ipa.cha.ClassHierarchyException;
38+
import com.ibm.wala.ipa.cha.IClassHierarchy;
3339
import com.ibm.wala.shrikeCT.InvalidClassFileException;
3440
import com.ibm.wala.ssa.SSAOptions;
3541
import com.ibm.wala.util.CancelException;
@@ -45,6 +51,8 @@ public class StreamAnalyzer extends ASTVisitor {
4551

4652
private static final int N_FOR_STREAMS_DEFAULT = 2;
4753

54+
private static final String ENTRY_POINT_FILE = "entry_points.txt";
55+
4856
private static void addImplicitEntryPoints(Collection<Entrypoint> target, Iterable<Entrypoint> source) {
4957
for (Entrypoint implicitEntryPoint : source)
5058
if (target.add(implicitEntryPoint))
@@ -200,13 +208,22 @@ public Map<IJavaProject, Collection<Entrypoint>> analyze() throws CoreException
200208
* graph.
201209
* @return The {@link Entrypoint}s used in building the {@link CallGraph}.
202210
*/
203-
protected Collection<Entrypoint> buildCallGraph(EclipseProjectAnalysisEngine<InstanceKey> engine)
204-
throws IOException, CoreException, CallGraphBuilderCancelException, CancelException {
211+
protected Collection<Entrypoint> buildCallGraph(EclipseProjectAnalysisEngine<InstanceKey> engine) throws IOException, CoreException, CallGraphBuilderCancelException, CancelException {
205212
// if we haven't built the call graph yet.
206213
if (!this.enginesWithBuiltCallGraphsToEntrypointsUsed.keySet().contains(engine)) {
207-
// find explicit entry points.
208-
Set<Entrypoint> entryPoints = Util.findEntryPoints(engine.getClassHierarchy());
209-
entryPoints.forEach(ep -> LOGGER.info(() -> "Adding explicit entry point: " + ep));
214+
215+
Set<Entrypoint> entryPoints;
216+
// find the entry_points.txt in the project directory
217+
File entryPointFile = getEntryPointsFile(engine.getProject().getResource().getLocation(), ENTRY_POINT_FILE);
218+
if (entryPointFile != null) {
219+
// find explicit entry points from entry_points.txt
220+
entryPoints = findEntryPointsFromFile(engine.getClassHierarchy(), entryPointFile);
221+
entryPoints.forEach(ep -> LOGGER.info(() -> "Adding explicit entry point from file: " + ep));
222+
} else {
223+
// find explicit entry points.
224+
entryPoints = Util.findEntryPoints(engine.getClassHierarchy());
225+
entryPoints.forEach(ep -> LOGGER.info(() -> "Adding explicit entry point: " + ep));
226+
}
210227

211228
if (this.findImplicitEntryPoints) {
212229
// also find implicit entry points.
@@ -258,6 +275,52 @@ protected Collection<Entrypoint> buildCallGraph(EclipseProjectAnalysisEngine<Ins
258275
return this.enginesWithBuiltCallGraphsToEntrypointsUsed.get(engine);
259276
}
260277

278+
/**
279+
* Read entry_points.txt and get a set of method signatures, then, get entry
280+
* points by those signatures
281+
*
282+
* @return a set of entry points
283+
* @throws IOException
284+
*/
285+
private static Set<Entrypoint> findEntryPointsFromFile(IClassHierarchy classHierarchy, File file)
286+
throws IOException {
287+
Set<String> signatures = new HashSet<>();
288+
289+
try (Scanner scanner = new Scanner(file)) {
290+
while (scanner.hasNextLine()) {
291+
String line = scanner.nextLine();
292+
signatures.add(line);
293+
}
294+
}
295+
296+
Set<Entrypoint> entrypoints = Util.findEntryPoints(classHierarchy, signatures);
297+
return entrypoints;
298+
}
299+
300+
/**
301+
* Search entry_points.txt in project directory recursively
302+
*
303+
* @param directory:
304+
* project directory
305+
* @param fileName:
306+
* the target file
307+
* @return null: the file does not exist / file: find the file
308+
*/
309+
private static File getEntryPointsFile(IPath directory, String fileName) {
310+
// If file does not exist, find the file in upper level
311+
Path directoryPath = Paths.get(directory.toString());
312+
File file;
313+
do {
314+
file = new File(directoryPath.resolve(ENTRY_POINT_FILE).toString());
315+
directoryPath = directoryPath.getParent();
316+
} while (!file.exists() && directoryPath != null);
317+
318+
if (!file.exists())
319+
return null;
320+
else
321+
return file;
322+
}
323+
261324
public Set<Stream> getStreamSet() {
262325
return this.streamSet;
263326
}

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
@@ -265,6 +265,24 @@ public static Set<Entrypoint> findEntryPoints(IClassHierarchy classHierarchy) {
265265
return result;
266266
}
267267

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