Skip to content

Remove "system_dependency_graph" key from analysis.json #130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version=2.3.0
version=2.3.1
6 changes: 3 additions & 3 deletions src/main/java/com/ibm/cldk/CodeAnalyzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ public class CodeAnalyzer implements Runnable {
public static String projectRootPom;

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

@Option(names = { "--include-test-classes" }, hidden = true, description = "Print logs to console.")
public static boolean includeTestClasses = false;
Expand Down Expand Up @@ -209,7 +209,7 @@ private static void analyze() throws Exception {
// Is noBuild is true, we will not build the project
build = noBuild ? null : build;
List<Dependency> sdgEdges = SystemDependencyGraph.construct(input, dependencies, build);
combinedJsonObject.add("system_dependency_graph", gson.toJsonTree(sdgEdges));
combinedJsonObject.add("call_graph", gson.toJsonTree(sdgEdges));
}
}
// Cleanup library dependencies directory
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/com/ibm/cldk/SymbolTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@
import com.ibm.cldk.javaee.utils.enums.CRUDOperationType;
import com.ibm.cldk.javaee.utils.enums.CRUDQueryType;
import com.ibm.cldk.utils.Log;
import org.jetbrains.annotations.NotNull;

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

Expand Down
105 changes: 8 additions & 97 deletions src/main/java/com/ibm/cldk/SystemDependencyGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import java.util.function.Supplier;
import java.util.stream.Collectors;

import static com.ibm.cldk.CodeAnalyzer.analysisLevel;
import static com.ibm.cldk.utils.AnalysisUtils.*;


