Class Graph<G extends Graph<G,​N,​E>,​N extends Node<N,​E,​G>,​E extends Edge<N,​E,​G>>

  • Type Parameters:
    N - the type of Nodes in this graph
    E - the type of Edges in this graph
    G - the type of this graph
    Direct Known Subclasses:
    BaseCallGraph, CFG

    public abstract class Graph<G extends Graph<G,​N,​E>,​N extends Node<N,​E,​G>,​E extends Edge<N,​E,​G>>
    extends java.lang.Object
    A generic graph, backed by an AdjacencyMatrix.

    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 AdjacencyMatrix<N,​E,​G> adjacencyMatrix
      The adjacency matrix of this graph, mapping nodes to the collection of edges attached to it.
      protected java.util.Collection<N> entrypoints
      The nodes of this graph that are entrypoints, that is, that can be executed from other graphs.
    • Constructor Summary

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

      All Methods Instance Methods Abstract Methods Concrete Methods 
      Modifier and Type Method Description
      <V> void accept​(GraphVisitor<G,​N,​E,​V> visitor, V tool)
      Accepts the given GraphVisitor.
      void addEdge​(E edge)
      Adds an edge to this graph.
      void addNode​(N node)
      Adds the given node to the set of nodes, optionally setting that as root.
      void addNode​(N node, boolean entrypoint)
      Adds the given node to the set of nodes, optionally marking this as entrypoint (that is, reachable executable from other graphs).
      void dump​(java.io.Writer writer)
      Dumps the content of this graph in the given writer, formatted as a dot file.
      void dump​(java.io.Writer writer, java.util.function.Function<N,​java.lang.String> labelGenerator)
      Dumps the content of this graph in the given writer, formatted as a dot file.
      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.
      AdjacencyMatrix<N,​E,​G> getAdjacencyMatrix()
      Yields the adjacency matrix backing this graph.
      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.
      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, that can be executed from other graphs.
      java.util.Collection<E> getIngoingEdges​(N node)
      Yields the ingoing edges to the given node.
      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.
      protected void preSimplify​(N node)
      Callback that is invoked on a node before simplifying it.
      protected 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.
      protected abstract DotGraph<N,​E,​G> toDot​(java.util.function.Function<N,​java.lang.String> labelGenerator)
      Converts this graph to a DotGraph instance.
      java.lang.String toString()  
      • Methods inherited from class java.lang.Object

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

      • adjacencyMatrix

        protected final AdjacencyMatrix<N extends Node<N,​E,​G>,​E extends Edge<N,​E,​G>,​G extends Graph<G,​N,​E>> adjacencyMatrix
        The adjacency matrix of this graph, mapping nodes to the collection of edges attached to it.
      • entrypoints

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

      • Graph

        protected Graph()
        Builds the graph.
      • Graph

        protected Graph​(java.util.Collection<N> entrypoints,
                        AdjacencyMatrix<N,​E,​G> adjacencyMatrix)
        Builds the graph.
        Parameters:
        entrypoints - the nodes of this graph that will be reachable from other graphs
        adjacencyMatrix - the matrix containing all the nodes and the edges that will be part of this graph
      • Graph

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

      • getAdjacencyMatrix

        public AdjacencyMatrix<N,​E,​G> getAdjacencyMatrix()
        Yields the adjacency matrix backing this graph.
        Returns:
        the matrix
      • getEntrypoints

        public final java.util.Collection<N> getEntrypoints()
        Yields the nodes of this graph that are entrypoints, that is, that can be executed from other graphs. This usually contains the first node of this graph, but might also contain other ones.
        Returns:
        the entrypoints of this graph.
      • getNodes

        public final java.util.Collection<N> getNodes()
        Yields the set of nodes of this graph.
        Returns:
        the collection of nodes
      • getEdges

        public final java.util.Collection<E> getEdges()
        Yields the set of edges of this graph.
        Returns:
        the collection of edges
      • addNode

        public final void addNode​(N node)
        Adds the given node to the set of nodes, optionally setting that as root. This is equivalent to invoking addNode(Node, boolean) with false as second parameter.
        Parameters:
        node - the node to add
      • addNode

        public final void addNode​(N node,
                                  boolean entrypoint)
        Adds the given node to the set of nodes, optionally marking this as entrypoint (that is, reachable executable from other graphs). The first node of a graph should always be marked as entrypoint. Besides, nodes that might be reached through jumps from external graphs should be marked as entrypoints as well.
        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)
        Adds an edge to this graph.
        Parameters:
        edge - the edge to add
        Throws:
        java.lang.UnsupportedOperationException - if the source or the destination of the given edge are not part of this graph
      • getNodesCount

        public final int getNodesCount()
        Yields the total number of nodes of this graph.
        Returns:
        the number of nodes
      • getEdgesCount

        public final int getEdgesCount()
        Yields the total number of edges of this graph.
        Returns:
        the number of edges
      • getEdgeConnecting

        public final E getEdgeConnecting​(N source,
                                         N destination)
        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.
        Parameters:
        source - the source node
        destination - the destination node
        Returns:
        the edge connecting source to destination, or null
      • getIngoingEdges

        public final java.util.Collection<E> getIngoingEdges​(N node)
        Yields the ingoing edges to the given node.
        Parameters:
        node - the node
        Returns:
        the collection of ingoing edges
      • getOutgoingEdges

        public final java.util.Collection<E> getOutgoingEdges​(N node)
        Yields the outgoing edges from the given node.
        Parameters:
        node - the node
        Returns:
        the collection of outgoing edges
      • followersOf

        public final 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. Yields null if the node is not in this graph.
        Parameters:
        node - the node
        Returns:
        the collection of followers
      • predecessorsOf

        public final 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. Yields null if the node is not in this graph.
        Parameters:
        node - the node
        Returns:
        the collection of predecessors
      • dump

        public void dump​(java.io.Writer writer)
                  throws java.io.IOException
        Dumps the content of this graph in the given writer, formatted as a dot file.
        Parameters:
        writer - the writer where the content will be written
        Throws:
        java.io.IOException - if an exception happens while writing something to the given writer
      • dump

        public void dump​(java.io.Writer writer,
                         java.util.function.Function<N,​java.lang.String> labelGenerator)
                  throws java.io.IOException
        Dumps the content of this graph in the given writer, formatted as a dot file. The content of each vertex will be enriched by invoking labelGenerator on the vertex itself, to obtain an extra description to be concatenated with the standard call to the vertex's toString().
        Parameters:
        writer - the writer where the content will be written
        labelGenerator - the function used to generate extra labels
        Throws:
        java.io.IOException - if an exception happens while writing something to the given writer
      • toDot

        protected abstract DotGraph<N,​E,​G> toDot​(java.util.function.Function<N,​java.lang.String> labelGenerator)
        Converts this graph to a DotGraph instance.
        Parameters:
        labelGenerator - the generator that the DotGraph will use to enrich node labels
        Returns:
        the converted DotGraph
      • isEqualTo

        public 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.
        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

        protected 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 Edge.canBeSimplified().
        Parameters:
        target - the class of the Node 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

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