From 5830c2400d45b005bd3304989d8e8004c2bc793c Mon Sep 17 00:00:00 2001 From: jacosro Date: Sun, 7 Jun 2020 22:59:01 +0200 Subject: [PATCH 1/3] Added output node to method declaration + changed return to output --- .../graphs/sdg/MethodCallReplacerVisitor.java | 26 +++++++++++++------ src/main/java/tfm/graphs/sdg/SDGBuilder.java | 22 ++++++++++++++++ src/main/java/tfm/nodes/type/NodeType.java | 2 ++ 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java b/src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java index 5331beb..e15337c 100644 --- a/src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java +++ b/src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java @@ -252,17 +252,27 @@ class MethodCallReplacerVisitor extends VoidVisitorAdapter { } } - // 'Return' node - GraphNode returnNode = sdg.addNode("return", new EmptyStmt(), TypeNodeFactory.fromType(NodeType.METHOD_CALL_RETURN)); - sdg.addControlDependencyArc(methodCallNode, returnNode); + // Add 'output' node of the call - sdg.addReturnArc(returnNode, originalMethodCallNode); + // First, check if method has an output node + Optional> optionalDeclarationOutputNode = sdg.outgoingEdgesOf(methodDeclarationNode).stream() + .filter(arc -> sdg.getEdgeTarget(arc).getNodeType() == NodeType.METHOD_OUTPUT) + .map(arc -> (GraphNode) sdg.getEdgeTarget(arc)) + .findFirst(); - methodCFG.vertexSet().stream() - .filter(node -> node.getAstNode() instanceof ReturnStmt) - .map(node -> (GraphNode) node) - .forEach(node -> sdg.addReturnArc(node, returnNode)); + if (!optionalDeclarationOutputNode.isPresent()) { + // Method return type is void, do nothing + return; + } + + GraphNode declarationOutputNode = optionalDeclarationOutputNode.get(); + + // If method has output node, then create output call node and link them + GraphNode callReturnNode = sdg.addNode("output", new EmptyStmt(), TypeNodeFactory.fromType(NodeType.METHOD_CALL_RETURN)); + sdg.addControlDependencyArc(methodCallNode, callReturnNode); + sdg.addReturnArc(callReturnNode, originalMethodCallNode); + sdg.addReturnArc(declarationOutputNode, callReturnNode); Logger.log("MethodCallReplacerVisitor", String.format("%s | Method '%s' called", methodCallExpr, methodDeclaration.getNameAsString())); } diff --git a/src/main/java/tfm/graphs/sdg/SDGBuilder.java b/src/main/java/tfm/graphs/sdg/SDGBuilder.java index 48701ea..ac5e95d 100644 --- a/src/main/java/tfm/graphs/sdg/SDGBuilder.java +++ b/src/main/java/tfm/graphs/sdg/SDGBuilder.java @@ -5,13 +5,19 @@ import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.expr.*; +import com.github.javaparser.ast.stmt.EmptyStmt; import com.github.javaparser.ast.stmt.ExpressionStmt; +import com.github.javaparser.ast.stmt.ReturnStmt; import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import tfm.arcs.Arc; import tfm.graphs.pdg.PDG; import tfm.nodes.GraphNode; +import tfm.nodes.TypeNodeFactory; +import tfm.nodes.type.NodeType; import tfm.utils.Context; +import java.lang.reflect.Type; + class SDGBuilder extends VoidVisitorAdapter { SDG sdg; @@ -53,6 +59,22 @@ class SDGBuilder extends VoidVisitorAdapter { // Add CFG sdg.setMethodCFG(methodDeclaration, pdg.getCfg()); + + // Add output node + if (methodDeclaration.getType().isVoidType()) { + // If method return type is void, do nothing + return; + } + + GraphNode outputNode = sdg.addNode("output", new EmptyStmt(), TypeNodeFactory.fromType(NodeType.METHOD_OUTPUT)); + + sdg.addControlDependencyArc(methodDeclarationNode, outputNode); + + // Add return arc from all return statements to the output node + pdg.getCfg().vertexSet().stream() + .filter(node -> node.getAstNode() instanceof ReturnStmt) + .map(node -> (GraphNode) node) + .forEach(node -> sdg.addReturnArc(node, outputNode)); } @Override diff --git a/src/main/java/tfm/nodes/type/NodeType.java b/src/main/java/tfm/nodes/type/NodeType.java index 1851d62..19f5a16 100644 --- a/src/main/java/tfm/nodes/type/NodeType.java +++ b/src/main/java/tfm/nodes/type/NodeType.java @@ -22,6 +22,8 @@ public enum NodeType { /** An argument or globally accessible variable that * has been modified in a method declaration. */ FORMAL_OUT, + /** A node representing the return value of a non-void method declaration. */ + METHOD_OUTPUT, /** A node representing the return value of a non-void method call. */ METHOD_CALL_RETURN, } -- GitLab From b51799999256d2f9590a303d90453ae37d11d519 Mon Sep 17 00:00:00 2001 From: jacosro Date: Sun, 7 Jun 2020 23:02:06 +0200 Subject: [PATCH 2/3] Remove METHOD_CALL_RETURN type --- src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java | 2 +- src/main/java/tfm/nodes/type/NodeType.java | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java b/src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java index e15337c..8a50152 100644 --- a/src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java +++ b/src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java @@ -268,7 +268,7 @@ class MethodCallReplacerVisitor extends VoidVisitorAdapter { GraphNode declarationOutputNode = optionalDeclarationOutputNode.get(); // If method has output node, then create output call node and link them - GraphNode callReturnNode = sdg.addNode("output", new EmptyStmt(), TypeNodeFactory.fromType(NodeType.METHOD_CALL_RETURN)); + GraphNode callReturnNode = sdg.addNode("output", new EmptyStmt(), TypeNodeFactory.fromType(NodeType.METHOD_OUTPUT)); sdg.addControlDependencyArc(methodCallNode, callReturnNode); sdg.addReturnArc(callReturnNode, originalMethodCallNode); diff --git a/src/main/java/tfm/nodes/type/NodeType.java b/src/main/java/tfm/nodes/type/NodeType.java index 19f5a16..8717239 100644 --- a/src/main/java/tfm/nodes/type/NodeType.java +++ b/src/main/java/tfm/nodes/type/NodeType.java @@ -23,7 +23,5 @@ public enum NodeType { * has been modified in a method declaration. */ FORMAL_OUT, /** A node representing the return value of a non-void method declaration. */ - METHOD_OUTPUT, - /** A node representing the return value of a non-void method call. */ - METHOD_CALL_RETURN, + METHOD_OUTPUT } -- GitLab From 71ef93c811eef4f3285512e66f25f07ae717ee93 Mon Sep 17 00:00:00 2001 From: jacosro Date: Mon, 8 Jun 2020 20:53:25 +0200 Subject: [PATCH 3/3] Apply requested changes --- .../java/tfm/arcs/pdg/DataDependencyArc.java | 4 ++++ src/main/java/tfm/arcs/sdg/ReturnArc.java | 16 ---------------- .../graphs/sdg/MethodCallReplacerVisitor.java | 13 ++++++++++--- src/main/java/tfm/graphs/sdg/SDG.java | 19 +++++-------------- src/main/java/tfm/graphs/sdg/SDGBuilder.java | 2 +- src/main/java/tfm/nodes/type/NodeType.java | 2 ++ 6 files changed, 22 insertions(+), 34 deletions(-) delete mode 100644 src/main/java/tfm/arcs/sdg/ReturnArc.java diff --git a/src/main/java/tfm/arcs/pdg/DataDependencyArc.java b/src/main/java/tfm/arcs/pdg/DataDependencyArc.java index 649f84c..a0c7725 100644 --- a/src/main/java/tfm/arcs/pdg/DataDependencyArc.java +++ b/src/main/java/tfm/arcs/pdg/DataDependencyArc.java @@ -21,6 +21,10 @@ public class DataDependencyArc extends Arc { super(variable); } + public DataDependencyArc() { + super(); + } + @Override public Map getDotAttributes() { Map map = super.getDotAttributes(); diff --git a/src/main/java/tfm/arcs/sdg/ReturnArc.java b/src/main/java/tfm/arcs/sdg/ReturnArc.java deleted file mode 100644 index ea3a55a..0000000 --- a/src/main/java/tfm/arcs/sdg/ReturnArc.java +++ /dev/null @@ -1,16 +0,0 @@ -package tfm.arcs.sdg; - -import org.jgrapht.io.Attribute; -import org.jgrapht.io.DefaultAttribute; -import tfm.arcs.Arc; - -import java.util.Map; - -public class ReturnArc extends Arc { - @Override - public Map getDotAttributes() { - Map map = super.getDotAttributes(); - map.put("style", DefaultAttribute.createAttribute("dashed")); - return map; - } -} diff --git a/src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java b/src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java index 8a50152..ab9d7cb 100644 --- a/src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java +++ b/src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java @@ -255,6 +255,13 @@ class MethodCallReplacerVisitor extends VoidVisitorAdapter { // Add 'output' node of the call // First, check if method has an output node + + if (methodDeclaration.getType().isVoidType()) { + return; + } + + // If not void, find the output node + Optional> optionalDeclarationOutputNode = sdg.outgoingEdgesOf(methodDeclarationNode).stream() .filter(arc -> sdg.getEdgeTarget(arc).getNodeType() == NodeType.METHOD_OUTPUT) .map(arc -> (GraphNode) sdg.getEdgeTarget(arc)) @@ -268,11 +275,11 @@ class MethodCallReplacerVisitor extends VoidVisitorAdapter { GraphNode declarationOutputNode = optionalDeclarationOutputNode.get(); // If method has output node, then create output call node and link them - GraphNode callReturnNode = sdg.addNode("output", new EmptyStmt(), TypeNodeFactory.fromType(NodeType.METHOD_OUTPUT)); + GraphNode callReturnNode = sdg.addNode("output", new EmptyStmt(), TypeNodeFactory.fromType(NodeType.METHOD_CALL_RETURN)); sdg.addControlDependencyArc(methodCallNode, callReturnNode); - sdg.addReturnArc(callReturnNode, originalMethodCallNode); - sdg.addReturnArc(declarationOutputNode, callReturnNode); + sdg.addDataDependencyArc(callReturnNode, originalMethodCallNode); + sdg.addParameterInOutArc(declarationOutputNode, callReturnNode); Logger.log("MethodCallReplacerVisitor", String.format("%s | Method '%s' called", methodCallExpr, methodDeclaration.getNameAsString())); } diff --git a/src/main/java/tfm/graphs/sdg/SDG.java b/src/main/java/tfm/graphs/sdg/SDG.java index c17afc2..56fe2d5 100644 --- a/src/main/java/tfm/graphs/sdg/SDG.java +++ b/src/main/java/tfm/graphs/sdg/SDG.java @@ -1,23 +1,17 @@ package tfm.graphs.sdg; import com.github.javaparser.ast.CompilationUnit; -import com.github.javaparser.ast.Node; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.MethodDeclaration; -import com.github.javaparser.ast.stmt.EmptyStmt; import com.github.javaparser.ast.stmt.ExpressionStmt; -import com.github.javaparser.ast.stmt.ReturnStmt; import tfm.arcs.Arc; -import tfm.arcs.cfg.ControlFlowArc; 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.graphs.Buildable; import tfm.graphs.Graph; import tfm.graphs.cfg.CFG; -import tfm.graphs.pdg.PDG; import tfm.nodes.*; import tfm.slicing.Slice; import tfm.slicing.Sliceable; @@ -26,9 +20,6 @@ import tfm.utils.Context; import tfm.utils.Utils; import java.util.*; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Collectors; public class SDG extends Graph implements Sliceable, Buildable> { private boolean built = false; @@ -74,6 +65,10 @@ public class SDG extends Graph implements Sliceable, Buildable from, GraphNode to) { + this.addDataDependencyArc(from, to, null); + } + public void addDataDependencyArc(GraphNode from, GraphNode to, String variable) { this.addEdge(from, to, new DataDependencyArc(variable)); } @@ -82,14 +77,10 @@ public class SDG extends Graph implements Sliceable, Buildable from, GraphNode to) { + public void addParameterInOutArc(GraphNode from, GraphNode to) { this.addEdge(from, to, new ParameterInOutArc()); } - public void addReturnArc(GraphNode from, GraphNode to) { - this.addEdge(from, to, new ReturnArc()); - } - public List> findDeclarationsOfVariable(String variable, GraphNode root) { return this.methodCFGMap.values().stream() .filter(cfg -> cfg.containsVertex(root)) diff --git a/src/main/java/tfm/graphs/sdg/SDGBuilder.java b/src/main/java/tfm/graphs/sdg/SDGBuilder.java index ac5e95d..98ca2ba 100644 --- a/src/main/java/tfm/graphs/sdg/SDGBuilder.java +++ b/src/main/java/tfm/graphs/sdg/SDGBuilder.java @@ -74,7 +74,7 @@ class SDGBuilder extends VoidVisitorAdapter { pdg.getCfg().vertexSet().stream() .filter(node -> node.getAstNode() instanceof ReturnStmt) .map(node -> (GraphNode) node) - .forEach(node -> sdg.addReturnArc(node, outputNode)); + .forEach(node -> sdg.addDataDependencyArc(node, outputNode)); } @Override diff --git a/src/main/java/tfm/nodes/type/NodeType.java b/src/main/java/tfm/nodes/type/NodeType.java index 8717239..c44bcaf 100644 --- a/src/main/java/tfm/nodes/type/NodeType.java +++ b/src/main/java/tfm/nodes/type/NodeType.java @@ -22,6 +22,8 @@ public enum NodeType { /** An argument or globally accessible variable that * has been modified in a method declaration. */ FORMAL_OUT, + /** 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 } -- GitLab