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;
|
package grafos;
|
||||||
|
|
||||||
import com.github.javaparser.ast.Node;
|
import com.github.javaparser.ast.Node;
|
||||||
|
import com.github.javaparser.ast.NodeList;
|
||||||
import com.github.javaparser.ast.body.MethodDeclaration;
|
import com.github.javaparser.ast.body.MethodDeclaration;
|
||||||
import com.github.javaparser.ast.expr.Expression;
|
import com.github.javaparser.ast.expr.Expression;
|
||||||
import com.github.javaparser.ast.stmt.*;
|
import com.github.javaparser.ast.stmt.*;
|
||||||
|
@ -9,6 +10,7 @@ import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
public class Visitador extends VoidVisitorAdapter<CFG> {
|
public class Visitador extends VoidVisitorAdapter<CFG> {
|
||||||
//********************************************************/
|
//********************************************************/
|
||||||
|
@ -16,6 +18,8 @@ public class Visitador extends VoidVisitorAdapter<CFG> {
|
||||||
//********************************************************/
|
//********************************************************/
|
||||||
|
|
||||||
private List<Node> prevNode;
|
private List<Node> prevNode;
|
||||||
|
private Stack<SwitchStmt> switchStack = new Stack<>();
|
||||||
|
private List<BreakStmt> brokenStmts = new LinkedList<>();
|
||||||
|
|
||||||
//********************************************************/
|
//********************************************************/
|
||||||
//*********************** Metodos ************************/
|
//*********************** Metodos ************************/
|
||||||
|
@ -139,7 +143,7 @@ public class Visitador extends VoidVisitorAdapter<CFG> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ForeachStmt n, CFG graph) {
|
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.addNode(copy);
|
||||||
graph.connect(prevNode, copy);
|
graph.connect(prevNode, copy);
|
||||||
prevNode = Collections.singletonList(copy);
|
prevNode = Collections.singletonList(copy);
|
||||||
|
@ -148,6 +152,59 @@ public class Visitador extends VoidVisitorAdapter<CFG> {
|
||||||
prevNode = Collections.singletonList(copy);
|
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
|
@Override
|
||||||
public void visit(ExpressionStmt es, CFG graph) {
|
public void visit(ExpressionStmt es, CFG graph) {
|
||||||
graph.addNode(es);
|
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