Expand Down Expand Up @@ -114,76 +115,13 @@ private static JSONExporter<CallableVertex, AbstractGraphEdge> getGraphExporter(
/**
* Convert SDG to a formal Graph representation.
*
* @param entryPoints
* @param sdg
* @param callGraph
* @param edgeLabels
* @return
*/
private static org.jgrapht.Graph<CallableVertex, AbstractGraphEdge> buildGraph(
Supplier<Iterator<Statement>> entryPoints,
Graph<Statement> sdg, CallGraph callGraph,
BiFunction<Statement, Statement, String> edgeLabels) {
private static org.jgrapht.Graph<CallableVertex, AbstractGraphEdge> buildOnlyCallGraph(CallGraph callGraph) {

org.jgrapht.Graph<CallableVertex, AbstractGraphEdge> graph = new DefaultDirectedGraph<>(
AbstractGraphEdge.class);

// We'll use forward and backward search on the DFS to identify which CFG nodes
// are dominant
// This is a forward DFS search (or exit time first search)
int dfsNumber = 0;
Map<Statement, Integer> dfsFinish = HashMapFactory.make();
Iterator<Statement> search = DFS.iterateFinishTime(sdg, entryPoints.get());

while (search.hasNext()) {
dfsFinish.put(search.next(), dfsNumber++);
}

// This is a reverse DFS search (or entry time first search)
int reverseDfsNumber = 0;
Map<Statement, Integer> dfsStart = HashMapFactory.make();
Iterator<Statement> reverseSearch = DFS.iterateDiscoverTime(sdg, entryPoints.get());

while (reverseSearch.hasNext()) {
dfsStart.put(reverseSearch.next(), reverseDfsNumber++);
}

// Populate graph
sdg.stream()
.filter(dfsFinish::containsKey)
.sorted(Comparator.comparingInt(dfsFinish::get))
.forEach(p -> sdg.getSuccNodes(p).forEachRemaining(s -> {
if (dfsFinish.containsKey(s)
&& dfsStart.get(p) != null && dfsStart.get(s) != null
&& !((dfsStart.get(p) >= dfsStart.get(s))
&& (dfsFinish.get(p) <= dfsFinish.get(s)))
&& !p.getNode().getMethod().equals(s.getNode().getMethod())) {

// Add the source nodes to the graph as vertices
Map<String, String> source = Optional.ofNullable(getCallableFromSymbolTable(p.getNode().getMethod())).orElseGet(() -> createAndPutNewCallableInSymbolTable(p.getNode().getMethod()));
// Add the target nodes to the graph as vertices
Map<String, String> target = Optional.ofNullable(getCallableFromSymbolTable(s.getNode().getMethod())).orElseGet(() -> createAndPutNewCallableInSymbolTable(s.getNode().getMethod()));

if (source != null && target != null) {
CallableVertex source_vertex = new CallableVertex(source);
CallableVertex target_vertex = new CallableVertex(target);
graph.addVertex(source_vertex);
graph.addVertex(target_vertex);
String edgeType = edgeLabels.apply(p, s);
SystemDepEdge graphEdge = new SystemDepEdge(p, s, edgeType);
SystemDepEdge cgEdge = (SystemDepEdge) graph.getEdge(source_vertex, target_vertex);
if (cgEdge == null || !cgEdge.equals(graphEdge)) {
graph.addEdge(
source_vertex,
target_vertex,
graphEdge);
} else {
graphEdge.incrementWeight();
}
}
}
}));

callGraph.getEntrypointNodes()
.forEach(p -> {
// Get call statements that may execute in a given method
Expand Down Expand Up @@ -264,7 +202,6 @@ public static List<Dependency> construct(
try {
System.setOut(new PrintStream(NullOutputStream.INSTANCE));
System.setErr(new PrintStream(NullOutputStream.INSTANCE));
// builder = Util.makeRTABuilder(new JavaLanguage(), options, cache, cha);
builder = Util.makeRTABuilder(options, cache, cha);
callGraph = builder.makeCallGraph(options, null);
} finally {
Expand All @@ -283,40 +220,14 @@ public static List<Dependency> construct(
}
});

org.jgrapht.Graph<CallableVertex, AbstractGraphEdge> graph;

graph = buildOnlyCallGraph(callGraph);

// Build SDG graph
Log.info("Building System Dependency Graph.");
SDG<? extends InstanceKey> sdg = new SDG<>(
callGraph,
builder.getPointerAnalysis(),
new ModRef<>(),
Slicer.DataDependenceOptions.NO_HEAP_NO_EXCEPTIONS,
Slicer.ControlDependenceOptions.NO_EXCEPTIONAL_EDGES);

// Prune the Graph to keep only application classes.
Graph<Statement> prunedGraph = GraphSlicer.prune(sdg,
statement -> (statement.getNode()
.getMethod()
.getDeclaringClass()
.getClassLoader()
.getReference()
.equals(ClassLoaderReference.Application))
);

// A supplier to get entries
Supplier<Iterator<Statement>> sdgEntryPointsSupplier = () -> callGraph.getEntrypointNodes().stream()
.map(n -> (Statement) new MethodEntryStatement(n)).iterator();

org.jgrapht.Graph<CallableVertex, AbstractGraphEdge> sdgGraph = buildGraph(
sdgEntryPointsSupplier,
prunedGraph, callGraph,
(p, s) -> String.valueOf(sdg.getEdgeLabels(p, s).iterator().next())
);

List<Dependency> edges = sdgGraph.edgeSet().stream()
List<Dependency> edges = graph.edgeSet().stream()
.map(abstractGraphEdge -> {
CallableVertex source = sdgGraph.getEdgeSource(abstractGraphEdge);
CallableVertex target = sdgGraph.getEdgeTarget(abstractGraphEdge);
CallableVertex source = graph.getEdgeSource(abstractGraphEdge);
CallableVertex target = graph.getEdgeTarget(abstractGraphEdge);
if (abstractGraphEdge instanceof CallEdge) {
return new CallDependency(source, target, abstractGraphEdge);
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/com/ibm/cldk/CodeAnalyzerIntegrationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ void callGraphShouldHaveKnownEdges() throws Exception {
// Read the output JSON
Gson gson = new Gson();
JsonObject jsonObject = gson.fromJson(runCodeAnalyzerOnCallGraphTest.getStdout(), JsonObject.class);
JsonArray systemDepGraph = jsonObject.getAsJsonArray("system_dependency_graph");
Assertions.assertTrue(StreamSupport.stream(systemDepGraph.spliterator(), false)
JsonArray callGraph = jsonObject.getAsJsonArray("call_graph");
Assertions.assertTrue(StreamSupport.stream(callGraph.spliterator(), false)
.map(JsonElement::getAsJsonObject)
.anyMatch(entry ->
"CALL_DEP".equals(entry.get("type").getAsString()) &&
Expand Down