Skip to content
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

Merge 1.X.X to 2.0 as new version 2.1.0 #98

Closed
wants to merge 57 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
a15f700
Fixes for issues 61, 62, and 64. New patch marked version v1.0.2.
rahlk Nov 5, 2024
29fd643
Update main.yml
rahlk Nov 5, 2024
3e73301
Update main.yml
rahlk Nov 5, 2024
61fc5b8
Update main.yml
rahlk Nov 7, 2024
27c09f9
Add root pom path to the CLI
rahlk Nov 7, 2024
ffdef39
Add root pom path to the CLI
rahlk Nov 7, 2024
7a4fb10
Merge pull request #68 from IBM/remove-no-copy-deps-and-add-path-to-r…
rahlk Nov 7, 2024
bb56aca
Merge pull request #67 from IBM/mark-a-release-on-1.X.X
rahlk Nov 7, 2024
934a54f
Add root pom path to the CLI
rahlk Nov 7, 2024
1acec4a
Add root pom path to the CLI
rahlk Nov 7, 2024
7d740b9
Add root pom path to the CLI
rahlk Nov 7, 2024
0925555
mvnw now looks for absolute path
rahlk Nov 11, 2024
bb3b2b6
Merge pull request #71 from IBM/1.0.4
rahlk Nov 11, 2024
b9d53a9
Upgrade to WALA 1.6.7
rahlk Nov 11, 2024
17a3bff
Merge pull request #72 from IBM/1.0.4
rahlk Nov 11, 2024
21ef81a
mvn.bat -> mvn.cmd
rahlk Nov 13, 2024
75944f1
Merge pull request #75 from IBM/1.0.5
rahlk Nov 13, 2024
ff079c5
Fix issue 76--symbol table is none.
rahlk Nov 19, 2024
1c07358
Merge pull request #77 from IBM/1.0.6
rahlk Nov 19, 2024
7b7a451
Bump version to 1.0.6
rahlk Nov 19, 2024
9946546
Fix issue #79
rahlk Dec 3, 2024
b32343b
Merge pull request #80 from IBM/1.0.7-dev
rahlk Dec 3, 2024
e311d96
Fix issue #79
rahlk Dec 3, 2024
42caced
Merge branch '1.X.X' into 1.0.7
rahlk Dec 3, 2024
cb285fa
Merge pull request #81 from IBM/1.0.7
rahlk Dec 3, 2024
1ad2b92
Fix issue #83
rahlk Dec 12, 2024
392d12a
Cyclomatic complexity computation for analysis level 1
sinha108 Jan 13, 2025
ebe64b6
Added catch clause count to computation of cyclomatic complexity for …
sinha108 Jan 13, 2025
83d55e0
Clean up callable declaration string to remove embedded comments.
sinha108 Jan 15, 2025
5d14706
Fixing issue 87 with maven wrapper
rahlk Jan 15, 2025
f30e384
Fixing issue 87 with maven wrapper
rahlk Jan 15, 2025
8253562
Merge pull request #89 from IBM/cyclomatic-complexity-analysis-level1
rahlk Jan 15, 2025
6e745c4
Fixing issue 87 with maven wrapper
rahlk Jan 15, 2025
93e5efb
Fixing issue 87 with maven wrapper
rahlk Jan 15, 2025
0dcde52
Fixing issue 87 with maven wrapper
rahlk Jan 15, 2025
ff1184b
Throw a more discriptive error message when build commands fail.
rahlk Jan 17, 2025
8bdbace
Merge pull request #92 from IBM/fix-issue-87
rahlk Jan 18, 2025
e94761f
Don't fail on build errors during download dependencies phase
rahlk Jan 20, 2025
65ebcf2
Merge pull request #94 from IBM/feature-request-on-issue-93
rahlk Jan 20, 2025
10b48d8
Update command checker to proactively set maven/gradle. Update make -…
rahlk Jan 21, 2025
3433add
Add more test cases
rahlk Jan 21, 2025
5a4ea53
Add more test cases
rahlk Jan 21, 2025
a790730
Update command checker to proactively set maven/gradle. Update make -…
rahlk Jan 21, 2025
7b38a27
Update command checker to proactively set maven/gradle. Update make -…
rahlk Jan 21, 2025
98ea868
Add Integration Tests to replicate behaviour.
rahlk Jan 22, 2025
2310996
Add Integration Tests to replicate behaviour.
rahlk Jan 22, 2025
c3bbc67
Refactor Integration Tests.
rahlk Jan 23, 2025
69c2067
Refactor Integration Tests.
rahlk Jan 23, 2025
5355c2f
Fixed failing Integration tests
rahlk Jan 24, 2025
575f6a7
Enhance the lookup for jmods folder. We now use a recursive folder se…
rahlk Jan 24, 2025
2abc7d8
Merge pull request #96 from IBM/fix-issue-95
rofrano Jan 24, 2025
5cf8398
Set Java version to 11
rahlk Jan 24, 2025
6180850
Attempt fix for issue 74 by moving dowloaded dependencies to the proj…
rahlk Jan 31, 2025
231e40a
Attempt fix for issue 74 by moving dowloaded dependencies to the proj…
rahlk Jan 31, 2025
86c5bca
Update quickstart example with a bug fix.
rahlk Feb 3, 2025
412d3d4
Merge pull request #99 from IBM/fix-issue-74
rahlk Feb 3, 2025
1af764f
Remove dangling file
rahlk Feb 3, 2025
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
3 changes: 2 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Codeanalyzer CI
on:
push:
branches:
- main
- 1.X.X

