Loading iacfg/pom.xml +7 −2 Original line number Diff line number Diff line Loading @@ -12,8 +12,8 @@ <artifactId>iacfg</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <maven.compiler.source>21</maven.compiler.source> <maven.compiler.target>21</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> Loading @@ -28,6 +28,11 @@ <version>1.3.0</version> <scope>compile</scope> </dependency> <dependency> <groupId>es.upv.mist.slicing</groupId> <artifactId>sdg-cli</artifactId> <version>1.3.0</version> </dependency> </dependencies> </project> No newline at end of file iacfg/src/main/java/es/upv/mist/slicing/I_ACFG.java +122 −19 Original line number Diff line number Diff line package es.upv.mist.slicing; import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.CallableDeclaration; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.ConstructorDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import es.upv.mist.slicing.graphs.sdg.SDG; import com.github.javaparser.utils.CodeGenerationUtils; import es.upv.mist.slicing.arcs.pdg.ControlDependencyArc; import es.upv.mist.slicing.cli.GraphLog; import es.upv.mist.slicing.graphs.CallGraph; import es.upv.mist.slicing.graphs.ClassGraph; import es.upv.mist.slicing.graphs.Graph; import es.upv.mist.slicing.graphs.augmented.ACFG; import es.upv.mist.slicing.graphs.cfg.CFG; import es.upv.mist.slicing.graphs.sdg.InterproceduralDefinitionFinder; import es.upv.mist.slicing.graphs.sdg.InterproceduralUsageFinder; import es.upv.mist.slicing.nodes.GraphNode; import es.upv.mist.slicing.nodes.VariableAction; import es.upv.mist.slicing.nodes.io.ActualIONode; import es.upv.mist.slicing.nodes.io.CallNode; import es.upv.mist.slicing.utils.ASTUtils; import es.upv.mist.slicing.utils.StaticTypeSolver; import org.apache.commons.cli.ParseException; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.utils.CodeGenerationUtils; import es.upv.mist.slicing.graphs.augmented.ACFG; import java.io.File; import java.io.FileNotFoundException; import java.util.Map; import java.io.IOException; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Stream; public class I_ACFG extends SDG { public class I_ACFG extends Graph { protected static final Map<CallableDeclaration<?>, ACFG> acfgMap = ASTUtils.newIdentityHashMap(); protected static final Map<CallableDeclaration<?>, CFG> acfgMap = ASTUtils.newIdentityHashMap(); protected CallGraph callGraph; protected GraphNode<?> secuentialNode = null; public static void main(String[] args) throws ParseException { public static void main(String[] args) throws ParseException, IOException { String ruta = "/src/main/java/es/upv/mist/slicing/tests/"; String fichero = "Test_Entrevista.java"; String fichero = "Test.java"; I_ACFG iAcfg = new I_ACFG(); iAcfg.generarACFG(ruta, fichero); } public void generarACFG(String ruta, String fichero) { public void generarACFG(String ruta, String fichero) throws IOException { NodeList<CompilationUnit> units = new NodeList<>(); File file = new File(CodeGenerationUtils.mavenModuleRoot(I_ACFG.class)+ruta+fichero); CompilationUnit compilationUnit = null; StaticJavaParser.getConfiguration().setAttributeComments(false); Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.INFO, "Configuring JavaParser"); StaticTypeSolver.addTypeSolverJRE(); try { units.add(compilationUnit = StaticJavaParser.parse(file)); units.add(StaticJavaParser.parse(file)); } catch (FileNotFoundException e) { System.out.println("No se encontró el archivo"); } createClassGraph(units); buildACFGs(units); System.out.println("TESTING: " + acfgMap.toString()); createCallGraph(units); dataFlowAnalysis(); copyACFGs(); expandCalls(); new GraphLog<>(this){}.generateImages("migrafo"); /* acfgMap.forEach((declaration, cfg)-> { CFGLog cfgLog = new CFGLog(cfg); try { cfgLog.generateImages(declaration.getNameAsString()); } catch (IOException e) { System.out.println("ERROR"); } }); */ System.out.println(); } protected void buildACFGs(NodeList<CompilationUnit> nodeList) { Loading Loading @@ -82,9 +107,87 @@ public class I_ACFG extends SDG { }, null); } protected Stream<File> findJavaFile(File file) { Stream.Builder<File> builder = Stream.builder(); builder.accept(file); return builder.build(); /** Create class graph from the list of compilation units. */ protected void createClassGraph(NodeList<CompilationUnit> nodeList){ ClassGraph.getNewInstance().build(nodeList); } /** Create call graph from the list of compilation units. */ protected void createCallGraph(NodeList<CompilationUnit> nodeList) { callGraph = new CallGraph(acfgMap, ClassGraph.getInstance()); callGraph.build(nodeList); } /** Perform interprocedural analyses to determine the actual and formal nodes. */ protected void dataFlowAnalysis() { new InterproceduralDefinitionFinder(callGraph, acfgMap).save(); // 3.1 new InterproceduralUsageFinder(callGraph, acfgMap).save(); // 3.2 } /** Build a PDG per declaration, based on the CFGs built previously and enhanced by data analyses. */ protected void copyACFGs() { for (CFG acfg : acfgMap.values()) { // for debugging // APDG pdg = new APDG((ACFG) acfg); // pdg.build(acfg.getDeclaration()); acfg.vertexSet().forEach(this::addVertex); acfg.edgeSet().forEach(arc -> addEdge(acfg.getEdgeSource(arc), acfg.getEdgeTarget(arc), arc)); } } protected void expandCalls() { // debug statement to print graph // new PDGLog(PDG.this).generateImages("pdg-debug") for (GraphNode<?> graphNode : Set.copyOf(vertexSet())) { secuentialNode = null; CallNode endCallNode = null; Deque<CallNode> callNodeStack = new LinkedList<>(); for (VariableAction action : List.copyOf(graphNode.getVariableActions())) { if (action instanceof VariableAction.CallMarker) { VariableAction.CallMarker variableAction = (VariableAction.CallMarker) action; // Compute the call node, if entering the marker. Additionally, it places the node // in the graph and makes it control-dependent on its container. if (!variableAction.isEnter()) { callNodeStack.pop(); } else { CallNode callNode = CallNode.create(variableAction.getCall()); endCallNode = CallNode.create(variableAction.getCall()); if (graphNode.isImplicitInstruction()) callNode.markAsImplicit(); addVertex(callNode); addControlDependencyArc(graphNode, callNode); callNodeStack.push(callNode); } } else if (action instanceof VariableAction.Movable) { // Move the variable to its own node, add that node to the graph and connect it. var movable = (VariableAction.Movable) action; movable.move(this); connectRealNode(graphNode, callNodeStack.peek(), movable.getRealNode()); } } if(endCallNode != null && secuentialNode != null) { addVertex(endCallNode); addControlDependencyArc(secuentialNode, endCallNode); } assert callNodeStack.isEmpty(); } } public void addControlDependencyArc(GraphNode<?> from, GraphNode<?> to) { this.addEdge(from, to, new ControlDependencyArc()); } /** Connects the real node to the proper parent, control-dependent-wise. */ protected void connectRealNode(GraphNode<?> graphNode, CallNode callNode, GraphNode<?> realNode) { if (realNode instanceof ActualIONode || realNode instanceof CallNode.Return) { assert callNode != null; if(secuentialNode != realNode) { addControlDependencyArc(secuentialNode == null ? callNode : secuentialNode, realNode); secuentialNode = realNode; } } else { addControlDependencyArc(graphNode, realNode); } } } No newline at end of file iacfg/src/main/java/es/upv/mist/slicing/tests/Test.java 0 → 100644 +36 −0 Original line number Diff line number Diff line package es.upv.mist.slicing.tests; public class Test { public static void main(String[] args) { int x = 1; boolean a = true; while (x < 100) { if (x < 50) { System.out.println(x); x = incrementar(x); } else { System.out.println(x); x = incrementarBucle(x); } } } private static int incrementar(int a){ return a+1; } private static int incrementarBucle(int a){ if(a>0){ int x = 0; for(int i = 0; i<a; i++){ x = x + i; } return x; } else { return a; } } } iacfg/src/main/java/es/upv/mist/slicing/tests/Test_Entrevista.javadeleted 100644 → 0 +0 −27 Original line number Diff line number Diff line package es.upv.mist.slicing.tests; public class Test_Entrevista { public static void main(String[] args) { int x = 1; while (x > 1) { if (x > 10) { x++; } else { while (x > 1) { if (x > 10) { x++; } else { if (x > 10) { x++; } else { x--; } } } } } } } sdg-cli/src/main/java/es/upv/mist/slicing/cli/GraphLog.java +15 −5 Original line number Diff line number Diff line Loading @@ -71,13 +71,9 @@ public abstract class GraphLog<G extends Graph> { } public void generateImages(String imageName, String format) throws IOException { this.imageName = imageName + "-" + graph.getClass().getSimpleName(); this.format = format; generated = true; File tmpDot = File.createTempFile("graph-source-", ".dot"); tmpDot.getParentFile().mkdirs(); getImageFile().getParentFile().mkdirs(); File tmpDot = getDotFile(imageName); // Graph -> DOT -> file try (Writer w = new FileWriter(tmpDot)) { getDOTExporter().exportGraph(graph, w); Loading @@ -97,6 +93,20 @@ public abstract class GraphLog<G extends Graph> { } } public File getDotFile(String imageName) throws IOException { this.imageName = imageName + "-" + graph.getClass().getSimpleName(); File tmpDot = File.createTempFile("graph-source-", ".dot"); tmpDot.getParentFile().mkdirs(); getImageFile().getParentFile().mkdirs(); // Graph -> DOT -> file try (Writer w = new FileWriter(tmpDot)) { getDOTExporter().exportGraph(graph, w); } return tmpDot; } public void openVisualRepresentation() throws IOException { if (!generated) generateImages(); openFileForUser(getImageFile()); Loading Loading
iacfg/pom.xml +7 −2 Original line number Diff line number Diff line Loading @@ -12,8 +12,8 @@ <artifactId>iacfg</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <maven.compiler.source>21</maven.compiler.source> <maven.compiler.target>21</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> Loading @@ -28,6 +28,11 @@ <version>1.3.0</version> <scope>compile</scope> </dependency> <dependency> <groupId>es.upv.mist.slicing</groupId> <artifactId>sdg-cli</artifactId> <version>1.3.0</version> </dependency> </dependencies> </project> No newline at end of file
iacfg/src/main/java/es/upv/mist/slicing/I_ACFG.java +122 −19 Original line number Diff line number Diff line package es.upv.mist.slicing; import com.github.javaparser.StaticJavaParser; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.CallableDeclaration; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.ConstructorDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import es.upv.mist.slicing.graphs.sdg.SDG; import com.github.javaparser.utils.CodeGenerationUtils; import es.upv.mist.slicing.arcs.pdg.ControlDependencyArc; import es.upv.mist.slicing.cli.GraphLog; import es.upv.mist.slicing.graphs.CallGraph; import es.upv.mist.slicing.graphs.ClassGraph; import es.upv.mist.slicing.graphs.Graph; import es.upv.mist.slicing.graphs.augmented.ACFG; import es.upv.mist.slicing.graphs.cfg.CFG; import es.upv.mist.slicing.graphs.sdg.InterproceduralDefinitionFinder; import es.upv.mist.slicing.graphs.sdg.InterproceduralUsageFinder; import es.upv.mist.slicing.nodes.GraphNode; import es.upv.mist.slicing.nodes.VariableAction; import es.upv.mist.slicing.nodes.io.ActualIONode; import es.upv.mist.slicing.nodes.io.CallNode; import es.upv.mist.slicing.utils.ASTUtils; import es.upv.mist.slicing.utils.StaticTypeSolver; import org.apache.commons.cli.ParseException; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.utils.CodeGenerationUtils; import es.upv.mist.slicing.graphs.augmented.ACFG; import java.io.File; import java.io.FileNotFoundException; import java.util.Map; import java.io.IOException; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Stream; public class I_ACFG extends SDG { public class I_ACFG extends Graph { protected static final Map<CallableDeclaration<?>, ACFG> acfgMap = ASTUtils.newIdentityHashMap(); protected static final Map<CallableDeclaration<?>, CFG> acfgMap = ASTUtils.newIdentityHashMap(); protected CallGraph callGraph; protected GraphNode<?> secuentialNode = null; public static void main(String[] args) throws ParseException { public static void main(String[] args) throws ParseException, IOException { String ruta = "/src/main/java/es/upv/mist/slicing/tests/"; String fichero = "Test_Entrevista.java"; String fichero = "Test.java"; I_ACFG iAcfg = new I_ACFG(); iAcfg.generarACFG(ruta, fichero); } public void generarACFG(String ruta, String fichero) { public void generarACFG(String ruta, String fichero) throws IOException { NodeList<CompilationUnit> units = new NodeList<>(); File file = new File(CodeGenerationUtils.mavenModuleRoot(I_ACFG.class)+ruta+fichero); CompilationUnit compilationUnit = null; StaticJavaParser.getConfiguration().setAttributeComments(false); Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.INFO, "Configuring JavaParser"); StaticTypeSolver.addTypeSolverJRE(); try { units.add(compilationUnit = StaticJavaParser.parse(file)); units.add(StaticJavaParser.parse(file)); } catch (FileNotFoundException e) { System.out.println("No se encontró el archivo"); } createClassGraph(units); buildACFGs(units); System.out.println("TESTING: " + acfgMap.toString()); createCallGraph(units); dataFlowAnalysis(); copyACFGs(); expandCalls(); new GraphLog<>(this){}.generateImages("migrafo"); /* acfgMap.forEach((declaration, cfg)-> { CFGLog cfgLog = new CFGLog(cfg); try { cfgLog.generateImages(declaration.getNameAsString()); } catch (IOException e) { System.out.println("ERROR"); } }); */ System.out.println(); } protected void buildACFGs(NodeList<CompilationUnit> nodeList) { Loading Loading @@ -82,9 +107,87 @@ public class I_ACFG extends SDG { }, null); } protected Stream<File> findJavaFile(File file) { Stream.Builder<File> builder = Stream.builder(); builder.accept(file); return builder.build(); /** Create class graph from the list of compilation units. */ protected void createClassGraph(NodeList<CompilationUnit> nodeList){ ClassGraph.getNewInstance().build(nodeList); } /** Create call graph from the list of compilation units. */ protected void createCallGraph(NodeList<CompilationUnit> nodeList) { callGraph = new CallGraph(acfgMap, ClassGraph.getInstance()); callGraph.build(nodeList); } /** Perform interprocedural analyses to determine the actual and formal nodes. */ protected void dataFlowAnalysis() { new InterproceduralDefinitionFinder(callGraph, acfgMap).save(); // 3.1 new InterproceduralUsageFinder(callGraph, acfgMap).save(); // 3.2 } /** Build a PDG per declaration, based on the CFGs built previously and enhanced by data analyses. */ protected void copyACFGs() { for (CFG acfg : acfgMap.values()) { // for debugging // APDG pdg = new APDG((ACFG) acfg); // pdg.build(acfg.getDeclaration()); acfg.vertexSet().forEach(this::addVertex); acfg.edgeSet().forEach(arc -> addEdge(acfg.getEdgeSource(arc), acfg.getEdgeTarget(arc), arc)); } } protected void expandCalls() { // debug statement to print graph // new PDGLog(PDG.this).generateImages("pdg-debug") for (GraphNode<?> graphNode : Set.copyOf(vertexSet())) { secuentialNode = null; CallNode endCallNode = null; Deque<CallNode> callNodeStack = new LinkedList<>(); for (VariableAction action : List.copyOf(graphNode.getVariableActions())) { if (action instanceof VariableAction.CallMarker) { VariableAction.CallMarker variableAction = (VariableAction.CallMarker) action; // Compute the call node, if entering the marker. Additionally, it places the node // in the graph and makes it control-dependent on its container. if (!variableAction.isEnter()) { callNodeStack.pop(); } else { CallNode callNode = CallNode.create(variableAction.getCall()); endCallNode = CallNode.create(variableAction.getCall()); if (graphNode.isImplicitInstruction()) callNode.markAsImplicit(); addVertex(callNode); addControlDependencyArc(graphNode, callNode); callNodeStack.push(callNode); } } else if (action instanceof VariableAction.Movable) { // Move the variable to its own node, add that node to the graph and connect it. var movable = (VariableAction.Movable) action; movable.move(this); connectRealNode(graphNode, callNodeStack.peek(), movable.getRealNode()); } } if(endCallNode != null && secuentialNode != null) { addVertex(endCallNode); addControlDependencyArc(secuentialNode, endCallNode); } assert callNodeStack.isEmpty(); } } public void addControlDependencyArc(GraphNode<?> from, GraphNode<?> to) { this.addEdge(from, to, new ControlDependencyArc()); } /** Connects the real node to the proper parent, control-dependent-wise. */ protected void connectRealNode(GraphNode<?> graphNode, CallNode callNode, GraphNode<?> realNode) { if (realNode instanceof ActualIONode || realNode instanceof CallNode.Return) { assert callNode != null; if(secuentialNode != realNode) { addControlDependencyArc(secuentialNode == null ? callNode : secuentialNode, realNode); secuentialNode = realNode; } } else { addControlDependencyArc(graphNode, realNode); } } } No newline at end of file
iacfg/src/main/java/es/upv/mist/slicing/tests/Test.java 0 → 100644 +36 −0 Original line number Diff line number Diff line package es.upv.mist.slicing.tests; public class Test { public static void main(String[] args) { int x = 1; boolean a = true; while (x < 100) { if (x < 50) { System.out.println(x); x = incrementar(x); } else { System.out.println(x); x = incrementarBucle(x); } } } private static int incrementar(int a){ return a+1; } private static int incrementarBucle(int a){ if(a>0){ int x = 0; for(int i = 0; i<a; i++){ x = x + i; } return x; } else { return a; } } }
iacfg/src/main/java/es/upv/mist/slicing/tests/Test_Entrevista.javadeleted 100644 → 0 +0 −27 Original line number Diff line number Diff line package es.upv.mist.slicing.tests; public class Test_Entrevista { public static void main(String[] args) { int x = 1; while (x > 1) { if (x > 10) { x++; } else { while (x > 1) { if (x > 10) { x++; } else { if (x > 10) { x++; } else { x--; } } } } } } }
sdg-cli/src/main/java/es/upv/mist/slicing/cli/GraphLog.java +15 −5 Original line number Diff line number Diff line Loading @@ -71,13 +71,9 @@ public abstract class GraphLog<G extends Graph> { } public void generateImages(String imageName, String format) throws IOException { this.imageName = imageName + "-" + graph.getClass().getSimpleName(); this.format = format; generated = true; File tmpDot = File.createTempFile("graph-source-", ".dot"); tmpDot.getParentFile().mkdirs(); getImageFile().getParentFile().mkdirs(); File tmpDot = getDotFile(imageName); // Graph -> DOT -> file try (Writer w = new FileWriter(tmpDot)) { getDOTExporter().exportGraph(graph, w); Loading @@ -97,6 +93,20 @@ public abstract class GraphLog<G extends Graph> { } } public File getDotFile(String imageName) throws IOException { this.imageName = imageName + "-" + graph.getClass().getSimpleName(); File tmpDot = File.createTempFile("graph-source-", ".dot"); tmpDot.getParentFile().mkdirs(); getImageFile().getParentFile().mkdirs(); // Graph -> DOT -> file try (Writer w = new FileWriter(tmpDot)) { getDOTExporter().exportGraph(graph, w); } return tmpDot; } public void openVisualRepresentation() throws IOException { if (!generated) generateImages(); openFileForUser(getImageFile()); Loading