1
Fork 0

rustdoc: fix fallout of merging ast::ViewItem into ast::Item.

This commit is contained in:
Eduard Burtescu 2014-12-26 10:55:16 +02:00
parent f83a972224
commit 3102b9e19e
10 changed files with 224 additions and 250 deletions

View file

@ -18,8 +18,7 @@ pub use self::TypeKind::*;
pub use self::StructField::*; pub use self::StructField::*;
pub use self::VariantKind::*; pub use self::VariantKind::*;
pub use self::Mutability::*; pub use self::Mutability::*;
pub use self::ViewItemInner::*; pub use self::Import::*;
pub use self::ViewPath::*;
pub use self::ItemEnum::*; pub use self::ItemEnum::*;
pub use self::Attribute::*; pub use self::Attribute::*;
pub use self::TyParamBound::*; pub use self::TyParamBound::*;
@ -309,6 +308,8 @@ impl Item {
#[derive(Clone, RustcEncodable, RustcDecodable)] #[derive(Clone, RustcEncodable, RustcDecodable)]
pub enum ItemEnum { pub enum ItemEnum {
ExternCrateItem(String, Option<String>),
ImportItem(Import),
StructItem(Struct), StructItem(Struct),
EnumItem(Enum), EnumItem(Enum),
FunctionItem(Function), FunctionItem(Function),
@ -318,8 +319,6 @@ pub enum ItemEnum {
ConstantItem(Constant), ConstantItem(Constant),
TraitItem(Trait), TraitItem(Trait),
ImplItem(Impl), ImplItem(Impl),
/// `use` and `extern crate`
ViewItemItem(ViewItem),
/// A method signature only. Used for required methods in traits (ie, /// A method signature only. Used for required methods in traits (ie,
/// non-default-methods). /// non-default-methods).
TyMethodItem(TyMethod), TyMethodItem(TyMethod),
@ -349,27 +348,21 @@ impl Clean<Item> for doctree::Module {
} else { } else {
"".to_string() "".to_string()
}; };
let mut foreigns = Vec::new(); let items: Vec<Item> =
for subforeigns in self.foreigns.clean(cx).into_iter() { self.extern_crates.iter().map(|x| x.clean(cx))
for foreign in subforeigns.into_iter() { .chain(self.imports.iter().flat_map(|x| x.clean(cx).into_iter()))
foreigns.push(foreign) .chain(self.structs.iter().map(|x| x.clean(cx)))
} .chain(self.enums.iter().map(|x| x.clean(cx)))
} .chain(self.fns.iter().map(|x| x.clean(cx)))
let items: Vec<Vec<Item> > = vec!( .chain(self.foreigns.iter().flat_map(|x| x.clean(cx).into_iter()))
self.structs.clean(cx), .chain(self.mods.iter().map(|x| x.clean(cx)))
self.enums.clean(cx), .chain(self.typedefs.iter().map(|x| x.clean(cx)))
self.fns.clean(cx), .chain(self.statics.iter().map(|x| x.clean(cx)))
foreigns, .chain(self.constants.iter().map(|x| x.clean(cx)))
self.mods.clean(cx), .chain(self.traits.iter().map(|x| x.clean(cx)))
self.typedefs.clean(cx), .chain(self.impls.iter().map(|x| x.clean(cx)))
self.statics.clean(cx), .chain(self.macros.iter().map(|x| x.clean(cx)))
self.constants.clean(cx), .collect();
self.traits.clean(cx),
self.impls.clean(cx),
self.view_items.clean(cx).into_iter()
.flat_map(|s| s.into_iter()).collect(),
self.macros.clean(cx),
);
// determine if we should display the inner contents or // determine if we should display the inner contents or
// the outer `mod` item for the source code. // the outer `mod` item for the source code.
@ -395,9 +388,7 @@ impl Clean<Item> for doctree::Module {
def_id: ast_util::local_def(self.id), def_id: ast_util::local_def(self.id),
inner: ModuleItem(Module { inner: ModuleItem(Module {
is_crate: self.is_crate, is_crate: self.is_crate,
items: items.iter() items: items
.flat_map(|x| x.iter().map(|x| (*x).clone()))
.collect(),
}) })
} }
} }
@ -2120,12 +2111,21 @@ impl Clean<Item> for doctree::Impl {
} }
} }
#[derive(Clone, RustcEncodable, RustcDecodable)] impl Clean<Item> for doctree::ExternCrate {
pub struct ViewItem { fn clean(&self, cx: &DocContext) -> Item {
pub inner: ViewItemInner, Item {
name: None,
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
def_id: ast_util::local_def(0),
visibility: self.vis.clean(cx),
stability: None,
inner: ExternCrateItem(self.name.clean(cx), self.path.clone())
}
}
} }
impl Clean<Vec<Item>> for ast::ViewItem { impl Clean<Vec<Item>> for doctree::Import {
fn clean(&self, cx: &DocContext) -> Vec<Item> { fn clean(&self, cx: &DocContext) -> Vec<Item> {
// We consider inlining the documentation of `pub use` statements, but we // We consider inlining the documentation of `pub use` statements, but we
// forcefully don't inline if this is not public or if the // forcefully don't inline if this is not public or if the
@ -2136,81 +2136,63 @@ impl Clean<Vec<Item>> for ast::ViewItem {
None => false, None => false,
} }
}); });
let convert = |&: node: &ast::ViewItem_| { let (mut ret, inner) = match self.node {
Item { ast::ViewPathGlob(ref p) => {
name: None, (vec![], GlobImport(resolve_use_source(cx, p.clean(cx), self.id)))
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
def_id: ast_util::local_def(0),
visibility: self.vis.clean(cx),
stability: None,
inner: ViewItemItem(ViewItem { inner: node.clean(cx) }),
} }
}; ast::ViewPathList(ref p, ref list) => {
let mut ret = Vec::new();
match self.node {
ast::ViewItemUse(ref path) if !denied => {
match path.node {
ast::ViewPathGlob(..) => ret.push(convert(&self.node)),
ast::ViewPathList(ref a, ref list, ref b) => {
// Attempt to inline all reexported items, but be sure // Attempt to inline all reexported items, but be sure
// to keep any non-inlineable reexports so they can be // to keep any non-inlineable reexports so they can be
// listed in the documentation. // listed in the documentation.
let remaining = list.iter().filter(|path| { let mut ret = vec![];
let remaining = if !denied {
let mut remaining = vec![];
for path in list.iter() {
match inline::try_inline(cx, path.node.id(), None) { match inline::try_inline(cx, path.node.id(), None) {
Some(items) => { Some(items) => {
ret.extend(items.into_iter()); false ret.extend(items.into_iter());
} }
None => true, None => {
} remaining.push(path.clean(cx));
}).map(|a| a.clone()).collect::<Vec<ast::PathListItem>>();
if remaining.len() > 0 {
let path = ast::ViewPathList(a.clone(),
remaining,
b.clone());
let path = syntax::codemap::dummy_spanned(path);
ret.push(convert(&ast::ViewItemUse(P(path))));
}
}
ast::ViewPathSimple(ident, _, id) => {
match inline::try_inline(cx, id, Some(ident)) {
Some(items) => ret.extend(items.into_iter()),
None => ret.push(convert(&self.node)),
} }
} }
} }
} remaining
ref n => ret.push(convert(n)), } else {
} list.clean(cx)
};
if remaining.is_empty() {
return ret; return ret;
} }
(ret, ImportList(resolve_use_source(cx, p.clean(cx), self.id),
remaining))
} }
ast::ViewPathSimple(i, ref p) => {
#[derive(Clone, RustcEncodable, RustcDecodable)] if !denied {
pub enum ViewItemInner { match inline::try_inline(cx, self.id, Some(i)) {
ExternCrate(String, Option<String>, ast::NodeId), Some(items) => return items,
Import(ViewPath) None => {}
}
}
(vec![], SimpleImport(i.clean(cx),
resolve_use_source(cx, p.clean(cx), self.id)))
} }
impl Clean<ViewItemInner> for ast::ViewItem_ {
fn clean(&self, cx: &DocContext) -> ViewItemInner {
match self {
&ast::ViewItemExternCrate(ref i, ref p, ref id) => {
let string = match *p {
None => None,
Some((ref x, _)) => Some(x.get().to_string()),
}; };
ExternCrate(i.clean(cx), string, *id) ret.push(Item {
} name: None,
&ast::ViewItemUse(ref vp) => { attrs: self.attrs.clean(cx),
Import(vp.clean(cx)) source: self.whence.clean(cx),
} def_id: ast_util::local_def(0),
} visibility: self.vis.clean(cx),
stability: None,
inner: ImportItem(inner)
});
ret
} }
} }
#[derive(Clone, RustcEncodable, RustcDecodable)] #[derive(Clone, RustcEncodable, RustcDecodable)]
pub enum ViewPath { pub enum Import {
// use source as str; // use source as str;
SimpleImport(String, ImportSource), SimpleImport(String, ImportSource),
// use source::*; // use source::*;
@ -2225,21 +2207,6 @@ pub struct ImportSource {
pub did: Option<ast::DefId>, pub did: Option<ast::DefId>,
} }
impl Clean<ViewPath> for ast::ViewPath {
fn clean(&self, cx: &DocContext) -> ViewPath {
match self.node {
ast::ViewPathSimple(ref i, ref p, id) =>
SimpleImport(i.clean(cx), resolve_use_source(cx, p.clean(cx), id)),
ast::ViewPathGlob(ref p, id) =>
GlobImport(resolve_use_source(cx, p.clean(cx), id)),
ast::ViewPathList(ref p, ref pl, id) => {
ImportList(resolve_use_source(cx, p.clean(cx), id),
pl.clean(cx))
}
}
}
}
#[derive(Clone, RustcEncodable, RustcDecodable)] #[derive(Clone, RustcEncodable, RustcDecodable)]
pub struct ViewListIdent { pub struct ViewListIdent {
pub name: String, pub name: String,

View file

@ -25,6 +25,8 @@ pub struct Module {
pub attrs: Vec<ast::Attribute>, pub attrs: Vec<ast::Attribute>,
pub where_outer: Span, pub where_outer: Span,
pub where_inner: Span, pub where_inner: Span,
pub extern_crates: Vec<ExternCrate>,
pub imports: Vec<Import>,
pub structs: Vec<Struct>, pub structs: Vec<Struct>,
pub enums: Vec<Enum>, pub enums: Vec<Enum>,
pub fns: Vec<Function>, pub fns: Vec<Function>,
@ -38,7 +40,6 @@ pub struct Module {
pub stab: Option<attr::Stability>, pub stab: Option<attr::Stability>,
pub impls: Vec<Impl>, pub impls: Vec<Impl>,
pub foreigns: Vec<ast::ForeignMod>, pub foreigns: Vec<ast::ForeignMod>,
pub view_items: Vec<ast::ViewItem>,
pub macros: Vec<Macro>, pub macros: Vec<Macro>,
pub is_crate: bool, pub is_crate: bool,
} }
@ -53,6 +54,8 @@ impl Module {
where_outer: syntax::codemap::DUMMY_SP, where_outer: syntax::codemap::DUMMY_SP,
where_inner: syntax::codemap::DUMMY_SP, where_inner: syntax::codemap::DUMMY_SP,
attrs : Vec::new(), attrs : Vec::new(),
extern_crates: Vec::new(),
imports : Vec::new(),
structs : Vec::new(), structs : Vec::new(),
enums : Vec::new(), enums : Vec::new(),
fns : Vec::new(), fns : Vec::new(),
@ -62,7 +65,6 @@ impl Module {
constants : Vec::new(), constants : Vec::new(),
traits : Vec::new(), traits : Vec::new(),
impls : Vec::new(), impls : Vec::new(),
view_items : Vec::new(),
foreigns : Vec::new(), foreigns : Vec::new(),
macros : Vec::new(), macros : Vec::new(),
is_crate : false, is_crate : false,
@ -202,6 +204,22 @@ pub struct Macro {
pub stab: Option<attr::Stability>, pub stab: Option<attr::Stability>,
} }
pub struct ExternCrate {
pub name: Ident,
pub path: Option<String>,
pub vis: ast::Visibility,
pub attrs: Vec<ast::Attribute>,
pub whence: Span,
}
pub struct Import {
pub id: NodeId,
pub vis: ast::Visibility,
pub attrs: Vec<ast::Attribute>,
pub node: ast::ViewPath_,
pub whence: Span,
}
pub fn struct_type_from_def(sd: &ast::StructDef) -> StructType { pub fn struct_type_from_def(sd: &ast::StructDef) -> StructType {
if sd.ctor_id.is_some() { if sd.ctor_id.is_some() {
// We are in a tuple-struct // We are in a tuple-struct

View file

@ -617,7 +617,7 @@ impl fmt::String for UnsafetySpace {
} }
} }
impl fmt::String for clean::ViewPath { impl fmt::String for clean::Import {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { match *self {
clean::SimpleImport(ref name, ref src) => { clean::SimpleImport(ref name, ref src) => {

View file

@ -22,29 +22,31 @@ use clean;
#[derive(Copy, PartialEq, Clone)] #[derive(Copy, PartialEq, Clone)]
pub enum ItemType { pub enum ItemType {
Module = 0, Module = 0,
Struct = 1, ExternCrate = 1,
Enum = 2, Import = 2,
Function = 3, Struct = 3,
Typedef = 4, Enum = 4,
Static = 5, Function = 5,
Trait = 6, Typedef = 6,
Impl = 7, Static = 7,
ViewItem = 8, Trait = 8,
TyMethod = 9, Impl = 9,
Method = 10, TyMethod = 10,
StructField = 11, Method = 11,
Variant = 12, StructField = 12,
// we used to have ForeignFunction and ForeignStatic. they are retired now. Variant = 13,
Macro = 15, Macro = 14,
Primitive = 16, Primitive = 15,
AssociatedType = 17, AssociatedType = 16,
Constant = 18, Constant = 17,
} }
impl ItemType { impl ItemType {
pub fn from_item(item: &clean::Item) -> ItemType { pub fn from_item(item: &clean::Item) -> ItemType {
match item.inner { match item.inner {
clean::ModuleItem(..) => ItemType::Module, clean::ModuleItem(..) => ItemType::Module,
clean::ExternCrateItem(..) => ItemType::ExternCrate,
clean::ImportItem(..) => ItemType::Import,
clean::StructItem(..) => ItemType::Struct, clean::StructItem(..) => ItemType::Struct,
clean::EnumItem(..) => ItemType::Enum, clean::EnumItem(..) => ItemType::Enum,
clean::FunctionItem(..) => ItemType::Function, clean::FunctionItem(..) => ItemType::Function,
@ -53,7 +55,6 @@ impl ItemType {
clean::ConstantItem(..) => ItemType::Constant, clean::ConstantItem(..) => ItemType::Constant,
clean::TraitItem(..) => ItemType::Trait, clean::TraitItem(..) => ItemType::Trait,
clean::ImplItem(..) => ItemType::Impl, clean::ImplItem(..) => ItemType::Impl,
clean::ViewItemItem(..) => ItemType::ViewItem,
clean::TyMethodItem(..) => ItemType::TyMethod, clean::TyMethodItem(..) => ItemType::TyMethod,
clean::MethodItem(..) => ItemType::Method, clean::MethodItem(..) => ItemType::Method,
clean::StructFieldItem(..) => ItemType::StructField, clean::StructFieldItem(..) => ItemType::StructField,
@ -83,6 +84,8 @@ impl ItemType {
pub fn to_static_str(&self) -> &'static str { pub fn to_static_str(&self) -> &'static str {
match *self { match *self {
ItemType::Module => "mod", ItemType::Module => "mod",
ItemType::ExternCrate => "externcrate",
ItemType::Import => "import",
ItemType::Struct => "struct", ItemType::Struct => "struct",
ItemType::Enum => "enum", ItemType::Enum => "enum",
ItemType::Function => "fn", ItemType::Function => "fn",
@ -90,7 +93,6 @@ impl ItemType {
ItemType::Static => "static", ItemType::Static => "static",
ItemType::Trait => "trait", ItemType::Trait => "trait",
ItemType::Impl => "impl", ItemType::Impl => "impl",
ItemType::ViewItem => "viewitem",
ItemType::TyMethod => "tymethod", ItemType::TyMethod => "tymethod",
ItemType::Method => "method", ItemType::Method => "method",
ItemType::StructField => "structfield", ItemType::StructField => "structfield",

View file

@ -35,7 +35,7 @@
pub use self::ExternalLocation::*; pub use self::ExternalLocation::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::cmp::Ordering::{self, Less, Greater, Equal}; use std::cmp::Ordering;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::default::Default; use std::default::Default;
use std::fmt; use std::fmt;
@ -1497,18 +1497,19 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
// the order of item types in the listing // the order of item types in the listing
fn reorder(ty: ItemType) -> u8 { fn reorder(ty: ItemType) -> u8 {
match ty { match ty {
ItemType::ViewItem => 0, ItemType::ExternCrate => 0,
ItemType::Primitive => 1, ItemType::Import => 1,
ItemType::Module => 2, ItemType::Primitive => 2,
ItemType::Macro => 3, ItemType::Module => 3,
ItemType::Struct => 4, ItemType::Macro => 4,
ItemType::Enum => 5, ItemType::Struct => 5,
ItemType::Constant => 6, ItemType::Enum => 6,
ItemType::Static => 7, ItemType::Constant => 7,
ItemType::Trait => 8, ItemType::Static => 8,
ItemType::Function => 9, ItemType::Trait => 9,
ItemType::Typedef => 10, ItemType::Function => 10,
_ => 11 + ty as u8, ItemType::Typedef => 12,
_ => 13 + ty as u8,
} }
} }
@ -1518,25 +1519,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
if ty1 == ty2 { if ty1 == ty2 {
return i1.name.cmp(&i2.name); return i1.name.cmp(&i2.name);
} }
(reorder(ty1), idx1).cmp(&(reorder(ty2), idx2))
let tycmp = reorder(ty1).cmp(&reorder(ty2));
if let Equal = tycmp {
// for reexports, `extern crate` takes precedence.
match (&i1.inner, &i2.inner) {
(&clean::ViewItemItem(ref a), &clean::ViewItemItem(ref b)) => {
match (&a.inner, &b.inner) {
(&clean::ExternCrate(..), _) => return Less,
(_, &clean::ExternCrate(..)) => return Greater,
_ => {}
}
}
(_, _) => {}
}
idx1.cmp(&idx2)
} else {
tycmp
}
} }
indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2)); indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2));
@ -1547,12 +1530,17 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
let myitem = &items[idx]; let myitem = &items[idx];
let myty = Some(shortty(myitem)); let myty = Some(shortty(myitem));
if myty != curty { if curty == Some(ItemType::ExternCrate) && myty == Some(ItemType::Import) {
// Put `extern crate` and `use` re-exports in the same section.
curty = myty;
} else if myty != curty {
if curty.is_some() { if curty.is_some() {
try!(write!(w, "</table>")); try!(write!(w, "</table>"));
} }
curty = myty; curty = myty;
let (short, name) = match myty.unwrap() { let (short, name) = match myty.unwrap() {
ItemType::ExternCrate |
ItemType::Import => ("reexports", "Reexports"),
ItemType::Module => ("modules", "Modules"), ItemType::Module => ("modules", "Modules"),
ItemType::Struct => ("structs", "Structs"), ItemType::Struct => ("structs", "Structs"),
ItemType::Enum => ("enums", "Enums"), ItemType::Enum => ("enums", "Enums"),
@ -1562,7 +1550,6 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
ItemType::Constant => ("constants", "Constants"), ItemType::Constant => ("constants", "Constants"),
ItemType::Trait => ("traits", "Traits"), ItemType::Trait => ("traits", "Traits"),
ItemType::Impl => ("impls", "Implementations"), ItemType::Impl => ("impls", "Implementations"),
ItemType::ViewItem => ("reexports", "Reexports"),
ItemType::TyMethod => ("tymethods", "Type Methods"), ItemType::TyMethod => ("tymethods", "Type Methods"),
ItemType::Method => ("methods", "Methods"), ItemType::Method => ("methods", "Methods"),
ItemType::StructField => ("fields", "Struct Fields"), ItemType::StructField => ("fields", "Struct Fields"),
@ -1578,28 +1565,25 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
} }
match myitem.inner { match myitem.inner {
clean::ViewItemItem(ref item) => { clean::ExternCrateItem(ref name, ref src) => {
match item.inner {
clean::ExternCrate(ref name, ref src, _) => {
match *src { match *src {
Some(ref src) => Some(ref src) => {
try!(write!(w, "<tr><td><code>extern crate \"{}\" as {}", try!(write!(w, "<tr><td><code>{}extern crate \"{}\" as {};",
src.as_slice(),
name.as_slice())),
None =>
try!(write!(w, "<tr><td><code>extern crate {}",
name.as_slice())),
}
try!(write!(w, ";</code></td></tr>"));
}
clean::Import(ref import) => {
try!(write!(w, "<tr><td><code>{}{}</code></td></tr>",
VisSpace(myitem.visibility), VisSpace(myitem.visibility),
*import)); src.as_slice(),
name.as_slice()))
} }
None => {
try!(write!(w, "<tr><td><code>{}extern crate {};",
VisSpace(myitem.visibility), name.as_slice()))
}
}
try!(write!(w, "</code></td></tr>"));
} }
clean::ImportItem(ref import) => {
try!(write!(w, "<tr><td><code>{}{}</code></td></tr>",
VisSpace(myitem.visibility), *import));
} }
_ => { _ => {

View file

@ -245,7 +245,6 @@ nav.sub {
.content .highlighted.method { background-color: #c6afb3; } .content .highlighted.method { background-color: #c6afb3; }
.content .highlighted.tymethod { background-color: #c6afb3; } .content .highlighted.tymethod { background-color: #c6afb3; }
.content .highlighted.type { background-color: #c6afb3; } .content .highlighted.type { background-color: #c6afb3; }
.content .highlighted.ffi { background-color: #c6afb3; }
.docblock.short.nowrap { .docblock.short.nowrap {
display: block; display: block;
@ -365,7 +364,6 @@ p a:hover { text-decoration: underline; }
.content span.fn, .content a.fn, .block a.current.fn { color: #8c6067; } .content span.fn, .content a.fn, .block a.current.fn { color: #8c6067; }
.content span.method, .content a.method, .block a.current.method { color: #8c6067; } .content span.method, .content a.method, .block a.current.method { color: #8c6067; }
.content span.tymethod, .content a.tymethod, .block a.current.tymethod { color: #8c6067; } .content span.tymethod, .content a.tymethod, .block a.current.tymethod { color: #8c6067; }
.content span.ffi, .content a.ffi, .block a.current.ffi { color: #8c6067; }
.content .fnname { color: #8c6067; } .content .fnname { color: #8c6067; }
.search-input { .search-input {

View file

@ -555,6 +555,8 @@
// This mapping table should match the discriminants of // This mapping table should match the discriminants of
// `rustdoc::html::item_type::ItemType` type in Rust. // `rustdoc::html::item_type::ItemType` type in Rust.
var itemTypes = ["mod", var itemTypes = ["mod",
"externcrate",
"import",
"struct", "struct",
"enum", "enum",
"fn", "fn",
@ -562,13 +564,10 @@
"static", "static",
"trait", "trait",
"impl", "impl",
"viewitem",
"tymethod", "tymethod",
"method", "method",
"structfield", "structfield",
"variant", "variant",
"ffi", // retained for backward compatibility
"ffs", // retained for backward compatibility
"macro", "macro",
"primitive", "primitive",
"associatedtype", "associatedtype",

View file

@ -149,7 +149,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
} }
} }
clean::ViewItemItem(..) => { clean::ExternCrateItem(..) | clean::ImportItem(_) => {
if i.visibility != Some(ast::Public) { if i.visibility != Some(ast::Public) {
return None return None
} }

View file

@ -21,7 +21,7 @@ use syntax::ast::Public;
use clean::{Crate, Item, ModuleItem, Module, EnumItem, Enum}; use clean::{Crate, Item, ModuleItem, Module, EnumItem, Enum};
use clean::{ImplItem, Impl, Trait, TraitItem, TraitMethod, ProvidedMethod, RequiredMethod}; use clean::{ImplItem, Impl, Trait, TraitItem, TraitMethod, ProvidedMethod, RequiredMethod};
use clean::{TypeTraitItem, ViewItemItem, PrimitiveItem, Stability}; use clean::{TypeTraitItem, ExternCrateItem, ImportItem, PrimitiveItem, Stability};
use html::render::cache; use html::render::cache;
@ -199,7 +199,8 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
})) }))
} }
// no stability information for the following items: // no stability information for the following items:
ViewItemItem(_) | PrimitiveItem(_) => (Counts::zero(), None), ExternCrateItem(..) | ImportItem(_) |
PrimitiveItem(_) => (Counts::zero(), None),
_ => (item_counts, None) _ => (item_counts, None)
} }
} }

View file

@ -20,7 +20,6 @@ use syntax::ast_map;
use syntax::attr; use syntax::attr;
use syntax::attr::AttrMetaMethods; use syntax::attr::AttrMetaMethods;
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::ptr::P;
use rustc::middle::stability; use rustc::middle::stability;
@ -142,9 +141,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
m: &ast::Mod, m: &ast::Mod,
name: Option<ast::Ident>) -> Module { name: Option<ast::Ident>) -> Module {
let mut om = Module::new(name); let mut om = Module::new(name);
for item in m.view_items.iter() {
self.visit_view_item(item, &mut om);
}
om.where_outer = span; om.where_outer = span;
om.where_inner = m.inner; om.where_inner = m.inner;
om.attrs = attrs; om.attrs = attrs;
@ -157,68 +153,41 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
om om
} }
pub fn visit_view_item(&mut self, item: &ast::ViewItem, om: &mut Module) { fn visit_view_path(&mut self, path: ast::ViewPath_,
if item.vis != ast::Public {
return om.view_items.push(item.clone());
}
let please_inline = item.attrs.iter().any(|item| {
match item.meta_item_list() {
Some(list) => {
list.iter().any(|i| i.name().get() == "inline")
}
None => false,
}
});
let item = match item.node {
ast::ViewItemUse(ref vpath) => {
match self.visit_view_path(&**vpath, om, please_inline) {
None => return,
Some(path) => {
ast::ViewItem {
node: ast::ViewItemUse(path),
.. item.clone()
}
}
}
}
ast::ViewItemExternCrate(..) => item.clone()
};
om.view_items.push(item);
}
fn visit_view_path(&mut self, path: &ast::ViewPath,
om: &mut Module, om: &mut Module,
please_inline: bool) -> Option<P<ast::ViewPath>> { id: ast::NodeId,
match path.node { please_inline: bool) -> Option<ast::ViewPath_> {
ast::ViewPathSimple(dst, _, id) => { match path {
ast::ViewPathSimple(dst, base) => {
if self.resolve_id(id, Some(dst), false, om, please_inline) { if self.resolve_id(id, Some(dst), false, om, please_inline) {
return None None
} } else {
} Some(ast::ViewPathSimple(dst, base))
ast::ViewPathList(ref p, ref paths, ref b) => {
let mut mine = Vec::new();
for path in paths.iter() {
if !self.resolve_id(path.node.id(), None, false, om,
please_inline) {
mine.push(path.clone());
} }
} }
ast::ViewPathList(p, paths) => {
let mine = paths.into_iter().filter(|path| {
!self.resolve_id(path.node.id(), None, false, om,
please_inline)
}).collect::<Vec<ast::PathListItem>>();
if mine.len() == 0 { return None } if mine.len() == 0 {
return Some(P(::syntax::codemap::Spanned { None
node: ast::ViewPathList(p.clone(), mine, b.clone()), } else {
span: path.span, Some(ast::ViewPathList(p, mine))
})) }
} }
// these are feature gated anyway // these are feature gated anyway
ast::ViewPathGlob(_, id) => { ast::ViewPathGlob(base) => {
if self.resolve_id(id, None, true, om, please_inline) { if self.resolve_id(id, None, true, om, please_inline) {
return None None
} else {
Some(ast::ViewPathGlob(base))
} }
} }
} }
Some(P(path.clone()))
} }
fn resolve_id(&mut self, id: ast::NodeId, renamed: Option<ast::Ident>, fn resolve_id(&mut self, id: ast::NodeId, renamed: Option<ast::Ident>,
@ -242,9 +211,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
if glob { if glob {
match it.node { match it.node {
ast::ItemMod(ref m) => { ast::ItemMod(ref m) => {
for vi in m.view_items.iter() {
self.visit_view_item(vi, om);
}
for i in m.items.iter() { for i in m.items.iter() {
self.visit_item(&**i, None, om); self.visit_item(&**i, None, om);
} }
@ -268,6 +234,45 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
debug!("Visiting item {:?}", item); debug!("Visiting item {:?}", item);
let name = renamed.unwrap_or(item.ident); let name = renamed.unwrap_or(item.ident);
match item.node { match item.node {
ast::ItemExternCrate(ref p) => {
let path = match *p {
None => None,
Some((ref x, _)) => Some(x.get().to_string()),
};
om.extern_crates.push(ExternCrate {
name: name,
path: path,
vis: item.vis,
attrs: item.attrs.clone(),
whence: item.span,
})
}
ast::ItemUse(ref vpath) => {
let node = vpath.node.clone();
let node = if item.vis == ast::Public {
let please_inline = item.attrs.iter().any(|item| {
match item.meta_item_list() {
Some(list) => {
list.iter().any(|i| i.name().get() == "inline")
}
None => false,
}
});
match self.visit_view_path(node, om, item.id, please_inline) {
None => return,
Some(p) => p
}
} else {
node
};
om.imports.push(Import {
id: item.id,
vis: item.vis,
attrs: item.attrs.clone(),
node: node,
whence: item.span,
});
}
ast::ItemMod(ref m) => { ast::ItemMod(ref m) => {
om.mods.push(self.visit_mod_contents(item.span, om.mods.push(self.visit_mod_contents(item.span,
item.attrs.clone(), item.attrs.clone(),