Visitador: added switchStmt with breaks
This commit is contained in:
parent
fcdab2da3f
commit
137d01938c
4 changed files with 125 additions and 1 deletions
|
@ -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<CFG> {
|
||||
//********************************************************/
|
||||
|
@ -16,6 +18,8 @@ public class Visitador extends VoidVisitorAdapter<CFG> {
|
|||
//********************************************************/
|
||||
|
||||
private List<Node> prevNode;
|
||||
private Stack<SwitchStmt> switchStack = new Stack<>();
|
||||
private List<BreakStmt> brokenStmts = new LinkedList<>();
|
||||
|
||||
//********************************************************/
|
||||
//*********************** Metodos ************************/
|
||||
|
@ -139,7 +143,7 @@ public class Visitador extends VoidVisitorAdapter<CFG> {
|
|||
|
||||
@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<CFG> {
|
|||
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);
|
||||
|
|
28
src/test/res/mytest/BasicSwitch.java
Normal file
28
src/test/res/mytest/BasicSwitch.java
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
23
src/test/res/mytest/BasicSwitchDefault.java
Normal file
23
src/test/res/mytest/BasicSwitchDefault.java
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
16
src/test/res/mytest/BasicSwitchNoBreak.java
Normal file
16
src/test/res/mytest/BasicSwitchNoBreak.java
Normal file
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue