about summary refs log tree commit diff
path: root/src/rustdoc
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-02-01 22:41:41 -0800
committerBrian Anderson <banderson@mozilla.com>2012-02-01 22:41:54 -0800
commit2b67de06c8f0436563284e01fe0e925f2ba225b4 (patch)
tree7b32ecef70c57d319d84813369254170dc2560f0 /src/rustdoc
parentae0d49aa06c1ed73320f32896710b6d015bea9c0 (diff)
downloadrust-2b67de06c8f0436563284e01fe0e925f2ba225b4.tar.gz
rust-2b67de06c8f0436563284e01fe0e925f2ba225b4.zip
rustdoc: Add support for type items
Diffstat (limited to 'src/rustdoc')
-rw-r--r--src/rustdoc/attr_parser.rs13
-rw-r--r--src/rustdoc/attr_pass.rs27
-rw-r--r--src/rustdoc/desc_pass.rs26
-rw-r--r--src/rustdoc/desc_to_brief_pass.rs21
-rw-r--r--src/rustdoc/doc.rs21
-rw-r--r--src/rustdoc/extract.rs24
-rw-r--r--src/rustdoc/fold.rs24
-rw-r--r--src/rustdoc/markdown_pass.rs37
-rw-r--r--src/rustdoc/prune_undoc_items_pass.rs29
-rw-r--r--src/rustdoc/prune_unexported_pass.rs6
-rw-r--r--src/rustdoc/tystr_pass.rs37
11 files changed, 253 insertions, 12 deletions
diff --git a/src/rustdoc/attr_parser.rs b/src/rustdoc/attr_parser.rs
index 818efe018fe..8e44960cf44 100644
--- a/src/rustdoc/attr_parser.rs
+++ b/src/rustdoc/attr_parser.rs
@@ -11,10 +11,10 @@ import core::tuple;
 
 export crate_attrs, mod_attrs, fn_attrs, arg_attrs,
        const_attrs, enum_attrs, variant_attrs, res_attrs,
-       iface_attrs, method_attrs, impl_attrs;
+       iface_attrs, method_attrs, impl_attrs, type_attrs;
 export parse_crate, parse_mod, parse_fn, parse_const,
        parse_enum, parse_variant, parse_res,
