Skip to content

Commit 3b66988

Browse files
authored
Merge pull request #21 from jacosro/14-switch-library
Switch from edg.graphlib to JGraphT
2 parents 1a40875 + 2b465f8 commit 3b66988

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+832
-2256
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
.idea/
33
target/
44
out/
5+
.settings

lib/graphlib.jar

-21.9 KB
Binary file not shown.

pom.xml

+12-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
</build>
2222

2323
<dependencies>
24-
2524
<dependency>
2625
<groupId>com.github.javaparser</groupId>
2726
<artifactId>javaparser-symbol-solver-core</artifactId>
@@ -41,5 +40,17 @@
4140
<version>1.3.0</version>
4241
</dependency>
4342

43+
<dependency>
44+
<groupId>org.jgrapht</groupId>
45+
<artifactId>jgrapht-io</artifactId>
46+
<version>1.3.0</version>
47+
</dependency>
48+
49+
<dependency>
50+
<groupId>org.junit.jupiter</groupId>
51+
<artifactId>junit-jupiter</artifactId>
52+
<version>5.5.2</version>
53+
<scope>test</scope>
54+
</dependency>
4455
</dependencies>
4556
</project>

readme.md

+35-19
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ Find `Slice` class (`tfm/slicing`), set the program path and execute. The sliced
3434

3535
## Structure
3636

37-
Graphs are built using a library called `graphlib`, located in `lib/graphlib.jar`. This library is old and has some issues I had to fix...
37+
Graphs are built using a library called `JGraphT`.
3838

39-
The main class is the `Graph` class, which extends from `graphlib`'s `Graph` class. This class includes some behaviour fixes, and some general interest methods (like `toString`, `toGraphvizRepresentation`, etc.)
39+
The main class is the `Graph` class, which extends from `JGraphT`'s `DefaultDirectedGraph` class. This class includes some general interest methods (like `toString`, etc.)
4040

4141
Every graph has a set of nodes and arrows. `GraphNode` and `Arc` classes are used to represent them respectively.
4242

@@ -104,7 +104,7 @@ Forget about the `tfm/scopes` folder, it was an idea I had to discard and it has
104104

105105
### General
106106

