From 0dde2d97d89230440b93c2af8a4cd92c8740cd1e Mon Sep 17 00:00:00 2001 From: Carlos Galindo Date: Wed, 16 Dec 2020 12:20:04 +0100 Subject: [PATCH 1/2] Partial support for nested calls: unify behaviour of NOT visiting nested calls. * CallGraph, VariableVisitor: unify visit arguments behaviour to avoid lookup errors of calls by the CallGraph that were not registered by VariableVisitor. --- .../main/java/es/upv/mist/slicing/graphs/CallGraph.java | 9 ++++++--- .../java/es/upv/mist/slicing/nodes/VariableVisitor.java | 2 +- .../main/java/es/upv/mist/slicing/utils/ASTUtils.java | 9 +++++++++ 3 files changed, 16 insertions(+), 4 deletions(-) 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 2d7cb4b..75c407b 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/nodes/VariableVisitor.java b/sdg-core/src/main/java/es/upv/mist/slicing/nodes/VariableVisitor.java index 7f4f590..fffef92 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 d67b16f..d0f9ec5 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; + } } -- GitLab From 16a059a1da296f831d2b2c90268a1f21f4912c45 Mon Sep 17 00:00:00 2001 From: Carlos Galindo Date: Wed, 16 Dec 2020 12:23:50 +0100 Subject: [PATCH 2/2] Nested call support: call markers need to be analyzed as a stack. --- .../es/upv/mist/slicing/graphs/pdg/PDG.java | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) 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 dbeb00c..d361b90 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) { -- GitLab