Commit aaea10e1 authored by jacosro's avatar jacosro
Browse files

Cheery-Pick: First approx: Changed id type to long and delegated id handling to IdHelper singleton

parent e39d4f23
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ public class PDGLog extends GraphLog<PDG> {

        Logger.log("Nodes with variable info");
        Logger.log(graph.vertexSet().stream()
                .sorted(Comparator.comparingInt(GraphNode::getId))
                .sorted(Comparator.comparingLong(GraphNode::getId))
                .map(node ->
                        String.format("GraphNode { id: %s, instruction: %s, declared: %s, defined: %s, used: %s }",
                                node.getId(),
+10 −143
Original line number Diff line number Diff line
@@ -9,7 +9,6 @@ import tfm.nodes.NodeFactory;
import tfm.utils.ASTUtils;

import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
@@ -17,59 +16,25 @@ import java.util.stream.Collectors;
 * */
public abstract class Graph extends DirectedPseudograph<GraphNode<?>, Arc> {

    protected static final int DEFAULT_VERTEX_START_ID = 0;

    private int nextVertexId;

    public Graph() {
        this(DEFAULT_VERTEX_START_ID);
    }

    protected Graph(int vertexStartId) {
    protected Graph() {
        super(null, null, false);
        this.nextVertexId = vertexStartId;
    }

    private <ASTNode extends Node> GraphNode<ASTNode> addNode(GraphNode<ASTNode> node) {
        this.addVertex(node);

        return node;
    }

    private <ASTNode extends Node> GraphNode<ASTNode> addNode(int id, String instruction, ASTNode node) {
        GraphNode<ASTNode> newNode = NodeFactory.graphNode(id, instruction, node);

        return this.addNode(newNode);
    }

    public <ASTNode extends Node> GraphNode<ASTNode> addNode(String instruction, ASTNode node) {
        return this.addNode(getNextVertexId(), instruction, node);
    }

    /**
     * Adds the given node to the graph.
     *
     * One must be careful with this method, as the given node will have
     * an id corresponding to the graph in which it was created, and may not fit
     * in the current graph.
     *
     * @param node the node to add to the graph
     * @param copyId whether to copy the node id or generate a new one
     * @return the node instance added to the graph
     */
    public <ASTNode extends Node> GraphNode<ASTNode> addNode(GraphNode<ASTNode> node, boolean copyId) {
        GraphNode<ASTNode> copy = NodeFactory.computedGraphNode(
                copyId ? node.getId() : getNextVertexId(),
                node.getInstruction(),
                node.getAstNode(),
                node.getDeclaredVariables(),
                node.getDefinedVariables(),
                node.getUsedVariables()
        );
    public <ASTNode extends Node> void addNode(GraphNode<ASTNode> node) {
        this.addVertex(node);
    }

        this.addVertex(copy);
    public <ASTNode extends Node> GraphNode<ASTNode> addNode(String instruction, ASTNode node) {
        GraphNode<ASTNode> newNode = NodeFactory.graphNode(instruction, node);

        return copy;
        this.addNode(newNode);

        return newNode;
    }

    @SuppressWarnings("unchecked")
@@ -80,7 +45,7 @@ public abstract class Graph extends DirectedPseudograph<GraphNode<?>, Arc> {
                .map(node -> (GraphNode<ASTNode>) node);
    }

    public Optional<GraphNode<?>> findNodeById(int id) {
    public Optional<GraphNode<?>> findNodeById(long id) {
        return vertexSet().stream()
                .filter(node -> Objects.equals(node.getId(), id))
                .findFirst();
@@ -93,10 +58,6 @@ public abstract class Graph extends DirectedPseudograph<GraphNode<?>, Arc> {
                .collect(Collectors.joining(System.lineSeparator()));
    }

    protected synchronized int getNextVertexId() {
        return nextVertexId++;
    }

    public List<GraphNode<?>> findDeclarationsOfVariable(String variable) {
        return vertexSet().stream()
                .filter(node -> node.getDeclaredVariables().contains(variable))
@@ -115,98 +76,4 @@ public abstract class Graph extends DirectedPseudograph<GraphNode<?>, Arc> {
                null,
                Arc::getDotAttributes);
    }

    /**
     * Modifies a current node in the graph by the changes done in the MutableGraphNode instance
     * inside the function passed as parameter
     *
     * @param id the id of the node to be modified
     * @param modifyFn a consumer which takes a MutableGraphNode as parameter
     */
    public <ASTNode extends Node> void modifyNode(int id, Consumer<MutableGraphNode<ASTNode>> modifyFn) {
        this.findNodeById(id).ifPresent(node -> {
            Set<Arc> incomingArcs = new HashSet<>(incomingEdgesOf(node));
            Set<Arc> outgoingArcs = new HashSet<>(outgoingEdgesOf(node));

            this.removeVertex(node);

            MutableGraphNode<ASTNode> modifiedNode = new MutableGraphNode<>((GraphNode<ASTNode>) node);

            modifyFn.accept(modifiedNode);

            GraphNode<ASTNode> newNode = modifiedNode.toGraphNode();

            this.addVertex(newNode);

            for (Arc incomingArc : incomingArcs) {
                GraphNode<?> from = getEdgeSource(incomingArc);
                this.addEdge(from, newNode, incomingArc);
            }

            for (Arc outgoingArc : outgoingArcs) {
                GraphNode<?> to = getEdgeTarget(outgoingArc);
                this.addEdge(newNode, to, outgoingArc);
            }
        });
    }

    public static class MutableGraphNode<ASTNode extends Node> {
        private int id;
        private String instruction;
        private ASTNode astNode;
        private Set<String> declaredVariables;
        private Set<String> definedVariables;
        private Set<String> usedVariables;

        private boolean mustCompute;

        MutableGraphNode(GraphNode<ASTNode> node) {
            this.id = node.getId();
            this.instruction = node.getInstruction();
            this.astNode = node.getAstNode();
            this.declaredVariables = node.getDeclaredVariables();
            this.definedVariables = node.getDefinedVariables();
            this.usedVariables = node.getUsedVariables();
        }

        GraphNode<ASTNode> toGraphNode() {
            return mustCompute
                    ? NodeFactory.graphNode(id, instruction, astNode)
                    : NodeFactory.computedGraphNode(
                        id,
                        instruction,
                        astNode,
                        declaredVariables,
                        definedVariables,
                        usedVariables
                    );
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getInstruction() {
            return instruction;
        }

        public void setInstruction(String instruction) {
            this.instruction = instruction;
        }

        public ASTNode getAstNode() {
            return astNode;
        }

        public void setAstNode(ASTNode astNode) {
            this.astNode = astNode;

            // If the AST node changes, we need to compute all variables for it
            mustCompute = true;
        }
    }
}
+11 −5
Original line number Diff line number Diff line
@@ -10,12 +10,10 @@ import java.util.Optional;

public abstract class GraphWithRootNode<ASTRootNode extends Node> extends Graph implements Buildable<MethodDeclaration> {

    protected final int ROOT_NODE_ID = 0;

    protected GraphNode<ASTRootNode> rootNode;

    public GraphWithRootNode() {
        super(1);
    protected GraphWithRootNode() {
        super();
    }

    /**
@@ -31,7 +29,7 @@ public abstract class GraphWithRootNode<ASTRootNode extends Node> extends Graph
            return false;
        }

        GraphNode<ASTRootNode> root = NodeFactory.graphNode(ROOT_NODE_ID, instruction, rootNodeAst);
        GraphNode<ASTRootNode> root = NodeFactory.graphNode(instruction, rootNodeAst);
        this.rootNode = root;
        this.addVertex(root);

@@ -42,6 +40,14 @@ public abstract class GraphWithRootNode<ASTRootNode extends Node> extends Graph
        return Optional.ofNullable(rootNode);
    }

    public void setRootNode(GraphNode<ASTRootNode> rootNode) {
        if (!this.containsVertex(rootNode)) {
            throw new IllegalArgumentException("Cannot set root node: " + rootNode + " is not contained in graph!");
        }

        this.rootNode = rootNode;
    }

    @Override
    public boolean removeVertex(GraphNode<?> graphNode) {
        if (Objects.equals(graphNode, rootNode)) {
+1 −1
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ public class CFG extends GraphWithRootNode<MethodDeclaration> {
        return findLastDefinitionsFrom(new HashSet<>(), startNode.getId(), startNode, variable);
    }

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

        Set<GraphNode<?>> res = new HashSet<>();
+4 −4
Original line number Diff line number Diff line
@@ -38,10 +38,6 @@ public class PDGBuilder {
        if (!methodDeclaration.getBody().isPresent())
            throw new IllegalStateException("Method needs to have a body");

        this.pdg.buildRootNode("ENTER " + methodDeclaration.getNameAsString(), methodDeclaration);

        assert this.pdg.getRootNode().isPresent();

        BlockStmt methodBody = methodDeclaration.getBody().get();

        // build CFG
@@ -53,6 +49,10 @@ public class PDGBuilder {
                .filter(node -> !Objects.equals(node, cfg.getExitNode()))
                .forEach(node -> pdg.addVertex(node));

        assert this.cfg.getRootNode().isPresent();
        
        pdg.setRootNode(cfg.getRootNode().get());

        // Build control dependency
        ControlDependencyBuilder controlDependencyBuilder = new ControlDependencyBuilder(pdg, cfg);
        controlDependencyBuilder.analyze();
Loading