From 2ff95c0ca9d595c28a5c900865d78418f29e55fd Mon Sep 17 00:00:00 2001 From: jacosro Date: Thu, 11 Jun 2020 01:16:22 +0200 Subject: [PATCH] Added support for node subtypes --- src/main/java/tfm/arcs/Arc.java | 12 ---- src/main/java/tfm/graphs/sdg/SDG.java | 2 +- .../sdg/sumarcs/NaiveSummaryArcsBuilder.java | 56 +++++++++---------- src/main/java/tfm/nodes/type/NodeType.java | 18 +++++- 4 files changed, 46 insertions(+), 42 deletions(-) diff --git a/src/main/java/tfm/arcs/Arc.java b/src/main/java/tfm/arcs/Arc.java index 950ae8f..ef0ffd5 100644 --- a/src/main/java/tfm/arcs/Arc.java +++ b/src/main/java/tfm/arcs/Arc.java @@ -7,7 +7,6 @@ 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.nodes.GraphNode; @@ -87,17 +86,6 @@ public abstract class Arc extends DefaultEdge { throw new UnsupportedOperationException("Not a ParameterInOutArc"); } - /** @see ReturnArc */ - public final boolean isReturnArc() { - return this instanceof ReturnArc; - } - - public final ReturnArc asReturnArc() { - if (isReturnArc()) - return (ReturnArc) this; - throw new UnsupportedOperationException("Not a ReturnArc"); - } - /** @see SummaryArc */ public final boolean isSummaryArc() { return this instanceof SummaryArc; diff --git a/src/main/java/tfm/graphs/sdg/SDG.java b/src/main/java/tfm/graphs/sdg/SDG.java index bcabf95..8f524de 100644 --- a/src/main/java/tfm/graphs/sdg/SDG.java +++ b/src/main/java/tfm/graphs/sdg/SDG.java @@ -82,7 +82,7 @@ public class SDG extends Graph implements Sliceable, Buildable from, GraphNode to) { + public void addSummaryArc(GraphNode from, GraphNode to) { this.addEdge(from, to, new SummaryArc()); } diff --git a/src/main/java/tfm/graphs/sdg/sumarcs/NaiveSummaryArcsBuilder.java b/src/main/java/tfm/graphs/sdg/sumarcs/NaiveSummaryArcsBuilder.java index 8f11678..f2eb784 100644 --- a/src/main/java/tfm/graphs/sdg/sumarcs/NaiveSummaryArcsBuilder.java +++ b/src/main/java/tfm/graphs/sdg/sumarcs/NaiveSummaryArcsBuilder.java @@ -1,7 +1,6 @@ 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; @@ -27,19 +26,19 @@ public class NaiveSummaryArcsBuilder extends SummaryArcsBuilder { GraphNode methodDeclarationNode = optionalMethodDeclarationNode.get(); - Set> formalOutNodes = sdg.outgoingEdgesOf(methodDeclarationNode).stream() - .filter(arc -> sdg.getEdgeTarget(arc).getNodeType() == NodeType.FORMAL_OUT) - .map(arc -> (GraphNode) sdg.getEdgeTarget(arc)) + Set> 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 formalOutNode : formalOutNodes) { - Set> reachableFormalInNodes = this.findReachableFormalInNodes(formalOutNode); + for (GraphNode formalOutNode : formalOutNodes) { + Set> reachableFormalInNodes = this.findReachableFormalInNodes(formalOutNode); - Set> actualInNodes = reachableFormalInNodes.stream().flatMap(this::getActualInsStream).collect(Collectors.toSet()); - Set> actualOutNodes = this.getActualOuts(formalOutNode); + Set> actualInNodes = reachableFormalInNodes.stream().flatMap(this::getActualInsStream).collect(Collectors.toSet()); + Set> actualOutNodes = this.getActualOuts(formalOutNode); - for (GraphNode actualOutNode : actualOutNodes) { - for (GraphNode actualInNode : actualInNodes) { + for (GraphNode actualOutNode : actualOutNodes) { + for (GraphNode actualInNode : actualInNodes) { if (this.belongToSameMethodCall(actualInNode, actualOutNode)) { sdg.addSummaryArc(actualInNode, actualOutNode); } @@ -49,17 +48,17 @@ public class NaiveSummaryArcsBuilder extends SummaryArcsBuilder { } } - private Set> findReachableFormalInNodes(GraphNode formalOutNode) { + private Set> findReachableFormalInNodes(GraphNode formalOutNode) { return this.doFindReachableFormalInNodes(formalOutNode, Utils.emptySet()); } - private Set> doFindReachableFormalInNodes(GraphNode root, Set visited) { + private Set> doFindReachableFormalInNodes(GraphNode root, Set visited) { visited.add(root.getId()); - Set> res = Utils.emptySet(); + Set> res = Utils.emptySet(); - if (root.getNodeType() == NodeType.FORMAL_IN) { - res.add((GraphNode) root); + if (root.getNodeType().is(NodeType.FORMAL_IN)) { + res.add(root); } else { for (Arc arc : sdg.incomingEdgesOf(root)) { GraphNode nextNode = sdg.getEdgeSource(arc); @@ -77,33 +76,34 @@ public class NaiveSummaryArcsBuilder extends SummaryArcsBuilder { return res; } - private Stream> getActualInsStream(GraphNode formalIn) { + private Stream> getActualInsStream(GraphNode formalIn) { return sdg.incomingEdgesOf(formalIn).stream() .filter(Arc::isParameterInOutArc) - .filter(arc -> sdg.getEdgeSource(arc).getNodeType() == NodeType.ACTUAL_IN) - .map(arc -> (GraphNode) sdg.getEdgeSource(arc)); + .filter(arc -> sdg.getEdgeSource(arc).getNodeType().is(NodeType.ACTUAL_IN)) + .map(arc -> sdg.getEdgeSource(arc)); } - private Set> getActualOuts(GraphNode formalOut) { + private Set> getActualOuts(GraphNode formalOut) { return sdg.outgoingEdgesOf(formalOut).stream() .filter(Arc::isParameterInOutArc) - .filter(arc -> sdg.getEdgeTarget(arc).getNodeType() == NodeType.ACTUAL_OUT) - .map(arc -> (GraphNode) 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 actualIn, GraphNode actualOut) { - Optional> optionalInCallNode = this.getCallNode(actualIn); - Optional> optionalOutCallNode = this.getCallNode(actualOut); + private boolean belongToSameMethodCall(GraphNode actualIn, GraphNode actualOut) { + Optional> optionalInCallNode = this.getCallNode(actualIn); + Optional> optionalOutCallNode = this.getCallNode(actualOut); return optionalInCallNode.isPresent() && optionalOutCallNode.isPresent() && optionalInCallNode.get() == optionalOutCallNode.get(); } - private Optional> getCallNode(GraphNode actualInOrOut) { + private Optional> getCallNode(GraphNode actualInOrOut) { return sdg.incomingEdgesOf(actualInOrOut).stream() - .filter(arc -> sdg.getEdgeSource(arc).getNodeType() == NodeType.METHOD_CALL) - .map(arc -> (GraphNode) sdg.getEdgeSource(arc)) - .findFirst(); + .filter(arc -> sdg.getEdgeSource(arc).getNodeType().is(NodeType.METHOD_CALL)) + .map(arc -> sdg.getEdgeSource(arc)) + .findFirst() + .map(node -> (GraphNode) node); } } diff --git a/src/main/java/tfm/nodes/type/NodeType.java b/src/main/java/tfm/nodes/type/NodeType.java index c44bcaf..acfabdb 100644 --- a/src/main/java/tfm/nodes/type/NodeType.java +++ b/src/main/java/tfm/nodes/type/NodeType.java @@ -25,5 +25,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; + } } -- GitLab