Skip to content

Commit d4ce559

Browse files
committed
Fixed cardinality problem with project and entrypoints.
1 parent cf18708 commit d4ce559

File tree

4 files changed

+72
-49
lines changed

4 files changed

+72
-49
lines changed

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

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

55
import java.io.IOException;
66
import java.util.Collection;
7+
import java.util.HashMap;
78
import java.util.HashSet;
89
import java.util.Iterator;
910
import java.util.Map;
@@ -23,6 +24,7 @@
2324
import com.ibm.safe.internal.exceptions.PropertiesException;
2425
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
2526
import com.ibm.wala.ipa.callgraph.AnalysisOptions.ReflectionOptions;
27+
import com.ibm.wala.ipa.callgraph.CallGraph;
2628
import com.ibm.wala.ipa.callgraph.CallGraphBuilderCancelException;
2729
import com.ibm.wala.ipa.callgraph.Entrypoint;
2830
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
@@ -46,15 +48,18 @@ private static void addImplicitEntryPoints(Collection<Entrypoint> target, Iterab
4648
LOGGER.info(() -> "Adding implicit entry point: " + implicitEntryPoint);
4749
}
4850

49-
private Set<EclipseProjectAnalysisEngine<InstanceKey>> enginesWithBuiltCallGraphs = new HashSet<>();
51+
/**
52+
* Map from {@link EclipseProjectAnalysisEngine}s that have their
53+
* {@link CallGraph}s built to the {@link Entrypoint}s that were used to build
54+
* the graph.
55+
*/
56+
private Map<EclipseProjectAnalysisEngine<InstanceKey>, Collection<Entrypoint>> enginesWithBuiltCallGraphsToEntrypointsUsed = new HashMap<>();
5057

5158
private boolean findImplicitEntryPoints = true;
5259

5360
private boolean findImplicitTestEntryPoints;
5461

5562
private Set<Stream> streamSet = new HashSet<>();
56-
57-
private Set<Entrypoint> entryPoints = new HashSet<>();
5863

