about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-09-26 11:57:25 -0700
committerAlex Crichton <alex@alexcrichton.com>2013-09-26 11:57:25 -0700
commitca697d370594aaed020fb252a216b632abc56d33 (patch)
tree380a49a5b2a8bb629f7c2ddd7ef268bd72f54a2a
parentc429c7c04b9c19c2ca5992b5f4e094e83832dcb8 (diff)
downloadrust-ca697d370594aaed020fb252a216b632abc56d33.tar.gz
rust-ca697d370594aaed020fb252a216b632abc56d33.zip
rustdoc: Generate documentation for foreign items
This slurps up everything inside of an 'extern' block into the enclosing module
in order to document them. The documentation must be on the items themselves,
and they'll show up next to everything else on the module index pages.

Closes #5953
-rw-r--r--src/librustdoc/clean.rs38
-rw-r--r--src/librustdoc/doctree.rs2
-rw-r--r--src/librustdoc/html/render.rs69
-rw-r--r--src/librustdoc/passes.rs3
-rw-r--r--src/librustdoc/visit_ast.rs3
-rw-r--r--src/libsyntax/parse/parser.rs6
6 files changed, 88 insertions, 33 deletions
diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs
index ae7cbf76bcc..bfd71345c15 100644
--- a/src/librustdoc/clean.rs
+++ b/src/librustdoc/clean.rs
@@ -149,6 +149,8 @@ pub enum ItemEnum {
     MethodItem(Method),
     StructFieldItem(StructField),
     VariantItem(Variant),
+    ForeignFunctionItem(Function),
+    ForeignStaticItem(Static),
 }
 
 #[deriving(Clone, Encodable, Decodable)]