permissions:
contents: write
Expand Down Expand Up @@ -53,5 +53,6 @@ jobs:
with:
files: build/libs/*.jar
tag_name: ${{ steps.newtag.outputs.tag }}
prerelease: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24 changes: 23 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ repositories {
mavenLocal()
}

java {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}

if (project.hasProperty('mainClass')) {
mainClassName = project.getProperty('mainClass')
Expand Down Expand Up @@ -119,7 +123,25 @@ dependencies {
implementation('org.jgrapht:jgrapht-ext:1.5.2')
implementation('com.github.javaparser:javaparser-symbol-solver-core:3.25.9')

testImplementation group: 'junit', name: 'junit', version: '4.13.2'
// TestContainers
testImplementation 'org.testcontainers:testcontainers:1.19.3'
testImplementation 'org.testcontainers:junit-jupiter:1.19.3'

// JUnit 5
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.1'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.10.1' // for @ParameterizedTest
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.1'

// SLF4J - for TestContainers logging
testImplementation 'org.slf4j:slf4j-api:2.0.9'
testImplementation 'org.slf4j:slf4j-simple:2.0.9'

}

test {
useJUnitPlatform()
// Optional: Enable TestContainers reuse to speed up tests
systemProperty 'testcontainers.reuse.enable', 'true'
}

task fatJar(type: Jar) {
Expand Down
7 changes: 6 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
version=1.1.0
<<<<<<< HEAD
version=1.1.1

=======
version=1.1.0
>>>>>>> 9792b653d3b4509e5b74120747e13e69417da994
20 changes: 13 additions & 7 deletions src/main/java/com/ibm/cldk/CodeAnalyzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
import com.ibm.cldk.entities.JavaCompilationUnit;
import com.ibm.cldk.utils.BuildProject;
import com.ibm.cldk.utils.Log;
import com.ibm.wala.ipa.callgraph.CallGraphBuilderCancelException;
import com.ibm.wala.ipa.cha.ClassHierarchyException;
import org.apache.commons.lang3.tuple.Pair;
import picocli.CommandLine;
import picocli.CommandLine.Command;
Expand All @@ -40,7 +38,7 @@


class VersionProvider implements CommandLine.IVersionProvider {
public String[] getVersion() throws Exception {
public String[] getVersion() {
String version = getClass().getPackage().getImplementationVersion();
return new String[]{ version != null ? version : "unknown" };
}
Expand Down Expand Up @@ -69,13 +67,18 @@ public class CodeAnalyzer implements Runnable {
@Option(names = {"--no-build"}, description = "Do not build your application. Use this option if you have already built your application.")
private static boolean noBuild = false;

@Option(names = {"-f", "--project-root-path"}, description = "Path to the root pom.xml/build.gradle file of the project.")
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;

@Option(names = {"-v", "--verbose"}, description = "Print logs to console.")
private static boolean verbose = false;

@Option(names = {"--no-clean-dependencies"}, description = "Do not attempt to auto-clean dependencies")
public static boolean noCleanDependencies = false;

private static final String outputFileName = "analysis.json";

public static Gson gson = new GsonBuilder()
Expand Down Expand Up @@ -108,22 +111,25 @@ private static void analyze() throws Exception {

JsonObject combinedJsonObject = new JsonObject();
Map<String, JavaCompilationUnit> symbolTable;
projectRootPom = projectRootPom == null ? input : projectRootPom;
// First of all if, sourceAnalysis is provided, we will analyze the source code instead of the project.
if (sourceAnalysis != null) {
// Construct symbol table for source code
Log.debug("Single file analysis.");
Pair<Map<String, JavaCompilationUnit>, Map<String, List<Problem>>> symbolTableExtractionResult = SymbolTable.extractSingle(sourceAnalysis);
symbolTable = symbolTableExtractionResult.getLeft();
}

else {
} else {
// download library dependencies of project for type resolution
String dependencies = null;
if (BuildProject.downloadLibraryDependencies(input)) {
try {if (BuildProject.downloadLibraryDependencies(input, projectRootPom)) {
dependencies = String.valueOf(BuildProject.libDownloadPath);
} else {
Log.warn("Failed to download library dependencies of project");
}
} catch (IllegalStateException illegalStateException) {
Log.warn("Failed to download library dependencies of project");
}

boolean analysisFileExists = output != null && Files.exists(Paths.get(output + File.separator + outputFileName));

// if target files are specified, compute symbol table information for the given files
Expand Down
27 changes: 25 additions & 2 deletions src/main/java/com/ibm/cldk/SymbolTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import com.github.javaparser.ast.body.*;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.nodeTypes.NodeWithName;
import com.github.javaparser.ast.stmt.BlockStmt;
import com.github.javaparser.ast.stmt.*;
import com.github.javaparser.ast.type.ReferenceType;
import com.github.javaparser.ast.type.Type;
import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
Expand Down Expand Up @@ -276,7 +276,9 @@ private static Pair<String, Callable> processCallableDeclaration(CallableDeclara

// add the complete declaration string, including modifiers, throws, and
// parameter names
callableNode.setDeclaration(callableDecl.getDeclarationAsString(true, true, true).strip());
callableNode.setDeclaration(callableDecl
.getDeclarationAsString(true, true, true)
.strip().replaceAll("//.*\n", ""));

// add information about callable parameters: for each parameter, type, name,
// annotations,
Expand Down Expand Up @@ -304,11 +306,32 @@ private static Pair<String, Callable> processCallableDeclaration(CallableDeclara
callableNode.setAccessedFields(getAccessedFields(body, classFields, typeName));
callableNode.setCallSites(getCallSites(body));
callableNode.setVariableDeclarations(getVariableDeclarations(body));
callableNode.setCyclomaticComplexity(getCyclomaticComplexity(callableDecl));

String callableSignature = (callableDecl instanceof MethodDeclaration) ? callableDecl.getSignature().asString() : callableDecl.getSignature().asString().replace(callableDecl.getSignature().getName(), "<init>");
return Pair.of(callableSignature, callableNode);
}

/**
* Computes cyclomatic complexity for the given callable.
*
* @param callableDeclaration Callable to compute cyclomatic complexity for
* @return cyclomatic complexity
*/
private static int getCyclomaticComplexity(CallableDeclaration callableDeclaration) {
int ifStmtCount = callableDeclaration.findAll(IfStmt.class).size();
int loopStmtCount = callableDeclaration.findAll(DoStmt.class).size() +
callableDeclaration.findAll(ForStmt.class).size() +
callableDeclaration.findAll(ForEachStmt.class).size() +
callableDeclaration.findAll(WhileStmt.class).size();
int switchCaseCount = callableDeclaration.findAll(SwitchStmt.class).stream()
.map(stmt -> stmt.getEntries().size())
.reduce(0, Integer::sum);
int conditionalExprCount = callableDeclaration.findAll(ConditionalExpr.class).size();
int catchClauseCount = callableDeclaration.findAll(CatchClause.class).size();
return ifStmtCount + loopStmtCount + switchCaseCount + conditionalExprCount + catchClauseCount + 1;
}

