Skip to content

Commit

Permalink
Remove dangling file
Browse files Browse the repository at this point in the history
Signed-off-by: Rahul Krishna <[email protected]>
  • Loading branch information
rahlk committed Feb 3, 2025
2 parents 412d3d4 + 9792b65 commit 1af764f
Show file tree
Hide file tree
Showing 15 changed files with 352 additions and 93 deletions.
43 changes: 43 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

### Describe the bug

A clear and concise description of what the bug is.

### Steps To Reproduce

Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

### Observed behavior

Describe what you saw and why you think it's a bug?

### Expected behavior

A clear and concise description of what you expected to happen.

### Screenshots

If applicable, add screenshots to help explain your problem.

### Environment (please complete the following information):

- OS: [e.g. macOS 15.1 | Windows 11]
- Version of Java
- Version of Maven
- Version of Gradle

### Additional context

Add any other context about the problem here.
24 changes: 24 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

### Is your feature request related to a problem? Please describe

A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

### Describe the solution you'd like

A clear and concise description of what you want to happen.

### Describe alternatives you've considered

A clear and concise description of any alternative solutions or features you've considered.

### Additional context

Add any other context or screenshots about the feature request here.
26 changes: 26 additions & 0 deletions .github/ISSUE_TEMPLATE/user_story.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
name: User Story
about: Use this for creating User Stories
title: ''
labels: ''
assignees: ''

---

### Feature

**As a** [role]
**I need** [functionality]
**So that** [benefit]

### Details & Assumptions

- document what you know here...

### Acceptance Criteria

```gherkin
Given [some initial state]
When [some event]
Then [some measurable outcome]
```
4 changes: 4 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
<<<<<<< HEAD
version=1.1.1

