From c429c7c04b9c19c2ca5992b5f4e094e83832dcb8 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 26 Sep 2013 11:09:47 -0700 Subject: rustdoc: Fix broken struct field search links Takes the same approach as variants, writes a redirect index page back to the struct with an anchor to the field in question. Closes #9524 --- src/librustdoc/html/render.rs | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 4f8c11d8285..e019599835c 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -521,6 +521,14 @@ impl Context { } } } + clean::StructItem(s) => { + let mut it = s.fields.move_iter(); + do self.recurse(name) |this| { + for item in it { + f(this, item); + } + } + } _ => {} } } @@ -590,6 +598,8 @@ impl<'self> fmt::Default for Item<'self> { clean::EnumItem(ref e) => item_enum(fmt.buf, it.item, e), clean::TypedefItem(ref t) => item_typedef(fmt.buf, it.item, t), clean::VariantItem(*) => item_variant(fmt.buf, it.cx, it.item), + clean::StructFieldItem(*) => item_struct_field(fmt.buf, it.cx, + it.item), _ => {} } } @@ -980,11 +990,12 @@ fn render_struct(w: &mut io::Writer, it: &clean::Item, for field in fields.iter() { match field.inner { clean::StructFieldItem(ref ty) => { - write!(w, " {}{}: {},\n{}", + write!(w, " {}{name}: \ + {},\n{}", VisSpace(field.visibility), - field.name.get_ref().as_slice(), ty.type_, - tab); + tab, + name = field.name.get_ref().as_slice()); } _ => unreachable!() } @@ -1170,3 +1181,12 @@ fn item_variant(w: &mut io::Writer, cx: &Context, it: &clean::Item) { *cx.current.last(), it.name.get_ref().as_slice()); } + +fn item_struct_field(w: &mut io::Writer, cx: &Context, it: &clean::Item) { + write!(w, "\ + \ + ", + *cx.current.last(), + it.name.get_ref().as_slice()); +} -- cgit 1.4.1-3-g733a5 From ca697d370594aaed020fb252a216b632abc56d33 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 26 Sep 2013 11:57:25 -0700 Subject: 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 --- src/librustdoc/clean.rs | 38 ++++++++++++++++++++++++ src/librustdoc/doctree.rs | 2 ++ src/librustdoc/html/render.rs | 69 +++++++++++++++++++++++++------------------ src/librustdoc/passes.rs | 3 +- src/librustdoc/visit_ast.rs | 3 ++ src/libsyntax/parse/parser.rs | 6 ++-- 6 files changed, 88 insertions(+), 33 deletions(-) (limited to 'src') 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 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 for ast::path_list_ident { } } +impl Clean<~[Item]> for ast::foreign_mod { + fn clean(&self) -> ~[Item] { + self.items.clean() + } +} + +impl Clean 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, "

{}

