Visitador: added switchStmt with breaks

This commit is contained in:
Carlos Galindo 2019-04-03 15:34:25 +02:00
parent fcdab2da3f
commit 137d01938c
Signed by untrusted user who does not match committer: kauron
GPG key ID: 83E68706DEE119A3
4 changed files with 125 additions and 1 deletions

View file

@ -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);

View 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);
}
}

View 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);
}
}

View 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);
}
}