Newer
Older
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.stmt.ExpressionStmt;
import com.github.javaparser.ast.stmt.ForEachStmt;
import com.github.javaparser.ast.stmt.IfStmt;
import com.github.javaparser.ast.stmt.WhileStmt;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import tfm.scopes.IfElseScope;
import tfm.scopes.Scope;
import tfm.scopes.ScopeHolder;
import tfm.scopes.VariableScope;
import tfm.variables.actions.VariableDefinition;
import tfm.variables.actions.VariableUse;
import java.util.List;
import java.util.Set;
public class PDGVisitor extends VoidVisitorAdapter<ScopeHolder<PDGNode>> {
// private VariableSet variableSet;
protected PDGGraph graph;
protected ScopeHolder<PDGNode> globalScope;
public PDGVisitor(PDGGraph graph, ScopeHolder<PDGNode> scopeHolder) {
public void visit(ExpressionStmt n, ScopeHolder<PDGNode> scope) {
PDGNode expressionNode = graph.addNode(expression.toString(), n);
graph.addControlDependencyArc(scope.getRoot(), expressionNode);
VariableScope<PDGNode> expressionScope = new VariableScope<>(expressionNode);
new VariableExtractor()
.setOnVariableDeclarationListener(variable ->
expressionScope.addVariableDeclaration(variable, expressionNode)
expressionScope.addVariableDefinition(variable, expressionNode)
expressionScope.addVariableUse(variable, expressionNode);
Scope<PDGNode> searchScope = scope.isVariableDefined(variable) ? scope : globalScope;
searchScope.getLastDefinitions(variable)
.forEach(variableDefinition -> graph.addDataDependencyArc(
variableDefinition.getNode(),
expressionNode,
variable
));
public void visit(IfStmt ifStmt, ScopeHolder<PDGNode> scope) {
PDGNode ifNode = graph.addNode(
String.format("if (%s)", ifStmt.getCondition().toString()),
graph.addControlDependencyArc(scope.getRoot(), ifNode);
ScopeHolder<PDGNode> ifScope = ifStmt.hasElseBranch() ? new IfElseScope<>(ifNode) : new ScopeHolder<>(ifNode);
new VariableExtractor()
.setOnVariableUseListener(variable -> {
Scope<PDGNode> searchScope = scope.isVariableDefined(variable) ? scope : globalScope;
searchScope.getLastDefinitions(variable)
.forEach(variableDefinition ->
graph.addDataDependencyArc(
variableDefinition.getNode(),
ifNode,
variable
)
);
if (!ifStmt.hasElseBranch()) {
ifStmt.getThenStmt().accept(this, ifScope);
} else {
@SuppressWarnings("unchecked")
IfElseScope<PDGNode> ifElseScope = (IfElseScope<PDGNode>) ifScope;
ifStmt.getThenStmt().accept(this, ifElseScope.getThenScope());
ifStmt.getElseStmt().get().accept(this, ifElseScope.getElseScope());
}
public void visit(WhileStmt whileStmt, ScopeHolder<PDGNode> scope) {
// assert whileStmt.getBegin().isPresent();
PDGNode whileNode = graph.addNode(
String.format("while (%s)", whileStmt.getCondition().toString()),
graph.addControlDependencyArc(scope.getRoot(), whileNode);
ScopeHolder<PDGNode> whileScope = new ScopeHolder<>(whileNode);
new VariableExtractor()
.setOnVariableUseListener(variable -> {
Scope<PDGNode> searchScope = scope.isVariableDefined(variable) ? scope : globalScope;
searchScope.getLastDefinitions(variable)
.forEach(variableDefinition -> graph.addDataDependencyArc(
variableDefinition.getNode(),
whileNode,
variable
));
})
.visit(whileStmt.getCondition());
buildLoopDataDependencies(whileScope);
scope.addSubscope(whileScope);
}
private void buildLoopDataDependencies(ScopeHolder<PDGNode> scope) {
scope.getDefinedVariables()
List<VariableDefinition<PDGNode>> firstDef = scope.getFirstDefinitions(variable);
List<VariableDefinition<PDGNode>> lastDef = scope.getLastDefinitions(variable);
Set<Integer> usesFromLastDef = new HashSet<>();
scope.getVariableUsesBeforeNode(variable, variableDefinition.getNode())
.forEach(use -> {
if (!usesFromLastDef.contains(use.getNode().getId())) {
lastDef.forEach(def -> graph.addDataDependencyArc(
def.getNode(),
use.getNode(),
variable)
);
usesFromLastDef.add(use.getNode().getId());
}
});
}
// // 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));
// }
public void visit(ForEachStmt forEachStmt, ScopeHolder<PDGNode> scope) {
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
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
// // 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);
// public void visit(SwitchStmt switchStmt, PDGNode node) {
// PDGNode switchNode = graph.addNode(switchStmt.toString());
//
// graph.addControlDependencyArc(parent, switchNode);
//
// switchStmt.getSelector().accept(this, parent);
// switchStmt.getEntries()
// .forEach(switchEntryStmt -> switchEntryStmt.accept(this, switchNode));
// }