\n", 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, " = "); let tag = if s.contains("\n") { "pre" } else { "code" }; write!(f.buf, "<{tag}>{}", s.as_slice(), tag=tag); @@ -729,7 +740,7 @@ fn item_module(w: &mut io::Writer, cx: &Context, write!(w, " - + ", 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) -- cgit 1.4.1-3-g733a5 From 6a277dc4ba7f29e5a429e763f6faba3041b90c94 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 26 Sep 2013 12:27:38 -0700 Subject: rustdoc: Strip implementations of private traits Closes #5416 --- src/librustdoc/passes.rs | 50 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs index b962694fe68..bf35c93caae 100644 --- a/src/librustdoc/passes.rs +++ b/src/librustdoc/passes.rs @@ -10,6 +10,7 @@ use std::num; use std::uint; +use std::hashmap::HashSet; use syntax::ast; @@ -50,9 +51,10 @@ pub fn strip_hidden(crate: clean::Crate) -> plugins::PluginResult { /// Strip private items from the point of view of a crate or externally from a /// crate, specified by the `xcrate` flag. -pub fn strip_private(crate: clean::Crate) -> plugins::PluginResult { - struct Stripper; - impl fold::DocFolder for Stripper { +pub fn strip_private(mut crate: clean::Crate) -> plugins::PluginResult { + // This stripper collects all *retained* nodes. + struct Stripper<'self>(&'self mut HashSet); + impl<'self> fold::DocFolder for Stripper<'self> { fn fold_item(&mut self, i: Item) -> Option { match i.inner { // These items can all get re-exported @@ -98,6 +100,7 @@ pub fn strip_private(crate: clean::Crate) -> plugins::PluginResult { }; let i = if fastreturn { + self.insert(i.id); return Some(i); } else { self.fold_item_recur(i) @@ -109,15 +112,50 @@ pub fn strip_private(crate: clean::Crate) -> plugins::PluginResult { // emptied modules/impls have no need to exist clean::ModuleItem(ref m) if m.items.len() == 0 => None, clean::ImplItem(ref i) if i.methods.len() == 0 => None, - _ => Some(i), + _ => { + self.insert(i.id); + Some(i) + } } } None => None, } } } - let mut stripper = Stripper; - let crate = stripper.fold_crate(crate); + + // This stripper discards all private impls of traits + struct ImplStripper<'self>(&'self HashSet); + impl<'self> fold::DocFolder for ImplStripper<'self> { + fn fold_item(&mut self, i: Item) -> Option { + match i.inner { + clean::ImplItem(ref imp) => { + match imp.trait_ { + Some(clean::ResolvedPath{ id, _ }) => { + if !self.contains(&id) { + return None; + } + } + Some(*) | None => {} + } + } + _ => {} + } + self.fold_item_recur(i) + } + } + + let mut retained = HashSet::new(); + // First, strip all private items + { + let mut stripper = Stripper(&mut retained); + crate = stripper.fold_crate(crate); + } + + // Next, strip all private implementations of traits + { + let mut stripper = ImplStripper(&retained); + crate = stripper.fold_crate(crate); + } (crate, None) } -- cgit 1.4.1-3-g733a5 From 42bcf638b0213747e01af87353413755b9ebc270 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 26 Sep 2013 12:53:06 -0700 Subject: rustdoc: Render stability attributes Closes #8965 --- src/librustdoc/clean.rs | 20 ++++++++++++++++++++ src/librustdoc/html/render.rs | 13 +++++++++++++ src/librustdoc/html/static/main.css | 15 +++++++++++++++ src/libsyntax/attr.rs | 2 +- 4 files changed, 49 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs index bfd71345c15..623ac82486d 100644 --- a/src/librustdoc/clean.rs +++ b/src/librustdoc/clean.rs @@ -16,6 +16,7 @@ use its = syntax::parse::token::ident_to_str; use syntax; use syntax::ast; use syntax::ast_util; +use syntax::attr; use syntax::attr::AttributeMethods; use std; @@ -206,6 +207,25 @@ impl Clean for ast::Attribute { } } +// This is a rough approximation that gets us what we want. +impl<'self> attr::AttrMetaMethods for &'self Attribute { + fn name(&self) -> @str { + match **self { + Word(ref n) | List(ref n, _) | NameValue(ref n, _) => + n.to_managed() + } + } + + fn value_str(&self) -> Option<@str> { + match **self { + NameValue(_, ref v) => Some(v.to_managed()), + _ => None, + } + } + fn meta_item_list<'a>(&'a self) -> Option<&'a [@ast::MetaItem]> { None } + fn name_str_pair(&self) -> Option<(@str, @str)> { None } +} + #[deriving(Clone, Encodable, Decodable)] pub struct TyParam { name: ~str, diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 70f433ff2a3..3320842c046 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -28,6 +28,7 @@ use extra::json::ToJson; use extra::sort; use syntax::ast; +use syntax::attr; use clean; use doctree; @@ -568,6 +569,18 @@ impl<'self> Item<'self> { impl<'self> fmt::Default for Item<'self> { fn fmt(it: &Item<'self>, fmt: &mut fmt::Formatter) { + match attr::find_stability(it.item.attrs.iter()) { + Some(stability) => { + write!(fmt.buf, + "{lvl}", + lvl = stability.level.to_str(), + reason = match stability.text { + Some(s) => s, None => @"", + }); + } + None => {} + } + // Write the breadcrumb trail header for the top write!(fmt.buf, "

"); match it.item.inner { diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css index 97f59798240..11ca7a09311 100644 --- a/src/librustdoc/html/static/main.css +++ b/src/librustdoc/html/static/main.css @@ -269,3 +269,18 @@ a { float: left; padding: 20px; } + +.stability { + border-left: 5px solid #000; + border-radius: 3px; + padding: 0 3px; + float: right; + background: #fff; + text-transform: lowercase; +} +.stability.Deprecated { border-color: #D60027; color: #880017; } +.stability.Experimental { border-color: #EC5315; color: #a53c0e; } +.stability.Unstable { border-color: #FFD700; color: #b39800; } +.stability.Stable { border-color: #AEC516; color: #7c8b10; } +.stability.Frozen { border-color: #009431; color: #007726; } +.stability.Locked { border-color: #0084B6; color: #00668c; } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 295485d6f6e..47a7d0fbf9e 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -320,7 +320,7 @@ pub struct Stability { } /// The available stability levels. -#[deriving(Eq,Ord,Clone)] +#[deriving(Eq,Ord,Clone,ToStr)] pub enum StabilityLevel { Deprecated, Experimental, -- cgit 1.4.1-3-g733a5

{}static {}: {} = {}{}static {}: {}{} {}