From 137d01938c767b4538290a4d6dcdd8f062b3f145 Mon Sep 17 00:00:00 2001 From: Carlos Galindo Date: Wed, 3 Apr 2019 15:34:25 +0200 Subject: [PATCH] Visitador: added switchStmt with breaks --- src/main/java/grafos/Visitador.java | 59 ++++++++++++++++++++- src/test/res/mytest/BasicSwitch.java | 28 ++++++++++ src/test/res/mytest/BasicSwitchDefault.java | 23 ++++++++ src/test/res/mytest/BasicSwitchNoBreak.java | 16 ++++++ 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 src/test/res/mytest/BasicSwitch.java create mode 100644 src/test/res/mytest/BasicSwitchDefault.java create mode 100644 src/test/res/mytest/BasicSwitchNoBreak.java diff --git a/src/main/java/grafos/Visitador.java b/src/main/java/grafos/Visitador.java index 56a9799..86a4969 100755 --- a/src/main/java/grafos/Visitador.java +++ b/src/main/java/grafos/Visitador.java @@ -1,6 +1,7 @@ package grafos; import com.github.javaparser.ast.Node; +import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.stmt.*; @@ -9,6 +10,7 @@ import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import java.util.Collections; import java.util.LinkedList; import java.util.List; +import java.util.Stack; public class Visitador extends VoidVisitorAdapter { //********************************************************/ @@ -16,6 +18,8 @@ public class Visitador extends VoidVisitorAdapter { //********************************************************/ private List prevNode; + private Stack switchStack = new Stack<>(); + private List brokenStmts = new LinkedList<>(); //********************************************************/ //*********************** Metodos ************************/ @@ -139,7 +143,7 @@ public class Visitador extends VoidVisitorAdapter { @Override public void visit(ForeachStmt n, CFG graph) { - ForeachStmt copy = new ForeachStmt(n.getTokenRange().isPresent() ? n.getTokenRange().get() : null, n.getVariable(), n.getIterable(), new EmptyStmt()); + ForeachStmt copy = new ForeachStmt(n.getTokenRange().orElse(null), n.getVariable(), n.getIterable(), new EmptyStmt()); graph.addNode(copy); graph.connect(prevNode, copy); prevNode = Collections.singletonList(copy); @@ -148,6 +152,59 @@ public class Visitador extends VoidVisitorAdapter { prevNode = Collections.singletonList(copy); } + @Override + public void visit(SwitchEntryStmt n, CFG graph) { + // Case header + Node caseNode = new SwitchEntryStmt(n.getTokenRange().orElse(null), n.getLabel().orElse(null), new NodeList<>()); + graph.addNode(caseNode); + graph.connect(prevNode, caseNode); + prevNode = Collections.singletonList(caseNode); + // Case body + n.getStatements().accept(this, graph); + } + + @Override + public void visit(SwitchStmt n, CFG graph) { + // Link previous statement to the switch's selector + Node selectorNode = new SwitchStmt(n.getTokenRange().orElse(null), n.getSelector(), new NodeList<>()); + graph.addNode(selectorNode); + graph.connect(prevNode, selectorNode); + // Analyze switch's cases + prevNode = Collections.singletonList(selectorNode); + switchStack.push(n); + for (SwitchEntryStmt entry : n.getEntries()) { + entry.accept(this, graph); + if (prevNode.isEmpty()) { + prevNode = Collections.singletonList(selectorNode); + } else { + prevNode = new LinkedList<>(prevNode); + prevNode.add(selectorNode); + } + } + switchStack.pop(); + // The next statement will be linked to: + // 1. All break statements that broke from the switch + // 2. If the switch doesn't have a default statement, the switch's selector + // 3. If the last entry doesn't break, to the last statement + prevNode = new LinkedList<>(prevNode); // 3 + prevNode.remove(selectorNode); + prevNode.addAll(brokenStmts); // 1 + if (n.getEntries().get(n.getEntries().size() - 1).getLabel().isPresent()) + prevNode.add(selectorNode); // 2 + } + + @Override + public void visit(BreakStmt n, CFG graph) { + if (!switchStack.isEmpty() && !n.getLabel().isPresent()) { + graph.addNode(n); + graph.connect(prevNode, n); + brokenStmts.add(n); + prevNode = Collections.emptyList(); + return; + } + super.visit(n, graph); + } + @Override public void visit(ExpressionStmt es, CFG graph) { graph.addNode(es); diff --git a/src/test/res/mytest/BasicSwitch.java b/src/test/res/mytest/BasicSwitch.java new file mode 100644 index 0000000..1ea12d6 --- /dev/null +++ b/src/test/res/mytest/BasicSwitch.java @@ -0,0 +1,28 @@ +package mytest; + +public class BasicSwitch { + public static void main(String[] args) { + int x = Integer.valueOf(args[0]); + int y = -1; + switch (x) { + case 1: + y = 10; + break; + case 2: + y = 20; + break; + case 3: + y = 30; + break; + case 4: + case 5: + y = 100; + break; + case 6: + System.err.println("Error"); + case 10: + y = 0; + } + System.out.println(y); + } +} diff --git a/src/test/res/mytest/BasicSwitchDefault.java b/src/test/res/mytest/BasicSwitchDefault.java new file mode 100644 index 0000000..70262e3 --- /dev/null +++ b/src/test/res/mytest/BasicSwitchDefault.java @@ -0,0 +1,23 @@ +package mytest; + +public class BasicSwitchDefault { + public static void main(String[] args) { + int x = Integer.valueOf(args[0]); + int y; + switch (x % 3) { + case 0: + y = 10; + break; + case 1: + y = 20; + break; + case 2: + y = 30; + break; + default: + y = -1; + break; + } + System.out.println(y); + } +} diff --git a/src/test/res/mytest/BasicSwitchNoBreak.java b/src/test/res/mytest/BasicSwitchNoBreak.java new file mode 100644 index 0000000..ab94ff6 --- /dev/null +++ b/src/test/res/mytest/BasicSwitchNoBreak.java @@ -0,0 +1,16 @@ +package mytest; + +public class BasicSwitchNoBreak { + public static void main(String[] args) { + String res = ""; + switch (args[0]) { + case "a": + res = "abc"; + case "b": + res = "bac"; + case "c": + res = "cab"; + } + System.out.println(res); + } +}