Commit 49e06a6d authored by Carlos Galindo's avatar Carlos Galindo
Browse files

Move parsing to `main` class and use Buildable interface

parent 7f01457b
Loading
Loading
Loading
Loading
Loading
+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;
@@ -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;
@@ -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;
@@ -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);
@@ -60,7 +66,6 @@ public class ICFG extends Graph {
            copyCFGs();
            expandCalls();
            joinCFGs();
        built = true;
        }

        protected void buildCFGs(NodeList<CompilationUnit> nodeList) {
@@ -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));
            }
        }
@@ -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");
@@ -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;
@@ -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;
                        }
@@ -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);
@@ -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
+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) {