5252import java .util .function .Supplier ;
5353import java .util .stream .Collectors ;
5454
55+ import static com .ibm .cldk .CodeAnalyzer .analysisLevel ;
5556import static com .ibm .cldk .utils .AnalysisUtils .*;
5657
5758
@@ -114,76 +115,13 @@ private static JSONExporter<CallableVertex, AbstractGraphEdge> getGraphExporter(
114115 /**
115116 * Convert SDG to a formal Graph representation.
116117 *
117- * @param entryPoints
118- * @param sdg
119118 * @param callGraph
120- * @param edgeLabels
121119 * @return
122120 */
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 ) {
127122
128123 org .jgrapht .Graph <CallableVertex , AbstractGraphEdge > graph = new DefaultDirectedGraph <>(
129124 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-
187125 callGraph .getEntrypointNodes ()
188126 .forEach (p -> {
189127 // Get call statements that may execute in a given method
@@ -264,7 +202,6 @@ public static List<Dependency> construct(
264202 try {
265203 System .setOut (new PrintStream (NullOutputStream .INSTANCE ));
266204 System .setErr (new PrintStream (NullOutputStream .INSTANCE ));
267- // builder = Util.makeRTABuilder(new JavaLanguage(), options, cache, cha);
268205 builder = Util .makeRTABuilder (options , cache , cha );
269206 callGraph = builder .makeCallGraph (options , null );
270207 } finally {
@@ -283,40 +220,14 @@ public static List<Dependency> construct(
283220 }
284221 });
285222
223+ org .jgrapht .Graph <CallableVertex , AbstractGraphEdge > graph ;
224+
225+ graph = buildOnlyCallGraph (callGraph );
286226
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 ()
317228 .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 );
320231 if (abstractGraphEdge instanceof CallEdge ) {
321232 return new CallDependency (source , target , abstractGraphEdge );
322233 } else {
0 commit comments