summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/codegen/mod.rs3
-rw-r--r--src/ir/context.rs31
-rw-r--r--src/ir/dot.rs53
-rw-r--r--src/ir/item.rs30
-rw-r--r--src/ir/mod.rs1
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;