@@ -172,6 +174,7 @@ impl Clean<Item> for doctree::Module {
             inner: ModuleItem(Module {
                items: std::vec::concat(&[self.structs.clean(),
                               self.enums.clean(), self.fns.clean(),
+                              std::vec::concat(self.foreigns.clean()),
                               self.mods.clean(), self.typedefs.clean(),
                               self.statics.clean(), self.traits.clean(),
                               self.impls.clean(), self.view_items.clean()])
@@ -968,6 +971,41 @@ impl Clean<ViewListIdent> for ast::path_list_ident {
     }
 }
 
+impl Clean<~[Item]> for ast::foreign_mod {
+    fn clean(&self) -> ~[Item] {
+        self.items.clean()
+    }
+}
+
+impl Clean<Item> for ast::foreign_item {
+    fn clean(&self) -> Item {
+        let inner = match self.node {
+            ast::foreign_item_fn(ref decl, ref generics) => {
+                ForeignFunctionItem(Function {
+                    decl: decl.clean(),
+                    generics: generics.clean(),
+                    purity: ast::extern_fn,
+                })
+            }
+            ast::foreign_item_static(ref ty, mutbl) => {
+                ForeignStaticItem(Static {
+                    type_: ty.clean(),
+                    mutability: if mutbl {Mutable} else {Immutable},
+                    expr: ~"",
+                })
+            }
+        };
+        Item {
+            name: Some(self.ident.clean()),
+            attrs: self.attrs.clean(),
+            source: self.span.clean(),
+            id: self.id,
+            visibility: self.vis.clean(),
+            inner: inner,
+        }
+    }
+}
+
 // Utilities
 
 trait ToSource {
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index a4e3f795498..835781907f3 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -30,6 +30,7 @@ pub struct Module {
     traits: ~[Trait],
     vis: ast::visibility,
     impls: ~[Impl],
+    foreigns: ~[ast::foreign_mod],
     view_items: ~[ast::view_item],
 }
 
@@ -50,6 +51,7 @@ impl Module {
             traits     : ~[],
             impls      : ~[],
             view_items : ~[],
+            foreigns   : ~[],
         }
     }
 }
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index e019599835c..70f433ff2a3 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -540,19 +540,21 @@ impl Context {
 
 fn shortty(item: &clean::Item) -> &'static str {
     match item.inner {
-        clean::ModuleItem(*)      => "mod",
-        clean::StructItem(*)      => "struct",
-        clean::EnumItem(*)        => "enum",
-        clean::FunctionItem(*)    => "fn",
-        clean::TypedefItem(*)     => "typedef",
-        clean::StaticItem(*)      => "static",
-        clean::TraitItem(*)       => "trait",
-        clean::ImplItem(*)        => "impl",
-        clean::ViewItemItem(*)    => "viewitem",
-        clean::TyMethodItem(*)    => "tymethod",
-        clean::MethodItem(*)      => "method",
-        clean::StructFieldItem(*) => "structfield",
-        clean::VariantItem(*)     => "variant",
+        clean::ModuleItem(*)          => "mod",
+        clean::StructItem(*)          => "struct",
+        clean::EnumItem(*)            => "enum",
+        clean::FunctionItem(*)        => "fn",
+        clean::TypedefItem(*)         => "typedef",
+        clean::StaticItem(*)          => "static",
+        clean::TraitItem(*)           => "trait",
+        clean::ImplItem(*)            => "impl",
+        clean::ViewItemItem(*)        => "viewitem",
+        clean::TyMethodItem(*)        => "tymethod",
+        clean::MethodItem(*)          => "method",
+        clean::StructFieldItem(*)     => "structfield",
+        clean::VariantItem(*)         => "variant",
+        clean::ForeignFunctionItem(*) => "ffi",
+        clean::ForeignStaticItem(*)   => "ffs",
     }
 }
 
@@ -592,7 +594,8 @@ impl<'self> fmt::Default for Item<'self> {
         match it.item.inner {
             clean::ModuleItem(ref m) => item_module(fmt.buf, it.cx,
                                                     it.item, m.items),
-            clean::FunctionItem(ref f) => item_function(fmt.buf, it.item, f),
+            clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f) =>
+                item_function(fmt.buf, it.item, f),
             clean::TraitItem(ref t) => item_trait(fmt.buf, it.item, t),
             clean::StructItem(ref s) => item_struct(fmt.buf, it.item, s),
             clean::EnumItem(ref e) => item_enum(fmt.buf, it.item, e),
@@ -673,6 +676,10 @@ fn item_module(w: &mut io::Writer, cx: &Context,
             (_, &clean::EnumItem(*)) => false,
             (&clean::StaticItem(*), _) => true,
             (_, &clean::StaticItem(*)) => false,
+            (&clean::ForeignFunctionItem(*), _) => true,
+            (_, &clean::ForeignFunctionItem(*)) => false,
+            (&clean::ForeignStaticItem(*), _) => true,
+            (_, &clean::ForeignStaticItem(*)) => false,
             (&clean::TraitItem(*), _) => true,
             (_, &clean::TraitItem(*)) => false,
             (&clean::FunctionItem(*), _) => true,
@@ -700,27 +707,31 @@ fn item_module(w: &mut io::Writer, cx: &Context,
             }
             curty = myty;
             write!(w, "<h2>{}</h2>\n<table>", match myitem.inner {
-                clean::ModuleItem(*)      => "Modules",
-                clean::StructItem(*)      => "Structs",
-                clean::EnumItem(*)        => "Enums",
-                clean::FunctionItem(*)    => "Functions",
-                clean::TypedefItem(*)     => "Type Definitions",
-                clean::StaticItem(*)      => "Statics",
-                clean::TraitItem(*)       => "Traits",
-                clean::ImplItem(*)        => "Implementations",
-                clean::ViewItemItem(*)    => "Reexports",
-                clean::TyMethodItem(*)    => "Type Methods",
-                clean::MethodItem(*)      => "Methods",
-                clean::StructFieldItem(*) => "Struct Fields",
-                clean::VariantItem(*)     => "Variants",
+                clean::ModuleItem(*)          => "Modules",
+                clean::StructItem(*)          => "Structs",
+                clean::EnumItem(*)            => "Enums",
+                clean::FunctionItem(*)        => "Functions",
+                clean::TypedefItem(*)         => "Type Definitions",
+                clean::StaticItem(*)          => "Statics",
+                clean::TraitItem(*)           => "Traits",
+                clean::ImplItem(*)            => "Implementations",
+                clean::ViewItemItem(*)        => "Reexports",
+                clean::TyMethodItem(*)        => "Type Methods",
+                clean::MethodItem(*)          => "Methods",
+                clean::StructFieldItem(*)     => "Struct Fields",
+                clean::VariantItem(*)         => "Variants",
+                clean::ForeignFunctionItem(*) => "Foreign Functions",
+                clean::ForeignStaticItem(*)   => "Foreign Statics",
             });
         }
 
         match myitem.inner {
-            clean::StaticItem(ref s) => {
+            clean::StaticItem(ref s) | clean::ForeignStaticItem(ref s) => {
                 struct Initializer<'self>(&'self str);
                 impl<'self> fmt::Default for Initializer<'self> {
                     fn fmt(s: &Initializer<'self>, f: &mut fmt::Formatter) {
+                        if s.len() == 0 { return; }
+                        write!(f.buf, "<code> = </code>");
                         let tag = if s.contains("\n") { "pre" } else { "code" };
                         write!(f.buf, "<{tag}>{}</{tag}>",
                                s.as_slice(), tag=tag);
@@ -729,7 +740,7 @@ fn item_module(w: &mut io::Writer, cx: &Context,
 
                 write!(w, "
                     <tr>
-                        <td><code>{}static {}: {} = </code>{}</td>
+                        <td><code>{}static {}: {}</code>{}</td>
                         <td class='docblock'>{}&nbsp;</td>
                     </tr>
                 ",
diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs
index 91e2b3bfcf1..b962694fe68 100644
--- a/src/librustdoc/passes.rs
+++ b/src/librustdoc/passes.rs
@@ -59,7 +59,8 @@ pub fn strip_private(crate: clean::Crate) -> plugins::PluginResult {
                 clean::TypedefItem(*) | clean::StaticItem(*) |
                 clean::StructItem(*) | clean::EnumItem(*) |
                 clean::TraitItem(*) | clean::FunctionItem(*) |
-                clean::ViewItemItem(*) | clean::MethodItem(*) => {
+                clean::ViewItemItem(*) | clean::MethodItem(*) |
+                clean::ForeignFunctionItem(*) | clean::ForeignStaticItem(*) => {
                     // XXX: re-exported items should get surfaced in the docs as
                     //      well (using the output of resolve analysis)
                     if i.visibility != Some(ast::public) {
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index c4b9b9efe56..8e89c07ef00 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -174,6 +174,9 @@ impl RustdocVisitor {
                     };
                     om.impls.push(i);
                 },
+                ast::item_foreign_mod(ref fm) => {
+                    om.foreigns.push(fm.clone());
+                }
                 _ => (),
             }
         }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 74447b5dae1..7bea1f098c3 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -4204,9 +4204,9 @@ impl Parser {
     }
 
     // parse a function declaration from a foreign module
-    fn parse_item_foreign_fn(&self,  attrs: ~[Attribute]) -> @foreign_item {
+    fn parse_item_foreign_fn(&self, vis: ast::visibility,
+                             attrs: ~[Attribute]) -> @foreign_item {
         let lo = self.span.lo;
-        let vis = self.parse_visibility();
 
         // Parse obsolete purity.
         let purity = self.parse_fn_purity();
@@ -4740,7 +4740,7 @@ impl Parser {
         if (self.is_keyword(keywords::Fn) || self.is_keyword(keywords::Pure) ||
                 self.is_keyword(keywords::Unsafe)) {
             // FOREIGN FUNCTION ITEM
-            let item = self.parse_item_foreign_fn(attrs);
+            let item = self.parse_item_foreign_fn(visibility, attrs);
             return iovi_foreign_item(item);
         }
         self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)