5964
public StreamAnalyzer() {
6065
this(false);
@@ -74,7 +79,14 @@ public StreamAnalyzer(boolean visitDocTags, boolean findImplicitEntryPoints, boo
7479
this.findImplicitTestEntryPoints = findImplicitTestEntryPoints;
7580
}
7681

77-
public void analyze() throws CoreException {
82+
/**
83+
* Analyzes this {@link StreamAnalyzer}'s streams.
84+
*
85+
* @return {@link Map} of project's analyzed along with the entry points used.
86+
*/
87+
public Map<IJavaProject, Collection<Entrypoint>> analyze() throws CoreException {
88+
Map<IJavaProject, Collection<Entrypoint>> ret = new HashMap<>();
89+
7890
// collect the projects to be analyzed.
7991
Map<IJavaProject, Set<Stream>> projectToStreams = this.getStreamSet().stream().filter(s -> s.getStatus().isOK())
8092
.collect(Collectors.groupingBy(Stream::getCreationJavaProject, Collectors.toSet()));
@@ -92,21 +104,24 @@ public void analyze() throws CoreException {
92104
}
93105

94106
// build the call graph for the project.
107+
Collection<Entrypoint> entryPoints = null;
95108
try {
96-
this.buildCallGraph(engine);
97-
} catch (NoEntryPointException e) {
98-
LOGGER.log(Level.WARNING,
99-
"No entry point exception caught while processing: " + engine.getProject().getElementName(), e);
109+
entryPoints = this.buildCallGraph(engine);
110+
} catch (IOException | CoreException | CancelException e) {
111+
LOGGER.log(Level.SEVERE,
112+
"Exception encountered while building call graph for: " + project.getElementName() + ".", e);
113+
throw new RuntimeException(e);
114+
}
115+
116+
// save the entry points.
117+
ret.put(project, entryPoints);
100118

119+
if (entryPoints.isEmpty()) {
101120
// add a status entry for each stream in the project
102121
for (Stream stream : projectToStreams.get(project))
103122
stream.addStatusEntry(PreconditionFailure.NO_ENTRY_POINT,
104123
"Project: " + engine.getProject().getElementName() + " has no entry points.");
105-
return;
106-
} catch (IOException | CoreException | CancelException e) {
107-
LOGGER.log(Level.SEVERE,
108-
"Exception encountered while building call graph for: " + project.getElementName() + ".", e);
109-
throw new RuntimeException(e);
124+
return ret;
110125
}
111126

112127
OrderingInference orderingInference = new OrderingInference(engine.getClassHierarchy());
@@ -149,12 +164,23 @@ public void analyze() throws CoreException {
149164
.collect(Collectors.toSet()))
150165
stream.check();
151166
} // end for each stream.
167+
168+
return ret;
152169
}
153170

154-
protected void buildCallGraph(EclipseProjectAnalysisEngine<InstanceKey> engine)
155-
throws IOException, CoreException, CallGraphBuilderCancelException, CancelException, NoEntryPointException {
171+
/**
172+
* Builds the call graph that is part of the
173+
* {@link EclipseProjectAnalysisEngine}.
174+
*
175+
* @param engine
176+
* The EclipseProjectAnalysisEngine for which to build the call
177+
* graph.
178+
* @return The {@link Entrypoint}s used in building the {@link CallGraph}.
179+
*/
180+
protected Collection<Entrypoint> buildCallGraph(EclipseProjectAnalysisEngine<InstanceKey> engine)
181+
throws IOException, CoreException, CallGraphBuilderCancelException, CancelException {
156182
// if we haven't built the call graph yet.
157-
if (!this.enginesWithBuiltCallGraphs.contains(engine)) {
183+
if (!this.enginesWithBuiltCallGraphsToEntrypointsUsed.keySet().contains(engine)) {
158184
// find explicit entry points.
159185
Set<Entrypoint> entryPoints = Util.findEntryPoints(engine.getClassHierarchy());
160186
entryPoints.forEach(ep -> LOGGER.info(() -> "Adding explicit entry point: " + ep));
@@ -177,8 +203,7 @@ protected void buildCallGraph(EclipseProjectAnalysisEngine<InstanceKey> engine)
177203
}
178204

179205
if (entryPoints.isEmpty())
180-
throw new NoEntryPointException(
181-
"Project: " + engine.getProject().getElementName() + " has no entry points.");
206+
LOGGER.warning(() -> "Project: " + engine.getProject().getElementName() + " has no entry points.");
182207

183208
// set options.
184209
AnalysisOptions options = engine.getDefaultOptions(entryPoints);
@@ -195,10 +220,9 @@ protected void buildCallGraph(EclipseProjectAnalysisEngine<InstanceKey> engine)
195220
}
196221
// TODO: Can I slice the graph so that only nodes relevant to the
197222
// instance in question are present?
198-
this.enginesWithBuiltCallGraphs.add(engine);
199-
200-
setEntryPoints(entryPoints);
223+
this.enginesWithBuiltCallGraphsToEntrypointsUsed.put(engine, entryPoints);
201224
}
225+
return this.enginesWithBuiltCallGraphsToEntrypointsUsed.get(engine);
202226
}
203227

204228
public Set<Stream> getStreamSet() {
@@ -252,13 +276,4 @@ public boolean visit(MethodInvocation node) {
252276

253277
return super.visit(node);
254278
}
255-
256-
protected void setEntryPoints(Set<Entrypoint> entryPoints) {
257-
this.entryPoints = entryPoints;
258-
}
259-
260-
public Set<Entrypoint> getEntryPoints() {
261-
return this.entryPoints;
262-
}
263-
264279
}

edu.cuny.hunter.streamrefactoring.core/src/edu/cuny/hunter/streamrefactoring/core/refactorings/ConvertToParallelStreamRefactoringProcessor.java

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
import static org.eclipse.jdt.ui.JavaElementLabels.getElementLabel;
55

66
import java.text.MessageFormat;
7+
import java.util.Collection;
8+
import java.util.Collections;
79
import java.util.HashMap;
8-
import java.util.HashSet;
910
import java.util.Map;
1011
import java.util.Optional;
1112
import java.util.Set;
@@ -132,8 +133,8 @@ public static void setLoggingLevel(int level) {
132133
private IJavaProject[] javaProjects;
133134

134135
private Set<Stream> streamSet;
135-
136-
private Set<Entrypoint> entryPoints = new HashSet<>();
136+
137+
private Map<IJavaProject, Collection<Entrypoint>> projectToEntryPoints;
137138

138139
private boolean useImplicitEntrypoints = true;
139140

@@ -208,14 +209,18 @@ public RefactoringStatus checkFinalConditions(final IProgressMonitor monitor, fi
208209
}
209210
}
210211

211-
analyzer.analyze();
212+
// analyze and set entry points.
213+
projectToEntryPoints = analyzer.analyze();
214+
215+
// map empty set to unprocessed projects.
216+
for (IJavaProject project : this.getJavaProjects())
217+
this.projectToEntryPoints.computeIfAbsent(project, p -> Collections.emptySet());
218+
212219

220+
// get the status of each stream.
213221
RefactoringStatus collectedStatus = getStreamSet().stream().map(Stream::getStatus)
214222
.collect(() -> new RefactoringStatus(), (a, b) -> a.merge(b), (a, b) -> a.merge(b));
215223
status.merge(collectedStatus);
216-
217-
// set entry points
218-
setEntryPoints(analyzer.getEntryPoints());
219224

220225
// if there are no fatal errors.
221226
if (!status.hasFatalError()) {
@@ -240,12 +245,8 @@ public RefactoringStatus checkFinalConditions(final IProgressMonitor monitor, fi
240245
}
241246
}
242247

243-
private void setEntryPoints(Set<Entrypoint> entryPoints) {
244-
this.entryPoints = entryPoints;
245-
}
246-
247-
public Set<Entrypoint> getEntryPoints() {
248-
return this.entryPoints;
248+
public Collection<Entrypoint> getEntryPoints(IJavaProject javaProject) {
249+
return this.projectToEntryPoints.get(javaProject);
249250
}
250251

251252
private boolean getUseImplicitEntrypoints() {

edu.cuny.hunter.streamrefactoring.eval/META-INF/MANIFEST.MF

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Export-Package: edu.cuny.hunter.streamrefactoring.eval.handlers,
2424
Import-Package: com.google.common.io,
2525
com.ibm.wala.classLoader,
2626
com.ibm.wala.ipa.callgraph,
27+
com.ibm.wala.types,
2728
edu.cuny.hunter.streamrefactoring.core.analysis,
2829
edu.cuny.hunter.streamrefactoring.core.refactorings,
2930
edu.cuny.hunter.streamrefactoring.core.utils,

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -246,14 +246,15 @@ public Object execute(ExecutionEvent event) throws ExecutionException {
246246
RefactoringStatus status = new ProcessorBasedRefactoring(processor)
247247
.checkAllConditions(new NullProgressMonitor());
248248
resultsTimeCollector.stop();
249-
250-
// print entry points
251-
Set<Entrypoint> entryPoints = processor.getEntryPoints();
252-
resultsPrinter.print(entryPoints.size());
249+
250+
// print entry points.
251+
Collection<Entrypoint> entryPoints = getProjectEntryPoints(javaProject, processor);
252+
resultsPrinter.print(entryPoints.size()); // number.
253253

254254
for (Entrypoint entryPoint : entryPoints) {
255-
entryPointsPrinter.printRecord(javaProject.getElementName(),
256-
entryPoint.getMethod().getSignature(), "! not implement now");
255+
com.ibm.wala.classLoader.IMethod method = entryPoint.getMethod();
256+
entryPointsPrinter.printRecord(javaProject.getElementName(), method.getSignature(),
257+
method.getDeclaringClass().getName());
257258
}
258259

259260
// #streams.
@@ -448,6 +449,11 @@ public Object execute(ExecutionEvent event) throws ExecutionException {
448449
return null;
449450
}
450451

452+
private static Collection<Entrypoint> getProjectEntryPoints(IJavaProject javaProject,
453+
ConvertToParallelStreamRefactoringProcessor processor) {
454+
return processor.getEntryPoints(javaProject);
455+
}
456+
451457
private Set<SearchMatch> findReferences(Set<? extends IJavaElement> elements) throws CoreException {
452458
Set<SearchMatch> ret = new HashSet<>();
453459
for (IJavaElement elem : elements)

0 commit comments

Comments
 (0)