4
4
5
5
import java .io .IOException ;
6
6
import java .util .Collection ;
7
+ import java .util .HashMap ;
7
8
import java .util .HashSet ;
8
9
import java .util .Iterator ;
9
10
import java .util .Map ;
23
24
import com .ibm .safe .internal .exceptions .PropertiesException ;
24
25
import com .ibm .wala .ipa .callgraph .AnalysisOptions ;
25
26
import com .ibm .wala .ipa .callgraph .AnalysisOptions .ReflectionOptions ;
27
+ import com .ibm .wala .ipa .callgraph .CallGraph ;
26
28
import com .ibm .wala .ipa .callgraph .CallGraphBuilderCancelException ;
27
29
import com .ibm .wala .ipa .callgraph .Entrypoint ;
28
30
import com .ibm .wala .ipa .callgraph .propagation .InstanceKey ;
@@ -46,7 +48,12 @@ private static void addImplicitEntryPoints(Collection<Entrypoint> target, Iterab
46
48
LOGGER .info (() -> "Adding implicit entry point: " + implicitEntryPoint );
47
49
}
48
50
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 <>();
50
57
51
58
private boolean findImplicitEntryPoints = true ;
52
59
@@ -72,7 +79,14 @@ public StreamAnalyzer(boolean visitDocTags, boolean findImplicitEntryPoints, boo
72
79
this .findImplicitTestEntryPoints = findImplicitTestEntryPoints ;
73
80
}
74
81
75
- 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
+
76
90
// collect the projects to be analyzed.
77
91
Map <IJavaProject , Set <Stream >> projectToStreams = this .getStreamSet ().stream ().filter (s -> s .getStatus ().isOK ())
78
92
.collect (Collectors .groupingBy (Stream ::getCreationJavaProject , Collectors .toSet ()));
@@ -90,21 +104,24 @@ public void analyze() throws CoreException {
90
104
}
91
105
92
106
// build the call graph for the project.
107
+ Collection <Entrypoint > entryPoints = null ;
93
108
try {
94
- this .buildCallGraph (engine );
95
- } catch (NoEntryPointException e ) {
96
- LOGGER .log (Level .WARNING ,
97
- "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 );
98
118
119
+ if (entryPoints .isEmpty ()) {
99
120
// add a status entry for each stream in the project
100
121
for (Stream stream : projectToStreams .get (project ))
101
122
stream .addStatusEntry (PreconditionFailure .NO_ENTRY_POINT ,
102
123
"Project: " + engine .getProject ().getElementName () + " has no entry points." );
103
- return ;
104
- } catch (IOException | CoreException | CancelException e ) {
105
- LOGGER .log (Level .SEVERE ,
106
- "Exception encountered while building call graph for: " + project .getElementName () + "." , e );
107
- throw new RuntimeException (e );
124
+ return ret ;
108
125
}
109
126
110
127
OrderingInference orderingInference = new OrderingInference (engine .getClassHierarchy ());
@@ -147,12 +164,23 @@ public void analyze() throws CoreException {
147
164
.collect (Collectors .toSet ()))
148
165
stream .check ();
149
166
} // end for each stream.
167
+
168
+ return ret ;
150
169
}
151
170
152
- protected void buildCallGraph (EclipseProjectAnalysisEngine <InstanceKey > engine )
153
- 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 {
154
182
// if we haven't built the call graph yet.
155
- if (!this .enginesWithBuiltCallGraphs .contains (engine )) {
183
+ if (!this .enginesWithBuiltCallGraphsToEntrypointsUsed . keySet () .contains (engine )) {
156
184
// find explicit entry points.
157
185
Set <Entrypoint > entryPoints = Util .findEntryPoints (engine .getClassHierarchy ());
158
186
entryPoints .forEach (ep -> LOGGER .info (() -> "Adding explicit entry point: " + ep ));
@@ -175,8 +203,7 @@ protected void buildCallGraph(EclipseProjectAnalysisEngine<InstanceKey> engine)
175
203
}
176
204
177
205
if (entryPoints .isEmpty ())
178
- throw new NoEntryPointException (
179
- "Project: " + engine .getProject ().getElementName () + " has no entry points." );
206
+ LOGGER .warning (() -> "Project: " + engine .getProject ().getElementName () + " has no entry points." );
180
207
181
208
// set options.
182
209
AnalysisOptions options = engine .getDefaultOptions (entryPoints );
@@ -193,8 +220,9 @@ protected void buildCallGraph(EclipseProjectAnalysisEngine<InstanceKey> engine)
193
220
}
194
221
// TODO: Can I slice the graph so that only nodes relevant to the
195
222
// instance in question are present?
196
- this .enginesWithBuiltCallGraphs . add (engine );
223
+ this .enginesWithBuiltCallGraphsToEntrypointsUsed . put (engine , entryPoints );
197
224
}
225
+ return this .enginesWithBuiltCallGraphsToEntrypointsUsed .get (engine );
198
226
}
199
227
200
228
public Set <Stream > getStreamSet () {
0 commit comments