From ab0eed34fd46bf7892a6668bfb137601d7d80c39 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 23 Jan 2012 19:23:02 -0800 Subject: [PATCH] rustdoc: Prune unexported items from the doc tree --- src/rustdoc/prune_unexported_pass.rs | 176 +++++++++++++++++++++++++++ src/rustdoc/rustdoc.rc | 1 + src/rustdoc/rustdoc.rs | 1 + 3 files changed, 178 insertions(+) create mode 100644 src/rustdoc/prune_unexported_pass.rs diff --git a/src/rustdoc/prune_unexported_pass.rs b/src/rustdoc/prune_unexported_pass.rs new file mode 100644 index 00000000000..16c6de59e49 --- /dev/null +++ b/src/rustdoc/prune_unexported_pass.rs @@ -0,0 +1,176 @@ +#[doc = "Prunes branches of the tree that are not exported"]; + +import rustc::syntax::ast; +import rustc::syntax::ast_util; +import rustc::middle::ast_map; + +export mk_pass; + +fn mk_pass() -> pass { + run +} + +fn run(srv: astsrv::srv, doc: doc::cratedoc) -> doc::cratedoc { + let fold = fold::fold({ + fold_mod: fold_mod + with *fold::default_seq_fold(srv) + }); + fold.fold_crate(fold, doc) +} + +fn fold_mod(fold: fold::fold, doc: doc::moddoc) -> doc::moddoc { + let doc = fold::default_seq_fold_mod(fold, doc); + ~{ + mods: doc::modlist(exported_mods(fold.ctxt, doc)), + fns: doc::fnlist(exported_fns(fold.ctxt, doc)) + with *doc + } +} + +fn exported_mods(srv: astsrv::srv, doc: doc::moddoc) -> [doc::moddoc] { + exported_things( + srv, doc, + exported_mods_from_crate, + exported_mods_from_mod + ) +} + +fn exported_fns(srv: astsrv::srv, doc: doc::moddoc) -> [doc::fndoc] { + exported_things( + srv, doc, + exported_fns_from_crate, + exported_fns_from_mod + ) +} + +fn exported_things( + srv: astsrv::srv, + doc: doc::moddoc, + from_crate: fn(astsrv::srv, doc::moddoc) -> [T], + from_mod: fn(astsrv::srv, doc::moddoc) -> [T] +) -> [T] { + if doc.id == ast::crate_node_id { + from_crate(srv, doc) + } else { + from_mod(srv, doc) + } +} + +fn exported_mods_from_crate( + srv: astsrv::srv, + doc: doc::moddoc +) -> [doc::moddoc] { + exported_mods_from(srv, doc, is_exported_from_crate) +} + +fn exported_mods_from_mod( + srv: astsrv::srv, + doc: doc::moddoc +) -> [doc::moddoc] { + exported_mods_from(srv, doc, bind is_exported_from_mod(_, doc.id, _)) +} + +fn exported_fns_from_crate( + srv: astsrv::srv, + doc: doc::moddoc +) -> [doc::fndoc] { + exported_fns_from(srv, doc, is_exported_from_crate) +} + +fn exported_fns_from_mod( + srv: astsrv::srv, + doc: doc::moddoc +) -> [doc::fndoc] { + exported_fns_from(srv, doc, bind is_exported_from_mod(_, doc.id, _)) +} + +fn exported_fns_from( + srv: astsrv::srv, + doc: doc::moddoc, + is_exported: fn(astsrv::srv, str) -> bool +) -> [doc::fndoc] { + vec::filter_map(*doc.fns) { |doc| + if is_exported(srv, doc.name) { + some(doc) + } else { + none + } + } +} + +fn exported_mods_from( + srv: astsrv::srv, + doc: doc::moddoc, + is_exported: fn(astsrv::srv, str) -> bool +) -> [doc::moddoc] { + vec::filter_map(*doc.mods) { |doc| + if is_exported(srv, doc.name) { + some(doc) + } else { + none + } + } +} + +fn is_exported_from_mod( + srv: astsrv::srv, + mod_id: doc::ast_id, + item_name: str +) -> bool { + astsrv::exec(srv) {|ctxt| + alt ctxt.map.get(mod_id) { + ast_map::node_item(item) { + alt item.node { + ast::item_mod(m) { + ast_util::is_exported(item_name, m) + } + } + } + } + } +} + +fn is_exported_from_crate( + srv: astsrv::srv, + item_name: str +) -> bool { + astsrv::exec(srv) {|ctxt| + ast_util::is_exported(item_name, ctxt.ast.node.module) + } +} + +#[test] +fn should_prune_unexported_fns() { + let source = "mod b { export a; fn a() { } fn b() { } }"; + let srv = astsrv::mk_srv_from_str(source); + let doc = extract::from_srv(srv, ""); + let doc = run(srv, doc); + assert vec::len(*doc.topmod.mods[0].fns) == 1u; +} + +#[test] +fn should_prune_unexported_modules() { + let source = "mod a { export a; mod a { } mod b { } }"; + let srv = astsrv::mk_srv_from_str(source); + let doc = extract::from_srv(srv, ""); + let doc = run(srv, doc); + assert vec::len(*doc.topmod.mods[0].mods) == 1u; +} + +#[test] +fn should_prune_unexported_fns_from_top_mod() { + let source = "export a; fn a() { } fn b() { }"; + let srv = astsrv::mk_srv_from_str(source); + let doc = extract::from_srv(srv, ""); + let doc = run(srv, doc); + assert vec::len(*doc.topmod.fns) == 1u; +} + +#[test] +fn should_prune_unexported_modules_from_top_mod() { + let source = "export a; mod a { } mod b { }"; + let srv = astsrv::mk_srv_from_str(source); + let doc = extract::from_srv(srv, ""); + let doc = run(srv, doc); + assert vec::len(*doc.topmod.mods) == 1u; +} diff --git a/src/rustdoc/rustdoc.rc b/src/rustdoc/rustdoc.rc index 61f2311a5b8..fe73191cd08 100644 --- a/src/rustdoc/rustdoc.rc +++ b/src/rustdoc/rustdoc.rc @@ -22,4 +22,5 @@ mod path_pass; mod attr_pass; mod tystr_pass; mod prune_undoc_pass; +mod prune_unexported_pass; mod astsrv; diff --git a/src/rustdoc/rustdoc.rs b/src/rustdoc/rustdoc.rs index a34149d4a5a..7d43b73eb98 100755 --- a/src/rustdoc/rustdoc.rs +++ b/src/rustdoc/rustdoc.rs @@ -92,6 +92,7 @@ fn run(source_file: str) { let srv = astsrv::mk_srv_from_file(source_file); let doc = extract::from_srv(srv, default_name); run_passes(srv, doc, [ + prune_unexported_pass::mk_pass(), tystr_pass::mk_pass(), path_pass::mk_pass(), attr_pass::mk_pass(),