Loading src/main/java/tfm/graphs/augmented/ACFG.java +0 −5 Original line number Diff line number Diff line Loading @@ -10,11 +10,6 @@ public class ACFG extends CFG { addControlFlowEdge(from, to, new ControlFlowArc.NonExecutable()); } @Override protected void setExitNode(GraphNode<?> exitNode) { super.setExitNode(exitNode); } @Override protected CFGBuilder newCFGBuilder() { return new ACFGBuilder(this); Loading src/main/java/tfm/graphs/augmented/ACFGBuilder.java +7 −3 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ package tfm.graphs.augmented; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.expr.BooleanLiteralExpr; import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.stmt.*; Loading Loading @@ -239,13 +240,16 @@ public class ACFGBuilder extends CFGBuilder { if (!methodDeclaration.getBody().isPresent()) throw new IllegalStateException("The method must have a body!"); graph.buildRootNode("ENTER " + methodDeclaration.getNameAsString(), methodDeclaration, TypeNodeFactory.fromType(NodeType.METHOD)); graph.buildRootNode("ENTER " + methodDeclaration.getNameAsString(), methodDeclaration, TypeNodeFactory.fromType(NodeType.METHOD_ENTER)); hangingNodes.add(graph.getRootNode().get()); for (Parameter param : methodDeclaration.getParameters()) connectTo(addFormalInGraphNode(param)); methodDeclaration.getBody().get().accept(this, arg); returnList.stream().filter(node -> !hangingNodes.contains(node)).forEach(hangingNodes::add); for (Parameter param : methodDeclaration.getParameters()) connectTo(addFormalOutGraphNode(param)); nonExecHangingNodes.add(graph.getRootNode().get()); GraphNode<EmptyStmt> exitNode = connectTo(new EmptyStmt(), "Exit"); ((ACFG) graph).setExitNode(exitNode); connectTo(graph.addNode("Exit", new EmptyStmt(), TypeNodeFactory.fromType(NodeType.METHOD_EXIT))); } } src/main/java/tfm/graphs/cfg/CFG.java +7 −16 Original line number Diff line number Diff line Loading @@ -3,9 +3,9 @@ package tfm.graphs.cfg; import com.github.javaparser.ast.body.MethodDeclaration; import tfm.arcs.Arc; import tfm.arcs.cfg.ControlFlowArc; import tfm.graphs.Graph; import tfm.graphs.GraphWithRootNode; import tfm.nodes.GraphNode; import tfm.nodes.type.NodeType; import tfm.utils.NodeNotFoundException; import java.util.HashSet; Loading @@ -21,7 +21,6 @@ import java.util.Set; */ public class CFG extends GraphWithRootNode<MethodDeclaration> { private boolean built = false; protected GraphNode<?> exitNode; public CFG() { super(); Loading Loading @@ -66,28 +65,20 @@ public class CFG extends GraphWithRootNode<MethodDeclaration> { @Override public boolean removeVertex(GraphNode<?> graphNode) { if (Objects.equals(graphNode, exitNode)) // Cannot remove exit node // Enter node's removal is checked in super#removeVertex(GraphNode) if (graphNode.getNodeType() == NodeType.METHOD_EXIT) return false; return super.removeVertex(graphNode); } public GraphNode<?> getExitNode() { return exitNode; } protected void setExitNode(GraphNode<?> exitNode) { if (this.exitNode != null) throw new IllegalStateException("Exit node already set!"); this.exitNode = exitNode; } @Override public void build(MethodDeclaration method) { method.accept(newCFGBuilder(), null); if (exitNode == null) throw new IllegalStateException("Exit node missing!"); if (vertexSet().stream().noneMatch(n -> n.getNodeType() == NodeType.METHOD_EXIT)) throw new IllegalStateException("There is no exit node after building the graph"); built = true; } }/**/ @Override public boolean isBuilt() { Loading src/main/java/tfm/graphs/cfg/CFGBuilder.java +35 −51 Original line number Diff line number Diff line Loading @@ -9,13 +9,15 @@ import com.github.javaparser.ast.stmt.*; import com.github.javaparser.ast.visitor.VoidVisitor; import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import tfm.nodes.GraphNode; import tfm.nodes.NodeFactory; import tfm.nodes.TypeNodeFactory; import tfm.nodes.type.NodeType; import tfm.utils.ASTUtils; import java.util.*; import static tfm.nodes.type.NodeType.FORMAL_IN; import static tfm.nodes.type.NodeType.FORMAL_OUT; /** * Populates a {@link CFG}, given one and an AST root node. * For now it only accepts {@link MethodDeclaration} as roots, as it disallows Loading Loading @@ -286,64 +288,46 @@ public class CFGBuilder extends VoidVisitorAdapter<Void> { @Override public void visit(MethodDeclaration methodDeclaration, Void arg) { // Sanity checks if (graph.getRootNode().isPresent()) throw new IllegalStateException("CFG is only allowed for one method, not multiple!"); if (!methodDeclaration.getBody().isPresent()) throw new IllegalStateException("The method must have a body!"); graph.buildRootNode("ENTER " + methodDeclaration.getNameAsString(), methodDeclaration, TypeNodeFactory.fromType(NodeType.METHOD)); // Compute variable in and out expressions (necessary to compute data dependence in SDG) List<ExpressionStmt> inVariableExpressions = new ArrayList<>(); List<ExpressionStmt> outVariableExpressions = new ArrayList<>(); for (Parameter parameter : methodDeclaration.getParameters()) { // In expression VariableDeclarationExpr inVariableDeclarationExpr = new VariableDeclarationExpr( new VariableDeclarator( parameter.getType(), parameter.getNameAsString(), new NameExpr(parameter.getNameAsString() + "_in") ) ); ExpressionStmt inExprStmt = new ExpressionStmt(inVariableDeclarationExpr); inVariableExpressions.add(inExprStmt); // Out expression VariableDeclarationExpr outVariableDeclarationExpr = new VariableDeclarationExpr( new VariableDeclarator( parameter.getType(), parameter.getNameAsString() + "_out", new NameExpr(parameter.getNameAsString()) ) ); ExpressionStmt outExprStmt = new ExpressionStmt(outVariableDeclarationExpr); outVariableExpressions.add(outExprStmt); } throw new IllegalStateException("The method must have a body! Abstract methods have no CFG"); // Create the root node graph.buildRootNode( "ENTER " + methodDeclaration.getNameAsString(), methodDeclaration, TypeNodeFactory.fromType(NodeType.METHOD_ENTER)); hangingNodes.add(graph.getRootNode().get()); // Add in variable nodes for (ExpressionStmt expressionStmt : inVariableExpressions) { GraphNode<ExpressionStmt> node = this.graph.addNode(expressionStmt.toString(), expressionStmt, TypeNodeFactory.fromType(NodeType.VARIABLE_IN)); connectTo(node); } // Create and connect formal-in nodes sequentially for (Parameter param : methodDeclaration.getParameters()) connectTo(addFormalInGraphNode(param)); // Visit the body of the method methodDeclaration.getBody().get().accept(this, arg); // Append all return statements (without repetition) returnList.stream().filter(node -> !hangingNodes.contains(node)).forEach(hangingNodes::add); // Add out variable nodes for (ExpressionStmt expressionStmt : outVariableExpressions) { GraphNode<ExpressionStmt> node = this.graph.addNode(expressionStmt.toString(), expressionStmt, TypeNodeFactory.fromType(NodeType.VARIABLE_OUT)); connectTo(node); // Create and connect formal-out nodes sequentially for (Parameter param : methodDeclaration.getParameters()) connectTo(addFormalOutGraphNode(param)); // Create and connect the exit node connectTo(graph.addNode("Exit", new EmptyStmt(), TypeNodeFactory.fromType(NodeType.METHOD_EXIT))); } protected GraphNode<ExpressionStmt> addFormalInGraphNode(Parameter param) { ExpressionStmt exprStmt = new ExpressionStmt(new VariableDeclarationExpr(new VariableDeclarator( param.getType(), param.getNameAsString(), new NameExpr(param.getNameAsString() + "_in")))); return graph.addNode(exprStmt.toString(), exprStmt, TypeNodeFactory.fromType(FORMAL_IN)); } GraphNode<EmptyStmt> exitNode = connectTo(new EmptyStmt(), "Exit"); graph.setExitNode(exitNode); protected GraphNode<ExpressionStmt> addFormalOutGraphNode(Parameter param) { ExpressionStmt exprStmt = new ExpressionStmt(new VariableDeclarationExpr(new VariableDeclarator( param.getType(), param.getNameAsString() + "_out", new NameExpr(param.getNameAsString())))); return graph.addNode(exprStmt.toString(), exprStmt, TypeNodeFactory.fromType(FORMAL_OUT)); } } src/main/java/tfm/graphs/pdg/ControlDependencyBuilder.java +4 −2 Original line number Diff line number Diff line Loading @@ -4,8 +4,10 @@ import tfm.arcs.Arc; import tfm.graphs.augmented.PPDG; import tfm.graphs.cfg.CFG; import tfm.nodes.GraphNode; import tfm.nodes.type.NodeType; import java.util.*; import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; /** Loading Loading @@ -41,7 +43,7 @@ class ControlDependencyBuilder { roots.remove(cfg.getRootNode().get()); Set<GraphNode<?>> cfgNodes = new HashSet<>(cfg.vertexSet()); cfgNodes.remove(cfg.getExitNode()); cfgNodes.removeIf(node -> node.getNodeType() == NodeType.METHOD_EXIT); for (GraphNode<?> node : cfgNodes) registerNode(node); Loading Loading
src/main/java/tfm/graphs/augmented/ACFG.java +0 −5 Original line number Diff line number Diff line Loading @@ -10,11 +10,6 @@ public class ACFG extends CFG { addControlFlowEdge(from, to, new ControlFlowArc.NonExecutable()); } @Override protected void setExitNode(GraphNode<?> exitNode) { super.setExitNode(exitNode); } @Override protected CFGBuilder newCFGBuilder() { return new ACFGBuilder(this); Loading
src/main/java/tfm/graphs/augmented/ACFGBuilder.java +7 −3 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ package tfm.graphs.augmented; import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.expr.BooleanLiteralExpr; import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.stmt.*; Loading Loading @@ -239,13 +240,16 @@ public class ACFGBuilder extends CFGBuilder { if (!methodDeclaration.getBody().isPresent()) throw new IllegalStateException("The method must have a body!"); graph.buildRootNode("ENTER " + methodDeclaration.getNameAsString(), methodDeclaration, TypeNodeFactory.fromType(NodeType.METHOD)); graph.buildRootNode("ENTER " + methodDeclaration.getNameAsString(), methodDeclaration, TypeNodeFactory.fromType(NodeType.METHOD_ENTER)); hangingNodes.add(graph.getRootNode().get()); for (Parameter param : methodDeclaration.getParameters()) connectTo(addFormalInGraphNode(param)); methodDeclaration.getBody().get().accept(this, arg); returnList.stream().filter(node -> !hangingNodes.contains(node)).forEach(hangingNodes::add); for (Parameter param : methodDeclaration.getParameters()) connectTo(addFormalOutGraphNode(param)); nonExecHangingNodes.add(graph.getRootNode().get()); GraphNode<EmptyStmt> exitNode = connectTo(new EmptyStmt(), "Exit"); ((ACFG) graph).setExitNode(exitNode); connectTo(graph.addNode("Exit", new EmptyStmt(), TypeNodeFactory.fromType(NodeType.METHOD_EXIT))); } }
src/main/java/tfm/graphs/cfg/CFG.java +7 −16 Original line number Diff line number Diff line Loading @@ -3,9 +3,9 @@ package tfm.graphs.cfg; import com.github.javaparser.ast.body.MethodDeclaration; import tfm.arcs.Arc; import tfm.arcs.cfg.ControlFlowArc; import tfm.graphs.Graph; import tfm.graphs.GraphWithRootNode; import tfm.nodes.GraphNode; import tfm.nodes.type.NodeType; import tfm.utils.NodeNotFoundException; import java.util.HashSet; Loading @@ -21,7 +21,6 @@ import java.util.Set; */ public class CFG extends GraphWithRootNode<MethodDeclaration> { private boolean built = false; protected GraphNode<?> exitNode; public CFG() { super(); Loading Loading @@ -66,28 +65,20 @@ public class CFG extends GraphWithRootNode<MethodDeclaration> { @Override public boolean removeVertex(GraphNode<?> graphNode) { if (Objects.equals(graphNode, exitNode)) // Cannot remove exit node // Enter node's removal is checked in super#removeVertex(GraphNode) if (graphNode.getNodeType() == NodeType.METHOD_EXIT) return false; return super.removeVertex(graphNode); } public GraphNode<?> getExitNode() { return exitNode; } protected void setExitNode(GraphNode<?> exitNode) { if (this.exitNode != null) throw new IllegalStateException("Exit node already set!"); this.exitNode = exitNode; } @Override public void build(MethodDeclaration method) { method.accept(newCFGBuilder(), null); if (exitNode == null) throw new IllegalStateException("Exit node missing!"); if (vertexSet().stream().noneMatch(n -> n.getNodeType() == NodeType.METHOD_EXIT)) throw new IllegalStateException("There is no exit node after building the graph"); built = true; } }/**/ @Override public boolean isBuilt() { Loading
src/main/java/tfm/graphs/cfg/CFGBuilder.java +35 −51 Original line number Diff line number Diff line Loading @@ -9,13 +9,15 @@ import com.github.javaparser.ast.stmt.*; import com.github.javaparser.ast.visitor.VoidVisitor; import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import tfm.nodes.GraphNode; import tfm.nodes.NodeFactory; import tfm.nodes.TypeNodeFactory; import tfm.nodes.type.NodeType; import tfm.utils.ASTUtils; import java.util.*; import static tfm.nodes.type.NodeType.FORMAL_IN; import static tfm.nodes.type.NodeType.FORMAL_OUT; /** * Populates a {@link CFG}, given one and an AST root node. * For now it only accepts {@link MethodDeclaration} as roots, as it disallows Loading Loading @@ -286,64 +288,46 @@ public class CFGBuilder extends VoidVisitorAdapter<Void> { @Override public void visit(MethodDeclaration methodDeclaration, Void arg) { // Sanity checks if (graph.getRootNode().isPresent()) throw new IllegalStateException("CFG is only allowed for one method, not multiple!"); if (!methodDeclaration.getBody().isPresent()) throw new IllegalStateException("The method must have a body!"); graph.buildRootNode("ENTER " + methodDeclaration.getNameAsString(), methodDeclaration, TypeNodeFactory.fromType(NodeType.METHOD)); // Compute variable in and out expressions (necessary to compute data dependence in SDG) List<ExpressionStmt> inVariableExpressions = new ArrayList<>(); List<ExpressionStmt> outVariableExpressions = new ArrayList<>(); for (Parameter parameter : methodDeclaration.getParameters()) { // In expression VariableDeclarationExpr inVariableDeclarationExpr = new VariableDeclarationExpr( new VariableDeclarator( parameter.getType(), parameter.getNameAsString(), new NameExpr(parameter.getNameAsString() + "_in") ) ); ExpressionStmt inExprStmt = new ExpressionStmt(inVariableDeclarationExpr); inVariableExpressions.add(inExprStmt); // Out expression VariableDeclarationExpr outVariableDeclarationExpr = new VariableDeclarationExpr( new VariableDeclarator( parameter.getType(), parameter.getNameAsString() + "_out", new NameExpr(parameter.getNameAsString()) ) ); ExpressionStmt outExprStmt = new ExpressionStmt(outVariableDeclarationExpr); outVariableExpressions.add(outExprStmt); } throw new IllegalStateException("The method must have a body! Abstract methods have no CFG"); // Create the root node graph.buildRootNode( "ENTER " + methodDeclaration.getNameAsString(), methodDeclaration, TypeNodeFactory.fromType(NodeType.METHOD_ENTER)); hangingNodes.add(graph.getRootNode().get()); // Add in variable nodes for (ExpressionStmt expressionStmt : inVariableExpressions) { GraphNode<ExpressionStmt> node = this.graph.addNode(expressionStmt.toString(), expressionStmt, TypeNodeFactory.fromType(NodeType.VARIABLE_IN)); connectTo(node); } // Create and connect formal-in nodes sequentially for (Parameter param : methodDeclaration.getParameters()) connectTo(addFormalInGraphNode(param)); // Visit the body of the method methodDeclaration.getBody().get().accept(this, arg); // Append all return statements (without repetition) returnList.stream().filter(node -> !hangingNodes.contains(node)).forEach(hangingNodes::add); // Add out variable nodes for (ExpressionStmt expressionStmt : outVariableExpressions) { GraphNode<ExpressionStmt> node = this.graph.addNode(expressionStmt.toString(), expressionStmt, TypeNodeFactory.fromType(NodeType.VARIABLE_OUT)); connectTo(node); // Create and connect formal-out nodes sequentially for (Parameter param : methodDeclaration.getParameters()) connectTo(addFormalOutGraphNode(param)); // Create and connect the exit node connectTo(graph.addNode("Exit", new EmptyStmt(), TypeNodeFactory.fromType(NodeType.METHOD_EXIT))); } protected GraphNode<ExpressionStmt> addFormalInGraphNode(Parameter param) { ExpressionStmt exprStmt = new ExpressionStmt(new VariableDeclarationExpr(new VariableDeclarator( param.getType(), param.getNameAsString(), new NameExpr(param.getNameAsString() + "_in")))); return graph.addNode(exprStmt.toString(), exprStmt, TypeNodeFactory.fromType(FORMAL_IN)); } GraphNode<EmptyStmt> exitNode = connectTo(new EmptyStmt(), "Exit"); graph.setExitNode(exitNode); protected GraphNode<ExpressionStmt> addFormalOutGraphNode(Parameter param) { ExpressionStmt exprStmt = new ExpressionStmt(new VariableDeclarationExpr(new VariableDeclarator( param.getType(), param.getNameAsString() + "_out", new NameExpr(param.getNameAsString())))); return graph.addNode(exprStmt.toString(), exprStmt, TypeNodeFactory.fromType(FORMAL_OUT)); } }
src/main/java/tfm/graphs/pdg/ControlDependencyBuilder.java +4 −2 Original line number Diff line number Diff line Loading @@ -4,8 +4,10 @@ import tfm.arcs.Arc; import tfm.graphs.augmented.PPDG; import tfm.graphs.cfg.CFG; import tfm.nodes.GraphNode; import tfm.nodes.type.NodeType; import java.util.*; import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; /** Loading Loading @@ -41,7 +43,7 @@ class ControlDependencyBuilder { roots.remove(cfg.getRootNode().get()); Set<GraphNode<?>> cfgNodes = new HashSet<>(cfg.vertexSet()); cfgNodes.remove(cfg.getExitNode()); cfgNodes.removeIf(node -> node.getNodeType() == NodeType.METHOD_EXIT); for (GraphNode<?> node : cfgNodes) registerNode(node); Loading