52
52
import java .util .function .Supplier ;
53
53
import java .util .stream .Collectors ;
54
54
55
+ import static com .ibm .cldk .CodeAnalyzer .analysisLevel ;
55
56
import static com .ibm .cldk .utils .AnalysisUtils .*;
56
57
57
58
@@ -114,76 +115,13 @@ private static JSONExporter<CallableVertex, AbstractGraphEdge> getGraphExporter(
114
115
/**
115
116
* Convert SDG to a formal Graph representation.
116
117
*
117
- * @param entryPoints
118
- * @param sdg
119
118
* @param callGraph
120
- * @param edgeLabels
121
119
* @return
122
120
*/
123
- private static org .jgrapht .Graph <CallableVertex , AbstractGraphEdge > buildGraph (
124
- Supplier <Iterator <Statement >> entryPoints ,
125
- Graph <Statement > sdg , CallGraph callGraph ,
126
- BiFunction <Statement , Statement , String > edgeLabels ) {
121
+ private static org .jgrapht .Graph <CallableVertex , AbstractGraphEdge > buildOnlyCallGraph (CallGraph callGraph ) {
127
122
128
123
org .jgrapht .Graph <CallableVertex , AbstractGraphEdge > graph = new DefaultDirectedGraph <>(
129
124
AbstractGraphEdge .class );
130
-
131
- // We'll use forward and backward search on the DFS to identify which CFG nodes
132
- // are dominant
133
- // This is a forward DFS search (or exit time first search)
134
- int dfsNumber = 0 ;
135
- Map <Statement , Integer > dfsFinish = HashMapFactory .make ();
136
- Iterator <Statement > search = DFS .iterateFinishTime (sdg , entryPoints .get ());
137
-
138
- while (search .hasNext ()) {
139
- dfsFinish .put (search .next (), dfsNumber ++);
140
- }
141
-
142
- // This is a reverse DFS search (or entry time first search)
143
- int reverseDfsNumber = 0 ;
144
- Map <Statement , Integer > dfsStart = HashMapFactory .make ();
145
- Iterator <Statement > reverseSearch = DFS .iterateDiscoverTime (sdg , entryPoints .get ());
146
-
147
- while (reverseSearch .hasNext ()) {
148
- dfsStart .put (reverseSearch .next (), reverseDfsNumber ++);
149
- }
150
-
151
- // Populate graph
152
- sdg .stream ()
153
- .filter (dfsFinish ::containsKey )
154
- .sorted (Comparator .comparingInt (dfsFinish ::get ))
155
- .forEach (p -> sdg .getSuccNodes (p ).forEachRemaining (s -> {
156
- if (dfsFinish .containsKey (s )
157
- && dfsStart .get (p ) != null && dfsStart .get (s ) != null
158
- && !((dfsStart .get (p ) >= dfsStart .get (s ))
159
- && (dfsFinish .get (p ) <= dfsFinish .get (s )))
160
- && !p .getNode ().getMethod ().equals (s .getNode ().getMethod ())) {
161
-
162
- // Add the source nodes to the graph as vertices
163
- Map <String , String > source = Optional .ofNullable (getCallableFromSymbolTable (p .getNode ().getMethod ())).orElseGet (() -> createAndPutNewCallableInSymbolTable (p .getNode ().getMethod ()));
164
- // Add the target nodes to the graph as vertices
165
- Map <String , String > target = Optional .ofNullable (getCallableFromSymbolTable (s .getNode ().getMethod ())).orElseGet (() -> createAndPutNewCallableInSymbolTable (s .getNode ().getMethod ()));
166
-
167
- if (source != null && target != null ) {
168
- CallableVertex source_vertex = new CallableVertex (source );
169
- CallableVertex target_vertex = new CallableVertex (target );
170
- graph .addVertex (source_vertex );
171
- graph .addVertex (target_vertex );
172
- String edgeType = edgeLabels .apply (p , s );
173
- SystemDepEdge graphEdge = new SystemDepEdge (p , s , edgeType );
174
- SystemDepEdge cgEdge = (SystemDepEdge ) graph .getEdge (source_vertex , target_vertex );
175
- if (cgEdge == null || !cgEdge .equals (graphEdge )) {
176
- graph .addEdge (
177
- source_vertex ,
178
- target_vertex ,
179
- graphEdge );
180
- } else {
181
- graphEdge .incrementWeight ();
182
- }
183
- }
184
- }
185
- }));
186
-
187
125
callGraph .getEntrypointNodes ()
188
126
.forEach (p -> {
189
127
// Get call statements that may execute in a given method
@@ -264,7 +202,6 @@ public static List<Dependency> construct(
264
202
try {
265
203
System .setOut (new PrintStream (NullOutputStream .INSTANCE ));
266
204
System .setErr (new PrintStream (NullOutputStream .INSTANCE ));
267
- // builder = Util.makeRTABuilder(new JavaLanguage(), options, cache, cha);
268
205
builder = Util .makeRTABuilder (options , cache , cha );
269
206
callGraph = builder .makeCallGraph (options , null );
270
207
} finally {
@@ -283,40 +220,14 @@ public static List<Dependency> construct(
283
220
}
284
221
});
285
222
223
+ org .jgrapht .Graph <CallableVertex , AbstractGraphEdge > graph ;
224
+
225
+ graph = buildOnlyCallGraph (callGraph );
286
226
287
- // Build SDG graph
288
- Log .info ("Building System Dependency Graph." );
289
- SDG <? extends InstanceKey > sdg = new SDG <>(
290
- callGraph ,
291
- builder .getPointerAnalysis (),
292
- new ModRef <>(),
293
- Slicer .DataDependenceOptions .NO_HEAP_NO_EXCEPTIONS ,
294
- Slicer .ControlDependenceOptions .NO_EXCEPTIONAL_EDGES );
295
-
296
- // Prune the Graph to keep only application classes.
297
- Graph <Statement > prunedGraph = GraphSlicer .prune (sdg ,
298
- statement -> (statement .getNode ()
299
- .getMethod ()
300
- .getDeclaringClass ()
301
- .getClassLoader ()
302
- .getReference ()
303
- .equals (ClassLoaderReference .Application ))
304
- );
305
-
306
- // A supplier to get entries
307
- Supplier <Iterator <Statement >> sdgEntryPointsSupplier = () -> callGraph .getEntrypointNodes ().stream ()
308
- .map (n -> (Statement ) new MethodEntryStatement (n )).iterator ();
309
-
310
- org .jgrapht .Graph <CallableVertex , AbstractGraphEdge > sdgGraph = buildGraph (
311
- sdgEntryPointsSupplier ,
312
- prunedGraph , callGraph ,
313
- (p , s ) -> String .valueOf (sdg .getEdgeLabels (p , s ).iterator ().next ())
314
- );
315
-
316
- List <Dependency > edges = sdgGraph .edgeSet ().stream ()
227
+ List <Dependency > edges = graph .edgeSet ().stream ()
317
228
.map (abstractGraphEdge -> {
318
- CallableVertex source = sdgGraph .getEdgeSource (abstractGraphEdge );
319
- CallableVertex target = sdgGraph .getEdgeTarget (abstractGraphEdge );
229
+ CallableVertex source = graph .getEdgeSource (abstractGraphEdge );
230
+ CallableVertex target = graph .getEdgeTarget (abstractGraphEdge );
320
231
if (abstractGraphEdge instanceof CallEdge ) {
321
232
return new CallDependency (source , target , abstractGraphEdge );
322
233
} else {
0 commit comments