Loading src/main/java/tfm/arcs/pdg/DataDependencyArc.java +4 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,10 @@ public class DataDependencyArc extends Arc { super(variable); } public DataDependencyArc() { super(); } @Override public Map<String, Attribute> getDotAttributes() { Map<String, Attribute> map = super.getDotAttributes(); Loading src/main/java/tfm/arcs/sdg/ReturnArc.javadeleted 100644 → 0 +0 −16 Original line number Diff line number Diff line 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<String, Attribute> getDotAttributes() { Map<String, Attribute> map = super.getDotAttributes(); map.put("style", DefaultAttribute.createAttribute("dashed")); return map; } } src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java +25 −8 Original line number Diff line number Diff line Loading @@ -252,17 +252,34 @@ class MethodCallReplacerVisitor extends VoidVisitorAdapter<Context> { } } // 'Return' node GraphNode<EmptyStmt> 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 methodCFG.vertexSet().stream() .filter(node -> node.getAstNode() instanceof ReturnStmt) .map(node -> (GraphNode<ReturnStmt>) node) .forEach(node -> sdg.addReturnArc(node, returnNode)); if (methodDeclaration.getType().isVoidType()) { return; } // If not void, find the output node Optional<GraphNode<EmptyStmt>> optionalDeclarationOutputNode = sdg.outgoingEdgesOf(methodDeclarationNode).stream() .filter(arc -> sdg.getEdgeTarget(arc).getNodeType() == NodeType.METHOD_OUTPUT) .map(arc -> (GraphNode<EmptyStmt>) sdg.getEdgeTarget(arc)) .findFirst(); if (!optionalDeclarationOutputNode.isPresent()) { // Method return type is void, do nothing return; } GraphNode<EmptyStmt> declarationOutputNode = optionalDeclarationOutputNode.get(); // If method has output node, then create output call node and link them GraphNode<EmptyStmt> callReturnNode = sdg.addNode("output", new EmptyStmt(), TypeNodeFactory.fromType(NodeType.METHOD_CALL_RETURN)); sdg.addControlDependencyArc(methodCallNode, callReturnNode); sdg.addDataDependencyArc(callReturnNode, originalMethodCallNode); sdg.addParameterInOutArc(declarationOutputNode, callReturnNode); Logger.log("MethodCallReplacerVisitor", String.format("%s | Method '%s' called", methodCallExpr, methodDeclaration.getNameAsString())); } Loading src/main/java/tfm/graphs/sdg/SDG.java +5 −14 Original line number Diff line number Diff line 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.arcs.sdg.SummaryArc; 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; Loading @@ -27,9 +21,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<NodeList<CompilationUnit>> { private boolean built = false; Loading Loading @@ -75,6 +66,10 @@ public class SDG extends Graph implements Sliceable, Buildable<NodeList<Compilat this.addEdge(from, to, new ControlDependencyArc()); } public void addDataDependencyArc(GraphNode<?> from, GraphNode<?> to) { this.addDataDependencyArc(from, to, null); } public void addDataDependencyArc(GraphNode<?> from, GraphNode<?> to, String variable) { this.addEdge(from, to, new DataDependencyArc(variable)); } Loading @@ -83,14 +78,10 @@ public class SDG extends Graph implements Sliceable, Buildable<NodeList<Compilat this.addEdge(from, to, new CallArc()); } public void addParameterInOutArc(GraphNode<ExpressionStmt> from, GraphNode<ExpressionStmt> 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 void addSummaryArc(GraphNode<ExpressionStmt> from, GraphNode<ExpressionStmt> to) { this.addEdge(from, to, new SummaryArc()); } Loading src/main/java/tfm/graphs/sdg/SDGBuilder.java +19 −7 Original line number Diff line number Diff line Loading @@ -3,21 +3,17 @@ package tfm.graphs.sdg; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.stmt.ExpressionStmt; import com.github.javaparser.ast.stmt.EmptyStmt; 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.graphs.sdg.sumarcs.NaiveSummaryArcsBuilder; import tfm.graphs.sdg.sumarcs.SummaryArcsBuilder; import tfm.nodes.GraphNode; import tfm.nodes.TypeNodeFactory; import tfm.nodes.type.NodeType; import tfm.utils.Context; import tfm.utils.Utils; import java.util.HashSet; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; class SDGBuilder extends VoidVisitorAdapter<Context> { Loading Loading @@ -60,6 +56,22 @@ class SDGBuilder extends VoidVisitorAdapter<Context> { // Add CFG sdg.setMethodCFG(methodDeclaration, pdg.getCfg()); // Add output node if (methodDeclaration.getType().isVoidType()) { // If method return type is void, do nothing return; } GraphNode<EmptyStmt> 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<ReturnStmt>) node) .forEach(node -> sdg.addDataDependencyArc(node, outputNode)); } @Override Loading Loading
src/main/java/tfm/arcs/pdg/DataDependencyArc.java +4 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,10 @@ public class DataDependencyArc extends Arc { super(variable); } public DataDependencyArc() { super(); } @Override public Map<String, Attribute> getDotAttributes() { Map<String, Attribute> map = super.getDotAttributes(); Loading
src/main/java/tfm/arcs/sdg/ReturnArc.javadeleted 100644 → 0 +0 −16 Original line number Diff line number Diff line 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<String, Attribute> getDotAttributes() { Map<String, Attribute> map = super.getDotAttributes(); map.put("style", DefaultAttribute.createAttribute("dashed")); return map; } }
src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java +25 −8 Original line number Diff line number Diff line Loading @@ -252,17 +252,34 @@ class MethodCallReplacerVisitor extends VoidVisitorAdapter<Context> { } } // 'Return' node GraphNode<EmptyStmt> 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 methodCFG.vertexSet().stream() .filter(node -> node.getAstNode() instanceof ReturnStmt) .map(node -> (GraphNode<ReturnStmt>) node) .forEach(node -> sdg.addReturnArc(node, returnNode)); if (methodDeclaration.getType().isVoidType()) { return; } // If not void, find the output node Optional<GraphNode<EmptyStmt>> optionalDeclarationOutputNode = sdg.outgoingEdgesOf(methodDeclarationNode).stream() .filter(arc -> sdg.getEdgeTarget(arc).getNodeType() == NodeType.METHOD_OUTPUT) .map(arc -> (GraphNode<EmptyStmt>) sdg.getEdgeTarget(arc)) .findFirst(); if (!optionalDeclarationOutputNode.isPresent()) { // Method return type is void, do nothing return; } GraphNode<EmptyStmt> declarationOutputNode = optionalDeclarationOutputNode.get(); // If method has output node, then create output call node and link them GraphNode<EmptyStmt> callReturnNode = sdg.addNode("output", new EmptyStmt(), TypeNodeFactory.fromType(NodeType.METHOD_CALL_RETURN)); sdg.addControlDependencyArc(methodCallNode, callReturnNode); sdg.addDataDependencyArc(callReturnNode, originalMethodCallNode); sdg.addParameterInOutArc(declarationOutputNode, callReturnNode); Logger.log("MethodCallReplacerVisitor", String.format("%s | Method '%s' called", methodCallExpr, methodDeclaration.getNameAsString())); } Loading
src/main/java/tfm/graphs/sdg/SDG.java +5 −14 Original line number Diff line number Diff line 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.arcs.sdg.SummaryArc; 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; Loading @@ -27,9 +21,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<NodeList<CompilationUnit>> { private boolean built = false; Loading Loading @@ -75,6 +66,10 @@ public class SDG extends Graph implements Sliceable, Buildable<NodeList<Compilat this.addEdge(from, to, new ControlDependencyArc()); } public void addDataDependencyArc(GraphNode<?> from, GraphNode<?> to) { this.addDataDependencyArc(from, to, null); } public void addDataDependencyArc(GraphNode<?> from, GraphNode<?> to, String variable) { this.addEdge(from, to, new DataDependencyArc(variable)); } Loading @@ -83,14 +78,10 @@ public class SDG extends Graph implements Sliceable, Buildable<NodeList<Compilat this.addEdge(from, to, new CallArc()); } public void addParameterInOutArc(GraphNode<ExpressionStmt> from, GraphNode<ExpressionStmt> 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 void addSummaryArc(GraphNode<ExpressionStmt> from, GraphNode<ExpressionStmt> to) { this.addEdge(from, to, new SummaryArc()); } Loading
src/main/java/tfm/graphs/sdg/SDGBuilder.java +19 −7 Original line number Diff line number Diff line Loading @@ -3,21 +3,17 @@ package tfm.graphs.sdg; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.stmt.ExpressionStmt; import com.github.javaparser.ast.stmt.EmptyStmt; 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.graphs.sdg.sumarcs.NaiveSummaryArcsBuilder; import tfm.graphs.sdg.sumarcs.SummaryArcsBuilder; import tfm.nodes.GraphNode; import tfm.nodes.TypeNodeFactory; import tfm.nodes.type.NodeType; import tfm.utils.Context; import tfm.utils.Utils; import java.util.HashSet; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; class SDGBuilder extends VoidVisitorAdapter<Context> { Loading Loading @@ -60,6 +56,22 @@ class SDGBuilder extends VoidVisitorAdapter<Context> { // Add CFG sdg.setMethodCFG(methodDeclaration, pdg.getCfg()); // Add output node if (methodDeclaration.getType().isVoidType()) { // If method return type is void, do nothing return; } GraphNode<EmptyStmt> 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<ReturnStmt>) node) .forEach(node -> sdg.addDataDependencyArc(node, outputNode)); } @Override Loading