about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-01-29 14:51:09 -0800
committerBrian Anderson <banderson@mozilla.com>2012-01-29 14:51:09 -0800
commit361f90e618c081afe2fa8b0a67370610781e413e (patch)
tree5e8115b759ee0a35f14a11f606c852385decd9e6
parent07ac2e1043c3a4e9ba0058f0b67798821d0118ee (diff)
downloadrust-361f90e618c081afe2fa8b0a67370610781e413e.tar.gz
rust-361f90e618c081afe2fa8b0a67370610781e413e.zip
rustdoc: Sort the items so modules are printed last
-rw-r--r--src/rustdoc/markdown_pass.rs88
-rwxr-xr-xsrc/rustdoc/rustdoc.rs2
2 files changed, 81 insertions, 9 deletions
diff --git a/src/rustdoc/markdown_pass.rs b/src/rustdoc/markdown_pass.rs
index 8c53ad75a1b..a67e43525a4 100644
--- a/src/rustdoc/markdown_pass.rs
+++ b/src/rustdoc/markdown_pass.rs
@@ -5,16 +5,65 @@ import std::io::writer_util;
 
 export mk_pass;
 
+// FIXME: This is a really convoluted interface to work around trying
+// to get a writer into a unique closure and then being able to test
+// what was written afterward
 fn mk_pass(
-    writer: fn~() -> io::writer
+    give_writer: fn~(fn(io::writer))
 ) -> pass {
-    ret fn~(
-        _srv: astsrv::srv,
+    fn~(
+        srv: astsrv::srv,
         doc: doc::cratedoc
     ) -> doc::cratedoc {
-        write_markdown(doc, writer());
+
+        fn mods_last(item1: doc::itemtag, item2: doc::itemtag) -> bool {
+            fn is_mod(item: doc::itemtag) -> bool {
+                alt item {
+                  doc::modtag(_) { true }
+                  _ { false }
+                }
+            }
+
+            let lteq = !is_mod(item1) || is_mod(item2);
+            lteq
+        }
+
+        give_writer {|writer|
+            // Sort the items so mods come last. All mods will be
+            // output at the same header level so sorting mods last
+            // makes the headers come out nested correctly.
+            let sorted_doc = sort_pass::mk_pass(mods_last)(srv, doc);
+
+            write_markdown(sorted_doc, writer);
+        }
         doc
-    };
+    }
+}
+
+#[test]
+fn should_write_modules_last() {
+    /*
+    Because the markdown pass writes all modules at the same level of
+    indentation (it doesn't 'nest' them), we need to make sure that we
+    write all of the modules contained in each module after all other
+    types of items, or else the header nesting will end up wrong, with
+    modules appearing to contain items that they do not.
+    */
+    let markdown = test::render(
+        "mod a { }\
+         fn b() { }\
+         mod c { }\
+         fn d() { }"
+    );
+
+    let idx_a = str::find(markdown, "# Module `a`");
+    let idx_b = str::find(markdown, "## Function `b`");
+    let idx_c = str::find(markdown, "# Module `c`");
+    let idx_d = str::find(markdown, "## Function `d`");
+
+    assert idx_b < idx_d;
+    assert idx_d < idx_a;
+    assert idx_a < idx_c;
 }
 
 type ctxt = {
@@ -487,13 +536,13 @@ fn should_write_resource_args() {
 #[cfg(test)]
 mod test {
     fn render(source: str) -> str {
-        let doc = create_doc(source);
-        let markdown = write_markdown_str(doc);
+        let (srv, doc) = create_doc_srv(source);
+        let markdown = write_markdown_str_srv(srv, doc);
         #debug("markdown: %s", markdown);
         markdown
     }
 
-    fn create_doc(source: str) -> doc::cratedoc {
+    fn create_doc_srv(source: str) -> (astsrv::srv, doc::cratedoc) {
         let srv = astsrv::mk_srv_from_str(source);
         let doc = extract::from_srv(srv, "");
         #debug("doc (extract): %?", doc);
@@ -503,6 +552,11 @@ mod test {
         #debug("doc (path): %?", doc);
         let doc = attr_pass::mk_pass()(srv, doc);
         #debug("doc (attr): %?", doc);
+        (srv, doc)
+    }
+
+    fn create_doc(source: str) -> doc::cratedoc {
+        let (_, doc) = create_doc_srv(source);
         doc
     }
 
@@ -515,6 +569,24 @@ mod test {
         ret io::mem_buffer_str(buffer);
     }
 
+    fn write_markdown_str_srv(
+        srv: astsrv::srv,
+        doc: doc::cratedoc
+    ) -> str {
+        let port = comm::port();
+        let chan = comm::chan(port);
+
+        let pass = mk_pass {|f|
+            let buffer = io::mk_mem_buffer();
+            let writer = io::mem_buffer_writer(buffer);
+            f(writer);
+            let result = io::mem_buffer_str(buffer);
+            comm::send(chan, result);
+        };
+        pass(srv, doc);
+        ret comm::recv(port);
+    }
+
     #[test]
     fn write_markdown_should_write_crate_header() {
         let srv = astsrv::mk_srv_from_str("");
diff --git a/src/rustdoc/rustdoc.rs b/src/rustdoc/rustdoc.rs
index 6374860573d..a27cd674863 100755
--- a/src/rustdoc/rustdoc.rs
+++ b/src/rustdoc/rustdoc.rs
@@ -105,6 +105,6 @@ fn run(source_file: str) {
         desc_to_brief_pass::mk_pass(),
         trim_pass::mk_pass(),
         unindent_pass::mk_pass(),
-        markdown_pass::mk_pass {|| std::io:: stdout()}
+        markdown_pass::mk_pass {|f| f(std::io:: stdout()) }
     ]);
 }
\ No newline at end of file