/**
* Processes the given field declaration to extract information about the
* declared field and
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/ibm/cldk/SystemDependencyGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ public static List<Dependency> construct(

// Initialize scope
AnalysisScope scope = ScopeUtils.createScope(input, dependencies, build);
IClassHierarchy cha = ClassHierarchyFactory.make(scope,
IClassHierarchy cha = ClassHierarchyFactory.makeWithRoot(scope,
new ECJClassLoaderFactory(scope.getExclusions()));
Log.done("There were a total of " + cha.getNumberOfClasses() + " classes of which "
+ AnalysisUtils.getNumberOfApplicationClasses(cha) + " are application classes.");
Expand Down
20 changes: 16 additions & 4 deletions src/main/java/com/ibm/cldk/utils/AnalysisUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
import com.ibm.wala.ipa.callgraph.impl.DefaultEntrypoint;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAConditionalBranchInstruction;
import com.ibm.wala.ssa.SSASwitchInstruction;
import com.ibm.wala.types.ClassLoaderReference;

import java.util.*;
Expand Down Expand Up @@ -99,10 +101,20 @@ public static Map<String, String> createAndPutNewCallableInSymbolTable(IMethod m
* @return int Cyclomatic complexity for method/constructor
*/
public static int getCyclomaticComplexity(IR ir) {
int branchCount = (int)Arrays.stream(ir.getInstructions())
.filter(inst -> inst instanceof SSAConditionalBranchInstruction)
.count();
return branchCount + 1;
if (ir == null) {
return 0;
}
int conditionalBranchCount = (int) Arrays.stream(ir.getInstructions())
.filter(inst -> inst instanceof SSAConditionalBranchInstruction)
.count();
int switchBranchCount = Arrays.stream(ir.getInstructions())
.filter(inst -> inst instanceof SSASwitchInstruction)
.map(inst -> ((SSASwitchInstruction) inst).getCasesAndLabels().length).reduce(0, Integer::sum);
Iterable<ISSABasicBlock> iterableBasicBlocks = ir::getBlocks;
int catchBlockCount = (int) StreamSupport.stream(iterableBasicBlocks.spliterator(), false)
.filter(ISSABasicBlock::isCatchBlock)
.count();
return conditionalBranchCount + switchBranchCount + catchBlockCount + 1;
}

public static void setCyclomaticComplexity(CallGraph callGraph) {
Expand Down
Loading
Loading