107-
- Switch to a (much) better graph library like [JGraphT](https://jgrapht.org/). It also supports graph visualization
107+
- Switch to a (much) better graph library like [JGraphT](https://jgrapht.org/). It also supports graph visualization (done).
108108
- Performance review
109109
- Make a test suite (test graph building, slicing, etc.)
110110
- Add support to more Java language features (lambdas, etc.)
@@ -114,36 +114,52 @@ Forget about the `tfm/scopes` folder, it was an idea I had to discard and it has
114114
### Build a CFG from a program
115115

116116
```java
117-
public CFGGraph buildCFG(File programFile) {
118-
JavaParser.getStaticConfiguration().setAttributeComments(false); // Always disable comments, just in case
119-
120-
Node astRoot = JavaParser.parse(programFile);
121-
122-
return Graphs.CFG.fromASTNode(astRoot); // Creates a new graph representing the program
117+
public class Example {
118+
public CFG buildCFG(File programFile) {
119+
// Always disable attribution of comments, just in case
120+
JavaParser.getStaticConfiguration().setAttributeComments(false);
121+
122+
Node astRoot = JavaParser.parse(programFile);
123+
Optional<MethodDeclaration> optMethod = astRoot.findFirst(MethodDeclaration.class);
124+
if (!optMethod.isPresent)
125+
throw new RuntimeException("No method could be found");
126+
127+
// Creates a new graph representing the program
128+
CFG cfg = new CFG();
129+
cfg.build(optMethod.get());
130+
return cfg;
131+
}
123132
}
124133
```
125134

126135
### Get a slice of the PDG of a program
127136

128137
```java
129-
public PDGGraph getSlice(File program, SlicingCriterion slicingCriterion) {
130-
JavaParser.getStaticConfiguration().setAttributeComments(false); // Always disable comments, just in case
131-
132-
Node astRoot = JavaParser.parse(programFile);
133-
134-
PDGGraph pdgGraph = Graphs.PDG.fromASTNode(astRoot);
135-
136-
return pdgGraph.slice(slicingCriterion);
138+
public class Example {
139+
public PDGGraph getSlice(File program, SlicingCriterion slicingCriterion) {
140+
// Always disable attribution of comments, just in case
141+
JavaParser.getStaticConfiguration().setAttributeComments(false);
142+
143+
Node astRoot = JavaParser.parse(programFile);
144+
Optional<MethodDeclaration> optMethod = astRoot.findFirst(MethodDeclaration.class);
145+
if (!optMethod.isPresent)
146+
throw new RuntimeException("No method could be found");
147+
148+
// Creates a new graph representing the program
149+
PDG pdg = new PDG();
150+
pdg.build(optMethod.get());
151+
// Slice PDG
152+
return pdg.slice(slicingCriterion);
153+
}
137154
}
138-
139155
```
140156

141157
## Workflow
142158

143159
- Branches:
144160
- `master` (only for stable versions)
145161
- `develop` (main branch)
146-
- `<issue number>`
162+
- `<issue number>-name`
147163

148164
1. Discover a new feature/fix
149165
2. Open an issue describing it and assign it

src/main/java/tfm/arcs/Arc.java

+48-41
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,79 @@
11
package tfm.arcs;
22

3-
import tfm.arcs.data.ArcData;
3+
import org.jgrapht.graph.DefaultEdge;
4+
import org.jgrapht.io.Attribute;
5+
import tfm.arcs.cfg.ControlFlowArc;
6+
import tfm.arcs.pdg.ControlDependencyArc;
7+
import tfm.arcs.pdg.DataDependencyArc;
48
import tfm.nodes.GraphNode;
59

10+
import java.util.HashMap;
11+
import java.util.Map;
612
import java.util.Objects;
713

8-
public abstract class Arc<D extends ArcData> extends edg.graphlib.Arrow<String, D> {
14+
public abstract class Arc extends DefaultEdge {
15+
public Arc() {
916

10-
@SuppressWarnings("unchecked")
11-
public Arc(GraphNode<?> from, GraphNode<?> to) {
12-
super((edg.graphlib.Vertex<String, D>) from, (edg.graphlib.Vertex<String, D>) to);
1317
}
1418

15-
public abstract boolean isControlFlowArrow();
19+
public final boolean isControlFlowArc() {
20+
return this instanceof ControlFlowArc;
21+
}
1622

17-
public abstract boolean isControlDependencyArrow();
23+
public final ControlFlowArc asControlFlowArc() {
24+
if (isControlFlowArc())
25+
return (ControlFlowArc) this;
26+
throw new UnsupportedOperationException("Not a ControlFlowArc");
27+
}
1828

19-
public abstract boolean isDataDependencyArrow();
29+
public final boolean isControlDependencyArc() {
30+
return this instanceof ControlDependencyArc;
31+
}
2032

21-
@Override
22-
public String toString() {
23-
return String.format("Arc{data: %s, %s -> %s}",
24-
getData(),
25-
getFrom(),
26-
getTo()
27-
);
33+
public final ControlDependencyArc asControlDependencyArc() {
34+
if (isControlDependencyArc())
35+
return (ControlDependencyArc) this;
36+
throw new UnsupportedOperationException("Not a ControlDependencyArc");
2837
}
2938

30-
public String toGraphvizRepresentation() {
31-
GraphNode from = (GraphNode) getFrom();
32-
GraphNode to = (GraphNode) getTo();
39+
public final boolean isDataDependencyArc() {
40+
return this instanceof DataDependencyArc;
41+
}
3342

34-
return String.format("%s -> %s",
35-
from.getId(),
36-
to.getId()
37-
);
43+
public final DataDependencyArc asDataDependencyArc() {
44+
if (isDataDependencyArc())
45+
return (DataDependencyArc) this;
46+
throw new UnsupportedOperationException("Not a DataDependencyArc");
3847
}
3948

40-
public GraphNode<?> getFromNode() {
41-
return (GraphNode<?>) super.getFrom();
49+
@Override
50+
public String toString() {
51+
return String.format("%s{%d -> %d}", getClass().getName(),
52+
((GraphNode<?>) getSource()).getId(), ((GraphNode<?>) getTarget()).getId());
4253
}
4354

44-
public GraphNode<?> getToNode() {
45-
return (GraphNode<?>) super.getTo();
55+
public String getLabel() {
56+
return "";
4657
}
4758

48-
@Override
49-
public int hashCode() {
50-
return Objects.hashCode(getData()) + getFrom().hashCode() + getTo().hashCode();
59+
public Map<String, Attribute> getDotAttributes() {
60+
return new HashMap<>();
5161
}
5262

5363
@Override
5464
public boolean equals(Object o) {
5565
if (this == o)
5666
return true;
57-
58-
if (!(o instanceof Arc))
67+
if (o == null)
5968
return false;
69+
if (!o.getClass().equals(this.getClass()))
70+
return false;
71+
return Objects.equals(getSource(), ((Arc) o).getSource()) &&
72+
Objects.equals(getTarget(), ((Arc) o).getTarget());
73+
}
6074

61-
Arc arc = (Arc) o;
62-
63-
GraphNode from = (GraphNode) arc.getFrom();
64-
GraphNode from2 = (GraphNode) getFrom();
65-
GraphNode to = (GraphNode) getTo();
66-
GraphNode to2 = (GraphNode) arc.getTo();
67-
68-
return Objects.equals(arc.getData(), getData()) &&
69-
Objects.equals(from.getId(), from2.getId()) &&
70-
Objects.equals(to.getId(), to2.getId());
75+
@Override
76+
public int hashCode() {
77+
return Objects.hash(getClass(), getSource(), getTarget());
7178
}
7279
}
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,8 @@
11
package tfm.arcs.cfg;
22

33
import tfm.arcs.Arc;
4-
import tfm.arcs.data.VoidArcData;
5-
import tfm.nodes.GraphNode;
64

7-
public class ControlFlowArc extends Arc<VoidArcData> {
8-
9-
public ControlFlowArc(GraphNode from, GraphNode to) {
10-
super(from, to);
11-
}
12-
13-
@Override
14-
public boolean isControlFlowArrow() {
15-
return true;
16-
}
17-
18-
@Override
19-
public boolean isControlDependencyArrow() {
20-
return false;
5+
public class ControlFlowArc extends Arc {
6+
public ControlFlowArc() {
217
}
22-
23-
@Override
24-
public boolean isDataDependencyArrow() {
25-
return false;
26-
}
27-
28-
@Override
29-
public String toString() {
30-
return String.format("ControlFlowArc{%s -> %s}",
31-
getFromNode().getId(),
32-
getToNode().getId()
33-
);
34-
}
35-
368
}

src/main/java/tfm/arcs/data/ArcData.java

-8
This file was deleted.

src/main/java/tfm/arcs/data/VariableArcData.java

-37
This file was deleted.

src/main/java/tfm/arcs/data/VoidArcData.java

-18
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,8 @@
11
package tfm.arcs.pdg;
22

33
import tfm.arcs.Arc;
4-
import tfm.arcs.data.ArcData;
5-
import tfm.nodes.GraphNode;
64

7-
public class ControlDependencyArc extends Arc<ArcData> {
8-
9-
public ControlDependencyArc(GraphNode from, GraphNode to) {
10-
super(from, to);
11-
}
12-
13-
@Override
14-
public boolean isControlFlowArrow() {
15-
return false;
16-
}
17-
18-
@Override
19-
public boolean isControlDependencyArrow() {
20-
return true;
21-
}
22-
23-
@Override
24-
public boolean isDataDependencyArrow() {
25-
return false;
26-
}
27-
28-
@Override
29-
public String toString() {
30-
return String.format("ControlDependencyArc{%s -> %s}",
31-
((GraphNode) getFrom()).getId(),
32-
((GraphNode) getTo()).getId()
33-
);
5+
public class ControlDependencyArc extends Arc {
6+
public ControlDependencyArc() {
347
}
358
}

0 commit comments

Comments
 (0)