Skip to content

Commit 676e267

Browse files
authored
Merge pull request #130 from codellm-devkit/129-misnamed-key-in-analysisjson-out-remove-system_dependency_graph-from-the-output-and-save-only-the-call_graph
Remove `"system_dependency_graph"` key from `analysis.json`
2 parents 6cb594b + dcdeb2c commit 676e267

File tree

5 files changed

+14
-105
lines changed

5 files changed

+14
-105
lines changed

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version=2.3.0
1+
version=2.3.1

src/main/java/com/ibm/cldk/CodeAnalyzer.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ public class CodeAnalyzer implements Runnable {
8686
public static String projectRootPom;
8787

8888
@Option(names = { "-a",
89-
"--analysis-level" }, description = "Level of analysis to perform. Options: 1 (for just symbol table) or 2 (for call graph). Default: 1")
90-
private static int analysisLevel = 1;
89+
"--analysis-level" }, description = "Level of analysis to perform. Options: 1 (for just symbol table); 2 (for call graph). Default: 1")
90+
public static int analysisLevel = 1;
9191

9292
@Option(names = { "--include-test-classes" }, hidden = true, description = "Print logs to console.")
9393
public static boolean includeTestClasses = false;
@@ -209,7 +209,7 @@ private static void analyze() throws Exception {
209209
// Is noBuild is true, we will not build the project
210210
build = noBuild ? null : build;
211211
List<Dependency> sdgEdges = SystemDependencyGraph.construct(input, dependencies, build);
212-
combinedJsonObject.add("system_dependency_graph", gson.toJsonTree(sdgEdges));
212+
combinedJsonObject.add("call_graph", gson.toJsonTree(sdgEdges));
213213
}
214214
}
215215
// Cleanup library dependencies directory

src/main/java/com/ibm/cldk/SymbolTable.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@
7171
import com.ibm.cldk.javaee.utils.enums.CRUDOperationType;
7272
import com.ibm.cldk.javaee.utils.enums.CRUDQueryType;
7373
import com.ibm.cldk.utils.Log;
74-
import org.jetbrains.annotations.NotNull;
7574

7675
@SuppressWarnings("rawtypes")
7776
public class SymbolTable {
@@ -241,7 +240,6 @@ private static JavaCompilationUnit processCompilationUnit(CompilationUnit parseR
241240
} else {
242241
// TODO: handle AnnotationDeclaration, RecordDeclaration
243242
// set the common type attributes only
244-
Log.warn("Found unsupported type declaration: " + typeDecl.toString());
245243
typeNode = new com.ibm.cldk.entities.Type();
246244
}
247245

src/main/java/com/ibm/cldk/SystemDependencyGraph.java

Lines changed: 8 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import java.util.function.Supplier;
5353
import java.util.stream.Collectors;
5454

55+
import static com.ibm.cldk.CodeAnalyzer.analysisLevel;
5556
import 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 {

src/test/java/com/ibm/cldk/CodeAnalyzerIntegrationTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ void callGraphShouldHaveKnownEdges() throws Exception {
143143
// Read the output JSON
144144
Gson gson = new Gson();
145145
JsonObject jsonObject = gson.fromJson(runCodeAnalyzerOnCallGraphTest.getStdout(), JsonObject.class);
146-
JsonArray systemDepGraph = jsonObject.getAsJsonArray("system_dependency_graph");
147-
Assertions.assertTrue(StreamSupport.stream(systemDepGraph.spliterator(), false)
146+
JsonArray callGraph = jsonObject.getAsJsonArray("call_graph");
147+
Assertions.assertTrue(StreamSupport.stream(callGraph.spliterator(), false)
148148
.map(JsonElement::getAsJsonObject)
149149
.anyMatch(entry ->
150150
"CALL_DEP".equals(entry.get("type").getAsString()) &&

0 commit comments

Comments
 (0)