Loading src/main/java/tfm/graphs/Graph.java +0 −6 Original line number Diff line number Diff line Loading @@ -58,12 +58,6 @@ public abstract class Graph extends DirectedPseudograph<GraphNode<?>, Arc> { .collect(Collectors.joining(System.lineSeparator())); } public List<GraphNode<?>> findDeclarationsOfVariable(String variable) { return vertexSet().stream() .filter(node -> node.getDeclaredVariables().contains(variable)) .collect(Collectors.toList()); } public boolean isEmpty() { return this.vertexSet().isEmpty(); } Loading src/main/java/tfm/graphs/pdg/PDG.java +8 −0 Original line number Diff line number Diff line Loading @@ -12,7 +12,9 @@ import tfm.slicing.Slice; import tfm.slicing.SlicingCriterion; import tfm.utils.NodeNotFoundException; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; /** * The <b>Program Dependence Graph</b> represents the statements of a method in Loading Loading @@ -77,4 +79,10 @@ public class PDG extends GraphWithRootNode<MethodDeclaration> implements Sliceab public boolean isBuilt() { return built; } public List<GraphNode<?>> findDeclarationsOfVariable(String variable) { return vertexSet().stream() .filter(node -> node.getDeclaredVariables().contains(variable)) .collect(Collectors.toList()); } } src/main/java/tfm/graphs/sdg/MethodCallReplacer.java +3 −1 Original line number Diff line number Diff line package tfm.graphs.sdg; import com.github.javaparser.ast.body.MethodDeclaration; import tfm.graphs.GraphWithRootNode; import tfm.nodes.GraphNode; import tfm.utils.Context; import tfm.utils.Logger; Loading @@ -20,7 +22,7 @@ class MethodCallReplacer { .forEach(context -> { Logger.log("MethodCallReplacer", context); Optional<GraphNode<?>> optionalRootNode = this.sdg.getRootNode(context); Optional<GraphNode<MethodDeclaration>> optionalRootNode = this.sdg.getRootNode(context); if (!optionalRootNode.isPresent()) { return; // We don't have visited the code (e.g. the MethodDeclaration for a method call) Loading src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java +16 −4 Original line number Diff line number Diff line Loading @@ -24,14 +24,26 @@ import java.util.stream.Collectors; class MethodCallReplacerVisitor extends VoidVisitorAdapter<Context> { private PDG pdg; private SDG sdg; private GraphNode<ExpressionStmt> methodCallNode; public MethodCallReplacerVisitor() { } public MethodCallReplacerVisitor(PDG pdg) { this.pdg = pdg; public MethodCallReplacerVisitor(SDG sdg) { this.sdg = sdg; } @Override public void visit(ExpressionStmt n, Context arg) { Optional<GraphNode<ExpressionStmt>> optionalNode = sdg.findNodeByASTNode(n); assert optionalNode.isPresent(); methodCallNode = optionalNode.get(); super.visit(n, arg); } @Override Loading Loading @@ -66,7 +78,7 @@ class MethodCallReplacerVisitor extends VoidVisitorAdapter<Context> { if (!Objects.equals(scopeName, currentClass.getNameAsString())) { // Check if 'scopeName' is a variable List<GraphNode<?>> declarations = pdg.findDeclarationsOfVariable(scopeName); List<GraphNode<?>> declarations = sdg.findDeclarationsOfVariable(scopeName, methodCallNode); if (declarations.isEmpty()) { // It is a static method call of another class. We do nothing Loading src/main/java/tfm/graphs/sdg/SDG.java +57 −10 Original line number Diff line number Diff line Loading @@ -4,12 +4,14 @@ import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.stmt.ExpressionStmt; import tfm.arcs.Arc; import tfm.arcs.pdg.ControlDependencyArc; import tfm.arcs.pdg.DataDependencyArc; import tfm.arcs.sdg.CallArc; import tfm.arcs.sdg.ParameterInOutArc; import tfm.graphs.Buildable; import tfm.graphs.Graph; import tfm.graphs.pdg.PDG; import tfm.nodes.*; import tfm.slicing.Slice; import tfm.slicing.Sliceable; Loading @@ -17,14 +19,16 @@ import tfm.slicing.SlicingCriterion; import tfm.utils.Context; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; public class SDG extends Graph implements Sliceable, Buildable<NodeList<CompilationUnit>> { private boolean built = false; private Map<Context, Long> contextToRootNodeId; private Map<Context, Long> contextToMethodRoot; public SDG() { this.contextToRootNodeId = new HashMap<>(); this.contextToMethodRoot = new HashMap<>(); } @Override Loading @@ -43,21 +47,45 @@ public class SDG extends Graph implements Sliceable, Buildable<NodeList<Compilat } public Set<Context> getContexts() { return contextToRootNodeId.keySet(); return contextToMethodRoot.keySet(); } public Optional<GraphNode<?>> getRootNode(Context context) { Long id = this.contextToRootNodeId.get(context); @SuppressWarnings("unchecked") public List<GraphNode<MethodDeclaration>> getMethodRoots() { return contextToMethodRoot.values().stream() .map(id -> findNodeById(id)) .filter(Optional::isPresent) .map(optional -> (GraphNode<MethodDeclaration>) optional.get()) .collect(Collectors.toList()); } @SuppressWarnings("unchecked") public Optional<GraphNode<MethodDeclaration>> getRootNode(Context context) { Long id = this.contextToMethodRoot.get(context); if (id == null) { return Optional.empty(); } return id != null ? findNodeById(id) : Optional.empty(); return findNodeById(id).map(node -> (GraphNode<MethodDeclaration>) node); } public void addRootNode(Context context, long id) { if (!findNodeById(id).isPresent()) { throw new IllegalArgumentException("Cannot add root node to SDG: " + id + " is not in graph!"); if (!findNodeById(id).isPresent()) throw new IllegalArgumentException("Root node with id " + id + " is not contained in graph!"); this.contextToMethodRoot.put(new Context(context), id); } public void addRootNode(Context context, GraphNode<MethodDeclaration> node) { addRootNode(context, node.getId()); } this.contextToRootNodeId.put(new Context(context), id); public Optional<Context> getContext(long id) { return contextToMethodRoot.entrySet().stream() .filter(entry -> Objects.equals(entry.getValue(), id)) .findFirst() .map(Map.Entry::getKey); } public void addControlDependencyArc(GraphNode<?> from, GraphNode<?> to) { Loading @@ -75,4 +103,23 @@ public class SDG extends Graph implements Sliceable, Buildable<NodeList<Compilat public void addParameterInOutArc(GraphNode<ExpressionStmt> from, GraphNode<ExpressionStmt> to) { this.addEdge(from, to, new ParameterInOutArc()); } public List<GraphNode<?>> findDeclarationsOfVariable(String variable, GraphNode<?> root) { List<GraphNode<?>> res = new ArrayList<>(); // First, expand the node for (Arc arc : incomingEdgesOf(root)) { if (arc.isDataDependencyArc() || arc.isControlDependencyArc()) { res.addAll(findDeclarationsOfVariable(variable, getEdgeSource(arc))); } } // Finally, the current node // This way, the last element of the list is the most recent declaration if (root.getDeclaredVariables().contains(variable)) { res.add(root); } return res; } } Loading
src/main/java/tfm/graphs/Graph.java +0 −6 Original line number Diff line number Diff line Loading @@ -58,12 +58,6 @@ public abstract class Graph extends DirectedPseudograph<GraphNode<?>, Arc> { .collect(Collectors.joining(System.lineSeparator())); } public List<GraphNode<?>> findDeclarationsOfVariable(String variable) { return vertexSet().stream() .filter(node -> node.getDeclaredVariables().contains(variable)) .collect(Collectors.toList()); } public boolean isEmpty() { return this.vertexSet().isEmpty(); } Loading
src/main/java/tfm/graphs/pdg/PDG.java +8 −0 Original line number Diff line number Diff line Loading @@ -12,7 +12,9 @@ import tfm.slicing.Slice; import tfm.slicing.SlicingCriterion; import tfm.utils.NodeNotFoundException; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; /** * The <b>Program Dependence Graph</b> represents the statements of a method in Loading Loading @@ -77,4 +79,10 @@ public class PDG extends GraphWithRootNode<MethodDeclaration> implements Sliceab public boolean isBuilt() { return built; } public List<GraphNode<?>> findDeclarationsOfVariable(String variable) { return vertexSet().stream() .filter(node -> node.getDeclaredVariables().contains(variable)) .collect(Collectors.toList()); } }
src/main/java/tfm/graphs/sdg/MethodCallReplacer.java +3 −1 Original line number Diff line number Diff line package tfm.graphs.sdg; import com.github.javaparser.ast.body.MethodDeclaration; import tfm.graphs.GraphWithRootNode; import tfm.nodes.GraphNode; import tfm.utils.Context; import tfm.utils.Logger; Loading @@ -20,7 +22,7 @@ class MethodCallReplacer { .forEach(context -> { Logger.log("MethodCallReplacer", context); Optional<GraphNode<?>> optionalRootNode = this.sdg.getRootNode(context); Optional<GraphNode<MethodDeclaration>> optionalRootNode = this.sdg.getRootNode(context); if (!optionalRootNode.isPresent()) { return; // We don't have visited the code (e.g. the MethodDeclaration for a method call) Loading
src/main/java/tfm/graphs/sdg/MethodCallReplacerVisitor.java +16 −4 Original line number Diff line number Diff line Loading @@ -24,14 +24,26 @@ import java.util.stream.Collectors; class MethodCallReplacerVisitor extends VoidVisitorAdapter<Context> { private PDG pdg; private SDG sdg; private GraphNode<ExpressionStmt> methodCallNode; public MethodCallReplacerVisitor() { } public MethodCallReplacerVisitor(PDG pdg) { this.pdg = pdg; public MethodCallReplacerVisitor(SDG sdg) { this.sdg = sdg; } @Override public void visit(ExpressionStmt n, Context arg) { Optional<GraphNode<ExpressionStmt>> optionalNode = sdg.findNodeByASTNode(n); assert optionalNode.isPresent(); methodCallNode = optionalNode.get(); super.visit(n, arg); } @Override Loading Loading @@ -66,7 +78,7 @@ class MethodCallReplacerVisitor extends VoidVisitorAdapter<Context> { if (!Objects.equals(scopeName, currentClass.getNameAsString())) { // Check if 'scopeName' is a variable List<GraphNode<?>> declarations = pdg.findDeclarationsOfVariable(scopeName); List<GraphNode<?>> declarations = sdg.findDeclarationsOfVariable(scopeName, methodCallNode); if (declarations.isEmpty()) { // It is a static method call of another class. We do nothing Loading
src/main/java/tfm/graphs/sdg/SDG.java +57 −10 Original line number Diff line number Diff line Loading @@ -4,12 +4,14 @@ import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.stmt.ExpressionStmt; import tfm.arcs.Arc; import tfm.arcs.pdg.ControlDependencyArc; import tfm.arcs.pdg.DataDependencyArc; import tfm.arcs.sdg.CallArc; import tfm.arcs.sdg.ParameterInOutArc; import tfm.graphs.Buildable; import tfm.graphs.Graph; import tfm.graphs.pdg.PDG; import tfm.nodes.*; import tfm.slicing.Slice; import tfm.slicing.Sliceable; Loading @@ -17,14 +19,16 @@ import tfm.slicing.SlicingCriterion; import tfm.utils.Context; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; public class SDG extends Graph implements Sliceable, Buildable<NodeList<CompilationUnit>> { private boolean built = false; private Map<Context, Long> contextToRootNodeId; private Map<Context, Long> contextToMethodRoot; public SDG() { this.contextToRootNodeId = new HashMap<>(); this.contextToMethodRoot = new HashMap<>(); } @Override Loading @@ -43,21 +47,45 @@ public class SDG extends Graph implements Sliceable, Buildable<NodeList<Compilat } public Set<Context> getContexts() { return contextToRootNodeId.keySet(); return contextToMethodRoot.keySet(); } public Optional<GraphNode<?>> getRootNode(Context context) { Long id = this.contextToRootNodeId.get(context); @SuppressWarnings("unchecked") public List<GraphNode<MethodDeclaration>> getMethodRoots() { return contextToMethodRoot.values().stream() .map(id -> findNodeById(id)) .filter(Optional::isPresent) .map(optional -> (GraphNode<MethodDeclaration>) optional.get()) .collect(Collectors.toList()); } @SuppressWarnings("unchecked") public Optional<GraphNode<MethodDeclaration>> getRootNode(Context context) { Long id = this.contextToMethodRoot.get(context); if (id == null) { return Optional.empty(); } return id != null ? findNodeById(id) : Optional.empty(); return findNodeById(id).map(node -> (GraphNode<MethodDeclaration>) node); } public void addRootNode(Context context, long id) { if (!findNodeById(id).isPresent()) { throw new IllegalArgumentException("Cannot add root node to SDG: " + id + " is not in graph!"); if (!findNodeById(id).isPresent()) throw new IllegalArgumentException("Root node with id " + id + " is not contained in graph!"); this.contextToMethodRoot.put(new Context(context), id); } public void addRootNode(Context context, GraphNode<MethodDeclaration> node) { addRootNode(context, node.getId()); } this.contextToRootNodeId.put(new Context(context), id); public Optional<Context> getContext(long id) { return contextToMethodRoot.entrySet().stream() .filter(entry -> Objects.equals(entry.getValue(), id)) .findFirst() .map(Map.Entry::getKey); } public void addControlDependencyArc(GraphNode<?> from, GraphNode<?> to) { Loading @@ -75,4 +103,23 @@ public class SDG extends Graph implements Sliceable, Buildable<NodeList<Compilat public void addParameterInOutArc(GraphNode<ExpressionStmt> from, GraphNode<ExpressionStmt> to) { this.addEdge(from, to, new ParameterInOutArc()); } public List<GraphNode<?>> findDeclarationsOfVariable(String variable, GraphNode<?> root) { List<GraphNode<?>> res = new ArrayList<>(); // First, expand the node for (Arc arc : incomingEdgesOf(root)) { if (arc.isDataDependencyArc() || arc.isControlDependencyArc()) { res.addAll(findDeclarationsOfVariable(variable, getEdgeSource(arc))); } } // Finally, the current node // This way, the last element of the list is the most recent declaration if (root.getDeclaredVariables().contains(variable)) { res.add(root); } return res; } }