diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index fe80d26d10933..617b985cb5f92 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -85,7 +85,7 @@ pub struct Context { /// header. This map will change depending on the surrounding context of the /// page. pub sidebar: HashMap<~str, Vec<~str> >, - /// This flag indicates whether [src] links should be generated or not. If + /// This flag indicates whether source links should be generated or not. If /// the source files are present in the html rendering, then this will be /// `true`. pub include_sources: bool, @@ -974,39 +974,19 @@ impl<'a> fmt::Show for Item<'a> { } try!(write!(fmt.buf, "{}", shortty(self.item), self.item.name.get_ref().as_slice())); - - // Write stability attributes - match attr::find_stability(self.item.attrs.iter()) { - Some(ref stability) => { - try!(write!(fmt.buf, - "{lvl}", - lvl = stability.level.to_str(), - reason = match stability.text { - Some(ref s) => (*s).clone(), - None => InternedString::new(""), - })); - } - None => {} - } - - // Write `src` tag - if self.cx.include_sources { - try!(write!(fmt.buf, "[src]", - self.link())); - } + try!(self.cx.item_heading_aux(fmt.buf, self.item)); try!(write!(fmt.buf, "\n")); match self.item.inner { - clean::ModuleItem(ref m) => { - item_module(fmt.buf, self.cx, self.item, m.items.as_slice()) - } + clean::ModuleItem(ref m) => + self.cx.item_module(fmt.buf, self.item, m.items.as_slice()), clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f) => - item_function(fmt.buf, self.item, f), - clean::TraitItem(ref t) => item_trait(fmt.buf, self.item, t), - clean::StructItem(ref s) => item_struct(fmt.buf, self.item, s), - clean::EnumItem(ref e) => item_enum(fmt.buf, self.item, e), - clean::TypedefItem(ref t) => item_typedef(fmt.buf, self.item, t), - clean::MacroItem(ref m) => item_macro(fmt.buf, self.item, m), + self.cx.item_function(fmt.buf, self.item, f), + clean::TraitItem(ref t) => self.cx.item_trait(fmt.buf, self.item, t), + clean::StructItem(ref s) => self.cx.item_struct(fmt.buf, self.item, s), + clean::EnumItem(ref e) => self.cx.item_enum(fmt.buf, self.item, e), + clean::TypedefItem(ref t) => self.cx.item_typedef(fmt.buf, self.item, t), + clean::MacroItem(ref m) => self.cx.item_macro(fmt.buf, self.item, m), _ => Ok(()) } } @@ -1053,619 +1033,675 @@ fn document(w: &mut Writer, item: &clean::Item) -> fmt::Result { Ok(()) } -fn item_module(w: &mut Writer, cx: &Context, - item: &clean::Item, items: &[clean::Item]) -> fmt::Result { - try!(document(w, item)); - debug!("{:?}", items); - let mut indices = Vec::from_fn(items.len(), |i| i); +impl Context { + /// Renders auxiliary tags and links in the heading of given item. + /// Should be placed between the heading text and the closing tag. + fn item_heading_aux(&self, w: &mut Writer, item: &clean::Item) -> fmt::Result { + // Write stability attributes + match attr::find_stability(item.attrs.iter()) { + Some(ref stability) => { + try!(write!(w, + "{lvl}", + lvl = stability.level.to_str(), + reason = match stability.text { + Some(ref s) => (*s).clone(), + None => InternedString::new(""), + })); + } + None => {} + } - fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> Ordering { - if shortty(i1) == shortty(i2) { - return i1.name.cmp(&i2.name); + // Write `src` tag + if self.include_sources { + let mut path = Vec::new(); + clean_srcpath(item.source.filename.as_bytes(), |component| { + path.push(component.to_owned()); + }); + let href = if item.source.loline == item.source.hiline { + format!("{}", item.source.loline) + } else { + format!("{}-{}", item.source.loline, item.source.hiline) + }; + try!(write!(w, "\ + [src]", + root = self.root_path, + krate = self.layout.krate, + path = path.connect("/"), + href = href)); } - match (&i1.inner, &i2.inner) { - (&clean::ViewItemItem(ref a), &clean::ViewItemItem(ref b)) => { - match (&a.inner, &b.inner) { - (&clean::ExternCrate(..), _) => Less, - (_, &clean::ExternCrate(..)) => Greater, - _ => idx1.cmp(&idx2), + + Ok(()) + } + + fn item_module(&self, w: &mut Writer, + item: &clean::Item, items: &[clean::Item]) -> fmt::Result { + try!(document(w, item)); + debug!("{:?}", items); + let mut indices = Vec::from_fn(items.len(), |i| i); + + fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> Ordering { + if shortty(i1) == shortty(i2) { + return i1.name.cmp(&i2.name); + } + match (&i1.inner, &i2.inner) { + (&clean::ViewItemItem(ref a), &clean::ViewItemItem(ref b)) => { + match (&a.inner, &b.inner) { + (&clean::ExternCrate(..), _) => Less, + (_, &clean::ExternCrate(..)) => Greater, + _ => idx1.cmp(&idx2), + } } + (&clean::ViewItemItem(..), _) => Less, + (_, &clean::ViewItemItem(..)) => Greater, + (&clean::ModuleItem(..), _) => Less, + (_, &clean::ModuleItem(..)) => Greater, + (&clean::MacroItem(..), _) => Less, + (_, &clean::MacroItem(..)) => Greater, + (&clean::StructItem(..), _) => Less, + (_, &clean::StructItem(..)) => Greater, + (&clean::EnumItem(..), _) => Less, + (_, &clean::EnumItem(..)) => Greater, + (&clean::StaticItem(..), _) => Less, + (_, &clean::StaticItem(..)) => Greater, + (&clean::ForeignFunctionItem(..), _) => Less, + (_, &clean::ForeignFunctionItem(..)) => Greater, + (&clean::ForeignStaticItem(..), _) => Less, + (_, &clean::ForeignStaticItem(..)) => Greater, + (&clean::TraitItem(..), _) => Less, + (_, &clean::TraitItem(..)) => Greater, + (&clean::FunctionItem(..), _) => Less, + (_, &clean::FunctionItem(..)) => Greater, + (&clean::TypedefItem(..), _) => Less, + (_, &clean::TypedefItem(..)) => Greater, + _ => idx1.cmp(&idx2), } - (&clean::ViewItemItem(..), _) => Less, - (_, &clean::ViewItemItem(..)) => Greater, - (&clean::ModuleItem(..), _) => Less, - (_, &clean::ModuleItem(..)) => Greater, - (&clean::MacroItem(..), _) => Less, - (_, &clean::MacroItem(..)) => Greater, - (&clean::StructItem(..), _) => Less, - (_, &clean::StructItem(..)) => Greater, - (&clean::EnumItem(..), _) => Less, - (_, &clean::EnumItem(..)) => Greater, - (&clean::StaticItem(..), _) => Less, - (_, &clean::StaticItem(..)) => Greater, - (&clean::ForeignFunctionItem(..), _) => Less, - (_, &clean::ForeignFunctionItem(..)) => Greater, - (&clean::ForeignStaticItem(..), _) => Less, - (_, &clean::ForeignStaticItem(..)) => Greater, - (&clean::TraitItem(..), _) => Less, - (_, &clean::TraitItem(..)) => Greater, - (&clean::FunctionItem(..), _) => Less, - (_, &clean::FunctionItem(..)) => Greater, - (&clean::TypedefItem(..), _) => Less, - (_, &clean::TypedefItem(..)) => Greater, - _ => idx1.cmp(&idx2), } - } - debug!("{:?}", indices); - indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2)); + debug!("{:?}", indices); + indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2)); - debug!("{:?}", indices); - let mut curty = None; - for &idx in indices.iter() { - let myitem = &items[idx]; + debug!("{:?}", indices); + let mut curty = None; + for &idx in indices.iter() { + let myitem = &items[idx]; - let myty = Some(shortty(myitem)); - if myty != curty { - if curty.is_some() { - try!(write!(w, "")); + let myty = Some(shortty(myitem)); + if myty != curty { + if curty.is_some() { + try!(write!(w, "")); + } + curty = myty; + let (short, name) = match myitem.inner { + clean::ModuleItem(..) => ("modules", "Modules"), + clean::StructItem(..) => ("structs", "Structs"), + clean::EnumItem(..) => ("enums", "Enums"), + clean::FunctionItem(..) => ("functions", "Functions"), + clean::TypedefItem(..) => ("types", "Type Definitions"), + clean::StaticItem(..) => ("statics", "Statics"), + clean::TraitItem(..) => ("traits", "Traits"), + clean::ImplItem(..) => ("impls", "Implementations"), + clean::ViewItemItem(..) => ("reexports", "Reexports"), + clean::TyMethodItem(..) => ("tymethods", "Type Methods"), + clean::MethodItem(..) => ("methods", "Methods"), + clean::StructFieldItem(..) => ("fields", "Struct Fields"), + clean::VariantItem(..) => ("variants", "Variants"), + clean::ForeignFunctionItem(..) => ("ffi-fns", "Foreign Functions"), + clean::ForeignStaticItem(..) => ("ffi-statics", "Foreign Statics"), + clean::MacroItem(..) => ("macros", "Macros"), + }; + try!(write!(w, + "

\ + {name}

\n", + id = short, name = name)); } - curty = myty; - let (short, name) = match myitem.inner { - clean::ModuleItem(..) => ("modules", "Modules"), - clean::StructItem(..) => ("structs", "Structs"), - clean::EnumItem(..) => ("enums", "Enums"), - clean::FunctionItem(..) => ("functions", "Functions"), - clean::TypedefItem(..) => ("types", "Type Definitions"), - clean::StaticItem(..) => ("statics", "Statics"), - clean::TraitItem(..) => ("traits", "Traits"), - clean::ImplItem(..) => ("impls", "Implementations"), - clean::ViewItemItem(..) => ("reexports", "Reexports"), - clean::TyMethodItem(..) => ("tymethods", "Type Methods"), - clean::MethodItem(..) => ("methods", "Methods"), - clean::StructFieldItem(..) => ("fields", "Struct Fields"), - clean::VariantItem(..) => ("variants", "Variants"), - clean::ForeignFunctionItem(..) => ("ffi-fns", "Foreign Functions"), - clean::ForeignStaticItem(..) => ("ffi-statics", "Foreign Statics"), - clean::MacroItem(..) => ("macros", "Macros"), - }; - try!(write!(w, - "

\ - {name}

\n
", - id = short, name = name)); - } - match myitem.inner { - clean::StaticItem(ref s) | clean::ForeignStaticItem(ref s) => { - struct Initializer<'a>(&'a str, Item<'a>); - impl<'a> fmt::Show for Initializer<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let Initializer(s, item) = *self; - if s.len() == 0 { return Ok(()); } - try!(write!(f.buf, " = ")); - if s.contains("\n") { - write!(f.buf, - "[definition]", - item.link()) - } else { - write!(f.buf, "{}", s.as_slice()) + match myitem.inner { + clean::StaticItem(ref s) | clean::ForeignStaticItem(ref s) => { + struct Initializer<'a>(&'a str, Item<'a>); + impl<'a> fmt::Show for Initializer<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let Initializer(s, item) = *self; + if s.len() == 0 { return Ok(()); } + try!(write!(f.buf, " = ")); + if s.contains("\n") { + write!(f.buf, + "[definition]", + item.link()) + } else { + write!(f.buf, "{}", s.as_slice()) + } } } + + try!(write!(w, " + + + + + ", + VisSpace(myitem.visibility), + *myitem.name.get_ref(), + s.type_, + Initializer(s.expr, Item { cx: self, item: myitem }), + Markdown(blank(myitem.doc_value())))); } - try!(write!(w, " - - - - - ", - VisSpace(myitem.visibility), - *myitem.name.get_ref(), - s.type_, - Initializer(s.expr, Item { cx: cx, item: myitem }), - Markdown(blank(myitem.doc_value())))); - } + clean::ViewItemItem(ref item) => { + match item.inner { + clean::ExternCrate(ref name, ref src, _) => { + try!(write!(w, "")); + } - clean::ViewItemItem(ref item) => { - match item.inner { - clean::ExternCrate(ref name, ref src, _) => { - try!(write!(w, "", + VisSpace(myitem.visibility), + *import)); } - try!(write!(w, ";")); } - clean::Import(ref import) => { - try!(write!(w, "", - VisSpace(myitem.visibility), - *import)); - } } - } - - _ => { - if myitem.name.is_none() { continue } - try!(write!(w, " - - - - - ", - *myitem.name.get_ref(), - Markdown(shorter(myitem.doc_value())), - class = shortty(myitem), - href = item_path(myitem), - title = full_path(cx, myitem))); + _ => { + if myitem.name.is_none() { continue } + try!(write!(w, " + + + + + ", + *myitem.name.get_ref(), + Markdown(shorter(myitem.doc_value())), + class = shortty(myitem), + href = item_path(myitem), + title = full_path(self, myitem))); + } } } + write!(w, "
{}static {}: {}{}{} 
{}static {}: {}{}{} 
extern crate {}", + name.as_slice())); + match *src { + Some(ref src) => try!(write!(w, " = \"{}\"", + src.as_slice())), + None => {} + } + try!(write!(w, ";
extern crate {}", - name.as_slice())); - match *src { - Some(ref src) => try!(write!(w, " = \"{}\"", - src.as_slice())), - None => {} + clean::Import(ref import) => { + try!(write!(w, "
{}{}
{}{}
{}{}
{}{}
") } - write!(w, "") -} - -fn item_function(w: &mut Writer, it: &clean::Item, - f: &clean::Function) -> fmt::Result { - try!(write!(w, "
{vis}{fn_style}fn \
-                    {name}{generics}{decl}
", - vis = VisSpace(it.visibility), - fn_style = FnStyleSpace(f.fn_style), - name = it.name.get_ref().as_slice(), - generics = f.generics, - decl = f.decl)); - document(w, it) -} -fn item_trait(w: &mut Writer, it: &clean::Item, - t: &clean::Trait) -> fmt::Result { - let mut parents = StrBuf::new(); - if t.parents.len() > 0 { - parents.push_str(": "); - for (i, p) in t.parents.iter().enumerate() { - if i > 0 { parents.push_str(" + "); } - parents.push_str(format!("{}", *p)); - } + fn item_function(&self, w: &mut Writer, it: &clean::Item, + f: &clean::Function) -> fmt::Result { + try!(write!(w, "
{vis}{fn_style}fn \
+                        {name}{generics}{decl}
", + vis = VisSpace(it.visibility), + fn_style = FnStyleSpace(f.fn_style), + name = it.name.get_ref().as_slice(), + generics = f.generics, + decl = f.decl)); + document(w, it) } - // Output the trait definition - try!(write!(w, "
{}trait {}{}{} ",
-                  VisSpace(it.visibility),
-                  it.name.get_ref().as_slice(),
-                  t.generics,
-                  parents));
-    let required = t.methods.iter().filter(|m| m.is_req()).collect::>();
-    let provided = t.methods.iter().filter(|m| !m.is_req()).collect::>();
-
-    if t.methods.len() == 0 {
-        try!(write!(w, "\\{ \\}"));
-    } else {
-        try!(write!(w, "\\{\n"));
-        for m in required.iter() {
-            try!(write!(w, "    "));
-            try!(render_method(w, m.item()));
-            try!(write!(w, ";\n"));
-        }
-        if required.len() > 0 && provided.len() > 0 {
-            try!(w.write("\n".as_bytes()));
-        }
-        for m in provided.iter() {
-            try!(write!(w, "    "));
-            try!(render_method(w, m.item()));
-            try!(write!(w, " \\{ ... \\}\n"));
+    fn item_trait(&self, w: &mut Writer, it: &clean::Item,
+                  t: &clean::Trait) -> fmt::Result {
+        let mut parents = StrBuf::new();
+        if t.parents.len() > 0 {
+            parents.push_str(": ");
+            for (i, p) in t.parents.iter().enumerate() {
+                if i > 0 { parents.push_str(" + "); }
+                parents.push_str(format!("{}", *p));
+            }
         }
-        try!(write!(w, "\\}"));
-    }
-    try!(write!(w, "
")); - - // Trait documentation - try!(document(w, it)); - - fn meth(w: &mut Writer, m: &clean::TraitMethod) -> fmt::Result { - try!(write!(w, "

", - shortty(m.item()), - *m.item().name.get_ref())); - try!(render_method(w, m.item())); - try!(write!(w, "

")); - try!(document(w, m.item())); - Ok(()) - } - // Output the documentation for each function individually - if required.len() > 0 { - try!(write!(w, " -

Required Methods

-
- ")); - for m in required.iter() { - try!(meth(w, *m)); + // Output the trait definition + try!(write!(w, "
{}trait {}{}{} ",
+                      VisSpace(it.visibility),
+                      it.name.get_ref().as_slice(),
+                      t.generics,
+                      parents));
+        let required: Vec<&clean::TraitMethod> =
+            t.methods.iter().filter(|m| m.is_req()).collect();
+        let provided: Vec<&clean::TraitMethod> =
+            t.methods.iter().filter(|m| !m.is_req()).collect();
+
+        if t.methods.len() == 0 {
+            try!(write!(w, "\\{ \\}"));
+        } else {
+            try!(write!(w, "\\{\n"));
+            for m in required.iter() {
+                try!(write!(w, "    "));
+                try!(self.render_method(w, m.item()));
+                try!(write!(w, ";\n"));
+            }
+            if required.len() > 0 && provided.len() > 0 {
+                try!(w.write("\n".as_bytes()));
+            }
+            for m in provided.iter() {
+                try!(write!(w, "    "));
+                try!(self.render_method(w, m.item()));
+                try!(write!(w, " \\{ ... \\}\n"));
+            }
+            try!(write!(w, "\\}"));
         }
-        try!(write!(w, "
")); - } - if provided.len() > 0 { - try!(write!(w, " -

Provided Methods

-
- ")); - for m in provided.iter() { - try!(meth(w, *m)); + try!(write!(w, "")); + + // Trait documentation + try!(document(w, it)); + + fn meth(w: &mut Writer, cx: &Context, m: &clean::TraitMethod) -> fmt::Result { + try!(write!(w, "

", + shortty(m.item()), + *m.item().name.get_ref())); + try!(cx.render_method(w, m.item())); + try!(write!(w, "")); + try!(cx.item_heading_aux(w, m.item())); + try!(write!(w, "

")); + try!(document(w, m.item())); + Ok(()) } - try!(write!(w, "
")); - } - match cache_key.get().unwrap().implementors.find(&it.id) { - Some(implementors) => { + // Output the documentation for each function individually + if required.len() > 0 { try!(write!(w, " -

Implementors

- ")); + None => {} } - None => {} + Ok(()) } - Ok(()) -} -fn render_method(w: &mut Writer, meth: &clean::Item) -> fmt::Result { - fn fun(w: &mut Writer, it: &clean::Item, fn_style: ast::FnStyle, - g: &clean::Generics, selfty: &clean::SelfTy, - d: &clean::FnDecl) -> fmt::Result { - write!(w, "{}fn {name}\ - {generics}{decl}", - match fn_style { - ast::UnsafeFn => "unsafe ", - _ => "", - }, - ty = shortty(it), - name = it.name.get_ref().as_slice(), - generics = *g, - decl = Method(selfty, d)) - } - match meth.inner { - clean::TyMethodItem(ref m) => { - fun(w, meth, m.fn_style, &m.generics, &m.self_, &m.decl) + fn render_method(&self, w: &mut Writer, meth: &clean::Item) -> fmt::Result { + fn fun(w: &mut Writer, it: &clean::Item, fn_style: ast::FnStyle, + g: &clean::Generics, selfty: &clean::SelfTy, + d: &clean::FnDecl) -> fmt::Result { + write!(w, "{}fn {name}\ + {generics}{decl}", + match fn_style { + ast::UnsafeFn => "unsafe ", + _ => "", + }, + ty = shortty(it), + name = it.name.get_ref().as_slice(), + generics = *g, + decl = Method(selfty, d)) } - clean::MethodItem(ref m) => { - fun(w, meth, m.fn_style, &m.generics, &m.self_, &m.decl) + match meth.inner { + clean::TyMethodItem(ref m) => { + fun(w, meth, m.fn_style, &m.generics, &m.self_, &m.decl) + } + clean::MethodItem(ref m) => { + fun(w, meth, m.fn_style, &m.generics, &m.self_, &m.decl) + } + _ => unreachable!() } - _ => unreachable!() } -} -fn item_struct(w: &mut Writer, it: &clean::Item, - s: &clean::Struct) -> fmt::Result { - try!(write!(w, "
"));
-    try!(render_struct(w,
-                       it,
-                       Some(&s.generics),
-                       s.struct_type,
-                       s.fields.as_slice(),
-                       "",
-                       true));
-    try!(write!(w, "
")); - - try!(document(w, it)); - let mut fields = s.fields.iter().filter(|f| { - match f.inner { - clean::StructFieldItem(clean::HiddenStructField) => false, - clean::StructFieldItem(clean::TypedStructField(..)) => true, - _ => false, - } - }).peekable(); - match s.struct_type { - doctree::Plain if fields.peek().is_some() => { - try!(write!(w, "

Fields

\n")); - for field in fields { - try!(write!(w, "")); + fn item_struct(&self, w: &mut Writer, it: &clean::Item, + s: &clean::Struct) -> fmt::Result { + try!(write!(w, "
"));
+        try!(self.render_struct(w,
+                                it,
+                                Some(&s.generics),
+                                s.struct_type,
+                                s.fields.as_slice(),
+                                "",
+                                true));
+        try!(write!(w, "
")); + + try!(document(w, it)); + let mut fields = s.fields.iter().filter(|f| { + match f.inner { + clean::StructFieldItem(clean::HiddenStructField) => false, + clean::StructFieldItem(clean::TypedStructField(..)) => true, + _ => false, } - try!(write!(w, "
\ - {name}", - name = field.name.get_ref().as_slice())); - try!(document(w, field)); - try!(write!(w, "
")); + }).peekable(); + match s.struct_type { + doctree::Plain if fields.peek().is_some() => { + try!(write!(w, "

Fields

\n")); + for field in fields { + try!(write!(w, "")); + } + try!(write!(w, "
\ + {name}", + name = field.name.get_ref().as_slice())); + try!(document(w, field)); + try!(write!(w, "
")); + } + _ => {} } - _ => {} + self.render_methods(w, it) } - render_methods(w, it) -} -fn item_enum(w: &mut Writer, it: &clean::Item, e: &clean::Enum) -> fmt::Result { - try!(write!(w, "
{}enum {}{}",
-                  VisSpace(it.visibility),
-                  it.name.get_ref().as_slice(),
-                  e.generics));
-    if e.variants.len() == 0 && !e.variants_stripped {
-        try!(write!(w, " \\{\\}"));
-    } else {
-        try!(write!(w, " \\{\n"));
-        for v in e.variants.iter() {
-            try!(write!(w, "    "));
-            let name = v.name.get_ref().as_slice();
-            match v.inner {
-                clean::VariantItem(ref var) => {
-                    match var.kind {
-                        clean::CLikeVariant => try!(write!(w, "{}", name)),
-                        clean::TupleVariant(ref tys) => {
-                            try!(write!(w, "{}(", name));
-                            for (i, ty) in tys.iter().enumerate() {
-                                if i > 0 {
-                                    try!(write!(w, ", "))
+    fn item_enum(&self, w: &mut Writer, it: &clean::Item, e: &clean::Enum) -> fmt::Result {
+        try!(write!(w, "
{}enum {}{}",
+                      VisSpace(it.visibility),
+                      it.name.get_ref().as_slice(),
+                      e.generics));
+        if e.variants.len() == 0 && !e.variants_stripped {
+            try!(write!(w, " \\{\\}"));
+        } else {
+            try!(write!(w, " \\{\n"));
+            for v in e.variants.iter() {
+                try!(write!(w, "    "));
+                let name = v.name.get_ref().as_slice();
+                match v.inner {
+                    clean::VariantItem(ref var) => {
+                        match var.kind {
+                            clean::CLikeVariant => try!(write!(w, "{}", name)),
+                            clean::TupleVariant(ref tys) => {
+                                try!(write!(w, "{}(", name));
+                                for (i, ty) in tys.iter().enumerate() {
+                                    if i > 0 {
+                                        try!(write!(w, ", "))
+                                    }
+                                    try!(write!(w, "{}", *ty));
                                 }
-                                try!(write!(w, "{}", *ty));
+                                try!(write!(w, ")"));
+                            }
+                            clean::StructVariant(ref s) => {
+                                try!(self.render_struct(w,
+                                                        v,
+                                                        None,
+                                                        s.struct_type,
+                                                        s.fields.as_slice(),
+                                                        "    ",
+                                                        false));
                             }
-                            try!(write!(w, ")"));
-                        }
-                        clean::StructVariant(ref s) => {
-                            try!(render_struct(w,
-                                               v,
-                                               None,
-                                               s.struct_type,
-                                               s.fields.as_slice(),
-                                               "    ",
-                                               false));
                         }
                     }
+                    _ => unreachable!()
                 }
-                _ => unreachable!()
+                try!(write!(w, ",\n"));
             }
-            try!(write!(w, ",\n"));
-        }
 
-        if e.variants_stripped {
-            try!(write!(w, "    // some variants omitted\n"));
+            if e.variants_stripped {
+                try!(write!(w, "    // some variants omitted\n"));
+            }
+            try!(write!(w, "\\}"));
         }
-        try!(write!(w, "\\}"));
-    }
-    try!(write!(w, "
")); - - try!(document(w, it)); - if e.variants.len() > 0 { - try!(write!(w, "

Variants

\n")); - for variant in e.variants.iter() { - try!(write!(w, "")); } - try!(write!(w, "")); - } - try!(write!(w, "
{name}", - name = variant.name.get_ref().as_slice())); - try!(document(w, variant)); - match variant.inner { - clean::VariantItem(ref var) => { - match var.kind { - clean::StructVariant(ref s) => { - let mut fields = s.fields.iter().filter(|f| { - match f.inner { - clean::StructFieldItem(ref t) => match *t { - clean::HiddenStructField => false, - clean::TypedStructField(..) => true, - }, - _ => false, + try!(write!(w, "")); + + try!(document(w, it)); + if e.variants.len() > 0 { + try!(write!(w, "

Variants

\n")); + for variant in e.variants.iter() { + try!(write!(w, "
{name}", + name = variant.name.get_ref().as_slice())); + try!(document(w, variant)); + match variant.inner { + clean::VariantItem(ref var) => { + match var.kind { + clean::StructVariant(ref s) => { + let mut fields = s.fields.iter().filter(|f| { + match f.inner { + clean::StructFieldItem(ref t) => match *t { + clean::HiddenStructField => false, + clean::TypedStructField(..) => true, + }, + _ => false, + } + }); + try!(write!(w, "

Fields

\n + ")); + for field in fields { + try!(write!(w, "")); } - }); - try!(write!(w, "

Fields

\n -
\ + {f}", + v = variant.name.get_ref().as_slice(), + f = field.name.get_ref().as_slice())); + try!(document(w, field)); + try!(write!(w, "
")); - for field in fields { - try!(write!(w, "")); + try!(write!(w, "
\ - {f}", - v = variant.name.get_ref().as_slice(), - f = field.name.get_ref().as_slice())); - try!(document(w, field)); - try!(write!(w, "
")); } - try!(write!(w, "
")); + _ => () } - _ => () } + _ => () } - _ => () + try!(write!(w, "
")); - - } - try!(render_methods(w, it)); - Ok(()) -} + try!(write!(w, "")); -fn render_struct(w: &mut Writer, it: &clean::Item, - g: Option<&clean::Generics>, - ty: doctree::StructType, - fields: &[clean::Item], - tab: &str, - structhead: bool) -> fmt::Result { - try!(write!(w, "{}{}{}", - VisSpace(it.visibility), - if structhead {"struct "} else {""}, - it.name.get_ref().as_slice())); - match g { - Some(g) => try!(write!(w, "{}", *g)), - None => {} + } + try!(self.render_methods(w, it)); + Ok(()) } - match ty { - doctree::Plain => { - try!(write!(w, " \\{\n{}", tab)); - let mut fields_stripped = false; - for field in fields.iter() { - match field.inner { - clean::StructFieldItem(clean::HiddenStructField) => { - fields_stripped = true; - } - clean::StructFieldItem(clean::TypedStructField(ref ty)) => { - try!(write!(w, " {}{}: {},\n{}", - VisSpace(field.visibility), - field.name.get_ref().as_slice(), - *ty, - tab)); - } - _ => unreachable!(), - }; - } - if fields_stripped { - try!(write!(w, " // some fields omitted\n{}", tab)); - } - try!(write!(w, "\\}")); + fn render_struct(&self, w: &mut Writer, it: &clean::Item, + g: Option<&clean::Generics>, + ty: doctree::StructType, + fields: &[clean::Item], + tab: &str, + structhead: bool) -> fmt::Result { + try!(write!(w, "{}{}{}", + VisSpace(it.visibility), + if structhead {"struct "} else {""}, + it.name.get_ref().as_slice())); + match g { + Some(g) => try!(write!(w, "{}", *g)), + None => {} } - doctree::Tuple | doctree::Newtype => { - try!(write!(w, "(")); - for (i, field) in fields.iter().enumerate() { - if i > 0 { - try!(write!(w, ", ")); + match ty { + doctree::Plain => { + try!(write!(w, " \\{\n{}", tab)); + let mut fields_stripped = false; + for field in fields.iter() { + match field.inner { + clean::StructFieldItem(clean::HiddenStructField) => { + fields_stripped = true; + } + clean::StructFieldItem(clean::TypedStructField(ref ty)) => { + try!(write!(w, " {}{}: {},\n{}", + VisSpace(field.visibility), + field.name.get_ref().as_slice(), + *ty, + tab)); + } + _ => unreachable!(), + }; + } + + if fields_stripped { + try!(write!(w, " // some fields omitted\n{}", tab)); } - match field.inner { - clean::StructFieldItem(clean::HiddenStructField) => { - try!(write!(w, "_")) + try!(write!(w, "\\}")); + } + doctree::Tuple | doctree::Newtype => { + try!(write!(w, "(")); + for (i, field) in fields.iter().enumerate() { + if i > 0 { + try!(write!(w, ", ")); } - clean::StructFieldItem(clean::TypedStructField(ref ty)) => { - try!(write!(w, "{}{}", VisSpace(field.visibility), *ty)) + match field.inner { + clean::StructFieldItem(clean::HiddenStructField) => { + try!(write!(w, "_")) + } + clean::StructFieldItem(clean::TypedStructField(ref ty)) => { + try!(write!(w, "{}{}", VisSpace(field.visibility), *ty)) + } + _ => unreachable!() } - _ => unreachable!() } + try!(write!(w, ");")); + } + doctree::Unit => { + try!(write!(w, ";")); } - try!(write!(w, ");")); - } - doctree::Unit => { - try!(write!(w, ";")); } + Ok(()) } - Ok(()) -} - -fn render_methods(w: &mut Writer, it: &clean::Item) -> fmt::Result { - match cache_key.get().unwrap().impls.find(&it.id) { - Some(v) => { - let mut non_trait = v.iter().filter(|p| { - p.ref0().trait_.is_none() - }); - let non_trait = non_trait.collect::)>>(); - let mut traits = v.iter().filter(|p| { - p.ref0().trait_.is_some() - }); - let traits = traits.collect::)>>(); - if non_trait.len() > 0 { - try!(write!(w, "

Methods

")); - for &(ref i, ref dox) in non_trait.move_iter() { - try!(render_impl(w, i, dox)); - } - } - if traits.len() > 0 { - try!(write!(w, "

Trait \ - Implementations

")); - let mut any_derived = false; - for & &(ref i, ref dox) in traits.iter() { - if !i.derived { - try!(render_impl(w, i, dox)); - } else { - any_derived = true; + fn render_methods(&self, w: &mut Writer, it: &clean::Item) -> fmt::Result { + match cache_key.get().unwrap().impls.find(&it.id) { + Some(v) => { + let mut non_trait = v.iter().filter(|p| { + p.ref0().trait_.is_none() + }); + let non_trait = non_trait.collect::)>>(); + let mut traits = v.iter().filter(|p| { + p.ref0().trait_.is_some() + }); + let traits = traits.collect::)>>(); + + if non_trait.len() > 0 { + try!(write!(w, "

Methods

")); + for &(ref i, ref dox) in non_trait.move_iter() { + try!(self.render_impl(w, i, dox)); } } - if any_derived { - try!(write!(w, "

Derived Implementations \ -

")); - for &(ref i, ref dox) in traits.move_iter() { - if i.derived { - try!(render_impl(w, i, dox)); + if traits.len() > 0 { + try!(write!(w, "

Trait \ + Implementations

")); + let mut any_derived = false; + for & &(ref i, ref dox) in traits.iter() { + if !i.derived { + try!(self.render_impl(w, i, dox)); + } else { + any_derived = true; + } + } + if any_derived { + try!(write!(w, "

Derived \ + Implementations

")); + for &(ref i, ref dox) in traits.move_iter() { + if i.derived { + try!(self.render_impl(w, i, dox)); + } } } } } + None => {} } - None => {} + Ok(()) } - Ok(()) -} -fn render_impl(w: &mut Writer, i: &clean::Impl, - dox: &Option<~str>) -> fmt::Result { - try!(write!(w, "

impl{} ", i.generics)); - let trait_id = match i.trait_ { - Some(ref ty) => { - try!(write!(w, "{} for ", *ty)); - match *ty { - clean::ResolvedPath { id, .. } => Some(id), - _ => None, + fn render_impl(&self, w: &mut Writer, i: &clean::Impl, + dox: &Option<~str>) -> fmt::Result { + try!(write!(w, "

impl{} ", i.generics)); + let trait_id = match i.trait_ { + Some(ref ty) => { + try!(write!(w, "{} for ", *ty)); + match *ty { + clean::ResolvedPath { id, .. } => Some(id), + _ => None, + } } + None => None + }; + try!(write!(w, "{}

", i.for_)); + match *dox { + Some(ref dox) => { + try!(write!(w, "
{}
", + Markdown(dox.as_slice()))); + } + None => {} } - None => None - }; - try!(write!(w, "{}

", i.for_)); - match *dox { - Some(ref dox) => { - try!(write!(w, "
{}
", - Markdown(dox.as_slice()))); - } - None => {} - } - fn docmeth(w: &mut Writer, item: &clean::Item, - dox: bool) -> io::IoResult<()> { - try!(write!(w, "

", - *item.name.get_ref())); - try!(render_method(w, item)); - try!(write!(w, "

\n")); - match item.doc_value() { - Some(s) if dox => { - try!(write!(w, "
{}
", Markdown(s))); - Ok(()) + fn docmeth(w: &mut Writer, cx: &Context, + item: &clean::Item, dox: bool) -> io::IoResult<()> { + try!(write!(w, "
")); + try!(write!(w, "

", + *item.name.get_ref())); + try!(cx.render_method(w, item)); + try!(write!(w, "")); + try!(cx.item_heading_aux(w, item)); + try!(write!(w, "

\n")); + match item.doc_value() { + Some(s) if dox => { + try!(write!(w, "
{}
", Markdown(s))); + Ok(()) + } + Some(..) | None => Ok(()) } - Some(..) | None => Ok(()) + try!(write!(w, "
")); } - } - try!(write!(w, "
")); - for meth in i.methods.iter() { - try!(docmeth(w, meth, true)); - } + try!(write!(w, "
")); + for meth in i.methods.iter() { + try!(docmeth(w, self, meth, true)); + } - // If we've implemented a trait, then also emit documentation for all - // default methods which weren't overridden in the implementation block. - match trait_id { - None => {} - Some(id) => { - try!({ - match cache_key.get().unwrap().traits.find(&id) { - Some(t) => { - for method in t.methods.iter() { - let n = method.item().name.clone(); - match i.methods.iter().find(|m| m.name == n) { - Some(..) => continue, - None => {} - } + // If we've implemented a trait, then also emit documentation for all + // default methods which weren't overridden in the implementation block. + match trait_id { + None => {} + Some(id) => { + try!({ + match cache_key.get().unwrap().traits.find(&id) { + Some(t) => { + for method in t.methods.iter() { + let n = method.item().name.clone(); + match i.methods.iter().find(|m| m.name == n) { + Some(..) => continue, + None => {} + } - try!(docmeth(w, method.item(), false)); + try!(docmeth(w, self, method.item(), false)); + } } + None => {} } - None => {} - } - Ok(()) - }) + Ok(()) + }) + } } + try!(write!(w, "
")); + Ok(()) } - try!(write!(w, "
")); - Ok(()) -} -fn item_typedef(w: &mut Writer, it: &clean::Item, - t: &clean::Typedef) -> fmt::Result { - try!(write!(w, "
type {}{} = {};
", - it.name.get_ref().as_slice(), - t.generics, - t.type_)); + fn item_typedef(&self, w: &mut Writer, it: &clean::Item, + t: &clean::Typedef) -> fmt::Result { + try!(write!(w, "
type {}{} = {};
", + it.name.get_ref().as_slice(), + t.generics, + t.type_)); + + document(w, it) + } - document(w, it) + fn item_macro(&self, w: &mut Writer, it: &clean::Item, + t: &clean::Macro) -> fmt::Result { + try!(w.write_str(highlight::highlight(t.source, Some("macro")))); + document(w, it) + } } impl<'a> fmt::Show for Sidebar<'a> { @@ -1761,8 +1797,3 @@ impl<'a> fmt::Show for Source<'a> { } } -fn item_macro(w: &mut Writer, it: &clean::Item, - t: &clean::Macro) -> fmt::Result { - try!(w.write_str(highlight::highlight(t.source, Some("macro")))); - document(w, it) -} diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css index 8b6c75565db25..eb32a20a1094d 100644 --- a/src/librustdoc/html/static/main.css +++ b/src/librustdoc/html/static/main.css @@ -89,7 +89,7 @@ h3.impl, h3.method, h4.method { h3.impl, h3.method { margin-top: 15px; } -h1, h2, h3, h4, section.sidebar, a.source, .search-input, .content table a { +h1, h2, h3, h4, section.sidebar, .source-link, .search-input, .content table a { font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; } @@ -222,9 +222,16 @@ nav.sub { .docblock h2 { font-size: 1.15em; } .docblock h3, .docblock h4, .docblock h5 { font-size: 1em; } -.content .source { +.content .source-link { float: right; - font-size: 23px; + font-size: 90%; + font-weight: 400; +} +.method .source-link { + visibility: hidden; +} +.method-container:hover .source-link { + visibility: visible; } .content table { @@ -288,8 +295,8 @@ a { color: #000; background: transparent; } -p a { color: #4e8bca; } -p a:hover { text-decoration: underline; } +.content p a { color: #4e8bca; } +.content p a:hover { text-decoration: underline; } .content a.trait, .block a.current.trait { color: #ed9603; } .content a.mod, .block a.current.mod { color: #4d76ae; } @@ -368,20 +375,28 @@ p a:hover { text-decoration: underline; } } .stability { - border-left: 6px solid #000; - border-radius: 3px; - font-weight: 400; - padding: 4px 10px; - text-transform: lowercase; - margin-left: 14px; -} - -.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; } + border-radius: 10px; + display: inline-block; + font-size: 0; + height: 12px; + width: 12px; + margin: 0 8px; + padding: 0 4px; + vertical-align: 12px; +} +.method .stability { + height: 10px; + width: 10px; + margin: 0 4px; + vertical-align: 9px; +} + +.stability.Deprecated { background-color: #C8344D; } +.stability.Experimental { background-color: #E58623; } +.stability.Unstable { background-color: #F2CF15; } +.stability.Stable { background-color: #809C10; } +.stability.Frozen { background-color: #108034; } +.stability.Locked { background-color: #007DAB; } :target { background: #FDFFD3; } @@ -413,11 +428,9 @@ pre.rust .lifetime { color: #B76514; } .sidebar { display: none; } - .content { margin-left: 0px; } - nav.sub { margin: 0 auto; } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index cf5163af7170f..36e07da999ad7 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -366,10 +366,14 @@ pub fn find_stability>(mut metas: It) "locked" => Locked, _ => continue // not a stability level }; + let text = match m.value_str() { + None => Some(m.name()), + Some(desc) => Some(desc) + }; return Some(Stability { level: level, - text: m.value_str() + text: text }); } None diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 8f3b77dd58c2d..c6f6a62f3299e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1088,9 +1088,9 @@ impl<'a> Parser<'a> { p.parse_arg_general(false) }); - let hi = p.last_span.hi; match p.token { token::SEMI => { + let hi = p.last_span.hi; p.bump(); debug!("parse_trait_methods(): parsing required method"); // NB: at the moment, visibility annotations on required @@ -1113,6 +1113,7 @@ impl<'a> Parser<'a> { debug!("parse_trait_methods(): parsing provided method"); let (inner_attrs, body) = p.parse_inner_attrs_and_block(); + let hi = p.last_span.hi; let attrs = attrs.append(inner_attrs.as_slice()); Provided(@ast::Method { ident: ident,