Commit 4fa5dfb8 authored by Javier Costa's avatar Javier Costa
Browse files

Merge branch 'develop' into ES-SDG

parents 4a9a5b6e ee4c9719
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -325,6 +325,16 @@ public class CFGBuilder extends VoidVisitorAdapter<Void> {
        returnList.stream().filter(node -> !hangingNodes.contains(node)).forEach(hangingNodes::add);

        createAndConnectFormalOutNodes(methodDeclaration);
        
        // Create and connect formal-out nodes sequentially
        for (Parameter param : methodDeclaration.getParameters()) {
            // Do not generate out for primitives
            if (param.getType().isPrimitiveType()) {
                continue;
            }

            connectTo(addFormalOutGraphNode(param));
        }
        // Create and connect the exit node
        connectTo(graph.addNode("Exit", new EmptyStmt(), TypeNodeFactory.fromType(NodeType.METHOD_EXIT)));
    }
+2 −0
Original line number Diff line number Diff line
@@ -59,10 +59,12 @@ public class MethodCallReplacerVisitor extends GraphNodeContentVisitor<Void> {
        for (int i = 0; i < parameters.size(); i++) {
            Parameter parameter = parameters.get(i);
            Expression argument;

            if (!parameter.isVarArgs()) {
                argument = arguments.get(i);
            } else {
                NodeList<Expression> varArgs = new NodeList<>(arguments.subList(i, arguments.size()));

                argument = new ArrayCreationExpr(
                        parameter.getType(),
                        new NodeList<>(new ArrayCreationLevel(varArgs.size())),
+1 −1
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ public class SDG extends Graph implements Sliceable, Buildable<NodeList<Compilat
        this.addEdge(from, to, new ParameterInOutArc());
    }

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

+28 −28
Original line number Diff line number Diff line
package tfm.graphs.sdg.sumarcs;

import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.stmt.ExpressionStmt;
import tfm.arcs.Arc;
import tfm.graphs.sdg.SDG;
import tfm.nodes.GraphNode;
@@ -34,19 +33,19 @@ public class NaiveSummaryArcsBuilder extends SummaryArcsBuilder {
    @Override
    public void visit() {
        for (GraphNode<MethodDeclaration> methodDeclarationNode : findAllMethodDeclarations()) {
            Set<GraphNode<ExpressionStmt>> formalOutNodes = sdg.outgoingEdgesOf(methodDeclarationNode).stream()
                    .filter(arc -> sdg.getEdgeTarget(arc).getNodeType() == NodeType.FORMAL_OUT)
                    .map(arc -> (GraphNode<ExpressionStmt>) sdg.getEdgeTarget(arc))
            Set<GraphNode<?>> formalOutNodes = sdg.outgoingEdgesOf(methodDeclarationNode).stream()
                    .filter(arc -> sdg.getEdgeTarget(arc).getNodeType().is(NodeType.FORMAL_OUT))
                    .map(arc -> (GraphNode<?>) sdg.getEdgeTarget(arc))
                    .collect(Collectors.toSet());

            for (GraphNode<ExpressionStmt> formalOutNode : formalOutNodes) {
                Set<GraphNode<ExpressionStmt>> reachableFormalInNodes = this.findReachableFormalInNodes(formalOutNode);
            for (GraphNode<?> formalOutNode : formalOutNodes) {
                Set<GraphNode<?>> reachableFormalInNodes = this.findReachableFormalInNodes(formalOutNode);

                Set<GraphNode<ExpressionStmt>> actualInNodes = reachableFormalInNodes.stream().flatMap(this::getActualInsStream).collect(Collectors.toSet());
                Set<GraphNode<ExpressionStmt>> actualOutNodes = this.getActualOuts(formalOutNode);
                Set<GraphNode<?>> actualInNodes = reachableFormalInNodes.stream().flatMap(this::getActualInsStream).collect(Collectors.toSet());
                Set<GraphNode<?>> actualOutNodes = this.getActualOuts(formalOutNode);

                for (GraphNode<ExpressionStmt> actualOutNode : actualOutNodes) {
                    for (GraphNode<ExpressionStmt> actualInNode : actualInNodes) {
                for (GraphNode<?> actualOutNode : actualOutNodes) {
                    for (GraphNode<?> actualInNode : actualInNodes) {
                        if (this.belongToSameMethodCall(actualInNode, actualOutNode)) {
                            sdg.addSummaryArc(actualInNode, actualOutNode);
                        }
@@ -56,17 +55,17 @@ public class NaiveSummaryArcsBuilder extends SummaryArcsBuilder {
        }
    }

    private Set<GraphNode<ExpressionStmt>> findReachableFormalInNodes(GraphNode<ExpressionStmt> formalOutNode) {
    private Set<GraphNode<?>> findReachableFormalInNodes(GraphNode<?> formalOutNode) {
        return this.doFindReachableFormalInNodes(formalOutNode, Utils.emptySet());
    }

    private Set<GraphNode<ExpressionStmt>> doFindReachableFormalInNodes(GraphNode<?> root, Set<Long> visited) {
    private Set<GraphNode<?>> doFindReachableFormalInNodes(GraphNode<?> root, Set<Long> visited) {
        visited.add(root.getId());

        Set<GraphNode<ExpressionStmt>> res = Utils.emptySet();
        Set<GraphNode<?>> res = Utils.emptySet();

        if (root.getNodeType() == NodeType.FORMAL_IN) {
            res.add((GraphNode<ExpressionStmt>) root);
        if (root.getNodeType().is(NodeType.FORMAL_IN)) {
            res.add(root);
        } else {
            for (Arc arc : sdg.incomingEdgesOf(root)) {
                GraphNode<?> nextNode = sdg.getEdgeSource(arc);
@@ -84,33 +83,34 @@ public class NaiveSummaryArcsBuilder extends SummaryArcsBuilder {
        return res;
    }

    private Stream<GraphNode<ExpressionStmt>> getActualInsStream(GraphNode<ExpressionStmt> formalIn) {
    private Stream<GraphNode<?>> getActualInsStream(GraphNode<?> formalIn) {
        return sdg.incomingEdgesOf(formalIn).stream()
                .filter(Arc::isParameterInOutArc)
                .filter(arc -> sdg.getEdgeSource(arc).getNodeType() == NodeType.ACTUAL_IN)
                .map(arc -> (GraphNode<ExpressionStmt>) sdg.getEdgeSource(arc));
                .filter(arc -> sdg.getEdgeSource(arc).getNodeType().is(NodeType.ACTUAL_IN))
                .map(arc -> sdg.getEdgeSource(arc));
    }

    private Set<GraphNode<ExpressionStmt>> getActualOuts(GraphNode<ExpressionStmt> formalOut) {
    private Set<GraphNode<?>> getActualOuts(GraphNode<?> formalOut) {
        return sdg.outgoingEdgesOf(formalOut).stream()
                .filter(Arc::isParameterInOutArc)
                .filter(arc -> sdg.getEdgeTarget(arc).getNodeType() == NodeType.ACTUAL_OUT)
                .map(arc -> (GraphNode<ExpressionStmt>) sdg.getEdgeTarget(arc))
                .filter(arc -> sdg.getEdgeTarget(arc).getNodeType().is(NodeType.ACTUAL_OUT))
                .map(arc -> (GraphNode<?>) sdg.getEdgeTarget(arc))
                .collect(Collectors.toSet());
    }

    private boolean belongToSameMethodCall(GraphNode<ExpressionStmt> actualIn, GraphNode<ExpressionStmt> actualOut) {
        Optional<GraphNode<ExpressionStmt>> optionalInCallNode = this.getCallNode(actualIn);
        Optional<GraphNode<ExpressionStmt>> optionalOutCallNode = this.getCallNode(actualOut);
    private boolean belongToSameMethodCall(GraphNode<?> actualIn, GraphNode<?> actualOut) {
        Optional<GraphNode<?>> optionalInCallNode = this.getCallNode(actualIn);
        Optional<GraphNode<?>> optionalOutCallNode = this.getCallNode(actualOut);

        return optionalInCallNode.isPresent() && optionalOutCallNode.isPresent()
                && optionalInCallNode.get() == optionalOutCallNode.get();
    }

    private Optional<GraphNode<ExpressionStmt>> getCallNode(GraphNode<ExpressionStmt> actualInOrOut) {
    private Optional<GraphNode<?>> getCallNode(GraphNode<?> actualInOrOut) {
        return sdg.incomingEdgesOf(actualInOrOut).stream()
                .filter(arc -> sdg.getEdgeSource(arc).getNodeType() == NodeType.METHOD_CALL)
                .map(arc -> (GraphNode<ExpressionStmt>) sdg.getEdgeSource(arc))
                .findFirst();
                .filter(arc -> sdg.getEdgeSource(arc).getNodeType().is(NodeType.METHOD_CALL))
                .map(arc -> sdg.getEdgeSource(arc))
                .findFirst()
                .map(node -> (GraphNode<?>) node);
    }
}
+17 −1
Original line number Diff line number Diff line
@@ -33,5 +33,21 @@ public enum NodeType {
    /** A node representing the return value of a non-void method call. */
    METHOD_CALL_RETURN,
    /** A node representing the return value of a non-void method declaration. */
    METHOD_OUTPUT
    METHOD_OUTPUT;

    public boolean is(NodeType type) {
        if (this == type) {
            return true;
        }

        if (this == METHOD_CALL_RETURN) {
            return type == ACTUAL_OUT;
        }

        if (this == METHOD_OUTPUT) {
            return type == FORMAL_OUT;
        }

        return false;
    }
}