Unverified Commit 7c29ef7b authored by Javier Costa's avatar Javier Costa Committed by GitHub
Browse files

Merge pull request #36 from jacosro/35-return-node

Added output node to method declaration + changed return to output
parents c48ab8ea c8508e47
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -21,6 +21,10 @@ public class DataDependencyArc extends Arc {
        super(variable);
    }

    public DataDependencyArc() {
        super();
    }

    @Override
    public Map<String, Attribute> getDotAttributes() {
        Map<String, Attribute> map = super.getDotAttributes();
+0 −16
Original line number Diff line number Diff line
package tfm.arcs.sdg;

import org.jgrapht.io.Attribute;
import org.jgrapht.io.DefaultAttribute;
import tfm.arcs.Arc;

import java.util.Map;

public class ReturnArc extends Arc {
    @Override
    public Map<String, Attribute> getDotAttributes() {
        Map<String, Attribute> map = super.getDotAttributes();
        map.put("style", DefaultAttribute.createAttribute("dashed"));
        return map;
    }
}
+25 −8
Original line number Diff line number Diff line
@@ -252,17 +252,34 @@ 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

        methodCFG.vertexSet().stream()
            .filter(node -> node.getAstNode() instanceof ReturnStmt)
            .map(node -> (GraphNode<ReturnStmt>) node)
            .forEach(node -> sdg.addReturnArc(node, returnNode));
        if (methodDeclaration.getType().isVoidType()) {
            return;
        }

        // If not void, find the 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();

        // 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.addDataDependencyArc(callReturnNode, originalMethodCallNode);
        sdg.addParameterInOutArc(declarationOutputNode, callReturnNode);

        Logger.log("MethodCallReplacerVisitor", String.format("%s | Method '%s' called", methodCallExpr, methodDeclaration.getNameAsString()));
    }
+5 −14
Original line number Diff line number Diff line
package tfm.graphs.sdg;

import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.stmt.EmptyStmt;
import com.github.javaparser.ast.stmt.ExpressionStmt;
import com.github.javaparser.ast.stmt.ReturnStmt;
import tfm.arcs.Arc;
import tfm.arcs.cfg.ControlFlowArc;
import tfm.arcs.pdg.ControlDependencyArc;
import tfm.arcs.pdg.DataDependencyArc;
import tfm.arcs.sdg.CallArc;
import tfm.arcs.sdg.ParameterInOutArc;
import tfm.arcs.sdg.ReturnArc;
import tfm.arcs.sdg.SummaryArc;
import tfm.graphs.Buildable;
import tfm.graphs.Graph;
import tfm.graphs.cfg.CFG;
import tfm.graphs.pdg.PDG;
import tfm.nodes.*;
import tfm.slicing.Slice;
import tfm.slicing.Sliceable;
@@ -27,9 +21,6 @@ import tfm.utils.Context;
import tfm.utils.Utils;

import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class SDG extends Graph implements Sliceable, Buildable<NodeList<CompilationUnit>> {
    private boolean built = false;
@@ -75,6 +66,10 @@ public class SDG extends Graph implements Sliceable, Buildable<NodeList<Compilat
        this.addEdge(from, to, new ControlDependencyArc());
    }

    public void addDataDependencyArc(GraphNode<?> from, GraphNode<?> to) {
        this.addDataDependencyArc(from, to, null);
    }

    public void addDataDependencyArc(GraphNode<?> from, GraphNode<?> to, String variable) {
        this.addEdge(from, to, new DataDependencyArc(variable));
    }
@@ -83,14 +78,10 @@ public class SDG extends Graph implements Sliceable, Buildable<NodeList<Compilat
        this.addEdge(from, to, new CallArc());
    }

    public void addParameterInOutArc(GraphNode<ExpressionStmt> from, GraphNode<ExpressionStmt> to) {
    public void addParameterInOutArc(GraphNode<?> from, GraphNode<?> to) {
        this.addEdge(from, to, new ParameterInOutArc());
    }

    public void addReturnArc(GraphNode<?> from, GraphNode<?> to) {
        this.addEdge(from, to, new ReturnArc());
    }

    public void addSummaryArc(GraphNode<ExpressionStmt> from, GraphNode<ExpressionStmt> to) {
        this.addEdge(from, to, new SummaryArc());
    }
+19 −7
Original line number Diff line number Diff line
@@ -3,21 +3,17 @@ package tfm.graphs.sdg;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.stmt.ExpressionStmt;
import com.github.javaparser.ast.stmt.EmptyStmt;
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.graphs.sdg.sumarcs.NaiveSummaryArcsBuilder;
import tfm.graphs.sdg.sumarcs.SummaryArcsBuilder;
import tfm.nodes.GraphNode;
import tfm.nodes.TypeNodeFactory;
import tfm.nodes.type.NodeType;
import tfm.utils.Context;
import tfm.utils.Utils;

import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

class SDGBuilder extends VoidVisitorAdapter<Context> {

@@ -60,6 +56,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.addDataDependencyArc(node, outputNode));
    }

    @Override
Loading