-       parse_iface, parse_method, parse_impl;
+       parse_iface, parse_method, parse_impl, parse_type;
 
 type crate_attrs = {
     name: option<str>
@@ -70,6 +70,11 @@ type impl_attrs = {
 
 type method_attrs = fn_attrs;
 
+type type_attrs = {
+    brief: option<str>,
+    desc: option<str>
+};
+
 #[cfg(test)]
 mod test {
 
@@ -507,4 +512,8 @@ fn parse_method(attrs: [ast::attribute]) -> method_attrs {
 
 fn parse_impl(attrs: [ast::attribute]) -> impl_attrs {
     parse_basic(attrs)
+}
+
+fn parse_type(attrs: [ast::attribute]) -> type_attrs {
+    parse_basic(attrs)
 }
\ No newline at end of file
diff --git a/src/rustdoc/attr_pass.rs b/src/rustdoc/attr_pass.rs
index 4e0c85c8ac3..3d12fdaaa67 100644
--- a/src/rustdoc/attr_pass.rs
+++ b/src/rustdoc/attr_pass.rs
@@ -27,7 +27,8 @@ fn run(
         fold_enum: fold_enum,
         fold_res: fold_res,
         fold_iface: fold_iface,
-        fold_impl: fold_impl
+        fold_impl: fold_impl,
+        fold_type: fold_type
         with *fold::default_seq_fold(srv)
     });
     fold.fold_crate(fold, doc)
@@ -449,6 +450,30 @@ fn should_extract_impl_method_docs() {
     assert doc.topmod.impls()[0].methods[0].failure == some("failure");
 }
 
+fn fold_type(
+    fold: fold::fold<astsrv::srv>,
+    doc: doc::tydoc
+) -> doc::tydoc {
+    let srv = fold.ctxt;
+    let doc = fold::default_seq_fold_type(fold, doc);
+    let attrs = parse_item_attrs(srv, doc.id, attr_parser::parse_type);
+
+    {
+        brief: attrs.brief,
+        desc: attrs.desc
+        with doc
+    }
+}
+
+#[test]
+fn should_extract_type_docs() {
+    let doc = test::mk_doc(
+        "#[doc(brief = \"brief\", desc = \"desc\")]\
+         type t = int;");
+    assert doc.topmod.types()[0].brief == some("brief");
+    assert doc.topmod.types()[0].desc == some("desc");
+}
+
 #[cfg(test)]
 mod test {
     fn mk_doc(source: str) -> doc::cratedoc {
diff --git a/src/rustdoc/desc_pass.rs b/src/rustdoc/desc_pass.rs
index 317c1f70a43..c7a204f53c5 100644
--- a/src/rustdoc/desc_pass.rs
+++ b/src/rustdoc/desc_pass.rs
@@ -22,7 +22,8 @@ fn run(
         fold_enum: fold_enum,
         fold_res: fold_res,
         fold_iface: fold_iface,
-        fold_impl: fold_impl
+        fold_impl: fold_impl,
+        fold_type: fold_type
         with *fold::default_seq_fold(op)
     });
     fold.fold_crate(fold, doc)
@@ -140,6 +141,14 @@ fn fold_impl(fold: fold::fold<op>, doc: doc::impldoc) -> doc::impldoc {
     }
 }
 
+fn fold_type(fold: fold::fold<op>, doc: doc::tydoc) -> doc::tydoc {
+    {
+        brief: maybe_apply_op(fold.ctxt, doc.brief),
+        desc: maybe_apply_op(fold.ctxt, doc.desc)
+        with doc
+    }
+}
+
 #[test]
 fn should_execute_op_on_enum_brief() {
     let doc = test::mk_doc("#[doc(brief = \" a \")] enum a { b }");
@@ -274,6 +283,21 @@ fn should_execute_op_on_impl_method_failure_condition() {
     assert doc.topmod.impls()[0].methods[0].failure == some("a");
 }
 
+
+#[test]
+fn should_execute_op_on_type_brief() {
+    let doc = test::mk_doc(
+        "#[doc(brief = \" a \")] type t = int;");
+    assert doc.topmod.types()[0].brief == some("a");
+}
+
+#[test]
+fn should_execute_op_on_type_desc() {
+    let doc = test::mk_doc(
+        "#[doc(desc = \" a \")] type t = int;");
+    assert doc.topmod.types()[0].desc == some("a");
+}
+
 #[cfg(test)]
 mod test {
     fn mk_doc(source: str) -> doc::cratedoc {
diff --git a/src/rustdoc/desc_to_brief_pass.rs b/src/rustdoc/desc_to_brief_pass.rs
index 315138db3d3..89b2b5d97bc 100644
--- a/src/rustdoc/desc_to_brief_pass.rs
+++ b/src/rustdoc/desc_to_brief_pass.rs
@@ -24,7 +24,8 @@ fn run(
         fold_enum: fold_enum,
         fold_res: fold_res,
         fold_iface: fold_iface,
-        fold_impl: fold_impl
+        fold_impl: fold_impl,
+        fold_type: fold_type
         with *fold::default_seq_fold(())
     });
     fold.fold_crate(fold, doc)
@@ -125,6 +126,17 @@ fn fold_impl(fold: fold::fold<()>, doc: doc::impldoc) -> doc::impldoc {
     }
 }
 
+fn fold_type(fold: fold::fold<()>, doc: doc::tydoc) -> doc::tydoc {
+    let doc = fold::default_seq_fold_type(fold, doc);
+    let (brief, desc) = modify(doc.brief, doc.desc);
+
+    {
+        brief: brief,
+        desc: desc
+        with doc
+    }
+}
+
 #[test]
 fn should_promote_mod_desc() {
     let doc = test::mk_doc("#[doc(desc = \"desc\")] mod m { }");
@@ -191,6 +203,13 @@ fn should_promote_impl_method_desc() {
     assert doc.topmod.impls()[0].methods[0].desc == none;
 }
 
+#[test]
+fn should_promote_type_desc() {
+    let doc = test::mk_doc("#[doc(desc = \"desc\")] type t = int;");
+    assert doc.topmod.types()[0].brief == some("desc");
+    assert doc.topmod.types()[0].desc == none;
+}
+
 #[cfg(test)]
 mod test {
     fn mk_doc(source: str) -> doc::cratedoc {
diff --git a/src/rustdoc/doc.rs b/src/rustdoc/doc.rs
index 9370ffb6c51..ed2aa2af1cc 100644
--- a/src/rustdoc/doc.rs
+++ b/src/rustdoc/doc.rs
@@ -13,7 +13,8 @@ enum itemtag {
     enumtag(enumdoc),
     restag(resdoc),
     ifacetag(ifacedoc),
-    impltag(impldoc)
+    impltag(impldoc),
+    tytag(tydoc)
 }
 
 type moddoc = {
@@ -107,6 +108,14 @@ type impldoc = {
     methods: [methoddoc]
 };
 
+type tydoc = {
+    id: ast_id,
+    name: str,
+    brief: option<str>,
+    desc: option<str>,
+    sig: option<str>
+};
+
 #[doc = "Some helper methods on moddoc, mostly for testing"]
 impl util for moddoc {
 
@@ -172,6 +181,15 @@ impl util for moddoc {
             }
         }
     }
+
+    fn types() -> [tydoc] {
+        vec::filter_map(*self.items) {|itemtag|
+            alt itemtag {
+              tytag(tydoc) { some(tydoc) }
+              _ { none }
+            }
+        }
+    }
 }
 
 #[doc = "Helper methods on itemtag"]
@@ -185,6 +203,7 @@ impl util for itemtag {
           doc::restag({name, _}) { name }
           doc::ifacetag({name, _}) { name }
           doc::impltag({name, _}) { name }
+          doc::tytag({name, _}) { name }
         }
     }
 }
diff --git a/src/rustdoc/extract.rs b/src/rustdoc/extract.rs
index a36536fd3e8..8e337e3d236 100644
--- a/src/rustdoc/extract.rs
+++ b/src/rustdoc/extract.rs
@@ -80,6 +80,11 @@ fn moddoc_from_mod(
                     impldoc_from_impl(methods, item.ident, item.id)
                 ))
               }
+              ast::item_ty(_, _) {
+                some(doc::tytag(
+                    tydoc_from_ty(item.ident, item.id)
+                ))
+              }
               _ {
                 none
               }
@@ -317,6 +322,25 @@ fn should_extract_impl_method_args() {
     assert doc.topmod.impls()[0].methods[0].args[0].name == "a";
 }
 
+fn tydoc_from_ty(
+    name: str,
+    id: ast::node_id
+) -> doc::tydoc {
+    {
+        id: id,
+        name: name,
+        brief: none,
+        desc: none,
+        sig: none
+    }
+}
+
+#[test]
+fn should_extract_tys() {
+    let doc = test::mk_doc("type a = int;");
+    assert doc.topmod.types()[0].name == "a";
+}
+
 #[cfg(test)]
 mod test {
 
diff --git a/src/rustdoc/fold.rs b/src/rustdoc/fold.rs
index ba5283bd6ff..667bb5d8580 100644
--- a/src/rustdoc/fold.rs
+++ b/src/rustdoc/fold.rs
@@ -12,6 +12,7 @@ export default_seq_fold_enum;
 export default_seq_fold_res;
 export default_seq_fold_iface;
 export default_seq_fold_impl;
+export default_seq_fold_type;
 
 enum fold<T> = t<T>;
 
@@ -23,6 +24,7 @@ type fold_enum<T> = fn~(fold: fold<T>, doc: doc::enumdoc) -> doc::enumdoc;
 type fold_res<T> = fn~(fold: fold<T>, doc: doc::resdoc) -> doc::resdoc;
 type fold_iface<T> = fn~(fold: fold<T>, doc: doc::ifacedoc) -> doc::ifacedoc;
 type fold_impl<T> = fn~(fold: fold<T>, doc: doc::impldoc) -> doc::impldoc;
+type fold_type<T> = fn~(fold: fold<T>, doc: doc::tydoc) -> doc::tydoc;
 
 type t<T> = {
     ctxt: T,
@@ -33,7 +35,8 @@ type t<T> = {
     fold_enum: fold_enum<T>,
     fold_res: fold_res<T>,
     fold_iface: fold_iface<T>,
-    fold_impl: fold_impl<T>
+    fold_impl: fold_impl<T>,
+    fold_type: fold_type<T>
 };
 
 
@@ -48,7 +51,8 @@ fn mk_fold<T:copy>(
     fold_enum: fold_enum<T>,
     fold_res: fold_res<T>,
     fold_iface: fold_iface<T>,
-    fold_impl: fold_impl<T>
+    fold_impl: fold_impl<T>,
+    fold_type: fold_type<T>
 ) -> fold<T> {
     fold({
         ctxt: ctxt,
@@ -59,7 +63,8 @@ fn mk_fold<T:copy>(
         fold_enum: fold_enum,
         fold_res: fold_res,
         fold_iface: fold_iface,
-        fold_impl: fold_impl
+        fold_impl: fold_impl,
+        fold_type: fold_type
     })
 }
 
@@ -73,7 +78,8 @@ fn default_seq_fold<T:copy>(ctxt: T) -> fold<T> {
         {|f, d| default_seq_fold_enum(f, d)},
         {|f, d| default_seq_fold_res(f, d)},
         {|f, d| default_seq_fold_iface(f, d)},
-        {|f, d| default_seq_fold_impl(f, d)}
+        {|f, d| default_seq_fold_impl(f, d)},
+        {|f, d| default_seq_fold_type(f, d)}
     )
 }
 
@@ -114,6 +120,9 @@ fn default_seq_fold_mod<T>(
               doc::impltag(impldoc) {
                 doc::impltag(fold.fold_impl(fold, impldoc))
               }
+              doc::tytag(tydoc) {
+                doc::tytag(fold.fold_type(fold, tydoc))
+              }
             }
         }
         with doc
@@ -162,6 +171,13 @@ fn default_seq_fold_impl<T>(
     doc
 }
 
+fn default_seq_fold_type<T>(
+    _fold: fold<T>,
+    doc: doc::tydoc
+) -> doc::tydoc {
+    doc
+}
+
 #[test]
 fn default_fold_should_produce_same_doc() {
     let source = "mod a { fn b() { } mod c { fn d() { } } }";
diff --git a/src/rustdoc/markdown_pass.rs b/src/rustdoc/markdown_pass.rs
index 4aab41e38cc..c15d6adc7ba 100644
--- a/src/rustdoc/markdown_pass.rs
+++ b/src/rustdoc/markdown_pass.rs
@@ -139,6 +139,7 @@ fn write_mod_contents(
           doc::restag(resdoc) { write_res(ctxt, resdoc) }
           doc::ifacetag(ifacedoc) { write_iface(ctxt, ifacedoc) }
           doc::impltag(impldoc) { write_impl(ctxt, impldoc) }
+          doc::tytag(tydoc) { write_type(ctxt, tydoc) }
         }
     }
 }
@@ -743,6 +744,42 @@ fn should_write_impl_method_failure_conditions() {
     assert str::contains(markdown, "Failure conditions: nuked");
 }
 
+fn write_type(
+    ctxt: ctxt,
+    doc: doc::tydoc
+) {
+    write_header(ctxt, h2, #fmt("Type `%s`", doc.name));
+    write_sig(ctxt, doc.sig);
+    write_brief(ctxt, doc.brief);
+    write_desc(ctxt, doc.desc);
+}
+
+#[test]
+fn should_write_type_header() {
+    let markdown = test::render("type t = int;");
+    assert str::contains(markdown, "## Type `t`");
+}
+
+#[test]
+fn should_write_type_brief() {
+    let markdown = test::render(
+        "#[doc(brief = \"brief\")] type t = int;");
+    assert str::contains(markdown, "\n\nbrief\n\n");
+}
+
+#[test]
+fn should_write_type_desc() {
+    let markdown = test::render(
+        "#[doc(desc = \"desc\")] type t = int;");
+    assert str::contains(markdown, "\n\ndesc\n\n");
+}
+
+#[test]
+fn should_write_type_signature() {
+    let markdown = test::render("type t = int;");
+    assert str::contains(markdown, "\n\n    type t = int\n\n");
+}
+
 #[cfg(test)]
 mod test {
     fn render(source: str) -> str {
diff --git a/src/rustdoc/prune_undoc_items_pass.rs b/src/rustdoc/prune_undoc_items_pass.rs
index 3fa3298bdc5..3ff29bd0e89 100644
--- a/src/rustdoc/prune_undoc_items_pass.rs
+++ b/src/rustdoc/prune_undoc_items_pass.rs
@@ -24,7 +24,8 @@ fn run(
         fold_enum: fold_enum,
         fold_res: fold_res,
         fold_iface: fold_iface,
-        fold_impl: fold_impl
+        fold_impl: fold_impl,
+        fold_type: fold_type
         with *fold::default_seq_fold(ctxt)
     });
     fold.fold_crate(fold, doc)
@@ -93,6 +94,14 @@ fn fold_mod(
                     none
                 }
               }
+              doc::tytag(tydoc) {
+                let doc = fold.fold_type(fold, tydoc);
+                if fold.ctxt.have_docs {
+                    some(doc::tytag(doc))
+                } else {
+                    none
+                }
+              }
               _ { some(itemtag) }
             }
         }
@@ -335,6 +344,24 @@ fn should_not_elide_undocumented_impl_methods() {
     assert vec::is_not_empty(doc.topmod.impls()[0].methods);
 }
 
+fn fold_type(
+    fold: fold::fold<ctxt>,
+    doc: doc::tydoc
+) -> doc::tydoc {
+    let doc = fold::default_seq_fold_type(fold, doc);
+
+    fold.ctxt.have_docs =
+        doc.brief != none
+        || doc.desc != none;
+    ret doc;
+}
+
+#[test]
+fn should_elide_undocumented_types() {
+    let doc = test::mk_doc("type t = int;");
+    assert vec::is_empty(doc.topmod.types());
+}
+
 #[cfg(test)]
 mod test {
     fn mk_doc(source: str) -> doc::cratedoc {
diff --git a/src/rustdoc/prune_unexported_pass.rs b/src/rustdoc/prune_unexported_pass.rs
index 94e7332e2cc..110b6952e96 100644
--- a/src/rustdoc/prune_unexported_pass.rs
+++ b/src/rustdoc/prune_unexported_pass.rs
@@ -220,6 +220,12 @@ fn should_prune_unexported_impls_from_top_mod() {
     assert vec::is_empty(doc.topmod.impls())
 }
 
+#[test]
+fn should_prune_unexported_types() {
+    let doc = test::mk_doc("export a; mod a { } type b = int;");
+    assert vec::is_empty(doc.topmod.types());
+}
+
 #[cfg(test)]
 mod test {
     fn mk_doc(source: str) -> doc::cratedoc {
diff --git a/src/rustdoc/tystr_pass.rs b/src/rustdoc/tystr_pass.rs
index 604e411dde0..a80905538b2 100644
--- a/src/rustdoc/tystr_pass.rs
+++ b/src/rustdoc/tystr_pass.rs
@@ -21,7 +21,8 @@ fn run(
         fold_enum: fold_enum,
         fold_res: fold_res,
         fold_iface: fold_iface,
-        fold_impl: fold_impl
+        fold_impl: fold_impl,
+        fold_type: fold_type
         with *fold::default_seq_fold(srv)
     });
     fold.fold_crate(fold, doc)
@@ -537,6 +538,40 @@ fn should_add_impl_method_arg_types() {
     assert fn_.args[1].ty == some("bool");
 }
 
+fn fold_type(
+    fold: fold::fold<astsrv::srv>,
+    doc: doc::tydoc
+) -> doc::tydoc {
+
+    let srv = fold.ctxt;
+
+    {
+        sig: astsrv::exec(srv) {|ctxt|
+            alt ctxt.ast_map.get(doc.id) {
+              ast_map::node_item(@{
+                ident: ident,
+                node: ast::item_ty(ty, params), _
+              }) {
+                some(#fmt(
+                    "type %s%s = %s",
+                    ident,
+                    pprust::typarams_to_str(params),
+                    pprust::ty_to_str(ty)
+                ))
+              }
+              _ { fail "expected type" }
+            }
+        }
+        with doc
+    }
+}
+
+#[test]
+fn should_add_type_signatures() {
+    let doc = test::mk_doc("type t<T> = int;");
+    assert doc.topmod.types()[0].sig == some("type t<T> = int");
+}
+
 #[cfg(test)]
 mod test {
     fn mk_doc(source: str) -> doc::cratedoc {