diff options
-rw-r--r-- | src/codegen/mod.rs | 3 | ||||
-rw-r--r-- | src/ir/context.rs | 31 | ||||
-rw-r--r-- | src/ir/dot.rs | 53 | ||||
-rw-r--r-- | src/ir/item.rs | 30 | ||||
-rw-r--r-- | src/ir/mod.rs | 1 |
5 files changed, 73 insertions, 45 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 77f654e6..aab59946 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -10,6 +10,7 @@ use ir::annotations::FieldAccessorKind; use ir::comp::{Base, CompInfo, CompKind, Field, Method, MethodKind}; use ir::context::{BindgenContext, ItemId}; use ir::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault}; +use ir::dot; use ir::enum_ty::{Enum, EnumVariant, EnumVariantValue}; use ir::function::{Function, FunctionSig}; use ir::int::IntKind; @@ -2502,7 +2503,7 @@ pub fn codegen(context: &mut BindgenContext) -> Vec<P<ast::Item>> { } if let Some(path) = context.options().emit_ir_graphviz.as_ref() { - match context.emit_ir_graphviz(path.clone()) { + match dot::write_dot_file(context, path) { Ok(()) => info!("Your dot file was generated successfully into: {}", path), Err(e) => error!("{}", e), } diff --git a/src/ir/context.rs b/src/ir/context.rs index 7383c09a..d2fb2bef 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -5,7 +5,7 @@ use super::int::IntKind; use super::item::{Item, ItemCanonicalPath, ItemSet}; use super::item_kind::ItemKind; use super::module::{Module, ModuleKind}; -use super::traversal::{self, Edge, ItemTraversal, Trace}; +use super::traversal::{self, Edge, ItemTraversal}; use super::ty::{FloatKind, TemplateDeclaration, Type, TypeKind}; use BindgenOptions; use cexpr; @@ -18,8 +18,6 @@ use std::cell::Cell; use std::collections::{HashMap, hash_map}; use std::collections::btree_map::{self, BTreeMap}; use std::fmt; -use std::fs::File; -use std::io::{self, Write}; use std::iter::IntoIterator; use syntax::ast::Ident; use syntax::codemap::{DUMMY_SP, Span}; @@ -1111,33 +1109,6 @@ impl<'ctx> BindgenContext<'ctx> { &self.options } - /// Output graphviz dot file. - pub fn emit_ir_graphviz(&self, path: String) -> io::Result<()> { - let file = try!(File::create(path)); - let mut dot_file = io::BufWriter::new(file); - writeln!(&mut dot_file, "digraph {{")?; - - let mut err: Option<io::Result<_>> = None; - - for (id, item) in self.items() { - writeln!(&mut dot_file, "{} {};", id.0, item.dot_attributes(self))?; - - item.trace(self, &mut |sub_id: ItemId, _edge_kind| { - match writeln!(&mut dot_file, "{} -> {};", id.0, sub_id.as_usize()) { - Ok(_) => {}, - Err(e) => err = Some(Err(e)), - } - }, &()); - - if err.is_some() { - return err.unwrap(); - } - } - - writeln!(&mut dot_file, "}}")?; - Ok(()) - } - /// Tokenizes a namespace cursor in order to get the name and kind of the /// namespace, fn tokenize_namespace(&self, diff --git a/src/ir/dot.rs b/src/ir/dot.rs new file mode 100644 index 00000000..b7a117bb --- /dev/null +++ b/src/ir/dot.rs @@ -0,0 +1,53 @@ +//! Generating Graphviz `dot` files from our IR. + +use std::fs::File; +use std::io::{self, Write}; +use std::path::Path; +use super::context::{BindgenContext, ItemId}; +use super::traversal::Trace; + +/// A trait for anything that can write attributes as `<table>` rows to a dot +/// file. +pub trait DotAttributes { + /// Write this thing's attributes to the given output. Each attribute must + /// be its own `<tr>...</tr>`. + fn dot_attributes<W>(&self, ctx: &BindgenContext, out: &mut W) -> io::Result<()> + where W: io::Write; +} + +/// Write a graphviz dot file containing our IR. +pub fn write_dot_file<P>(ctx: &BindgenContext, path: P) -> io::Result<()> + where P: AsRef<Path> +{ + let file = try!(File::create(path)); + let mut dot_file = io::BufWriter::new(file); + try!(writeln!(&mut dot_file, "digraph {{")); + + let mut err: Option<io::Result<_>> = None; + + for (id, item) in ctx.items() { + try!(writeln!(&mut dot_file, + r#"{} [fontname="courier", label=< <table border="0">"#, + id.as_usize())); + try!(item.dot_attributes(ctx, &mut dot_file)); + try!(writeln!(&mut dot_file, r#"</table> >];"#)); + + item.trace(ctx, &mut |sub_id: ItemId, _edge_kind| { + if err.is_some() { + return; + } + + match writeln!(&mut dot_file, "{} -> {};", id.as_usize(), sub_id.as_usize()) { + Ok(_) => {}, + Err(e) => err = Some(Err(e)), + } + }, &()); + + if let Some(err) = err { + return err; + } + } + + try!(writeln!(&mut dot_file, "}}")); + Ok(()) +} diff --git a/src/ir/item.rs b/src/ir/item.rs index 8f16a96f..48a70fc6 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -3,6 +3,7 @@ use super::annotations::Annotations; use super::context::{BindgenContext, ItemId, PartialType}; use super::derive::{CanDeriveCopy, CanDeriveDebug, CanDeriveDefault}; +use super::dot::{DotAttributes}; use super::function::Function; use super::item_kind::ItemKind; use super::module::Module; @@ -15,6 +16,7 @@ use std::cell::{Cell, RefCell}; use std::collections::BTreeSet; use std::fmt::Write; use std::iter; +use std::io; /// A trait to get the canonical name from an item. /// @@ -372,20 +374,6 @@ impl Item { self.id } - /// Get this `Item`'s dot attributes. - pub fn dot_attributes(&self, ctx: &BindgenContext) -> String { - format!("[fontname=\"courier\", label=< \ - <table border=\"0\"> \ - <tr><td>ItemId({})</td></tr> \ - <tr><td>name</td><td>{}</td></tr> \ - <tr><td>kind</td><td>{}</td></tr> \ - </table> \ - >]", - self.id.as_usize(), - self.name(ctx).get(), - self.kind.kind_name()) - } - /// Get this `Item`'s parent's identifier. /// /// For the root module, the parent's ID is its own ID. @@ -928,6 +916,20 @@ impl Item { /// A set of items. pub type ItemSet = BTreeSet<ItemId>; +impl DotAttributes for Item { + fn dot_attributes<W>(&self, ctx: &BindgenContext, out: &mut W) -> io::Result<()> + where W: io::Write + { + writeln!(out, + "<tr><td>{:?}</td></tr> + <tr><td>name</td><td>{}</td></tr> + <tr><td>kind</td><td>{}</td></tr>", + self.id, + self.name(ctx).get(), + self.kind.kind_name()) + } +} + impl TemplateDeclaration for ItemId { fn template_params(&self, ctx: &BindgenContext) -> Option<Vec<ItemId>> { ctx.resolve_item_fallible(*self) diff --git a/src/ir/mod.rs b/src/ir/mod.rs index e624e46b..ba549c51 100644 --- a/src/ir/mod.rs +++ b/src/ir/mod.rs @@ -7,6 +7,7 @@ pub mod annotations; pub mod comp; pub mod context; pub mod derive; +pub mod dot; pub mod enum_ty; pub mod function; pub mod int; |