Skip to content

Commit 147e449

Browse files
authored
Merge pull request #14 from sinha108/main
Computation of cyclomatic complexity for callables
2 parents d15f332 + 58b8105 commit 147e449

File tree

4 files changed

+41
-9
lines changed

4 files changed

+41
-9
lines changed

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,7 @@ private static void analyze() throws IOException, ClassHierarchyException, CallG
112112
gson.toJson(symbolTableExtractionResult.getRight(), new FileWriter(new File(outputPath.toString(), "parse_errors.json")));
113113
}
114114

115-
// Convert the JavaCompilationUnit to JSON
116-
String symbolTableJSONString = gson.toJson(symbolTable);
117-
JsonElement symbolTableJSON = gson.fromJson(symbolTableJSONString, JsonElement.class);
118-
119115
JsonObject combinedJsonObject = new JsonObject();
120-
combinedJsonObject.add("symbol_table", symbolTableJSON);
121116
if (analysisLevel > 1) {
122117
// Save SDG, IPCFG, and Call graph as JSON
123118
// If noBuild is not true, and build is also not provided, we will use "auto" as the build command
@@ -138,6 +133,12 @@ private static void analyze() throws IOException, ClassHierarchyException, CallG
138133
combinedJsonObject.add("system_dependency_graph", edges);
139134

140135
}
136+
137+
// Convert the JavaCompilationUnit to JSON and add to consolidated json object
138+
String symbolTableJSONString = gson.toJson(symbolTable);
139+
JsonElement symbolTableJSON = gson.fromJson(symbolTableJSONString, JsonElement.class);
140+
combinedJsonObject.add("symbol_table", symbolTableJSON);
141+
141142
String consolidatedJSONString = gson.toJson(combinedJsonObject);
142143
emit(consolidatedJSONString);
143144
}

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

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,18 @@
1313

1414
package com.ibm.northstar;
1515

16+
import com.ibm.northstar.entities.AbstractGraphEdge;
17+
import com.ibm.northstar.entities.CallEdge;
18+
import com.ibm.northstar.entities.Callable;
19+
import com.ibm.northstar.entities.SystemDepEdge;
1620
import com.ibm.northstar.utils.AnalysisUtils;
1721
import com.ibm.northstar.utils.Log;
18-
import com.ibm.northstar.entities.*;
1922
import com.ibm.northstar.utils.ScopeUtils;
2023
import com.ibm.wala.cast.ir.ssa.AstIRFactory;
21-
import com.ibm.wala.cast.java.client.impl.ZeroCFABuilderFactory;
2224
import com.ibm.wala.cast.java.translator.jdt.ecj.ECJClassLoaderFactory;
2325
import com.ibm.wala.classLoader.CallSiteReference;
26+
import com.ibm.wala.classLoader.IClass;
27+
import com.ibm.wala.classLoader.IMethod;
2428
import com.ibm.wala.ipa.callgraph.*;
2529
import com.ibm.wala.ipa.callgraph.AnalysisOptions.ReflectionOptions;
2630
import com.ibm.wala.ipa.callgraph.impl.Util;
@@ -51,8 +55,7 @@
5155
import java.util.function.Supplier;
5256

5357
import static com.ibm.northstar.CodeAnalyzer.gson;
54-
import static com.ibm.northstar.utils.AnalysisUtils.getCallableFromSymbolTable;
55-
import static com.ibm.northstar.utils.AnalysisUtils.createAndPutNewCallableInSymbolTable;
58+
import static com.ibm.northstar.utils.AnalysisUtils.*;
5659

5760
/**
5861
* The type Sdg 2 json.
@@ -223,6 +226,18 @@ public static String construct(
223226
IAnalysisCacheView cache = new AnalysisCacheImpl(AstIRFactory.makeDefaultFactory(),
224227
options.getSSAOptions());
225228

229+
// set cyclomatic complexity for callables in the symbol table
230+
int numClasses = cha.getNumberOfClasses();
231+
for (Iterator<IClass> classIter = cha.iterator(); classIter.hasNext(); ) {
232+
IClass cls = classIter.next();
233+
for (IMethod method: cls.getAllMethods()) {
234+
Callable callable = getCallableFromSymbolTable(method).getRight();
235+
if (callable != null) {
236+
callable.setCyclomaticComplexity(getCyclomaticComplexity(cache.getIR(method)));
237+
}
238+
}
239+
}
240+
226241
// Build call graph
227242
Log.info("Building call graph.");
228243

src/main/java/com/ibm/northstar/entities/Callable.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ public class Callable {
2424
private List<String> calledMethodDeclaringTypes;
2525
private List<CallSite> callSites;
2626
private List<VariableDeclaration> variableDeclarations;
27+
private int cyclomaticComplexity;
2728
}

src/main/java/com/ibm/northstar/utils/AnalysisUtils.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import com.ibm.wala.ipa.callgraph.Entrypoint;
2323
import com.ibm.wala.ipa.callgraph.impl.DefaultEntrypoint;
2424
import com.ibm.wala.ipa.cha.IClassHierarchy;
25+
import com.ibm.wala.ssa.IR;
26+
import com.ibm.wala.ssa.SSAConditionalBranchInstruction;
2527
import com.ibm.wala.types.ClassLoaderReference;
2628

2729
import java.util.*;
@@ -77,6 +79,19 @@ public static Pair<String, Callable> createAndPutNewCallableInSymbolTable(IMetho
7779
return Pair.of(declaringClassSignature, newCallable);
7880
}
7981

82+
/**
83+
* Computes and returns cyclomatic complexity for the given IR (for a method or constructor).
84+
*
85+
* @param ir IR for method or constructor
86+
* @return int Cyclomatic complexity for method/constructor
87+
*/
88+
public static int getCyclomaticComplexity(IR ir) {
89+
int branchCount = (int)Arrays.stream(ir.getInstructions())
90+
.filter(inst -> inst instanceof SSAConditionalBranchInstruction)
91+
.count();
92+
return branchCount + 1;
93+
}
94+
8095
public static Pair<String, Callable> getCallableFromSymbolTable(IMethod method) {
8196

8297
// Get the class name, with a . representation.

0 commit comments

Comments
 (0)