diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs index 0b5c0b8da95b8..8cbe1eed55af4 100644 --- a/src/librustdoc/clean.rs +++ b/src/librustdoc/clean.rs @@ -15,6 +15,7 @@ use its = syntax::parse::token::ident_to_str; use syntax; use syntax::ast; +use syntax::ast_util; use syntax::attr::AttributeMethods; use std; @@ -283,7 +284,7 @@ impl Clean for ast::method { attrs: self.attrs.clean(), source: self.span.clean(), id: self.self_id.clone(), - visibility: None, + visibility: self.vis.clean(), inner: MethodItem(Method { generics: self.generics.clean(), self_: self.explicit_self.clean(), diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 75d6cb588e8ec..6f05b042dba1c 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -13,6 +13,7 @@ use std::local_data; use std::rt::io; use syntax::ast; +use syntax::ast_util; use clean; use html::render::{cache_key, current_location_key}; diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 69c01cf8a45a2..070c0e5d98642 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -615,13 +615,21 @@ fn document(w: &mut io::Writer, item: &clean::Item) { fn item_module(w: &mut io::Writer, cx: &Context, item: &clean::Item, items: &[clean::Item]) { document(w, item); + debug2!("{:?}", items); let mut indices = vec::from_fn(items.len(), |i| i); - fn lt(i1: &clean::Item, i2: &clean::Item) -> bool { + fn lt(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> bool { if shortty(i1) == shortty(i2) { return i1.name < i2.name; } match (&i1.inner, &i2.inner) { + (&clean::ViewItemItem(ref a), &clean::ViewItemItem(ref b)) => { + match (&a.inner, &b.inner) { + (&clean::ExternMod(*), _) => true, + (_, &clean::ExternMod(*)) => false, + _ => idx1 < idx2, + } + } (&clean::ViewItemItem(*), _) => true, (_, &clean::ViewItemItem(*)) => false, (&clean::ModuleItem(*), _) => true, @@ -638,18 +646,19 @@ fn item_module(w: &mut io::Writer, cx: &Context, (_, &clean::FunctionItem(*)) => false, (&clean::TypedefItem(*), _) => true, (_, &clean::TypedefItem(*)) => false, - _ => false, + _ => idx1 < idx2, } } + debug2!("{:?}", indices); do sort::quick_sort(indices) |&i1, &i2| { - lt(&items[i1], &items[i2]) + lt(&items[i1], &items[i2], i1, i2) } + debug2!("{:?}", indices); let mut curty = ""; for &idx in indices.iter() { let myitem = &items[idx]; - if myitem.name.is_none() { loop } let myty = shortty(myitem); if myty != curty { diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs index 5c89dfb974da2..8376fa52882ad 100644 --- a/src/librustdoc/passes.rs +++ b/src/librustdoc/passes.rs @@ -46,6 +46,78 @@ pub fn strip_hidden(crate: clean::Crate) -> plugins::PluginResult { (crate, None) } +/// 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 { + fn fold_item(&mut self, i: Item) -> Option { + match i.inner { + // These items can all get re-exported + clean::TypedefItem(*) | clean::StaticItem(*) | + clean::StructItem(*) | clean::EnumItem(*) | + clean::TraitItem(*) | clean::FunctionItem(*) | + clean::ViewItemItem(*) | clean::MethodItem(*) => { + // XXX: re-exported items should get surfaced in the docs as + // well (using the output of resolve analysis) + if i.visibility != Some(ast::public) { + return None; + } + } + + // These are public-by-default (if the enum was public) + clean::VariantItem(*) => { + if i.visibility == Some(ast::private) { + return None; + } + } + + // We show these regardless of whether they're public/private + // because it's useful to see sometimes + clean::StructFieldItem(*) => {} + + // handled below + clean::ModuleItem(*) => {} + + // impls/tymethods have no control over privacy + clean::ImplItem(*) | clean::TyMethodItem(*) => {} + } + + let fastreturn = match i.inner { + // nothing left to do for traits (don't want to filter their + // methods out, visibility controlled by the trait) + clean::TraitItem(*) => true, + + // implementations of traits are always public. + clean::ImplItem(ref imp) if imp.trait_.is_some() => true, + + _ => false, + }; + + let i = if fastreturn { + return Some(i); + } else { + self.fold_item_recur(i) + }; + + match i { + Some(i) => { + match i.inner { + // 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), + } + } + None => None, + } + } + } + let mut stripper = Stripper; + let crate = stripper.fold_crate(crate); + (crate, None) +} + pub fn unindent_comments(crate: clean::Crate) -> plugins::PluginResult { struct CommentCleaner; impl fold::DocFolder for CommentCleaner { diff --git a/src/librustdoc/rustdoc.rs b/src/librustdoc/rustdoc.rs index 69092618da20c..dd52058be8ac4 100644 --- a/src/librustdoc/rustdoc.rs +++ b/src/librustdoc/rustdoc.rs @@ -56,11 +56,14 @@ static PASSES: &'static [Pass] = &[ "removes excess indentation on comments in order for markdown to like it"), ("collapse-docs", passes::collapse_docs, "concatenates all document attributes into one document attribute"), + ("strip-private", passes::strip_private, + "strips all private items from a crate which cannot be seen externally"), ]; static DEFAULT_PASSES: &'static [&'static str] = &[ "unindent-comments", "collapse-docs", + "strip-private", ]; local_data_key!(pub ctxtkey: @core::DocContext)