Skip to content
CFGGraph.java 1.76 KiB
Newer Older
Javier Costa's avatar
Javier Costa committed
package tfm.graphs;
Javier Costa's avatar
Javier Costa committed

import com.github.javaparser.ast.stmt.EmptyStmt;
import org.jgrapht.io.DOTExporter;
Javier Costa's avatar
Javier Costa committed
import tfm.arcs.Arc;
Javier Costa's avatar
Javier Costa committed
import tfm.arcs.cfg.ControlFlowArc;
Javier Costa's avatar
Javier Costa committed
import tfm.nodes.GraphNode;
Javier Costa's avatar
Javier Costa committed
import tfm.utils.NodeNotFoundException;
Javier Costa's avatar
Javier Costa committed

Javier Costa's avatar
Javier Costa committed
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
Javier Costa's avatar
Javier Costa committed

public class CFGGraph extends GraphWithRootNode {
Javier Costa's avatar
Javier Costa committed

    public CFGGraph() {
        super();
    }

    @Override
    protected GraphNode<?> buildRootNode() {
        return new GraphNode<>(getNextVertexId(), "Start", new EmptyStmt());
Javier Costa's avatar
Javier Costa committed
    }

Javier Costa's avatar
Javier Costa committed
    public void addControlFlowEdge(GraphNode<?> from, GraphNode<?> to) {
        super.addEdge(from, to, new ControlFlowArc());
Javier Costa's avatar
Javier Costa committed
    }
Javier Costa's avatar
Javier Costa committed

Javier Costa's avatar
Javier Costa committed
    public Set<GraphNode<?>> findLastDefinitionsFrom(GraphNode<?> startNode, String variable) {
        if (!this.containsVertex(startNode))
Javier Costa's avatar
Javier Costa committed
            throw new NodeNotFoundException(startNode, this);
        return findLastDefinitionsFrom(new HashSet<>(), startNode, startNode, variable);
    }

    private Set<GraphNode<?>> findLastDefinitionsFrom(Set<Integer> visited, GraphNode<?> startNode, GraphNode<?> currentNode, String variable) {
        visited.add(currentNode.getId());

        Set<GraphNode<?>> res = new HashSet<>();

Javier Costa's avatar
Javier Costa committed
        for (Arc arc : incomingEdgesOf(currentNode)) {
            ControlFlowArc controlFlowArc = arc.asControlFlowArc();
Javier Costa's avatar
Javier Costa committed

Javier Costa's avatar
Javier Costa committed
            GraphNode<?> from = this.getEdgeSource(controlFlowArc);
Javier Costa's avatar
Javier Costa committed

            if (!Objects.equals(startNode, from) && visited.contains(from.getId())) {
                continue;
            }

            if (from.getDefinedVariables().contains(variable)) {
                res.add(from);
            } else {
                res.addAll(findLastDefinitionsFrom(visited, startNode, from, variable));
            }
        }
        return res;
    }
Javier Costa's avatar
Javier Costa committed
}