Class CodeGraph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>

  • Type Parameters:
    G - the type of this graph
    N - the type of CodeNodes in this graph
    E - the type of CodeEdges in this graph
    All Implemented Interfaces:
    Graph<G,​N,​E>
    Direct Known Subclasses:
    CFG

    public abstract class CodeGraph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>
    extends java.lang.Object
    implements Graph<G,​N,​E>
    A Graph that contains a list of nodes, backed by a NodeList. The characteristic of this graph is that a nodes are mostly sequential, and can be almost perfectly stored as a list. The NodeList backing this graph also supports custom edges.

    Note that this class does not define Object.equals(Object) nor Object.hashCode(), since we leave the decision to be unique instances to implementers.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      protected java.util.Collection<N> entrypoints
      The nodes of this graph that are entrypoints, that is, that can be executed from other graphs.
      protected NodeList<G,​N,​E> list
      The node list of this graph.
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      protected CodeGraph​(E sequentialSingleton)
      Builds the graph.
      protected CodeGraph​(G other)
      Clones the given graph.
      protected CodeGraph​(java.util.Collection<N> entrypoints, NodeList<G,​N,​E> nodes)
      Builds the graph.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void addEdge​(E edge)
      Adds an edge to this graph.
      void addNode​(N node)
      Adds the given node to the set of nodes.
      void addNode​(N node, boolean entrypoint)
      Adds the given node to the set of nodes, optionally marking this as entrypoint (that is, root).
      boolean containsEdge​(E edge)
      Yields true if the given edge is contained in this graph.
      boolean containsNode​(N node)
      Yields true if the given node is contained in this graph.
      java.util.Collection<N> followersOf​(N node)
      Yields the collection of the nodes that are followers of the given one, that is, all nodes such that there exist an edge in this control flow graph going from the given node to such node.
      E getEdgeConnecting​(N source, N destination)
      Yields the edge connecting the two given nodes, if any.
      java.util.Collection<E> getEdges()
      Yields the set of edges of this graph.
      java.util.Collection<E> getEdgesConnecting​(N source, N destination)
      Yields all edges connecting the two given nodes, if any.
      int getEdgesCount()
      Yields the total number of edges of this graph.
      java.util.Collection<N> getEntrypoints()
      Yields the nodes of this graph that are entrypoints, that is, roots of the graph.
      java.util.Collection<E> getIngoingEdges​(N node)
      Yields the ingoing edges to the given node.
      NodeList<G,​N,​E> getNodeList()
      Yields the node list backing this graph.
      java.util.Collection<N> getNodes()
      Yields the set of nodes of this graph.
      int getNodesCount()
      Yields the total number of nodes of this graph.
      java.util.Collection<E> getOutgoingEdges​(N node)
      Yields the outgoing edges from the given node.
      boolean isEqualTo​(G graph)
      Checks if this graph is effectively equal to the given one, that is, if they have the same structure while potentially being different instances.
      java.util.Collection<N> predecessorsOf​(N node)
      Yields the collection of the nodes that are predecessors of the given vertex, that is, all nodes such that there exist an edge in this control flow graph going from such node to the given one.
      void preSimplify​(N node)
      Callback that is invoked on a node before simplifying it.
      java.util.Set<N> simplify​(java.lang.Class<? extends N> target, java.util.Collection<E> removedEdges, java.util.Map<org.apache.commons.lang3.tuple.Pair<E,​E>,​E> replacedEdges)
      Simplifies the adjacency matrix beneath this graph, removing all nodes that are instances of <T> and rewriting the edge set accordingly.
      SerializableGraph toSerializableGraph​(java.util.function.BiFunction<G,​N,​SerializableValue> descriptionGenerator)
      Yields an instance of SerializableGraph built from this one.
      java.lang.String toString()  
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Field Detail

      • entrypoints

        protected final java.util.Collection<N extends CodeNode<G,​N,​E>> entrypoints
        The nodes of this graph that are entrypoints, that is, that can be executed from other graphs.
    • Constructor Detail

      • CodeGraph

        protected CodeGraph​(E sequentialSingleton)
        Builds the graph.
        Parameters:
        sequentialSingleton - an instance of an edge of this list that can be used to invoke CodeEdge.newInstance(CodeNode, CodeNode) to obtain instances of sequential edges
      • CodeGraph

        protected CodeGraph​(java.util.Collection<N> entrypoints,
                            NodeList<G,​N,​E> nodes)
        Builds the graph.
        Parameters:
        entrypoints - the nodes of this graph that will be reachable from other graphs
        nodes - the list of nodes contained in this graph
      • CodeGraph

        protected CodeGraph​(G other)
        Clones the given graph.
        Parameters:
        other - the original graph
    • Method Detail

      • getNodeList

        public NodeList<G,​N,​E> getNodeList()
        Yields the node list backing this graph.
        Returns:
        the list
      • getEntrypoints

        public java.util.Collection<N> getEntrypoints()
        Description copied from interface: Graph
        Yields the nodes of this graph that are entrypoints, that is, roots of the graph. This usually contains the first node of this graph, but might also contain other ones.
        Specified by:
        getEntrypoints in interface Graph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>
        Returns:
        the entrypoints of this graph
      • getNodes

        public java.util.Collection<N> getNodes()
        Description copied from interface: Graph
        Yields the set of nodes of this graph.
        Specified by:
        getNodes in interface Graph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>
        Returns:
        the collection of nodes
      • getEdges

        public java.util.Collection<E> getEdges()
        Description copied from interface: Graph
        Yields the set of edges of this graph.
        Specified by:
        getEdges in interface Graph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>
        Returns:
        the collection of edges
      • addNode

        public void addNode​(N node,
                            boolean entrypoint)
        Description copied from interface: Graph
        Adds the given node to the set of nodes, optionally marking this as entrypoint (that is, root).
        Specified by:
        addNode in interface Graph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>
        Parameters:
        node - the node to add
        entrypoint - if true causes the given node to be considered as an entrypoint.
      • addEdge

        public void addEdge​(E edge)
        Description copied from interface: Graph
        Adds an edge to this graph.
        Specified by:
        addEdge in interface Graph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>
        Parameters:
        edge - the edge to add
      • getNodesCount

        public int getNodesCount()
        Description copied from interface: Graph
        Yields the total number of nodes of this graph.
        Specified by:
        getNodesCount in interface Graph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>
        Returns:
        the number of nodes
      • getEdgesCount

        public int getEdgesCount()
        Description copied from interface: Graph
        Yields the total number of edges of this graph.
        Specified by:
        getEdgesCount in interface Graph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>
        Returns:
        the number of edges
      • containsNode

        public boolean containsNode​(N node)
        Description copied from interface: Graph
        Yields true if the given node is contained in this graph.
        Specified by:
        containsNode in interface Graph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>
        Parameters:
        node - the node to check
        Returns:
        true if the node is in this graph
      • containsEdge

        public boolean containsEdge​(E edge)
        Description copied from interface: Graph
        Yields true if the given edge is contained in this graph.
        Specified by:
        containsEdge in interface Graph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>
        Parameters:
        edge - the edge to check
        Returns:
        true if the edge is in this graph
      • getEdgeConnecting

        public E getEdgeConnecting​(N source,
                                   N destination)
        Description copied from interface: Graph
        Yields the edge connecting the two given nodes, if any. Yields null if such edge does not exist, or if one of the two nodes is not inside this graph. If more than one edge connects the two nodes, this method returns one of them arbitrarily (but consistently: successive calls with the same parameters will always return the same edge). To retrieve all such edges, use Graph.getEdgesConnecting(Node, Node).
        Specified by:
        getEdgeConnecting in interface Graph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>
        Parameters:
        source - the source node
        destination - the destination node
        Returns:
        the edge connecting source to destination, or null
      • getEdgesConnecting

        public java.util.Collection<E> getEdgesConnecting​(N source,
                                                          N destination)
        Description copied from interface: Graph
        Yields all edges connecting the two given nodes, if any. Yields an empty collection if no edge exists, or if one of the two nodes is not inside this graph.
        Specified by:
        getEdgesConnecting in interface Graph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>
        Parameters:
        source - the source node
        destination - the destination node
        Returns:
        the edges connecting source to destination
      • getIngoingEdges

        public java.util.Collection<E> getIngoingEdges​(N node)
        Description copied from interface: Graph
        Yields the ingoing edges to the given node.
        Specified by:
        getIngoingEdges in interface Graph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>
        Parameters:
        node - the node
        Returns:
        the collection of ingoing edges
      • getOutgoingEdges

        public java.util.Collection<E> getOutgoingEdges​(N node)
        Description copied from interface: Graph
        Yields the outgoing edges from the given node.
        Specified by:
        getOutgoingEdges in interface Graph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>
        Parameters:
        node - the node
        Returns:
        the collection of outgoing edges
      • followersOf

        public java.util.Collection<N> followersOf​(N node)
        Description copied from interface: Graph
        Yields the collection of the nodes that are followers of the given one, that is, all nodes such that there exist an edge in this control flow graph going from the given node to such node. Yields null if the node is not in this graph.
        Specified by:
        followersOf in interface Graph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>
        Parameters:
        node - the node
        Returns:
        the collection of followers
      • predecessorsOf

        public java.util.Collection<N> predecessorsOf​(N node)
        Description copied from interface: Graph
        Yields the collection of the nodes that are predecessors of the given vertex, that is, all nodes such that there exist an edge in this control flow graph going from such node to the given one. Yields null if the node is not in this graph.
        Specified by:
        predecessorsOf in interface Graph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>
        Parameters:
        node - the node
        Returns:
        the collection of predecessors
      • isEqualTo

        public boolean isEqualTo​(G graph)
        Description copied from interface: Graph
        Checks if this graph is effectively equal to the given one, that is, if they have the same structure while potentially being different instances.
        Specified by:
        isEqualTo in interface Graph<G extends CodeGraph<G,​N,​E>,​N extends CodeNode<G,​N,​E>,​E extends CodeEdge<G,​N,​E>>
        Parameters:
        graph - the other graph
        Returns:
        true if this graph and the given one are effectively equals
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object
      • simplify

        public java.util.Set<N> simplify​(java.lang.Class<? extends N> target,
                                         java.util.Collection<E> removedEdges,
                                         java.util.Map<org.apache.commons.lang3.tuple.Pair<E,​E>,​E> replacedEdges)
        Simplifies the adjacency matrix beneath this graph, removing all nodes that are instances of <T> and rewriting the edge set accordingly. This method will throw an UnsupportedOperationException if one of the nodes being simplified has an outgoing edge that is not simplifiable, according to CodeEdge.isUnconditional().
        Parameters:
        target - the class of the CodeNode that needs to be simplified
        removedEdges - the collections of edges that got removed during the simplification, filled by this method (the collection will be cleared before simplifying)
        replacedEdges - the map of edges that got replaced during the simplification, filled by this method (the map will be cleared before simplifying); each entry refers to a single simplified edge, and is in the form <<ingoing removed, outgoing removed>, added>
        Returns:
        the set of nodes that have been simplified
        Throws:
        java.lang.UnsupportedOperationException - if there exists at least one node being simplified with an outgoing non-simplifiable edge
      • preSimplify

        public void preSimplify​(N node)
        Callback that is invoked on a node before simplifying it.
        Parameters:
        node - the node about to be simplified