Skip to content
Snippets Groups Projects
Commit f0e133e7 authored by Jonathan Andrade's avatar Jonathan Andrade
Browse files

expandCall method created

parent 77d78e04
No related branches found
No related tags found
No related merge requests found
Pipeline #246 failed
......@@ -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>
......@@ -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
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) {
......@@ -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
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;
}
}
}
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--;
}
}
}
}
}
}
}
......@@ -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);
......@@ -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());
......
......@@ -112,16 +112,19 @@ public class PDG extends GraphWithRootNode<CallableDeclaration<?>> {
* them via control dependency to the node they were located at.
*/
protected void expandCalls() {
// debug statement to print graph
// new PDGLog(PDG.this).generateImages("pdg-debug")
for (GraphNode<?> graphNode : Set.copyOf(vertexSet())) {
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.CallMarker) action).isEnter()) {
if (!variableAction.isEnter()) {
callNodeStack.pop();
} else {
CallNode callNode = CallNode.create(((VariableAction.CallMarker) action).getCall());
CallNode callNode = CallNode.create(variableAction.getCall());
if (graphNode.isImplicitInstruction())
callNode.markAsImplicit();
addVertex(callNode);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment