Commit a4c37974 authored by Carlos Galindo's avatar Carlos Galindo
Browse files

Merge branch 'callmarker-fixes' into 'develop'

Small fixes for future support of nested calls

See merge request !45
parents c4c00b25 16a059a1
Loading
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -127,18 +127,21 @@ public class CallGraph extends DirectedPseudograph<CallGraph.Vertex, CallGraph.E
            @Override
            public void visit(MethodCallExpr n, Void arg) {
                n.resolve().toAst().ifPresent(decl -> addEdge(declStack.peek(), decl, n));
                if (ASTUtils.shouldVisitArgumentsForMethodCalls(n))
                    super.visit(n, arg);
            }

            @Override
            public void visit(ObjectCreationExpr n, Void arg) {
                n.resolve().toAst().ifPresent(decl -> addEdge(declStack.peek(), decl, n));
                if (ASTUtils.shouldVisitArgumentsForMethodCalls(n))
                    super.visit(n, arg);
            }

            @Override
            public void visit(ExplicitConstructorInvocationStmt n, Void arg) {
                n.resolve().toAst().ifPresent(decl -> addEdge(declStack.peek(), decl, n));
                if (ASTUtils.shouldVisitArgumentsForMethodCalls(n))
                    super.visit(n, arg);
            }
        }, null);
+16 −15
Original line number Diff line number Diff line
@@ -11,6 +11,8 @@ import es.upv.mist.slicing.nodes.VariableAction;
import es.upv.mist.slicing.nodes.io.ActualIONode;
import es.upv.mist.slicing.nodes.io.CallNode;

import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

@@ -111,31 +113,30 @@ public class PDG extends GraphWithRootNode<CallableDeclaration<?>> {
         */
        protected void expandCalls() {
            for (GraphNode<?> graphNode : Set.copyOf(vertexSet())) {
                CallNode callNode = null;
                Deque<CallNode> callNodeStack = new LinkedList<>();
                for (VariableAction action : List.copyOf(graphNode.getVariableActions())) {
                    if (action instanceof VariableAction.CallMarker) {
                        callNode = updateCallNode(graphNode, (VariableAction.CallMarker) action);
                        // Compute the call node, if entering the marker. Additionally, it places the node
                        // in the graph and makes it control-dependent on its container.
                        if (!((VariableAction.CallMarker) action).isEnter()) {
                            callNodeStack.pop();
                        } else {
                            CallNode callNode = CallNode.create(((VariableAction.CallMarker) action).getCall());
                            addVertex(callNode);
                            addControlDependencyArc(graphNode, callNode);
                            callNodeStack.push(callNode);
                        }
                    } else if (action instanceof VariableAction.Movable) {
                        // Move the variable to its own node, add that node to the graph and connect it.
                        var movable = (VariableAction.Movable) action;
                        movable.move(PDG.this);
                        connectRealNode(graphNode, callNode, movable.getRealNode());
                        connectRealNode(graphNode, callNodeStack.peek(), movable.getRealNode());
                    }
                }
                assert callNode == null;
                assert callNodeStack.isEmpty();
            }
        }

        /** Compute the call node, if entering the marker. Additionally, it places the node
         * in the graph and makes it control-dependent on its container. */
        protected CallNode updateCallNode(GraphNode<?> graphNode, VariableAction.CallMarker marker) {
            if (!marker.isEnter())
                return null;
            var callNode = CallNode.create(marker.getCall());
            addVertex(callNode);
            addControlDependencyArc(graphNode, callNode);
            return callNode;
        }

        /** Connects the real node to the proper parent, control-dependent-wise. */
        protected void connectRealNode(GraphNode<?> graphNode, CallNode callNode, GraphNode<?> realNode) {
            if (realNode instanceof ActualIONode || realNode instanceof CallNode.Return) {
+1 −1
Original line number Diff line number Diff line
@@ -211,7 +211,7 @@ public class VariableVisitor extends GraphNodeContentVisitor<VariableVisitor.Act

    /** Tries to resolve and add the corresponding call markers. */
    protected boolean visitCall(Resolvable<? extends ResolvedMethodLikeDeclaration> call, Action arg) {
        if (ASTUtils.getResolvedAST(call.resolve()).isEmpty() || graphNode == null)
        if (ASTUtils.shouldVisitArgumentsForMethodCalls(call, graphNode))
            return true;
        graphNode.addCallMarker(call, true);
        ASTUtils.getResolvableScope(call).ifPresent(s -> s.accept(this, arg));
+9 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclarat
import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedMethodLikeDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration;
import es.upv.mist.slicing.nodes.GraphNode;

import java.util.List;
import java.util.Objects;
@@ -117,4 +118,12 @@ public class ASTUtils {
            return ((ResolvedConstructorDeclaration) resolvedDeclaration).toAst();
        throw new IllegalStateException("AST node of invalid type");
    }

    public static boolean shouldVisitArgumentsForMethodCalls(Resolvable<? extends ResolvedMethodLikeDeclaration> call) {
        return getResolvedAST(call.resolve()).isEmpty();
    }

    public static boolean shouldVisitArgumentsForMethodCalls(Resolvable<? extends ResolvedMethodLikeDeclaration> call, GraphNode<?> graphNode) {
        return shouldVisitArgumentsForMethodCalls(call) || graphNode == null;
    }
}