diff --git a/sdg-core/src/main/java/es/upv/mist/slicing/graphs/CallGraph.java b/sdg-core/src/main/java/es/upv/mist/slicing/graphs/CallGraph.java index 2d7cb4bdc662b2168e6961732cc1912da603e0c1..75c407b10592a2b3a50b52e5c9092b54ac4e6d56 100644 --- a/sdg-core/src/main/java/es/upv/mist/slicing/graphs/CallGraph.java +++ b/sdg-core/src/main/java/es/upv/mist/slicing/graphs/CallGraph.java @@ -127,19 +127,22 @@ public class CallGraph extends DirectedPseudograph addEdge(declStack.peek(), decl, n)); - super.visit(n, arg); + 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)); - super.visit(n, arg); + 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)); - super.visit(n, arg); + if (ASTUtils.shouldVisitArgumentsForMethodCalls(n)) + super.visit(n, arg); } }, null); } diff --git a/sdg-core/src/main/java/es/upv/mist/slicing/graphs/pdg/PDG.java b/sdg-core/src/main/java/es/upv/mist/slicing/graphs/pdg/PDG.java index dbeb00cd8f05e29260ef810031a24c3c6133d1be..d361b90025ef79a79dae0eee6f3a71e2101a6a7e 100644 --- a/sdg-core/src/main/java/es/upv/mist/slicing/graphs/pdg/PDG.java +++ b/sdg-core/src/main/java/es/upv/mist/slicing/graphs/pdg/PDG.java @@ -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> { */ protected void expandCalls() { for (GraphNode graphNode : Set.copyOf(vertexSet())) { - CallNode callNode = null; + Deque 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) { diff --git a/sdg-core/src/main/java/es/upv/mist/slicing/nodes/VariableVisitor.java b/sdg-core/src/main/java/es/upv/mist/slicing/nodes/VariableVisitor.java index 7f4f590db768568dac6b4d84f7550b3754c31516..fffef9244a673cc8fa9a65acff36012d10e975ec 100644 --- a/sdg-core/src/main/java/es/upv/mist/slicing/nodes/VariableVisitor.java +++ b/sdg-core/src/main/java/es/upv/mist/slicing/nodes/VariableVisitor.java @@ -211,7 +211,7 @@ public class VariableVisitor extends GraphNodeContentVisitor 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)); diff --git a/sdg-core/src/main/java/es/upv/mist/slicing/utils/ASTUtils.java b/sdg-core/src/main/java/es/upv/mist/slicing/utils/ASTUtils.java index d67b16f0e68404cd35f4cbc0b7d5cff19a2005dc..d0f9ec5533bc9baa6fc165c37ff0500769adece8 100644 --- a/sdg-core/src/main/java/es/upv/mist/slicing/utils/ASTUtils.java +++ b/sdg-core/src/main/java/es/upv/mist/slicing/utils/ASTUtils.java @@ -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 call) { + return getResolvedAST(call.resolve()).isEmpty(); + } + + public static boolean shouldVisitArgumentsForMethodCalls(Resolvable call, GraphNode graphNode) { + return shouldVisitArgumentsForMethodCalls(call) || graphNode == null; + } }