mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Switch libgraphviz from type params to associated types for Node/Edge.
This commit is contained in:
parent
7ec8f5c369
commit
baeae780e0
@ -62,7 +62,9 @@
|
||||
//! dot::render(&edges, output).unwrap()
|
||||
//! }
|
||||
//!
|
||||
//! impl<'a> dot::Labeller<'a, Nd, Ed> for Edges {
|
||||
//! impl<'a> dot::Labeller<'a> for Edges {
|
||||
//! type Node = Nd;
|
||||
//! type Edge = Ed;
|
||||
//! fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new("example1").unwrap() }
|
||||
//!
|
||||
//! fn node_id(&'a self, n: &Nd) -> dot::Id<'a> {
|
||||
@ -70,7 +72,9 @@
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! impl<'a> dot::GraphWalk<'a, Nd, Ed> for Edges {
|
||||
//! impl<'a> dot::GraphWalk<'a> for Edges {
|
||||
//! type Node = Nd;
|
||||
//! type Edge = Ed;
|
||||
//! fn nodes(&self) -> dot::Nodes<'a,Nd> {
|
||||
//! // (assumes that |N| \approxeq |E|)
|
||||
//! let &Edges(ref v) = self;
|
||||
@ -167,7 +171,9 @@
|
||||
//! dot::render(&graph, output).unwrap()
|
||||
//! }
|
||||
//!
|
||||
//! impl<'a> dot::Labeller<'a, Nd, Ed<'a>> for Graph {
|
||||
//! impl<'a> dot::Labeller<'a> for Graph {
|
||||
//! type Node = Nd;
|
||||
//! type Edge = Ed<'a>;
|
||||
//! fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new("example2").unwrap() }
|
||||
//! fn node_id(&'a self, n: &Nd) -> dot::Id<'a> {
|
||||
//! dot::Id::new(format!("N{}", n)).unwrap()
|
||||
@ -180,7 +186,9 @@
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! impl<'a> dot::GraphWalk<'a, Nd, Ed<'a>> for Graph {
|
||||
//! impl<'a> dot::GraphWalk<'a> for Graph {
|
||||
//! type Node = Nd;
|
||||
//! type Edge = Ed<'a>;
|
||||
//! fn nodes(&self) -> dot::Nodes<'a,Nd> { (0..self.nodes.len()).collect() }
|
||||
//! fn edges(&'a self) -> dot::Edges<'a,Ed<'a>> { self.edges.iter().collect() }
|
||||
//! fn source(&self, e: &Ed) -> Nd { let & &(s,_) = e; s }
|
||||
@ -225,7 +233,9 @@
|
||||
//! dot::render(&graph, output).unwrap()
|
||||
//! }
|
||||
//!
|
||||
//! impl<'a> dot::Labeller<'a, Nd<'a>, Ed<'a>> for Graph {
|
||||
//! impl<'a> dot::Labeller<'a> for Graph {
|
||||
//! type Node = Nd<'a>;
|
||||
//! type Edge = Ed<'a>;
|
||||
//! fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new("example3").unwrap() }
|
||||
//! fn node_id(&'a self, n: &Nd<'a>) -> dot::Id<'a> {
|
||||
//! dot::Id::new(format!("N{}", n.0)).unwrap()
|
||||
@ -239,7 +249,9 @@
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! impl<'a> dot::GraphWalk<'a, Nd<'a>, Ed<'a>> for Graph {
|
||||
//! impl<'a> dot::GraphWalk<'a> for Graph {
|
||||
//! type Node = Nd<'a>;
|
||||
//! type Edge = Ed<'a>;
|
||||
//! fn nodes(&'a self) -> dot::Nodes<'a,Nd<'a>> {
|
||||
//! self.nodes.iter().map(|s| &s[..]).enumerate().collect()
|
||||
//! }
|
||||
@ -447,45 +459,48 @@ impl<'a> Id<'a> {
|
||||
/// The graph instance is responsible for providing the DOT compatible
|
||||
/// identifiers for the nodes and (optionally) rendered labels for the nodes and
|
||||
/// edges, as well as an identifier for the graph itself.
|
||||
pub trait Labeller<'a,N,E> {
|
||||
pub trait Labeller<'a> {
|
||||
type Node;
|
||||
type Edge;
|
||||
|
||||
/// Must return a DOT compatible identifier naming the graph.
|
||||
fn graph_id(&'a self) -> Id<'a>;
|
||||
|
||||
/// Maps `n` to a unique identifier with respect to `self`. The
|
||||
/// implementor is responsible for ensuring that the returned name
|
||||
/// is a valid DOT identifier.
|
||||
fn node_id(&'a self, n: &N) -> Id<'a>;
|
||||
fn node_id(&'a self, n: &Self::Node) -> Id<'a>;
|
||||
|
||||
/// Maps `n` to one of the [graphviz `shape` names][1]. If `None`
|
||||
/// is returned, no `shape` attribute is specified.
|
||||
///
|
||||
/// [1]: http://www.graphviz.org/content/node-shapes
|
||||
fn node_shape(&'a self, _node: &N) -> Option<LabelText<'a>> {
|
||||
fn node_shape(&'a self, _node: &Self::Node) -> Option<LabelText<'a>> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Maps `n` to a label that will be used in the rendered output.
|
||||
/// The label need not be unique, and may be the empty string; the
|
||||
/// default is just the output from `node_id`.
|
||||
fn node_label(&'a self, n: &N) -> LabelText<'a> {
|
||||
fn node_label(&'a self, n: &Self::Node) -> LabelText<'a> {
|
||||
LabelStr(self.node_id(n).name)
|
||||
}
|
||||
|
||||
/// Maps `e` to a label that will be used in the rendered output.
|
||||
/// The label need not be unique, and may be the empty string; the
|
||||
/// default is in fact the empty string.
|
||||
fn edge_label(&'a self, e: &E) -> LabelText<'a> {
|
||||
fn edge_label(&'a self, e: &Self::Edge) -> LabelText<'a> {
|
||||
let _ignored = e;
|
||||
LabelStr("".into_cow())
|
||||
}
|
||||
|
||||
/// Maps `n` to a style that will be used in the rendered output.
|
||||
fn node_style(&'a self, _n: &N) -> Style {
|
||||
fn node_style(&'a self, _n: &Self::Node) -> Style {
|
||||
Style::None
|
||||
}
|
||||
|
||||
/// Maps `e` to a style that will be used in the rendered output.
|
||||
fn edge_style(&'a self, _e: &E) -> Style {
|
||||
fn edge_style(&'a self, _e: &Self::Edge) -> Style {
|
||||
Style::None
|
||||
}
|
||||
}
|
||||
@ -596,15 +611,18 @@ pub type Edges<'a,E> = Cow<'a,[E]>;
|
||||
/// `Cow<[T]>` to leave implementors the freedom to create
|
||||
/// entirely new vectors or to pass back slices into internally owned
|
||||
/// vectors.
|
||||
pub trait GraphWalk<'a, N: Clone, E: Clone> {
|
||||
pub trait GraphWalk<'a> {
|
||||
type Node: Clone;
|
||||
type Edge: Clone;
|
||||
|
||||
/// Returns all the nodes in this graph.
|
||||
fn nodes(&'a self) -> Nodes<'a, N>;
|
||||
fn nodes(&'a self) -> Nodes<'a, Self::Node>;
|
||||
/// Returns all of the edges in this graph.
|
||||
fn edges(&'a self) -> Edges<'a, E>;
|
||||
fn edges(&'a self) -> Edges<'a, Self::Edge>;
|
||||
/// The source node for `edge`.
|
||||
fn source(&'a self, edge: &E) -> N;
|
||||
fn source(&'a self, edge: &Self::Edge) -> Self::Node;
|
||||
/// The target node for `edge`.
|
||||
fn target(&'a self, edge: &E) -> N;
|
||||
fn target(&'a self, edge: &Self::Edge) -> Self::Node;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
@ -622,28 +640,26 @@ pub fn default_options() -> Vec<RenderOption> {
|
||||
|
||||
/// Renders directed graph `g` into the writer `w` in DOT syntax.
|
||||
/// (Simple wrapper around `render_opts` that passes a default set of options.)
|
||||
pub fn render<'a,
|
||||
N: Clone + 'a,
|
||||
E: Clone + 'a,
|
||||
G: Labeller<'a, N, E> + GraphWalk<'a, N, E>,
|
||||
W: Write>
|
||||
(g: &'a G,
|
||||
w: &mut W)
|
||||
-> io::Result<()> {
|
||||
pub fn render<'a,N,E,G,W>(g: &'a G, w: &mut W) -> io::Result<()>
|
||||
where N: Clone + 'a,
|
||||
E: Clone + 'a,
|
||||
G: Labeller<'a, Node=N, Edge=E> + GraphWalk<'a, Node=N, Edge=E>,
|
||||
W: Write
|
||||
{
|
||||
render_opts(g, w, &[])
|
||||
}
|
||||
|
||||
/// Renders directed graph `g` into the writer `w` in DOT syntax.
|
||||
/// (Main entry point for the library.)
|
||||
pub fn render_opts<'a,
|
||||
N: Clone + 'a,
|
||||
E: Clone + 'a,
|
||||
G: Labeller<'a, N, E> + GraphWalk<'a, N, E>,
|
||||
W: Write>
|
||||
(g: &'a G,
|
||||
w: &mut W,
|
||||
options: &[RenderOption])
|
||||
-> io::Result<()> {
|
||||
pub fn render_opts<'a, N, E, G, W>(g: &'a G,
|
||||
w: &mut W,
|
||||
options: &[RenderOption])
|
||||
-> io::Result<()>
|
||||
where N: Clone + 'a,
|
||||
E: Clone + 'a,
|
||||
G: Labeller<'a, Node=N, Edge=E> + GraphWalk<'a, Node=N, Edge=E>,
|
||||
W: Write
|
||||
{
|
||||
fn writeln<W: Write>(w: &mut W, arg: &[&str]) -> io::Result<()> {
|
||||
for &s in arg {
|
||||
try!(w.write_all(s.as_bytes()));
|
||||
@ -858,7 +874,9 @@ mod tests {
|
||||
Id::new(format!("N{}", *n)).unwrap()
|
||||
}
|
||||
|
||||
impl<'a> Labeller<'a, Node, &'a Edge> for LabelledGraph {
|
||||
impl<'a> Labeller<'a> for LabelledGraph {
|
||||
type Node = Node;
|
||||
type Edge = &'a Edge;
|
||||
fn graph_id(&'a self) -> Id<'a> {
|
||||
Id::new(&self.name[..]).unwrap()
|
||||
}
|
||||
@ -882,7 +900,9 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Labeller<'a, Node, &'a Edge> for LabelledGraphWithEscStrs {
|
||||
impl<'a> Labeller<'a> for LabelledGraphWithEscStrs {
|
||||
type Node = Node;
|
||||
type Edge = &'a Edge;
|
||||
fn graph_id(&'a self) -> Id<'a> {
|
||||
self.graph.graph_id()
|
||||
}
|
||||
@ -901,7 +921,9 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GraphWalk<'a, Node, &'a Edge> for LabelledGraph {
|
||||
impl<'a> GraphWalk<'a> for LabelledGraph {
|
||||
type Node = Node;
|
||||
type Edge = &'a Edge;
|
||||
fn nodes(&'a self) -> Nodes<'a, Node> {
|
||||
(0..self.node_labels.len()).collect()
|
||||
}
|
||||
@ -916,7 +938,9 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GraphWalk<'a, Node, &'a Edge> for LabelledGraphWithEscStrs {
|
||||
impl<'a> GraphWalk<'a> for LabelledGraphWithEscStrs {
|
||||
type Node = Node;
|
||||
type Edge = &'a Edge;
|
||||
fn nodes(&'a self) -> Nodes<'a, Node> {
|
||||
self.graph.nodes()
|
||||
}
|
||||
|
@ -52,7 +52,9 @@ fn replace_newline_with_backslash_l(s: String) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> {
|
||||
impl<'a, 'ast> dot::Labeller<'a> for LabelledCFG<'a, 'ast> {
|
||||
type Node = Node<'a>;
|
||||
type Edge = Edge<'a>;
|
||||
fn graph_id(&'a self) -> dot::Id<'a> { dot::Id::new(&self.name[..]).unwrap() }
|
||||
|
||||
fn node_id(&'a self, &(i,_): &Node<'a>) -> dot::Id<'a> {
|
||||
@ -97,7 +99,9 @@ impl<'a, 'ast> dot::Labeller<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for &'a cfg::CFG {
|
||||
impl<'a> dot::GraphWalk<'a> for &'a cfg::CFG {
|
||||
type Node = Node<'a>;
|
||||
type Edge = Edge<'a>;
|
||||
fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> {
|
||||
let mut v = Vec::new();
|
||||
self.graph.each_node(|i, nd| { v.push((i, nd)); true });
|
||||
@ -116,8 +120,10 @@ impl<'a> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for &'a cfg::CFG {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'ast> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for LabelledCFG<'a, 'ast>
|
||||
impl<'a, 'ast> dot::GraphWalk<'a> for LabelledCFG<'a, 'ast>
|
||||
{
|
||||
type Node = Node<'a>;
|
||||
type Edge = Edge<'a>;
|
||||
fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> { self.cfg.nodes() }
|
||||
fn edges(&'a self) -> dot::Edges<'a, Edge<'a>> { self.cfg.edges() }
|
||||
fn source(&'a self, edge: &Edge<'a>) -> Node<'a> { self.cfg.source(edge) }
|
||||
|
@ -173,7 +173,9 @@ impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> dot::Labeller<'a, Node, Edge> for ConstraintGraph<'a, 'tcx> {
|
||||
impl<'a, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'tcx> {
|
||||
type Node = Node;
|
||||
type Edge = Edge;
|
||||
fn graph_id(&self) -> dot::Id {
|
||||
dot::Id::new(&*self.graph_name).unwrap()
|
||||
}
|
||||
@ -224,7 +226,9 @@ fn edge_to_nodes(e: &Edge) -> (Node, Node) {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> dot::GraphWalk<'a, Node, Edge> for ConstraintGraph<'a, 'tcx> {
|
||||
impl<'a, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'tcx> {
|
||||
type Node = Node;
|
||||
type Edge = Edge;
|
||||
fn nodes(&self) -> dot::Nodes<Node> {
|
||||
let mut set = FnvHashSet();
|
||||
for node in self.node_ids.keys() {
|
||||
|
@ -129,7 +129,9 @@ impl<'a, 'tcx> DataflowLabeller<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> dot::Labeller<'a, Node<'a>, Edge<'a>> for DataflowLabeller<'a, 'tcx> {
|
||||
impl<'a, 'tcx> dot::Labeller<'a> for DataflowLabeller<'a, 'tcx> {
|
||||
type Node = Node<'a>;
|
||||
type Edge = Edge<'a>;
|
||||
fn graph_id(&'a self) -> dot::Id<'a> { self.inner.graph_id() }
|
||||
fn node_id(&'a self, n: &Node<'a>) -> dot::Id<'a> { self.inner.node_id(n) }
|
||||
fn node_label(&'a self, n: &Node<'a>) -> dot::LabelText<'a> {
|
||||
@ -143,7 +145,9 @@ impl<'a, 'tcx> dot::Labeller<'a, Node<'a>, Edge<'a>> for DataflowLabeller<'a, 't
|
||||
fn edge_label(&'a self, e: &Edge<'a>) -> dot::LabelText<'a> { self.inner.edge_label(e) }
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for DataflowLabeller<'a, 'tcx> {
|
||||
impl<'a, 'tcx> dot::GraphWalk<'a> for DataflowLabeller<'a, 'tcx> {
|
||||
type Node = Node<'a>;
|
||||
type Edge = Edge<'a>;
|
||||
fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> { self.inner.nodes() }
|
||||
fn edges(&'a self) -> dot::Edges<'a, Edge<'a>> { self.inner.edges() }
|
||||
fn source(&'a self, edge: &Edge<'a>) -> Node<'a> { self.inner.source(edge) }
|
||||
|
@ -253,7 +253,9 @@ fn dump_graph(tcx: &TyCtxt) {
|
||||
|
||||
pub struct GraphvizDepGraph(FnvHashSet<DepNode>, Vec<(DepNode, DepNode)>);
|
||||
|
||||
impl<'a, 'tcx> dot::GraphWalk<'a, DepNode, (DepNode, DepNode)> for GraphvizDepGraph {
|
||||
impl<'a, 'tcx> dot::GraphWalk<'a> for GraphvizDepGraph {
|
||||
type Node = DepNode;
|
||||
type Edge = (DepNode, DepNode);
|
||||
fn nodes(&self) -> dot::Nodes<DepNode> {
|
||||
let nodes: Vec<_> = self.0.iter().cloned().collect();
|
||||
nodes.into_cow()
|
||||
@ -269,7 +271,9 @@ impl<'a, 'tcx> dot::GraphWalk<'a, DepNode, (DepNode, DepNode)> for GraphvizDepGr
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> dot::Labeller<'a, DepNode, (DepNode, DepNode)> for GraphvizDepGraph {
|
||||
impl<'a, 'tcx> dot::Labeller<'a> for GraphvizDepGraph {
|
||||
type Node = DepNode;
|
||||
type Edge = (DepNode, DepNode);
|
||||
fn graph_id(&self) -> dot::Id {
|
||||
dot::Id::new("DependencyGraph").unwrap()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user