Newer
Older
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import tfm.variables.VariableSet;
import tfm.variables.actions.VariableDeclaration;
import tfm.variables.actions.VariableDefinition;
import java.util.ArrayList;
import java.util.List;
public class PDGVisitor extends VoidVisitorAdapter<PDGNode> {
// For loops: store variables used in conditions to look for their definitions in body
private List<String> variablesUsedInLoopCondition;
private List<String> variablesUsedInLoopBody;
private boolean inLoop;
public PDGVisitor(PDGGraph graph) {
this.graph = graph;
this.variableSet = new VariableSet();
this.variablesUsedInLoopCondition = new ArrayList<>();
this.variablesUsedInLoopBody = new ArrayList<>();
public void visit(ExpressionStmt n, PDGNode parent) {
PDGNode expressionNode = graph.addNode(expression.toString(), n.getBegin().get().line);
new VariableVisitor()
.setOnVariableDeclaration(variable ->
variableSet.addVariable(variable, new VariableDeclaration(expressionNode)))
.setOnVariableDefinition(variable -> {
variableSet.addDefinition(variable, new VariableDefinition(expressionNode));
if (variablesUsedInLoopCondition.contains(variable)) {
graph.addDataDependencyArc(expressionNode, parent, variable);
})
.setOnVariableUse(variable -> {
variableSet.getLastDefinitionOf(variable, expressionNode)
.ifPresent(variableDefinition -> graph.addDataDependencyArc(
(PDGNode) variableDefinition.getNode(),
expressionNode,
variable
));
// variableSet.addUse(variable, new VariableUse(expressionNode));
})
.visit(expression);
PDGNode ifNode = graph.addNode(
String.format("if (%s)", ifStmt.getCondition().toString()),
ifStmt.getBegin().get().line
);
graph.addControlDependencyArc(parent, ifNode);
new VariableVisitor()
.setOnVariableUse(variable -> {
variableSet.getLastDefinitionOf(variable, ifNode)
.ifPresent(variableDefinition -> graph.addDataDependencyArc(
(PDGNode) variableDefinition.getNode(),
ifNode,
variable
));
// variableSet.addUse(variable, new VariableUse(expressionNode));
})
.visit(ifStmt.getCondition());
// Default adapter visits else before then, we have to visit then branch first
ifStmt.getThenStmt().accept(this, ifNode);
ifStmt.getElseStmt().ifPresent(statement -> statement.accept(this, ifNode));
public void visit(WhileStmt whileStmt, PDGNode parent) {
// assert whileStmt.getBegin().isPresent();
PDGNode whileNode = graph.addNode(
String.format("while (%s)", whileStmt.getCondition().toString()),
whileStmt.getBegin().get().line
);
graph.addControlDependencyArc(parent, whileNode);
variablesUsedInLoopCondition.clear();
// variablesUsedInLoopBody.clear();
new VariableVisitor()
.setOnVariableUse(variable -> {
variablesUsedInLoopCondition.add(variable);
variableSet.getLastDefinitionOf(variable, whileNode)
.ifPresent(variableDefinition -> graph.addDataDependencyArc(
(PDGNode) variableDefinition.getNode(),
whileNode,
variable
));
})
.visit(whileStmt.getCondition());
new VariableVisitor()
.setOnVariableUse(variable ->
variableSet.getLastDefinitionOf(variable)
.ifPresent(variableDefinition -> graph.addDataDependencyArc(
(PDGNode) variableDefinition.getNode(),
whileNode
))
)
.visit(whileStmt.getBody());
// inLoop = false;
variablesUsedInLoopCondition.clear();
// variablesUsedInLoopBody.clear();
}
// @Override
// public void visit(ForStmt forStmt, PDGNode parent) {
// // Add initialization nodes
// forStmt.getInitialization().stream()
// .map(expression -> graph.addNode(expression.toString()))
// .forEach(pdgVertex -> graph.addControlDependencyArc(parent, pdgVertex));
//
// // Add condition node
// Expression condition = forStmt.getCompare().orElse(new BooleanLiteralExpr(true));
// PDGNode conditionNode = graph.addNode(condition.toString());
//
// graph.addControlDependencyArc(parent, conditionNode);
//
// // Visit for
// super.visit(forStmt, conditionNode);
//
// // Add update vertex
// forStmt.getUpdate().stream()
// .map(expression -> graph.addNode(expression.toString()))
// .forEach(pdgVertex -> graph.addControlDependencyArc(conditionNode, pdgVertex));
// }
158
159
160
161
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
public void visit(ForEachStmt forEachStmt, PDGNode parent) {
// // Initializer
// VariableDeclarationExpr iterator = new VariableDeclarationExpr(
// new VariableDeclarator(
// JavaParser.parseClassOrInterfaceType("Iterator"),
// "iterator",
// new ConditionalExpr(
// new MethodCallExpr(
// new MethodCallExpr(
// forEachStmt.getIterable(),
// "getClass"
// ),
// "isArray"
// ),
// new MethodCallExpr(
// new NameExpr("Arrays"),
// "asList",
// new NodeList<>(
// forEachStmt.getIterable()
// )
// ),
// new CastExpr(
// JavaParser.parseClassOrInterfaceType("Iterable"),
// new CastExpr(
// JavaParser.parseClassOrInterfaceType("Object"),
// forEachStmt.getIterable()
// )
// )
// )
// )
// );
//
// // Compare
// MethodCallExpr iteratorHasNext = new MethodCallExpr(
// new NameExpr("iterator"),
// "hasNext"
// );
//
// // Body
// Type variableType = forEachStmt.getVariable().getCommonType();
// String variableName = forEachStmt.getVariable().getVariables().get(0).getNameAsString();
//
// BlockStmt foreachBody = Utils.blockWrapper(forEachStmt.getBody());
// foreachBody.getStatements().addFirst(
// new ExpressionStmt(
// new VariableDeclarationExpr(
// new VariableDeclarator(
// variableType,
// variableName,
// new CastExpr(
// variableType,
// new MethodCallExpr(
// new NameExpr("iterator"),
// "next"
// )
// )
// )
// )
// )
// );
//
// new ForStmt(new NodeList<>(iterator), iteratorHasNext, new NodeList<>(), foreachBody)
// .accept(this, parent);
// @Override
// public void visit(SwitchStmt switchStmt, PDGNode parent) {
// PDGNode switchNode = graph.addNode(switchStmt.toString());
//
// graph.addControlDependencyArc(parent, switchNode);
//
// switchStmt.getSelector().accept(this, parent);
// switchStmt.getEntries()
// .forEach(switchEntryStmt -> switchEntryStmt.accept(this, switchNode));
// }