Skip to content
PDGVisitor.java 9.34 KiB
Newer Older
Javier Costa's avatar
Javier Costa committed
package tfm.visitors;
Javier Costa's avatar
Javier Costa committed

import com.github.javaparser.ast.expr.Expression;
Javier Costa's avatar
Javier Costa committed
import com.github.javaparser.ast.stmt.*;
Javier Costa's avatar
Javier Costa committed
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
Javier Costa's avatar
Javier Costa committed
import tfm.graphs.PDGGraph;
Javier Costa's avatar
Javier Costa committed
import tfm.nodes.PDGNode;
Javier Costa's avatar
Javier Costa committed
import tfm.variables.VariableSet;
import tfm.variables.actions.VariableDeclaration;
import tfm.variables.actions.VariableDefinition;
Javier Costa's avatar
Javier Costa committed

Javier Costa's avatar
Javier Costa committed
import java.util.ArrayList;
import java.util.List;
Javier Costa's avatar
Javier Costa committed
public class PDGVisitor extends VoidVisitorAdapter<PDGNode> {
Javier Costa's avatar
Javier Costa committed

Javier Costa's avatar
Javier Costa committed
    private VariableSet variableSet;
Javier Costa's avatar
Javier Costa committed
    private PDGGraph graph;

Javier Costa's avatar
Javier Costa committed
    // 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;

Javier Costa's avatar
Javier Costa committed
    public PDGVisitor(PDGGraph graph) {
        this.graph = graph;
Javier Costa's avatar
Javier Costa committed
        this.variableSet = new VariableSet();
        this.variablesUsedInLoopCondition = new ArrayList<>();
        this.variablesUsedInLoopBody = new ArrayList<>();
Javier Costa's avatar
Javier Costa committed
    }

    @Override
Javier Costa's avatar
Javier Costa committed
    public void visit(ExpressionStmt n, PDGNode parent) {
Javier Costa's avatar
Javier Costa committed
        Expression expression = n.getExpression();
Javier Costa's avatar
Javier Costa committed

Javier Costa's avatar
Javier Costa committed
        PDGNode expressionNode = graph.addNode(expression.toString(), n.getBegin().get().line);
Javier Costa's avatar
Javier Costa committed

Javier Costa's avatar
Javier Costa committed
        graph.addControlDependencyArc(parent, expressionNode);
Javier Costa's avatar
Javier Costa committed
        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);
Javier Costa's avatar
Javier Costa committed
                        }
Javier Costa's avatar
Javier Costa committed
                })
                .setOnVariableUse(variable -> {
                    variableSet.getLastDefinitionOf(variable, expressionNode)
                        .ifPresent(variableDefinition -> graph.addDataDependencyArc(
                                (PDGNode) variableDefinition.getNode(),
                                expressionNode,
                                variable
                        ));
//                    variableSet.addUse(variable, new VariableUse(expressionNode));
                })
                .visit(expression);
Javier Costa's avatar
Javier Costa committed
    public void visit(IfStmt ifStmt, PDGNode parent) {
Javier Costa's avatar
Javier Costa committed
        PDGNode ifNode = graph.addNode(
                String.format("if (%s)", ifStmt.getCondition().toString()),
                ifStmt.getBegin().get().line
        );

        graph.addControlDependencyArc(parent, ifNode);

Javier Costa's avatar
Javier Costa committed
        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());
Javier Costa's avatar
Javier Costa committed

Javier Costa's avatar
Javier Costa committed
        // 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));
Javier Costa's avatar
Javier Costa committed
    public void visit(WhileStmt whileStmt, PDGNode parent) {
Javier Costa's avatar
Javier Costa committed
        // assert whileStmt.getBegin().isPresent();

        PDGNode whileNode = graph.addNode(
                String.format("while (%s)", whileStmt.getCondition().toString()),
                whileStmt.getBegin().get().line
        );

        graph.addControlDependencyArc(parent, whileNode);

Javier Costa's avatar
Javier Costa committed
        variablesUsedInLoopCondition.clear();
//        variablesUsedInLoopBody.clear();
Javier Costa's avatar
Javier Costa committed

Javier Costa's avatar
Javier Costa committed
        new VariableVisitor()
                .setOnVariableUse(variable -> {
                    variablesUsedInLoopCondition.add(variable);
                    variableSet.getLastDefinitionOf(variable, whileNode)
                            .ifPresent(variableDefinition -> graph.addDataDependencyArc(
                                    (PDGNode) variableDefinition.getNode(),
                                    whileNode,
                                    variable
                            ));
                })
                .visit(whileStmt.getCondition());
Javier Costa's avatar
Javier Costa committed
//        inLoop = true;
Javier Costa's avatar
Javier Costa committed
        whileStmt.getBody().accept(this, whileNode);
Javier Costa's avatar
Javier Costa committed
        new VariableVisitor()
                .setOnVariableUse(variable ->
                        variableSet.getLastDefinitionOf(variable)
                            .ifPresent(variableDefinition -> graph.addDataDependencyArc(
                                    (PDGNode) variableDefinition.getNode(),
                                    whileNode
                            ))
                )
                .visit(whileStmt.getBody());
Javier Costa's avatar
Javier Costa committed

//        inLoop = false;
        variablesUsedInLoopCondition.clear();
//        variablesUsedInLoopBody.clear();
Javier Costa's avatar
Javier Costa committed

Javier Costa's avatar
Javier Costa committed
//    @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));
//    }

Javier Costa's avatar
Javier Costa committed
    @Override
Javier Costa's avatar
Javier Costa committed
    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);
Javier Costa's avatar
Javier Costa committed

//    @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));
//    }
Javier Costa's avatar
Javier Costa committed
}