about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-01-23 19:23:02 -0800
committerBrian Anderson <banderson@mozilla.com>2012-01-23 22:13:34 -0800
commitab0eed34fd46bf7892a6668bfb137601d7d80c39 (patch)
treefdc6bf0d28617060660f9ca9ec46f8bd20e1ed11
parent6766d0ead08ea261c081da7ee7854f1d21541d8c (diff)
downloadrust-ab0eed34fd46bf7892a6668bfb137601d7d80c39.tar.gz
rust-ab0eed34fd46bf7892a6668bfb137601d7d80c39.zip
rustdoc: Prune unexported items from the doc tree
-rw-r--r--src/rustdoc/prune_unexported_pass.rs176
-rw-r--r--src/rustdoc/rustdoc.rc1
-rwxr-xr-xsrc/rustdoc/rustdoc.rs1
3 files changed, 178 insertions, 0 deletions
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<astsrv::srv>, 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<T>(
+    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(),