Commit 5830c240 authored by jacosro's avatar jacosro
Browse files

Added output node to method declaration + changed return to output

parent 8c87900a
Loading
Loading
Loading
Loading
+18 −8
Original line number Diff line number Diff line
@@ -252,17 +252,27 @@ class MethodCallReplacerVisitor extends VoidVisitorAdapter<Context> {
            }
        }

        // 'Return' node
        GraphNode<EmptyStmt> returnNode = sdg.addNode("return", new EmptyStmt(), TypeNodeFactory.fromType(NodeType.METHOD_CALL_RETURN));
        sdg.addControlDependencyArc(methodCallNode, returnNode);
        // Add 'output' node of the call

        sdg.addReturnArc(returnNode, originalMethodCallNode);
        // First, check if method has an output node
        Optional<GraphNode<EmptyStmt>> optionalDeclarationOutputNode = sdg.outgoingEdgesOf(methodDeclarationNode).stream()
                .filter(arc -> sdg.getEdgeTarget(arc).getNodeType() == NodeType.METHOD_OUTPUT)
                .map(arc -> (GraphNode<EmptyStmt>) sdg.getEdgeTarget(arc))
                .findFirst();

        if (!optionalDeclarationOutputNode.isPresent()) {
            // Method return type is void, do nothing
            return;
        }

        GraphNode<EmptyStmt> declarationOutputNode = optionalDeclarationOutputNode.get();

        methodCFG.vertexSet().stream()
            .filter(node -> node.getAstNode() instanceof ReturnStmt)
            .map(node -> (GraphNode<ReturnStmt>) node)
            .forEach(node -> sdg.addReturnArc(node, returnNode));
        // If method has output node, then create output call node and link them
        GraphNode<EmptyStmt> callReturnNode = sdg.addNode("output", new EmptyStmt(), TypeNodeFactory.fromType(NodeType.METHOD_CALL_RETURN));

        sdg.addControlDependencyArc(methodCallNode, callReturnNode);
        sdg.addReturnArc(callReturnNode, originalMethodCallNode);
        sdg.addReturnArc(declarationOutputNode, callReturnNode);

        Logger.log("MethodCallReplacerVisitor", String.format("%s | Method '%s' called", methodCallExpr, methodDeclaration.getNameAsString()));
    }
+22 −0
Original line number Diff line number Diff line
@@ -5,13 +5,19 @@ import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.stmt.EmptyStmt;
import com.github.javaparser.ast.stmt.ExpressionStmt;
import com.github.javaparser.ast.stmt.ReturnStmt;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import tfm.arcs.Arc;
import tfm.graphs.pdg.PDG;
import tfm.nodes.GraphNode;
import tfm.nodes.TypeNodeFactory;
import tfm.nodes.type.NodeType;
import tfm.utils.Context;

import java.lang.reflect.Type;

class SDGBuilder extends VoidVisitorAdapter<Context> {

    SDG sdg;
@@ -53,6 +59,22 @@ class SDGBuilder extends VoidVisitorAdapter<Context> {

        // Add CFG
        sdg.setMethodCFG(methodDeclaration, pdg.getCfg());

        // Add output node
        if (methodDeclaration.getType().isVoidType()) {
            // If method return type is void, do nothing
            return;
        }

        GraphNode<EmptyStmt> outputNode = sdg.addNode("output", new EmptyStmt(), TypeNodeFactory.fromType(NodeType.METHOD_OUTPUT));

        sdg.addControlDependencyArc(methodDeclarationNode, outputNode);

        // Add return arc from all return statements to the output node
        pdg.getCfg().vertexSet().stream()
                .filter(node -> node.getAstNode() instanceof ReturnStmt)
                .map(node -> (GraphNode<ReturnStmt>) node)
                .forEach(node -> sdg.addReturnArc(node, outputNode));
    }

    @Override
+2 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ public enum NodeType {
    /** An argument or globally accessible variable that
     *  has been modified in a method declaration. */
    FORMAL_OUT,
    /** A node representing the return value of a non-void method declaration. */
    METHOD_OUTPUT,
    /** A node representing the return value of a non-void method call. */
    METHOD_CALL_RETURN,
}