Loading iacfg/src/main/java/es/upv/mist/slicing/graphs/icfg/ICFG.java +240 −238 Original line number Diff line number Diff line package es.upv.mist.slicing.graphs.icfg; import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.CallableDeclaration; Loading @@ -10,6 +9,7 @@ import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import es.upv.mist.slicing.arcs.Arc; import es.upv.mist.slicing.arcs.cfg.ControlFlowArc; import es.upv.mist.slicing.graphs.Buildable; import es.upv.mist.slicing.graphs.CallGraph; import es.upv.mist.slicing.graphs.ClassGraph; import es.upv.mist.slicing.graphs.Graph; Loading @@ -23,10 +23,7 @@ import es.upv.mist.slicing.nodes.io.ActualIONode; import es.upv.mist.slicing.nodes.io.CallNode; import es.upv.mist.slicing.nodes.io.MethodExitNode; import es.upv.mist.slicing.utils.ASTUtils; import es.upv.mist.slicing.utils.StaticTypeSolver; import java.io.File; import java.io.FileNotFoundException; import java.util.*; import static es.upv.mist.slicing.util.SingletonCollector.toSingleton; Loading @@ -34,25 +31,34 @@ import static es.upv.mist.slicing.util.SingletonCollector.toSingleton; /** * An interprocedural CFG, whose component CFGs are built as ACFGs. */ public class ICFG extends Graph { public class ICFG extends Graph implements Buildable<NodeList<CompilationUnit>> { protected static final Map<CallableDeclaration<?>, CFG> cfgMap = ASTUtils.newIdentityHashMap(); protected CallGraph callGraph; protected boolean built = false; public void build(File file) { if (built) return; NodeList<CompilationUnit> units = new NodeList<>(); public void addControlFlowArc(GraphNode<?> from, GraphNode<?> to) { addEdge(from, to, new ControlFlowArc()); } StaticJavaParser.getConfiguration().setAttributeComments(false); StaticTypeSolver.addTypeSolverJRE(); public void addNonExecControlFlowArc(GraphNode<?> from, GraphNode<?> to) { addEdge(from, to, new ControlFlowArc.NonExecutable()); } try { units.add(StaticJavaParser.parse(file)); } catch (FileNotFoundException e) { System.out.println("No se encontró el archivo"); @Override public void build(NodeList<CompilationUnit> arg) { if (built) return; new Builder().build(arg); built = true; } @Override public boolean isBuilt() { return built; } public class Builder { public void build(NodeList<CompilationUnit> units) { createClassGraph(units); buildCFGs(units); createCallGraph(units); Loading @@ -60,7 +66,6 @@ public class ICFG extends Graph { copyCFGs(); expandCalls(); joinCFGs(); built = true; } protected void buildCFGs(NodeList<CompilationUnit> nodeList) { Loading Loading @@ -109,7 +114,7 @@ public class ICFG extends Graph { /** Build a PDG per declaration, based on the CFGs built previously and enhanced by data analyses. */ protected void copyCFGs() { for (CFG cfg : cfgMap.values()) { cfg.vertexSet().forEach(this::addVertex); cfg.vertexSet().forEach(ICFG.this::addVertex); cfg.edgeSet().forEach(arc -> addEdge(cfg.getEdgeSource(arc), cfg.getEdgeTarget(arc), arc)); } } Loading Loading @@ -141,7 +146,7 @@ public class ICFG extends Graph { // movable1 --> movable2 ... --> movableN for (VariableAction va : List.copyOf(node.getVariableActions())) { if (va instanceof VariableAction.Movable movable) { movable.move(this); movable.move(ICFG.this); connectAppend(list, movable.getRealNode()); } else { throw new IllegalStateException("Enter node has non-movable actions"); Loading Loading @@ -232,7 +237,7 @@ public class ICFG extends Graph { } else if (va instanceof VariableAction.Movable movable) { if (containsVertex(movable.getRealNode())) continue; // Skip multi-action nodes movable.move(this); movable.move(ICFG.this); // Check whether to insert call node (when we move from input to output) if (input && !isActualIn(movable.getRealNode())) { input = false; Loading @@ -241,7 +246,7 @@ public class ICFG extends Graph { if (!(movable.getRealNode() instanceof CallNode.Return)) insertCallerNode(res, CallNode.Return.create(callMarker.getCall()), callMarker); else { addEdge(res.getLast(), movable.getRealNode(), new ControlFlowArc.NonExecutable()); addNonExecControlFlowArc(res.getLast(), movable.getRealNode()); res.add(movable.getRealNode()); continue; } Loading @@ -259,7 +264,7 @@ public class ICFG extends Graph { if (callMarker.getGraphNode().isImplicitInstruction()) node.markAsImplicit(); if (node instanceof CallNode.Return) { addEdge(sequence.getLast(), node, new ControlFlowArc.NonExecutable()); addNonExecControlFlowArc(sequence.getLast(), node); sequence.add(node); } else connectAppend(sequence, node); Loading Loading @@ -307,10 +312,7 @@ public class ICFG extends Graph { } private boolean isEnter(GraphNode<?> graphNode) { return this.incomingEdgesOf(graphNode).isEmpty(); return incomingEdgesOf(graphNode).isEmpty(); } public void addControlFlowArc(GraphNode<?> from, GraphNode<?> to) { this.addEdge(from, to, new ControlFlowArc()); } } No newline at end of file iacfg/src/test/java/es/upv/mist/slicing/graphs/icfg/ICFGTest.java +15 −2 Original line number Diff line number Diff line package es.upv.mist.slicing.graphs.icfg; import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.NodeList; import es.upv.mist.slicing.arcs.Arc; import es.upv.mist.slicing.cli.DOTAttributes; import es.upv.mist.slicing.cli.GraphLog; import es.upv.mist.slicing.utils.StaticTypeSolver; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; public class ICFGTest { public static void main(String[] args) throws IOException { File file = new File(Thread.currentThread().getContextClassLoader().getResource("Test.java").getPath()); StaticJavaParser.getConfiguration().setAttributeComments(false); StaticTypeSolver.addTypeSolverJRE(); File file = new File(Thread.currentThread().getContextClassLoader().getResource("Test.java").getPath()); NodeList<CompilationUnit> units = new NodeList<>(); try { units.add(StaticJavaParser.parse(file)); } catch (FileNotFoundException e) { System.out.println("No se encontró el archivo"); } ICFG icfg = new ICFG(); icfg.build(file); icfg.build(units); new GraphLog<>(icfg) { @Override protected DOTAttributes edgeAttributes(Arc arc) { Loading Loading
iacfg/src/main/java/es/upv/mist/slicing/graphs/icfg/ICFG.java +240 −238 Original line number Diff line number Diff line package es.upv.mist.slicing.graphs.icfg; import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.CallableDeclaration; Loading @@ -10,6 +9,7 @@ import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import es.upv.mist.slicing.arcs.Arc; import es.upv.mist.slicing.arcs.cfg.ControlFlowArc; import es.upv.mist.slicing.graphs.Buildable; import es.upv.mist.slicing.graphs.CallGraph; import es.upv.mist.slicing.graphs.ClassGraph; import es.upv.mist.slicing.graphs.Graph; Loading @@ -23,10 +23,7 @@ import es.upv.mist.slicing.nodes.io.ActualIONode; import es.upv.mist.slicing.nodes.io.CallNode; import es.upv.mist.slicing.nodes.io.MethodExitNode; import es.upv.mist.slicing.utils.ASTUtils; import es.upv.mist.slicing.utils.StaticTypeSolver; import java.io.File; import java.io.FileNotFoundException; import java.util.*; import static es.upv.mist.slicing.util.SingletonCollector.toSingleton; Loading @@ -34,25 +31,34 @@ import static es.upv.mist.slicing.util.SingletonCollector.toSingleton; /** * An interprocedural CFG, whose component CFGs are built as ACFGs. */ public class ICFG extends Graph { public class ICFG extends Graph implements Buildable<NodeList<CompilationUnit>> { protected static final Map<CallableDeclaration<?>, CFG> cfgMap = ASTUtils.newIdentityHashMap(); protected CallGraph callGraph; protected boolean built = false; public void build(File file) { if (built) return; NodeList<CompilationUnit> units = new NodeList<>(); public void addControlFlowArc(GraphNode<?> from, GraphNode<?> to) { addEdge(from, to, new ControlFlowArc()); } StaticJavaParser.getConfiguration().setAttributeComments(false); StaticTypeSolver.addTypeSolverJRE(); public void addNonExecControlFlowArc(GraphNode<?> from, GraphNode<?> to) { addEdge(from, to, new ControlFlowArc.NonExecutable()); } try { units.add(StaticJavaParser.parse(file)); } catch (FileNotFoundException e) { System.out.println("No se encontró el archivo"); @Override public void build(NodeList<CompilationUnit> arg) { if (built) return; new Builder().build(arg); built = true; } @Override public boolean isBuilt() { return built; } public class Builder { public void build(NodeList<CompilationUnit> units) { createClassGraph(units); buildCFGs(units); createCallGraph(units); Loading @@ -60,7 +66,6 @@ public class ICFG extends Graph { copyCFGs(); expandCalls(); joinCFGs(); built = true; } protected void buildCFGs(NodeList<CompilationUnit> nodeList) { Loading Loading @@ -109,7 +114,7 @@ public class ICFG extends Graph { /** Build a PDG per declaration, based on the CFGs built previously and enhanced by data analyses. */ protected void copyCFGs() { for (CFG cfg : cfgMap.values()) { cfg.vertexSet().forEach(this::addVertex); cfg.vertexSet().forEach(ICFG.this::addVertex); cfg.edgeSet().forEach(arc -> addEdge(cfg.getEdgeSource(arc), cfg.getEdgeTarget(arc), arc)); } } Loading Loading @@ -141,7 +146,7 @@ public class ICFG extends Graph { // movable1 --> movable2 ... --> movableN for (VariableAction va : List.copyOf(node.getVariableActions())) { if (va instanceof VariableAction.Movable movable) { movable.move(this); movable.move(ICFG.this); connectAppend(list, movable.getRealNode()); } else { throw new IllegalStateException("Enter node has non-movable actions"); Loading Loading @@ -232,7 +237,7 @@ public class ICFG extends Graph { } else if (va instanceof VariableAction.Movable movable) { if (containsVertex(movable.getRealNode())) continue; // Skip multi-action nodes movable.move(this); movable.move(ICFG.this); // Check whether to insert call node (when we move from input to output) if (input && !isActualIn(movable.getRealNode())) { input = false; Loading @@ -241,7 +246,7 @@ public class ICFG extends Graph { if (!(movable.getRealNode() instanceof CallNode.Return)) insertCallerNode(res, CallNode.Return.create(callMarker.getCall()), callMarker); else { addEdge(res.getLast(), movable.getRealNode(), new ControlFlowArc.NonExecutable()); addNonExecControlFlowArc(res.getLast(), movable.getRealNode()); res.add(movable.getRealNode()); continue; } Loading @@ -259,7 +264,7 @@ public class ICFG extends Graph { if (callMarker.getGraphNode().isImplicitInstruction()) node.markAsImplicit(); if (node instanceof CallNode.Return) { addEdge(sequence.getLast(), node, new ControlFlowArc.NonExecutable()); addNonExecControlFlowArc(sequence.getLast(), node); sequence.add(node); } else connectAppend(sequence, node); Loading Loading @@ -307,10 +312,7 @@ public class ICFG extends Graph { } private boolean isEnter(GraphNode<?> graphNode) { return this.incomingEdgesOf(graphNode).isEmpty(); return incomingEdgesOf(graphNode).isEmpty(); } public void addControlFlowArc(GraphNode<?> from, GraphNode<?> to) { this.addEdge(from, to, new ControlFlowArc()); } } No newline at end of file
iacfg/src/test/java/es/upv/mist/slicing/graphs/icfg/ICFGTest.java +15 −2 Original line number Diff line number Diff line package es.upv.mist.slicing.graphs.icfg; import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.NodeList; import es.upv.mist.slicing.arcs.Arc; import es.upv.mist.slicing.cli.DOTAttributes; import es.upv.mist.slicing.cli.GraphLog; import es.upv.mist.slicing.utils.StaticTypeSolver; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; public class ICFGTest { public static void main(String[] args) throws IOException { File file = new File(Thread.currentThread().getContextClassLoader().getResource("Test.java").getPath()); StaticJavaParser.getConfiguration().setAttributeComments(false); StaticTypeSolver.addTypeSolverJRE(); File file = new File(Thread.currentThread().getContextClassLoader().getResource("Test.java").getPath()); NodeList<CompilationUnit> units = new NodeList<>(); try { units.add(StaticJavaParser.parse(file)); } catch (FileNotFoundException e) { System.out.println("No se encontró el archivo"); } ICFG icfg = new ICFG(); icfg.build(file); icfg.build(units); new GraphLog<>(icfg) { @Override protected DOTAttributes edgeAttributes(Arc arc) { Loading