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,6 +16,8 @@ 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();
@@ -23,6 +25,14 @@ public class Node {
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.
* *
@@ -67,7 +77,8 @@ public class Node {
* @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)
@@ -90,7 +101,8 @@ public class Node {
* @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)
@@ -109,8 +121,7 @@ public class Node {
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;

View File

@@ -344,6 +344,8 @@ 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();
@@ -360,6 +362,8 @@ 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();
@@ -380,6 +384,8 @@ 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)
@@ -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,6 +459,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());
IdentifierContext ic = ctx.identifier(); IdentifierContext ic = ctx.identifier();
String label = ""; String label = "";
@@ -477,6 +486,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());
IdentifierContext ic = ctx.identifier(); IdentifierContext ic = ctx.identifier();
String label = ""; String label = "";
@@ -502,6 +513,8 @@ 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());
@@ -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());
@@ -563,8 +578,7 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
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;
@@ -606,6 +620,8 @@ 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);
@@ -663,6 +679,8 @@ public class NodeBuilder implements Java1_4ParserVisitor<WorkingGraph> {
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());
@@ -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());
@@ -750,6 +770,8 @@ 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) {
@@ -792,6 +814,8 @@ public class NodeBuilder implements Java1_4ParserVisitor<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;
@@ -869,6 +901,8 @@ public class NodeBuilder implements Java1_4ParserVisitor<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());
@@ -1230,6 +1264,8 @@ 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;
@@ -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,6 +1349,8 @@ 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);