Updated Line number to be a field of the Node of the CFG

This commit is contained in:
Nicolas Amaya
2025-12-14 16:08:41 -07:00
parent 35b5447c7d
commit 6d02dc8fa7
3 changed files with 171 additions and 157 deletions

View File

@@ -40,52 +40,13 @@ public class CFGBuilder {
ControlFlowGraph cfg = cfgs.get(0); ControlFlowGraph cfg = cfgs.get(0);
extractLineNumbers(cfg, tree);
System.out.println("CFG built: " + cfg.nodes().size() + " nodes, " + cfg.edges().size() + " edges"); System.out.println("CFG built: " + cfg.nodes().size() + " nodes, " + cfg.edges().size() + " edges");
return cfg; return cfg;
} }
private void extractLineNumbers(ControlFlowGraph cfg, ParseTree tree) {
Map<String, Integer> labelToLine = new HashMap<>();
collectLineNumbers(tree, labelToLine);
for (Node node : cfg.nodes()) {
String label = node.label();
Integer line = labelToLine.get(label);
if (line == null) {
for (Map.Entry<String, Integer> entry : labelToLine.entrySet()) {
if (label.contains(entry.getKey()) || entry.getKey().contains(label)) {
line = entry.getValue();
break;
}
}
}
nodeToLine.put(node, line != null ? line : -1);
}
}
private void collectLineNumbers(ParseTree tree, Map<String, Integer> map) {
if (tree instanceof ParserRuleContext) {
ParserRuleContext ctx = (ParserRuleContext) tree;
if (ctx.start != null) {
String text = ctx.getText();
if (text != null && text.length() < 200 && text.length() > 0) {
map.put(text, ctx.start.getLine());
}
}
}
for (int i = 0; i < tree.getChildCount(); i++) {
collectLineNumbers(tree.getChild(i), map);
}
}
public int getLineNumber(Node node) { public int getLineNumber(Node node) {
return nodeToLine.getOrDefault(node, -1); return node.getLineNumber();
} }
public List<Integer> getAllLineNumbers() { public List<Integer> getAllLineNumbers() {

View File

@@ -16,13 +16,23 @@ public class Node {
private Set<Edge> outEdges = new HashSet<>(); private Set<Edge> outEdges = new HashSet<>();
private String label; private String label;
private int lineNumber;
Node(String label) { Node(String label) {
if(label == null || label.length() < 1) if (label == null || label.length() < 1)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
this.label = label; this.label = label;
} }
public void setLineNumber(int lineNumber) {
this.lineNumber = lineNumber;
}
public int getLineNumber() {
return this.lineNumber;
}
/** /**
* Accesses the label for this node. * Accesses the label for this node.
* *
@@ -63,20 +73,21 @@ public class Node {
* Adds the indicated edge to this node as an in-edge. * Adds the indicated edge to this node as an in-edge.
* *
* @param edge * @param edge
* The edge to be added as an in-edge * The edge to be added as an in-edge
* @throws IllegalArgumentException * @throws IllegalArgumentException
* If the edge is null. * If the edge is null.
* @throws IllegalStateException * @throws IllegalStateException
* If the target node of the edge is not identical to this node. * If the target node of the edge is not
* identical to this node.
*/ */
public void addInEdge(Edge edge) { public void addInEdge(Edge edge) {
if(edge == null) if (edge == null)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
if(edge.target() != this) if (edge.target() != this)
throw new IllegalStateException(); throw new IllegalStateException();
if(edge.source().graph() == null || edge.target().graph() == null) if (edge.source().graph() == null || edge.target().graph() == null)
throw new IllegalStateException(); throw new IllegalStateException();
inEdges.add(edge); inEdges.add(edge);
@@ -86,31 +97,31 @@ public class Node {
* Adds the indicated edge to this node as an out-edge. * Adds the indicated edge to this node as an out-edge.
* *
* @param edge * @param edge
* The edge to be added as an out-edge * The edge to be added as an out-edge
* @throws IllegalArgumentException * @throws IllegalArgumentException
* If the edge is null. * If the edge is null.
* @throws IllegalStateException * @throws IllegalStateException
* If the source node of the edge is not identical to this node. * If the source node of the edge is not
* identical to this node.
*/ */
public void addOutEdge(Edge edge) { public void addOutEdge(Edge edge) {
if(edge == null) if (edge == null)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
if(edge.source() != this) if (edge.source() != this)
throw new IllegalStateException(); throw new IllegalStateException();
if(edge.source().graph() == null || (edge.target() != null && edge.target().graph() == null)) if (edge.source().graph() == null || (edge.target() != null && edge.target().graph() == null))
throw new IllegalStateException(); throw new IllegalStateException();
outEdges.add(edge); outEdges.add(edge);
} }
void setGraph(ControlFlowGraph graph) { void setGraph(ControlFlowGraph graph) {
if(this.graph != null) { if (this.graph != null) {
if(graph == null) if (graph == null)
this.graph = null; this.graph = null;
} } else if (graph == null)
else if(graph == null)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
else else
this.graph = graph; this.graph = graph;
@@ -123,8 +134,8 @@ public class Node {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if(obj instanceof Node) { if (obj instanceof Node) {
Node other = (Node)obj; Node other = (Node) obj;
return label.equals(other.label); return label.equals(other.label);
} }
@@ -142,8 +153,8 @@ public class Node {
boolean start = true; boolean start = true;
for(Edge edge : inEdges) { for (Edge edge : inEdges) {
if(start) if (start)
start = false; start = false;
else else
sb.append(", "); sb.append(", ");
@@ -155,8 +166,8 @@ public class Node {
start = true; start = true;
for(Edge edge : outEdges) { for (Edge edge : outEdges) {
if(start) if (start)
start = false; start = false;
else else
sb.append(", "); sb.append(", ");

View File

@@ -132,8 +132,8 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
private String getCurrentName() { private String getCurrentName() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for(String name : nameStack) { for (String name : nameStack) {
if(sb.length() == 0) if (sb.length() == 0)
sb.append(name); sb.append(name);
else { else {
sb.append('.'); sb.append('.');
@@ -164,7 +164,7 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
int childCount = arg0.getChildCount(); int childCount = arg0.getChildCount();
WorkingGraph result = null; WorkingGraph result = null;
for(int i = 0; i < childCount; i++) for (int i = 0; i < childCount; i++)
result = visit(arg0.getChild(i)); result = visit(arg0.getChild(i));
return result; return result;
@@ -344,11 +344,13 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g.buildNode(nodeCounter++ + ": block"); s.node = g.buildNode(nodeCounter++ + ": block");
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK)); s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK));
List<BlockStatementContext> statements = ctx.blockStatement(); List<BlockStatementContext> statements = ctx.blockStatement();
for(int i = 0, size = statements.size(); i < size; i++) for (int i = 0, size = statements.size(); i < size; i++)
s.connect(visitBlockStatement(statements.get(i))); s.connect(visitBlockStatement(statements.get(i)));
return s; return s;
@@ -360,11 +362,13 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g.buildNode(nodeCounter++ + ": block"); s.node = g.buildNode(nodeCounter++ + ": block");
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK)); s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK));
List<BlockStatementContext> statements = ctx.blockStatement(); List<BlockStatementContext> statements = ctx.blockStatement();
for(int i = 0, size = statements.size(); i < size; i++) { for (int i = 0, size = statements.size(); i < size; i++) {
WorkingGraph bs = visitBlockStatement(statements.get(i)); WorkingGraph bs = visitBlockStatement(statements.get(i));
bs.edges.add(g.buildEdge(bs.node, null, EdgeLabel.THROWN)); bs.edges.add(g.buildEdge(bs.node, null, EdgeLabel.THROWN));
@@ -380,18 +384,20 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g.buildNode(nodeCounter++ + ": block"); s.node = g.buildNode(nodeCounter++ + ": block");
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK)); s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK));
if(delayedThrown) if (delayedThrown)
s.edges.add(g.buildEdge(s.node, null, EdgeLabel.THROWN_DELAYED)); s.edges.add(g.buildEdge(s.node, null, EdgeLabel.THROWN_DELAYED));
List<BlockStatementContext> statements = ctx.blockStatement(); List<BlockStatementContext> statements = ctx.blockStatement();
for(int i = 0, size = statements.size(); i < size; i++) { for (int i = 0, size = statements.size(); i < size; i++) {
WorkingGraph bs = visitBlockStatement(statements.get(i)); WorkingGraph bs = visitBlockStatement(statements.get(i));
if(delayedThrown) if (delayedThrown)
if(i == size - 1) if (i == size - 1)
bs.edges.add(g.buildEdge(bs.node, null, EdgeLabel.THROWN)); bs.edges.add(g.buildEdge(bs.node, null, EdgeLabel.THROWN));
else else
bs.edges.add(g.buildEdge(bs.node, null, EdgeLabel.THROWN_DELAYED)); bs.edges.add(g.buildEdge(bs.node, null, EdgeLabel.THROWN_DELAYED));
@@ -410,11 +416,11 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
ControlFlowGraph getGraph(RuleContext ctx) { ControlFlowGraph getGraph(RuleContext ctx) {
RuleContext current = ctx; RuleContext current = ctx;
while(current != null && !(current instanceof MemberDeclarationContext) while (current != null && !(current instanceof MemberDeclarationContext)
&& !(current instanceof ClassBodyDeclarationContext) && !(current instanceof InterfaceBodyContext)) && !(current instanceof ClassBodyDeclarationContext) && !(current instanceof InterfaceBodyContext))
current = current.getParent(); current = current.getParent();
if(current != null) if (current != null)
return graphMap.get(current); return graphMap.get(current);
return null; return null;
@@ -427,7 +433,8 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
s.node = g.buildNode(nodeCounter++ + ": " + ctx.accept(new TreePrinter())); s.node = g.buildNode(nodeCounter++ + ": " + ctx.accept(new TreePrinter()));
s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK)); s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK));
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
return s; return s;
} }
@@ -452,16 +459,18 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g.buildNode(nodeCounter++ + ": " + ctx.accept(new TreePrinter())); s.node = g.buildNode(nodeCounter++ + ": " + ctx.accept(new TreePrinter()));
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
IdentifierContext ic = ctx.identifier(); IdentifierContext ic = ctx.identifier();
String label = ""; String label = "";
if(ic != null) if (ic != null)
label = ic.getText().intern(); label = ic.getText().intern();
List<Edge> list = s.breakEdges.get(label); List<Edge> list = s.breakEdges.get(label);
if(list == null) { if (list == null) {
list = new ArrayList<>(); list = new ArrayList<>();
s.breakEdges.put(label, list); s.breakEdges.put(label, list);
} }
@@ -477,16 +486,18 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g.buildNode(nodeCounter++ + ": " + ctx.accept(new TreePrinter())); s.node = g.buildNode(nodeCounter++ + ": " + ctx.accept(new TreePrinter()));
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
IdentifierContext ic = ctx.identifier(); IdentifierContext ic = ctx.identifier();
String label = ""; String label = "";
if(ic != null) if (ic != null)
label = ic.getText(); label = ic.getText();
List<Edge> list = s.continueEdges.get(label); List<Edge> list = s.continueEdges.get(label);
if(list == null) { if (list == null) {
list = new ArrayList<>(); list = new ArrayList<>();
s.continueEdges.put(label, list); s.continueEdges.put(label, list);
} }
@@ -502,18 +513,20 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g.buildNode(nodeCounter++ + ": do"); s.node = g.buildNode(nodeCounter++ + ": do");
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
WorkingGraph doBody = visitStatement(ctx.statement()); WorkingGraph doBody = visitStatement(ctx.statement());
g.buildEdge(s.node, doBody.node, EdgeLabel.BLANK); g.buildEdge(s.node, doBody.node, EdgeLabel.BLANK);
Node whileExpression = g Node whileExpression = g
.buildNode(nodeCounter++ + ": while " + ctx.parenthesizedExpression().accept(new TreePrinter()) + "; "); .buildNode(nodeCounter++ + ": while " + ctx.parenthesizedExpression().accept(new TreePrinter()) + "; ");
g.buildEdge(whileExpression, s.node, EdgeLabel.TRUE); g.buildEdge(whileExpression, s.node, EdgeLabel.TRUE);
for(Edge edge : doBody.edges) { for (Edge edge : doBody.edges) {
if(edge.label() == EdgeLabel.THROWN) if (edge.label() == EdgeLabel.THROWN)
s.edges.add(edge); s.edges.add(edge);
else else
edge.target = whileExpression; edge.target = whileExpression;
@@ -523,15 +536,15 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
List<Edge> nonLabelledBreakEdges = doBody.breakEdges.get(""); List<Edge> nonLabelledBreakEdges = doBody.breakEdges.get("");
if(nonLabelledBreakEdges != null) { if (nonLabelledBreakEdges != null) {
s.edges.addAll(nonLabelledBreakEdges); s.edges.addAll(nonLabelledBreakEdges);
s.breakEdges.remove(""); s.breakEdges.remove("");
} }
List<Edge> nonLabelledContinueEdges = doBody.continueEdges.get(""); List<Edge> nonLabelledContinueEdges = doBody.continueEdges.get("");
if(nonLabelledContinueEdges != null) { if (nonLabelledContinueEdges != null) {
for(Edge edge : nonLabelledContinueEdges) { for (Edge edge : nonLabelledContinueEdges) {
edge.setTarget(whileExpression); edge.setTarget(whileExpression);
s.edges.add(edge); s.edges.add(edge);
} }
@@ -550,6 +563,8 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g.buildNode(nodeCounter++ + ": if " + ctx.parenthesizedExpression().accept(new TreePrinter())); s.node = g.buildNode(nodeCounter++ + ": if " + ctx.parenthesizedExpression().accept(new TreePrinter()));
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
WorkingGraph trueNode = visitStatement(ctx.statement()); WorkingGraph trueNode = visitStatement(ctx.statement());
@@ -558,13 +573,12 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
ElseClauseContext elseClause = ctx.elseClause(); ElseClauseContext elseClause = ctx.elseClause();
if(elseClause != null) { if (elseClause != null) {
WorkingGraph elseNode = visitElseClause(elseClause); WorkingGraph elseNode = visitElseClause(elseClause);
s.edges.add(g.buildEdge(s.node, elseNode.node, EdgeLabel.FALSE)); s.edges.add(g.buildEdge(s.node, elseNode.node, EdgeLabel.FALSE));
s.connect(elseNode); s.connect(elseNode);
} } else
else
s.edges.add(g.buildEdge(s.node, null, EdgeLabel.FALSE)); s.edges.add(g.buildEdge(s.node, null, EdgeLabel.FALSE));
return s; return s;
@@ -577,18 +591,18 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = visitStatement(sc); WorkingGraph s = visitStatement(sc);
List<Edge> breakEdges = s.breakEdges.get(label); List<Edge> breakEdges = s.breakEdges.get(label);
if(breakEdges != null) { if (breakEdges != null) {
s.breakEdges.remove(label); s.breakEdges.remove(label);
s.edges.addAll(breakEdges); s.edges.addAll(breakEdges);
} }
List<Edge> continueEdges = s.continueEdges.get(label); List<Edge> continueEdges = s.continueEdges.get(label);
if(continueEdges != null) { if (continueEdges != null) {
s.continueEdges.remove(label); s.continueEdges.remove(label);
if(sc.forStatement() != null || sc.whileStatement() != null || sc.doStatement() != null) if (sc.forStatement() != null || sc.whileStatement() != null || sc.doStatement() != null)
for(Edge continueEdge : continueEdges) for (Edge continueEdge : continueEdges)
continueEdge.setTarget(s.node); continueEdge.setTarget(s.node);
} }
@@ -606,36 +620,38 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g.buildNode(nodeCounter++ + ": try"); s.node = g.buildNode(nodeCounter++ + ": try");
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK)); s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK));
WorkingGraph tryBody = visitTryBlock(tryBlock); WorkingGraph tryBody = visitTryBlock(tryBlock);
s.connect(tryBody); s.connect(tryBody);
for(CatchClauseContext catch_ : catchClauses) { for (CatchClauseContext catch_ : catchClauses) {
WorkingGraph catchClause = visitCatchClause(catch_); WorkingGraph catchClause = visitCatchClause(catch_);
for(Edge edge : s.edges) { for (Edge edge : s.edges) {
if(edge.label() == EdgeLabel.THROWN && edge.target() == null) if (edge.label() == EdgeLabel.THROWN && edge.target() == null)
edge.setTarget(catchClause.node); edge.setTarget(catchClause.node);
} }
s.edges.addAll(catchClause.edges); s.edges.addAll(catchClause.edges);
} }
if(finallyClause != null) { if (finallyClause != null) {
boolean delayedThrown = false; boolean delayedThrown = false;
for(Edge edge : s.edges) for (Edge edge : s.edges)
if(edge.label() == EdgeLabel.THROWN && edge.target() == null) { if (edge.label() == EdgeLabel.THROWN && edge.target() == null) {
delayedThrown = true; delayedThrown = true;
break; break;
} }
WorkingGraph finallyBody = visitFinallyClause(finallyClause, delayedThrown); WorkingGraph finallyBody = visitFinallyClause(finallyClause, delayedThrown);
for(Edge edge : s.edges) for (Edge edge : s.edges)
if(edge.target() == null) if (edge.target() == null)
edge.setTarget(finallyBody.node); edge.setTarget(finallyBody.node);
s.edges.addAll(finallyBody.edges); s.edges.addAll(finallyBody.edges);
@@ -658,11 +674,13 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
sb.append(forInit == null ? "; " : forInit.accept(new TreePrinter()) + "; "); sb.append(forInit == null ? "; " : forInit.accept(new TreePrinter()) + "; ");
sb.append(expression == null ? "; " : expression.accept(new TreePrinter()) + "; "); sb.append(expression == null ? "; " : expression.accept(new TreePrinter()) + "; ");
if(forUpdate != null) if (forUpdate != null)
sb.append(forUpdate.accept(new TreePrinter())); sb.append(forUpdate.accept(new TreePrinter()));
sb.append(")"); sb.append(")");
s.node = g.buildNode(sb.toString()); s.node = g.buildNode(sb.toString());
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
WorkingGraph forBody = visitStatement(ctx.statement()); WorkingGraph forBody = visitStatement(ctx.statement());
@@ -670,8 +688,8 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
s.edges.add(g.buildEdge(s.node, forBody.node, EdgeLabel.TRUE)); s.edges.add(g.buildEdge(s.node, forBody.node, EdgeLabel.TRUE));
s.edges.add(g.buildEdge(s.node, null, EdgeLabel.FALSE)); s.edges.add(g.buildEdge(s.node, null, EdgeLabel.FALSE));
for(Edge edge : forBody.edges) { for (Edge edge : forBody.edges) {
if(edge.target() == null && edge.label() != EdgeLabel.THROWN) if (edge.target() == null && edge.label() != EdgeLabel.THROWN)
edge.setTarget(s.node); edge.setTarget(s.node);
} }
// s.edges.addAll(forBody.edges); // s.edges.addAll(forBody.edges);
@@ -680,15 +698,15 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
List<Edge> nonLabelledBreakEdges = forBody.breakEdges.get(""); List<Edge> nonLabelledBreakEdges = forBody.breakEdges.get("");
if(nonLabelledBreakEdges != null) { if (nonLabelledBreakEdges != null) {
s.edges.addAll(nonLabelledBreakEdges); s.edges.addAll(nonLabelledBreakEdges);
s.breakEdges.remove(""); s.breakEdges.remove("");
} }
List<Edge> nonLabelledContinueEdges = forBody.continueEdges.get(""); List<Edge> nonLabelledContinueEdges = forBody.continueEdges.get("");
if(nonLabelledContinueEdges != null) { if (nonLabelledContinueEdges != null) {
for(Edge edge : nonLabelledContinueEdges) { for (Edge edge : nonLabelledContinueEdges) {
edge.setTarget(s.node); edge.setTarget(s.node);
s.edges.add(edge); s.edges.add(edge);
} }
@@ -706,6 +724,8 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
ParenthesizedExpressionContext condition = ctx.parenthesizedExpression(); ParenthesizedExpressionContext condition = ctx.parenthesizedExpression();
s.node = g.buildNode(nodeCounter++ + ": while " + condition.accept(new TreePrinter())); s.node = g.buildNode(nodeCounter++ + ": while " + condition.accept(new TreePrinter()));
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
WorkingGraph whileBody = visitStatement(ctx.statement()); WorkingGraph whileBody = visitStatement(ctx.statement());
@@ -713,8 +733,8 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
g.buildEdge(s.node, whileBody.node, EdgeLabel.TRUE); g.buildEdge(s.node, whileBody.node, EdgeLabel.TRUE);
s.edges.add(g.buildEdge(s.node, null, EdgeLabel.FALSE)); s.edges.add(g.buildEdge(s.node, null, EdgeLabel.FALSE));
for(Edge edge : whileBody.edges) { for (Edge edge : whileBody.edges) {
if(edge.label() == EdgeLabel.THROWN) if (edge.label() == EdgeLabel.THROWN)
s.edges.add(edge); s.edges.add(edge);
else else
edge.target = s.node; edge.target = s.node;
@@ -724,15 +744,15 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
List<Edge> nonLabelledBreakEdges = whileBody.breakEdges.get(""); List<Edge> nonLabelledBreakEdges = whileBody.breakEdges.get("");
if(nonLabelledBreakEdges != null) { if (nonLabelledBreakEdges != null) {
s.edges.addAll(nonLabelledBreakEdges); s.edges.addAll(nonLabelledBreakEdges);
s.breakEdges.remove(""); s.breakEdges.remove("");
} }
List<Edge> nonLabelledContinueEdges = whileBody.continueEdges.get(""); List<Edge> nonLabelledContinueEdges = whileBody.continueEdges.get("");
if(nonLabelledContinueEdges != null) { if (nonLabelledContinueEdges != null) {
for(Edge edge : nonLabelledContinueEdges) { for (Edge edge : nonLabelledContinueEdges) {
edge.setTarget(s.node); edge.setTarget(s.node);
s.edges.add(edge); s.edges.add(edge);
} }
@@ -750,25 +770,27 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
List<SwitchBlockStatementGroupContext> statementGroups = ctx.switchBlockStatementGroup(); List<SwitchBlockStatementGroupContext> statementGroups = ctx.switchBlockStatementGroup();
s.node = g.buildNode(nodeCounter++ + ": switch " + ctx.parenthesizedExpression().accept(new TreePrinter())); s.node = g.buildNode(nodeCounter++ + ": switch " + ctx.parenthesizedExpression().accept(new TreePrinter()));
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
if(!statementGroups.isEmpty()) if (!statementGroups.isEmpty())
for(SwitchBlockStatementGroupContext group : statementGroups) { for (SwitchBlockStatementGroupContext group : statementGroups) {
List<SwitchLabelContext> labels = group.switchLabel(); List<SwitchLabelContext> labels = group.switchLabel();
List<BlockStatementContext> statements = group.blockStatement(); List<BlockStatementContext> statements = group.blockStatement();
WorkingGraph first = visitBlockStatement(statements.get(0)); WorkingGraph first = visitBlockStatement(statements.get(0));
TreePrinter printer = new TreePrinter(); TreePrinter printer = new TreePrinter();
for(SwitchLabelContext label : labels) for (SwitchLabelContext label : labels)
s.edges.add(g.buildEdge(s.node, first.node, EdgeLabel.CASE, label.accept(printer))); s.edges.add(g.buildEdge(s.node, first.node, EdgeLabel.CASE, label.accept(printer)));
for(int i = 1, size = statements.size(); i < size; i++) { for (int i = 1, size = statements.size(); i < size; i++) {
WorkingGraph later = visitBlockStatement(statements.get(i)); WorkingGraph later = visitBlockStatement(statements.get(i));
for(List<Edge> list : later.breakEdges.values()) for (List<Edge> list : later.breakEdges.values())
first.edges.addAll(list); first.edges.addAll(list);
later.breakEdges.clear(); later.breakEdges.clear();
first.connect(later); first.connect(later);
} }
@@ -779,7 +801,7 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
List<SwitchLabelContext> extraLabels = ctx.switchLabel(); List<SwitchLabelContext> extraLabels = ctx.switchLabel();
for(SwitchLabelContext label : extraLabels) for (SwitchLabelContext label : extraLabels)
s.edges.add(g.buildEdge(s.node, null, EdgeLabel.CASE, label.accept(new TreePrinter()))); s.edges.add(g.buildEdge(s.node, null, EdgeLabel.CASE, label.accept(new TreePrinter())));
return s; return s;
@@ -791,7 +813,9 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g s.node = g
.buildNode(nodeCounter++ + ": synchronized " + ctx.parenthesizedExpression().accept(new TreePrinter())); .buildNode(nodeCounter++ + ": synchronized " + ctx.parenthesizedExpression().accept(new TreePrinter()));
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK)); s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK));
WorkingGraph block = visitBlock(ctx.block()); WorkingGraph block = visitBlock(ctx.block());
@@ -807,6 +831,8 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g.buildNode(nodeCounter++ + ": " + ctx.accept(new TreePrinter())); s.node = g.buildNode(nodeCounter++ + ": " + ctx.accept(new TreePrinter()));
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK)); s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK));
return s; return s;
@@ -818,6 +844,8 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g.buildNode(nodeCounter++ + ": " + ctx.accept(new TreePrinter())); s.node = g.buildNode(nodeCounter++ + ": " + ctx.accept(new TreePrinter()));
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
s.edges.add(g.buildEdge(s.node, null, EdgeLabel.THROWN)); s.edges.add(g.buildEdge(s.node, null, EdgeLabel.THROWN));
return s; return s;
@@ -829,6 +857,8 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g.buildNode(nodeCounter++ + ": *EMPTY* ; "); s.node = g.buildNode(nodeCounter++ + ": *EMPTY* ; ");
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK)); s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK));
return s; return s;
@@ -840,6 +870,8 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g.buildNode(nodeCounter++ + ": " + ctx.accept(new TreePrinter())); s.node = g.buildNode(nodeCounter++ + ": " + ctx.accept(new TreePrinter()));
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK)); s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK));
return s; return s;
@@ -868,7 +900,9 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g s.node = g
.buildNode(nodeCounter++ + ": catch ( " + ctx.formalParameter().type().accept(new TreePrinter()) + ")"); .buildNode(nodeCounter++ + ": catch ( " + ctx.formalParameter().type().accept(new TreePrinter()) + ")");
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
WorkingGraph body = visitBlock(ctx.block()); WorkingGraph body = visitBlock(ctx.block());
@@ -934,10 +968,10 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
public WorkingGraph visitCompilationUnit(CompilationUnitContext ctx) { public WorkingGraph visitCompilationUnit(CompilationUnitContext ctx) {
QualifiedIdentifierContext pkg = ctx.qualifiedIdentifier(); QualifiedIdentifierContext pkg = ctx.qualifiedIdentifier();
if(pkg != null) if (pkg != null)
nameStack.push(pkg.accept(new TreePrinter())); nameStack.push(pkg.accept(new TreePrinter()));
for(TypeDeclarationContext typeDeclaration : ctx.typeDeclaration()) for (TypeDeclarationContext typeDeclaration : ctx.typeDeclaration())
typeDeclaration.accept(this); typeDeclaration.accept(this);
return null; return null;
@@ -1008,10 +1042,10 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
List<FormalParameterContext> formals = ctx.formalParameter(); List<FormalParameterContext> formals = ctx.formalParameter();
int size = formals.size(); int size = formals.size();
if(size > 0) { if (size > 0) {
sb.append(formals.get(0).type().accept(new TreePrinter())); sb.append(formals.get(0).type().accept(new TreePrinter()));
for(int i = 1; i < size; i++) { for (int i = 1; i < size; i++) {
sb.append(", "); sb.append(", ");
sb.append(formals.get(i).type().accept(new TreePrinter())); sb.append(formals.get(i).type().accept(new TreePrinter()));
} }
@@ -1024,7 +1058,7 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
@Override @Override
public WorkingGraph visitMethodDeclaration(MethodDeclarationContext ctx) { public WorkingGraph visitMethodDeclaration(MethodDeclarationContext ctx) {
if(ctx.block() != null) { if (ctx.block() != null) {
String identifier = ctx.identifier().getText(); String identifier = ctx.identifier().getText();
String signature = getSignature(identifier, ctx.formalParameters()); String signature = getSignature(identifier, ctx.formalParameters());
ControlFlowGraph g = new ControlFlowGraph(getCurrentName() + "." + signature); ControlFlowGraph g = new ControlFlowGraph(getCurrentName() + "." + signature);
@@ -1035,21 +1069,21 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
g.buildEdge(g.entry, s.node, EdgeLabel.BLANK); g.buildEdge(g.entry, s.node, EdgeLabel.BLANK);
for(Edge edge : s.edges) { for (Edge edge : s.edges) {
EdgeLabel label = edge.label(); EdgeLabel label = edge.label();
if(edge.target() == null) { if (edge.target() == null) {
if(label == EdgeLabel.THROWN) if (label == EdgeLabel.THROWN)
edge.setTarget(g.abruptExit); edge.setTarget(g.abruptExit);
else else
edge.setTarget(g.normalExit); edge.setTarget(g.normalExit);
} }
} }
if(!s.breakEdges.isEmpty()) if (!s.breakEdges.isEmpty())
throw new IllegalStateException("WorkingGraph still contains break edges: " + s); throw new IllegalStateException("WorkingGraph still contains break edges: " + s);
if(!s.continueEdges.isEmpty()) if (!s.continueEdges.isEmpty())
throw new IllegalStateException("WorkingGraph still contains continue edges: " + s); throw new IllegalStateException("WorkingGraph still contains continue edges: " + s);
} }
@@ -1125,21 +1159,21 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
g.buildEdge(g.entry, s.node, EdgeLabel.BLANK); g.buildEdge(g.entry, s.node, EdgeLabel.BLANK);
for(Edge edge : s.edges) { for (Edge edge : s.edges) {
EdgeLabel label = edge.label(); EdgeLabel label = edge.label();
if(edge.target() == null) { if (edge.target() == null) {
if(label == EdgeLabel.THROWN) if (label == EdgeLabel.THROWN)
edge.setTarget(g.abruptExit); edge.setTarget(g.abruptExit);
else else
edge.setTarget(g.normalExit); edge.setTarget(g.normalExit);
} }
} }
if(!s.breakEdges.isEmpty()) if (!s.breakEdges.isEmpty())
throw new IllegalStateException("WorkingGraph still contains break edges: " + s); throw new IllegalStateException("WorkingGraph still contains break edges: " + s);
if(!s.continueEdges.isEmpty()) if (!s.continueEdges.isEmpty())
throw new IllegalStateException("WorkingGraph still contains continue edges: " + s); throw new IllegalStateException("WorkingGraph still contains continue edges: " + s);
return null; return null;
@@ -1155,21 +1189,21 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
g.buildEdge(g.entry, s.node, EdgeLabel.BLANK); g.buildEdge(g.entry, s.node, EdgeLabel.BLANK);
for(Edge edge : s.edges) { for (Edge edge : s.edges) {
EdgeLabel label = edge.label(); EdgeLabel label = edge.label();
if(edge.target() == null) { if (edge.target() == null) {
if(label == EdgeLabel.THROWN) if (label == EdgeLabel.THROWN)
edge.setTarget(g.abruptExit); edge.setTarget(g.abruptExit);
else else
edge.setTarget(g.normalExit); edge.setTarget(g.normalExit);
} }
} }
if(!s.breakEdges.isEmpty()) if (!s.breakEdges.isEmpty())
throw new IllegalStateException("WorkingGraph still contains break edges: " + s); throw new IllegalStateException("WorkingGraph still contains break edges: " + s);
if(!s.continueEdges.isEmpty()) if (!s.continueEdges.isEmpty())
throw new IllegalStateException("WorkingGraph still contains continue edges: " + s); throw new IllegalStateException("WorkingGraph still contains continue edges: " + s);
return null; return null;
@@ -1204,21 +1238,21 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
g.buildEdge(g.entry, s.node, EdgeLabel.BLANK); g.buildEdge(g.entry, s.node, EdgeLabel.BLANK);
for(Edge edge : s.edges) { for (Edge edge : s.edges) {
EdgeLabel label = edge.label(); EdgeLabel label = edge.label();
if(edge.target() == null) { if (edge.target() == null) {
if(label == EdgeLabel.THROWN) if (label == EdgeLabel.THROWN)
edge.setTarget(g.abruptExit); edge.setTarget(g.abruptExit);
else else
edge.setTarget(g.normalExit); edge.setTarget(g.normalExit);
} }
} }
if(!s.breakEdges.isEmpty()) if (!s.breakEdges.isEmpty())
throw new IllegalStateException("WorkingGraph still contains break edges: " + s); throw new IllegalStateException("WorkingGraph still contains break edges: " + s);
if(!s.continueEdges.isEmpty()) if (!s.continueEdges.isEmpty())
throw new IllegalStateException("WorkingGraph still contains continue edges: " + s); throw new IllegalStateException("WorkingGraph still contains continue edges: " + s);
return null; return null;
@@ -1230,17 +1264,19 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g.buildNode(nodeCounter++ + ": body"); s.node = g.buildNode(nodeCounter++ + ": body");
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK)); s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK));
WorkingGraph body = null; WorkingGraph body = null;
ExplicitConstructorInvocationContext eci = ctx.explicitConstructorInvocation(); ExplicitConstructorInvocationContext eci = ctx.explicitConstructorInvocation();
if(eci != null) { if (eci != null) {
body = visitExplicitConstructorInvocation(eci); body = visitExplicitConstructorInvocation(eci);
s.connect(body); s.connect(body);
} }
for(BlockStatementContext statement : ctx.blockStatement()) { for (BlockStatementContext statement : ctx.blockStatement()) {
body = visitBlockStatement(statement); body = visitBlockStatement(statement);
s.connect(body); s.connect(body);
} }
@@ -1254,6 +1290,8 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g.buildNode(nodeCounter++ + ": " + ctx.accept(new TreePrinter())); s.node = g.buildNode(nodeCounter++ + ": " + ctx.accept(new TreePrinter()));
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK)); s.edges.add(g.buildEdge(s.node, null, EdgeLabel.BLANK));
return s; return s;
@@ -1288,6 +1326,8 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g.buildNode(nodeCounter++ + ": else"); s.node = g.buildNode(nodeCounter++ + ": else");
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
WorkingGraph body = visitStatement(ctx.statement()); WorkingGraph body = visitStatement(ctx.statement());
@@ -1309,12 +1349,14 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
WorkingGraph s = new WorkingGraph(); WorkingGraph s = new WorkingGraph();
s.node = g.buildNode(nodeCounter++ + ": finally"); s.node = g.buildNode(nodeCounter++ + ": finally");
// addlinenumber
s.node.setLineNumber(ctx.getStart().getLine());
WorkingGraph body = visitFinallyBlock(ctx.block(), delayedThrown); WorkingGraph body = visitFinallyBlock(ctx.block(), delayedThrown);
s.edges.add(g.buildEdge(s.node, body.node, EdgeLabel.BLANK)); s.edges.add(g.buildEdge(s.node, body.node, EdgeLabel.BLANK));
if(delayedThrown) if (delayedThrown)
s.edges.add(g.buildEdge(s.node, body.node, EdgeLabel.THROWN_DELAYED)); s.edges.add(g.buildEdge(s.node, body.node, EdgeLabel.THROWN_DELAYED));
return s; return s;
@@ -1328,31 +1370,31 @@ class WorkingGraph {
public Map<String, List<Edge>> continueEdges = new HashMap<>(); public Map<String, List<Edge>> continueEdges = new HashMap<>();
public void connect(WorkingGraph s) { public void connect(WorkingGraph s) {
if(s == null) if (s == null)
return; return;
for(Edge edge : edges) { for (Edge edge : edges) {
if(edge.label() != EdgeLabel.THROWN && edge.target == null) if (edge.label() != EdgeLabel.THROWN && edge.target == null)
edge.setTarget(s.node); edge.setTarget(s.node);
} }
edges.addAll(s.edges); edges.addAll(s.edges);
for(String label : s.breakEdges.keySet()) { for (String label : s.breakEdges.keySet()) {
List<Edge> sEdges = s.breakEdges.get(label); List<Edge> sEdges = s.breakEdges.get(label);
List<Edge> thisEdges = breakEdges.get(label); List<Edge> thisEdges = breakEdges.get(label);
if(thisEdges == null) if (thisEdges == null)
breakEdges.put(label, sEdges); breakEdges.put(label, sEdges);
else else
thisEdges.addAll(sEdges); thisEdges.addAll(sEdges);
} }
for(String label : s.continueEdges.keySet()) { for (String label : s.continueEdges.keySet()) {
List<Edge> sEdges = s.continueEdges.get(label); List<Edge> sEdges = s.continueEdges.get(label);
List<Edge> thisEdges = continueEdges.get(label); List<Edge> thisEdges = continueEdges.get(label);
if(thisEdges == null) if (thisEdges == null)
continueEdges.put(label, sEdges); continueEdges.put(label, sEdges);
else else
thisEdges.addAll(sEdges); thisEdges.addAll(sEdges);