Loading src/main/java/tfm/graphs/PDGGraph.java +2 −1 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ import tfm.nodes.CFGNode; import tfm.nodes.GraphNode; import tfm.nodes.PDGNode; import tfm.slicing.SlicingCriterion; import tfm.utils.ASTUtils; import tfm.utils.Logger; import tfm.utils.NodeNotFoundException; import tfm.utils.Utils; Loading Loading @@ -175,7 +176,7 @@ public class PDGGraph extends Graph<PDGNode<?>> { PDGGraph sliceGraph = new PDGGraph(); Node astCopy = node.getAstNode().findRootNode().clone(); Node astCopy = ASTUtils.cloneAST(node.getAstNode()); astCopy.accept(new PDGCFGVisitor(sliceGraph), sliceGraph.getRootNode()); Loading src/main/java/tfm/graphs/SDGGraph.java +32 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,9 @@ package tfm.graphs; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.Parameter; import edg.graphlib.Vertex; import edg.graphlib.Visitor; import tfm.arcs.data.ArcData; import tfm.nodes.AuxiliarSDGNode; import tfm.nodes.PDGNode; import tfm.nodes.SDGNode; Loading @@ -10,6 +13,7 @@ import tfm.slicing.SlicingCriterion; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; public class SDGGraph extends Graph<SDGNode<?>> { Loading Loading @@ -69,4 +73,32 @@ public class SDGGraph extends Graph<SDGNode<?>> { } } } public SDGNode<MethodDeclaration> addMethod(MethodDeclaration methodDeclaration, PDGGraph pdgGraph) { SDGNode<MethodDeclaration> node = new SDGNode<>( getNextVertexId(), "ENTER " + methodDeclaration.getDeclarationAsString(false, false, true), methodDeclaration ); pdgGraph.depthFirstSearch(pdgGraph.getRootNode(), (Visitor<String, ArcData>) (g, v) -> { if (Objects.equals(g.getRootVertex(), v)) { return; // We don't care about root node (entry node) } PDGNode<?> pdgNode = (PDGNode) v; SDGNode<?> sdgNode = new SDGNode<>( getNextVertexId(), pdgNode.getData(), pdgNode.getAstNode() ); }); super.addVertex(node); return node; } } src/main/java/tfm/utils/ASTUtils.java 0 → 100644 +47 −0 Original line number Diff line number Diff line package tfm.utils; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.stmt.BlockStmt; import com.github.javaparser.ast.stmt.EmptyStmt; import com.github.javaparser.ast.stmt.Statement; import java.util.function.Predicate; public class ASTUtils { public static BlockStmt blockWrapper(Statement statement) { if (statement.isBlockStmt()) return statement.asBlockStmt(); return new BlockStmt(new NodeList<>(statement)); } public static boolean isLoop(Statement statement) { return statement.isWhileStmt() || statement.isDoStmt() || statement.isForStmt() || statement.isForEachStmt(); } public static Statement findFirstAncestorStatementFrom(Statement statement, Predicate<Statement> predicate) { if (predicate.test(statement)) { return statement; } if (!statement.getParentNode().isPresent()) { return new EmptyStmt(); } return findFirstAncestorStatementFrom((Statement) statement.getParentNode().get(), predicate); } /** * Clones an entire AST by cloning the root node of the given node * @param node - a node of the AST * @return the root node of the cloned AST */ public static Node cloneAST(Node node) { return node.findRootNode().clone(); } } src/main/java/tfm/utils/Utils.java +0 −26 Original line number Diff line number Diff line Loading @@ -16,32 +16,6 @@ public class Utils { public static final String PROGRAMS_FOLDER = "src/main/java/tfm/programs/"; public static BlockStmt blockWrapper(Statement statement) { if (statement.isBlockStmt()) return statement.asBlockStmt(); return new BlockStmt(new NodeList<>(statement)); } public static boolean isLoop(Statement statement) { return statement.isWhileStmt() || statement.isDoStmt() || statement.isForStmt() || statement.isForEachStmt(); } public static Statement findFirstAncestorStatementFrom(Statement statement, Predicate<Statement> predicate) { if (predicate.test(statement)) { return statement; } if (!statement.getParentNode().isPresent()) { return new EmptyStmt(); } return findFirstAncestorStatementFrom((Statement) statement.getParentNode().get(), predicate); } public static <E> List<E> emptyList() { return new ArrayList<>(0); } Loading src/main/java/tfm/visitors/CFGVisitor.java +4 −3 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import jdk.nashorn.internal.ir.Block; import tfm.graphs.CFGGraph; import tfm.nodes.CFGNode; import tfm.utils.ASTUtils; import tfm.utils.Utils; import java.util.*; Loading Loading @@ -101,7 +102,7 @@ public class CFGVisitor extends VoidVisitorAdapter<Void> { @Override public void visit(DoStmt doStmt, Void arg) { BlockStmt body = Utils.blockWrapper(doStmt.getBody()); BlockStmt body = ASTUtils.blockWrapper(doStmt.getBody()); body.accept(this, arg); Loading Loading @@ -143,7 +144,7 @@ public class CFGVisitor extends VoidVisitorAdapter<Void> { lastParentNodes.add(forNode); BlockStmt body = Utils.blockWrapper(forStmt.getBody()).clone(); BlockStmt body = ASTUtils.blockWrapper(forStmt.getBody()).clone(); forStmt.getUpdate().forEach(body::addStatement); Loading Loading @@ -228,7 +229,7 @@ public class CFGVisitor extends VoidVisitorAdapter<Void> { @Override public void visit(ContinueStmt continueStmt, Void arg) { Statement continuableStatement = Utils.findFirstAncestorStatementFrom(continueStmt, Utils::isLoop); Statement continuableStatement = ASTUtils.findFirstAncestorStatementFrom(continueStmt, ASTUtils::isLoop); CFGNode continuableNode = graph.findNodeByASTNode(continuableStatement).get(); Loading Loading
src/main/java/tfm/graphs/PDGGraph.java +2 −1 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ import tfm.nodes.CFGNode; import tfm.nodes.GraphNode; import tfm.nodes.PDGNode; import tfm.slicing.SlicingCriterion; import tfm.utils.ASTUtils; import tfm.utils.Logger; import tfm.utils.NodeNotFoundException; import tfm.utils.Utils; Loading Loading @@ -175,7 +176,7 @@ public class PDGGraph extends Graph<PDGNode<?>> { PDGGraph sliceGraph = new PDGGraph(); Node astCopy = node.getAstNode().findRootNode().clone(); Node astCopy = ASTUtils.cloneAST(node.getAstNode()); astCopy.accept(new PDGCFGVisitor(sliceGraph), sliceGraph.getRootNode()); Loading
src/main/java/tfm/graphs/SDGGraph.java +32 −0 Original line number Diff line number Diff line Loading @@ -3,6 +3,9 @@ package tfm.graphs; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.Parameter; import edg.graphlib.Vertex; import edg.graphlib.Visitor; import tfm.arcs.data.ArcData; import tfm.nodes.AuxiliarSDGNode; import tfm.nodes.PDGNode; import tfm.nodes.SDGNode; Loading @@ -10,6 +13,7 @@ import tfm.slicing.SlicingCriterion; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; public class SDGGraph extends Graph<SDGNode<?>> { Loading Loading @@ -69,4 +73,32 @@ public class SDGGraph extends Graph<SDGNode<?>> { } } } public SDGNode<MethodDeclaration> addMethod(MethodDeclaration methodDeclaration, PDGGraph pdgGraph) { SDGNode<MethodDeclaration> node = new SDGNode<>( getNextVertexId(), "ENTER " + methodDeclaration.getDeclarationAsString(false, false, true), methodDeclaration ); pdgGraph.depthFirstSearch(pdgGraph.getRootNode(), (Visitor<String, ArcData>) (g, v) -> { if (Objects.equals(g.getRootVertex(), v)) { return; // We don't care about root node (entry node) } PDGNode<?> pdgNode = (PDGNode) v; SDGNode<?> sdgNode = new SDGNode<>( getNextVertexId(), pdgNode.getData(), pdgNode.getAstNode() ); }); super.addVertex(node); return node; } }
src/main/java/tfm/utils/ASTUtils.java 0 → 100644 +47 −0 Original line number Diff line number Diff line package tfm.utils; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.stmt.BlockStmt; import com.github.javaparser.ast.stmt.EmptyStmt; import com.github.javaparser.ast.stmt.Statement; import java.util.function.Predicate; public class ASTUtils { public static BlockStmt blockWrapper(Statement statement) { if (statement.isBlockStmt()) return statement.asBlockStmt(); return new BlockStmt(new NodeList<>(statement)); } public static boolean isLoop(Statement statement) { return statement.isWhileStmt() || statement.isDoStmt() || statement.isForStmt() || statement.isForEachStmt(); } public static Statement findFirstAncestorStatementFrom(Statement statement, Predicate<Statement> predicate) { if (predicate.test(statement)) { return statement; } if (!statement.getParentNode().isPresent()) { return new EmptyStmt(); } return findFirstAncestorStatementFrom((Statement) statement.getParentNode().get(), predicate); } /** * Clones an entire AST by cloning the root node of the given node * @param node - a node of the AST * @return the root node of the cloned AST */ public static Node cloneAST(Node node) { return node.findRootNode().clone(); } }
src/main/java/tfm/utils/Utils.java +0 −26 Original line number Diff line number Diff line Loading @@ -16,32 +16,6 @@ public class Utils { public static final String PROGRAMS_FOLDER = "src/main/java/tfm/programs/"; public static BlockStmt blockWrapper(Statement statement) { if (statement.isBlockStmt()) return statement.asBlockStmt(); return new BlockStmt(new NodeList<>(statement)); } public static boolean isLoop(Statement statement) { return statement.isWhileStmt() || statement.isDoStmt() || statement.isForStmt() || statement.isForEachStmt(); } public static Statement findFirstAncestorStatementFrom(Statement statement, Predicate<Statement> predicate) { if (predicate.test(statement)) { return statement; } if (!statement.getParentNode().isPresent()) { return new EmptyStmt(); } return findFirstAncestorStatementFrom((Statement) statement.getParentNode().get(), predicate); } public static <E> List<E> emptyList() { return new ArrayList<>(0); } Loading
src/main/java/tfm/visitors/CFGVisitor.java +4 −3 Original line number Diff line number Diff line Loading @@ -10,6 +10,7 @@ import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import jdk.nashorn.internal.ir.Block; import tfm.graphs.CFGGraph; import tfm.nodes.CFGNode; import tfm.utils.ASTUtils; import tfm.utils.Utils; import java.util.*; Loading Loading @@ -101,7 +102,7 @@ public class CFGVisitor extends VoidVisitorAdapter<Void> { @Override public void visit(DoStmt doStmt, Void arg) { BlockStmt body = Utils.blockWrapper(doStmt.getBody()); BlockStmt body = ASTUtils.blockWrapper(doStmt.getBody()); body.accept(this, arg); Loading Loading @@ -143,7 +144,7 @@ public class CFGVisitor extends VoidVisitorAdapter<Void> { lastParentNodes.add(forNode); BlockStmt body = Utils.blockWrapper(forStmt.getBody()).clone(); BlockStmt body = ASTUtils.blockWrapper(forStmt.getBody()).clone(); forStmt.getUpdate().forEach(body::addStatement); Loading Loading @@ -228,7 +229,7 @@ public class CFGVisitor extends VoidVisitorAdapter<Void> { @Override public void visit(ContinueStmt continueStmt, Void arg) { Statement continuableStatement = Utils.findFirstAncestorStatementFrom(continueStmt, Utils::isLoop); Statement continuableStatement = ASTUtils.findFirstAncestorStatementFrom(continueStmt, ASTUtils::isLoop); CFGNode continuableNode = graph.findNodeByASTNode(continuableStatement).get(); Loading