=======
version=1.1.0
>>>>>>> 9792b653d3b4509e5b74120747e13e69417da994
13 changes: 2 additions & 11 deletions src/main/java/com/ibm/cldk/CodeAnalyzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -180,17 +180,8 @@ private static void analyze() throws Exception {
build = build == null ? "auto" : build;
// Is noBuild is true, we will not build the project
build = noBuild ? null : build;
String sdgAsJSONString = SystemDependencyGraph.construct(input, dependencies, build);
JsonElement sdgAsJSONElement = gson.fromJson(sdgAsJSONString, JsonElement.class);
JsonObject sdgAsJSONObject = sdgAsJSONElement.getAsJsonObject();
JsonElement edges = sdgAsJSONObject.get("edges");

// We don't really need these fields, so we'll remove it.
sdgAsJSONObject.remove("nodes");
sdgAsJSONObject.remove("creator");
sdgAsJSONObject.remove("version");
// Remove the 'edges' element and move the list of edges up one level
combinedJsonObject.add("system_dependency_graph", edges);
List<Dependency> sdgEdges = SystemDependencyGraph.construct(input, dependencies, build);
combinedJsonObject.add("system_dependency_graph", gson.toJsonTree(sdgEdges));
}
}
// Cleanup library dependencies directory
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/com/ibm/cldk/SymbolTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ private static JavaCompilationUnit processCompilationUnit(CompilationUnit parseR
typeNode.setCallableDeclarations(typeDecl.findAll(CallableDeclaration.class).stream()
.filter(c -> c.getParentNode().isPresent() && c.getParentNode().get() == typeDecl)
.map(meth -> {
Pair<String, Callable> callableDeclaration = processCallableDeclaration(meth, fieldNames, typeName);
Pair<String, Callable> callableDeclaration = processCallableDeclaration(meth, fieldNames, typeName, parseResult.getStorage().map(s -> s.getPath().toString()).orElse("<in-memory>"));
declaredMethodsAndConstructors.put(typeName, callableDeclaration.getLeft(), callableDeclaration.getRight());
return callableDeclaration;
}).collect(Collectors.toMap(p -> p.getLeft(), p -> p.getRight())));
Expand Down Expand Up @@ -249,9 +249,12 @@ private static ParameterInCallable processParameterDeclaration(Parameter paramDe
*/
@SuppressWarnings("unchecked")
private static Pair<String, Callable> processCallableDeclaration(CallableDeclaration callableDecl,
List<String> classFields, String typeName) {
List<String> classFields, String typeName, String filePath) {
Callable callableNode = new Callable();

// Set file path
callableNode.setFilePath(filePath);

// add callable signature
callableNode.setSignature(callableDecl.getSignature().asString());

Expand Down
148 changes: 93 additions & 55 deletions src/main/java/com/ibm/cldk/SystemDependencyGraph.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

import com.ibm.cldk.entities.AbstractGraphEdge;
import com.ibm.cldk.entities.CallEdge;
import com.ibm.cldk.entities.Callable;
import com.ibm.cldk.entities.CallableVertex;
import com.ibm.cldk.entities.SystemDepEdge;
import com.ibm.cldk.utils.AnalysisUtils;
import com.ibm.cldk.utils.Log;
Expand All @@ -40,20 +40,60 @@
import com.ibm.wala.util.graph.Graph;
import com.ibm.wala.util.graph.GraphSlicer;
import com.ibm.wala.util.graph.traverse.DFS;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.io.output.NullOutputStream;
import org.apache.commons.lang3.tuple.Pair;
import org.jgrapht.graph.DefaultDirectedGraph;
import org.jgrapht.nio.json.JSONExporter;

import java.io.IOException;
import java.io.PrintStream;
import java.io.StringWriter;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Supplier;

import static com.ibm.cldk.CodeAnalyzer.gson;
import static com.ibm.cldk.utils.AnalysisUtils.*;
import java.util.stream.Collectors;

import static com.ibm.cldk.utils.AnalysisUtils.createAndPutNewCallableInSymbolTable;
import static com.ibm.cldk.utils.AnalysisUtils.getCallableFromSymbolTable;


@Data
abstract class Dependency {
public CallableVertex source;
public CallableVertex target;
}

@Data
@EqualsAndHashCode(callSuper = true)
class SDGDependency extends Dependency {
public String sourceKind;
public String destinationKind;
public String type;
public String weight;

public SDGDependency(CallableVertex source, CallableVertex target, SystemDepEdge edge) {
super.source = source;
super.target = target;
this.sourceKind = edge.getSourceKind();
this.destinationKind = edge.getDestinationKind();
this.type = edge.getType();
this.weight = String.valueOf(edge.getWeight());
}
}

@Data
@EqualsAndHashCode(callSuper = true)
class CallDependency extends Dependency {
public String type;
public String weight;

public CallDependency(CallableVertex source, CallableVertex target, AbstractGraphEdge edge) {
this.source = source;
this.target = target;
this.type = edge.toString();
this.weight = String.valueOf(edge.getWeight());
}
}

/**
* The type Sdg 2 json.
Expand All @@ -66,18 +106,10 @@ public class SystemDependencyGraph {
* @return the graph exporter
*/


private static JSONExporter<Pair<String, Callable>, AbstractGraphEdge> getGraphExporter() {
JSONExporter<Pair<String, Callable>, AbstractGraphEdge> exporter = new JSONExporter<>(
pair -> {
Map <String, String> vertex = new HashMap<>();
vertex.put("class_interface_declarations", pair.getLeft());
vertex.put("callable", gson.toJson(pair.getRight()));
return gson.toJson(vertex);
}
);
// exporter.setVertexAttributeProvider(v -> v.getRight().getAttributes());
private static JSONExporter<CallableVertex, AbstractGraphEdge> getGraphExporter() {
JSONExporter<CallableVertex, AbstractGraphEdge> exporter = new JSONExporter<>();
exporter.setEdgeAttributeProvider(AbstractGraphEdge::getAttributes);
exporter.setVertexAttributeProvider(CallableVertex::getAttributes);
return exporter;
}

Expand All @@ -90,12 +122,12 @@ private static JSONExporter<Pair<String, Callable>, AbstractGraphEdge> getGraphE
* @param edgeLabels
* @return
*/
private static org.jgrapht.Graph<Pair<String, Callable>, AbstractGraphEdge> buildGraph(
private static org.jgrapht.Graph<CallableVertex, AbstractGraphEdge> buildGraph(
Supplier<Iterator<Statement>> entryPoints,
Graph<Statement> sdg, CallGraph callGraph,
BiFunction<Statement, Statement, String> edgeLabels) {

org.jgrapht.Graph<Pair<String, Callable>, AbstractGraphEdge> graph = new DefaultDirectedGraph<>(
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
Expand Down Expand Up @@ -130,21 +162,22 @@ private static org.jgrapht.Graph<Pair<String, Callable>, AbstractGraphEdge> buil
&& !p.getNode().getMethod().equals(s.getNode().getMethod())) {

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

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

String edgeType = edgeLabels.apply(p, s);
SystemDepEdge graphEdge = new SystemDepEdge(p, s, edgeType);
SystemDepEdge cgEdge = (SystemDepEdge) graph.getEdge(source, target);
if (source.getRight() != null && target.getRight() != null) {
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,
target,
source_vertex,
target_vertex,
graphEdge);
} else {
graphEdge.incrementWeight();
Expand All @@ -163,21 +196,22 @@ private static org.jgrapht.Graph<Pair<String, Callable>, AbstractGraphEdge> buil
.forEach(o -> {

// Add the source nodes to the graph as vertices
Pair<String, Callable> source = Optional.ofNullable(getCallableFromSymbolTable(p.getMethod())).orElseGet(() -> createAndPutNewCallableInSymbolTable(p.getMethod()));
graph.addVertex(source);
Map<String, String> source = Optional.ofNullable(getCallableFromSymbolTable(p.getMethod())).orElseGet(() -> createAndPutNewCallableInSymbolTable(p.getMethod()));
CallableVertex source_vertex = new CallableVertex(source);

// Add the target nodes to the graph as vertices
Pair<String, Callable> target = Optional.ofNullable(getCallableFromSymbolTable(o.getMethod())).orElseGet(() -> createAndPutNewCallableInSymbolTable(o.getMethod()));
graph.addVertex(target);

if (!source.equals(target) && source.getRight() != null && target.getRight() != null) {
Map<String, String> target = Optional.ofNullable(getCallableFromSymbolTable(o.getMethod())).orElseGet(() -> createAndPutNewCallableInSymbolTable(o.getMethod()));
CallableVertex target_vertex = new CallableVertex(target);

if (!source.equals(target) && target != null) {
// Get the edge between the source and the target
AbstractGraphEdge cgEdge = graph.getEdge(source, target);
graph.addVertex(source_vertex);
graph.addVertex(target_vertex);
AbstractGraphEdge cgEdge = graph.getEdge(source_vertex, target_vertex);
if (cgEdge instanceof CallEdge) {
((CallEdge) cgEdge).incrementWeight();
} else {
graph.addEdge(source, target, new CallEdge());
graph.addEdge(source_vertex, target_vertex, new CallEdge());
}
}
});
Expand All @@ -192,15 +226,15 @@ private static org.jgrapht.Graph<Pair<String, Callable>, AbstractGraphEdge> buil
*
* @param input the input
* @param dependencies the dependencies
* @param build The build options
* @param build The build options
* @return A List of triples containing the source, destination, and edge type
* @throws IOException the io exception
* @throws ClassHierarchyException the class hierarchy exception
* @throws IllegalArgumentException the illegal argument exception
* @throws CallGraphBuilderCancelException the call graph builder cancel
* exception
*/
public static String construct(
public static List<Dependency> construct(
String input, String dependencies, String build)
throws IOException, ClassHierarchyException, IllegalArgumentException, CallGraphBuilderCancelException {

Expand Down Expand Up @@ -243,12 +277,7 @@ public static String construct(
+ Math.ceil((double) (System.currentTimeMillis() - start_time) / 1000) + " seconds.");

// set cyclomatic complexity for callables in the symbol table
callGraph.forEach(cgNode -> {
Callable callable = getCallableFromSymbolTable(cgNode.getMethod()).getRight();
if (callable != null) {
callable.setCyclomaticComplexity(getCyclomaticComplexity(cgNode.getIR()));
}
});
AnalysisUtils.setCyclomaticComplexity(callGraph);

// Build SDG graph
Log.info("Building System Dependency Graph.");
Expand All @@ -266,22 +295,31 @@ public static String construct(
.getDeclaringClass()
.getClassLoader()
.getReference()
.equals(ClassLoaderReference.Application)));
.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<Pair<String, Callable>, AbstractGraphEdge> sdgGraph = buildGraph(
org.jgrapht.Graph<CallableVertex, AbstractGraphEdge> sdgGraph = buildGraph(
sdgEntryPointsSupplier,
prunedGraph, callGraph,
(p, s) -> String.valueOf(sdg.getEdgeLabels(p, s).iterator().next()));

JSONExporter<Pair<String, Callable>, AbstractGraphEdge> graphExporter = getGraphExporter();
(p, s) -> String.valueOf(sdg.getEdgeLabels(p, s).iterator().next())
);

StringWriter sdgWriter = new StringWriter();
graphExporter.exportGraph(sdgGraph, sdgWriter);
List<Dependency> edges = sdgGraph.edgeSet().stream()
.map(abstractGraphEdge -> {
CallableVertex source = sdgGraph.getEdgeSource(abstractGraphEdge);
CallableVertex target = sdgGraph.getEdgeTarget(abstractGraphEdge);
if (abstractGraphEdge instanceof CallEdge) {
return new CallDependency(source, target, abstractGraphEdge);
} else {
return new SDGDependency(source, target, (SystemDepEdge) abstractGraphEdge);
}
})
.collect(Collectors.toList());

return sdgWriter.toString();
return edges;
}
}
Loading

0 comments on commit 1af764f

Please sign in to comment.