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
This commit is contained in:
Alex Crichton 2013-09-26 11:57:25 -07:00
parent c429c7c04b
commit ca697d3705
6 changed files with 88 additions and 33 deletions

View File

@ -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 {

View File

@ -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 : ~[],
}
}
}

View File

@ -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>
",

View File

@ -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) {

View File

@ -174,6 +174,9 @@ impl RustdocVisitor {
};
om.impls.push(i);
},
ast::item_foreign_mod(ref fm) => {
om.foreigns.push(fm.clone());
}
_ => (),
}
}

View File

@ -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)