Newer
Older
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.visitor.GenericVisitor;
import com.github.javaparser.ast.visitor.VoidVisitor;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import tfm.utils.Logger;
public class CFGVisitor extends VoidVisitorAdapter<Void> {
private CFGGraph graph;
public CFGVisitor(CFGGraph graph) {
this.graph = graph;
this.lastParentNodes = Collections.asLifoQueue(
new ArrayDeque<>(
)
);
}
@Override
public void visit(ExpressionStmt expressionStmt, Void arg) {
String expression = expressionStmt.toString().replace("\"", "\\\"");
CFGNode nextNode = addNodeAndArcs(expression, expressionStmt);
}
// @Override
// public void visit(VariableDeclarationExpr variableDeclarationExpr, Void arg) {
// CFGNode<String> nextNode = addNodeAndArcs(variableDeclarationExpr.toString());
// Logger.log(variableDeclarationExpr);
//
// super.visit(variableDeclarationExpr, arg);
// }
@Override
public void visit(IfStmt ifStmt, Void arg) {
String.format("if (%s)", ifStmt.getCondition().toString()),
);
lastParentNodes.add(ifCondition);
// Visit "then"
Queue<CFGNode> lastThenNodes = new ArrayDeque<>(lastParentNodes);
if (ifStmt.hasElseBranch()) {
lastParentNodes.clear();
lastParentNodes.add(ifCondition); // Set if nodes as root
lastParentNodes.addAll(lastThenNodes);
} else {
lastParentNodes.add(ifCondition);
}
}
@Override
public void visit(WhileStmt whileStmt, Void arg) {
String.format("while (%s)", whileStmt.getCondition().toString()),
while (!lastParentNodes.isEmpty()) {
graph.addControlFlowEdge(lastParentNodes.poll(), whileCondition);
}
lastParentNodes.add(whileCondition);
}
@Override
public void visit(DoStmt doStmt, Void arg) {
BlockStmt body = Utils.blockWrapper(doStmt.getBody());
body.accept(this, arg);
CFGNode doWhileNode = addNodeAndArcs(
String.format("while (%s)", doStmt.getCondition()),
doStmt
);
if (!body.isEmpty()) {
Statement firstBodyStatement = body.getStatement(0);
graph.findNodeByStatement(firstBodyStatement)
.ifPresent(node -> graph.addControlFlowEdge(doWhileNode, node));
}
lastParentNodes.add(doWhileNode);
}
@Override
public void visit(ForStmt forStmt, Void arg) {
// String inizialization = forStmt.getInitialization().stream()
// .map(Node::toString)
// .collect(Collectors.joining(","));
//
// String update = forStmt.getUpdate().stream()
// .map(Node::toString)
// .collect(Collectors.joining(","));
Expression comparison = forStmt.getCompare().orElse(new BooleanLiteralExpr(true));
forStmt.getInitialization().forEach(expression -> new ExpressionStmt(expression).accept(this, null));
forStmt
);
lastParentNodes.add(forNode);
BlockStmt body = Utils.blockWrapper(forStmt.getBody());
body.accept(this, arg);
while (!lastParentNodes.isEmpty()) {
graph.addControlFlowEdge(lastParentNodes.poll(), forNode);
}
@Override
public void visit(ForEachStmt forEachStmt, Void arg) {
CFGNode foreachNode = addNodeAndArcs(
String.format("for (%s : %s)", forEachStmt.getVariable(), forEachStmt.getIterable()),
forEachStmt
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
lastParentNodes.add(foreachNode);
forEachStmt.getBody().accept(this, arg);
while (!lastParentNodes.isEmpty()) {
graph.addControlFlowEdge(lastParentNodes.poll(), foreachNode);
}
lastParentNodes.add(foreachNode);
}
@Override
public void visit(SwitchStmt switchStmt, Void arg) {
CFGNode switchNode = addNodeAndArcs(
String.format("switch (%s)", switchStmt.getSelector()),
switchStmt
);
lastParentNodes.add(switchNode);
List<CFGNode> lastEntryParents = new ArrayList<>();
switchStmt.getEntries().forEach(entry -> {
Optional<BreakStmt> entryBreak = entry.findFirst(BreakStmt.class, breakStmt -> {
Optional<Node> parent = breakStmt.getParentNode();
return parent.isPresent() && parent.get() .equals(entry);
});
new BlockStmt(entry.getStatements()).accept(this, arg);
if (entryBreak.isPresent()) {
while (!lastParentNodes.isEmpty()) {
lastEntryParents.add(lastParentNodes.poll());
}
}
lastParentNodes.add(switchNode);
});
lastParentNodes.clear();
lastParentNodes.addAll(lastEntryParents);
}
@Override
public void visit(BreakStmt breakStmt, Void arg) {
}
@Override
public void visit(ContinueStmt continueStmt, Void arg) {
@Override
public void visit(MethodDeclaration methodDeclaration, Void arg) {
super.visit(methodDeclaration, arg);
private CFGNode addNodeAndArcs(String nodeData, Statement statement) {
CFGNode node = graph.addNode(nodeData, statement);
CFGNode parent = lastParentNodes.poll(); // ALWAYS exists a parent