Commit f0e133e7 authored by Jonathan Andrade's avatar Jonathan Andrade
Browse files

expandCall method created

parent 77d78e04
Loading
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -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
+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) {
@@ -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
+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;
		}
	}
}
+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--;
						}
					}
				}
			}
		}
	}
}
+15 −5
Original line number Diff line number Diff line
@@ -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());
Loading