about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustdoc/clean.rs3
-rw-r--r--src/librustdoc/html/format.rs1
-rw-r--r--src/librustdoc/html/render.rs17
-rw-r--r--src/librustdoc/passes.rs72
-rw-r--r--src/librustdoc/rustdoc.rs3
5 files changed, 91 insertions, 5 deletions
diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs
index 0b5c0b8da95..8cbe1eed55a 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<Item> 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 75d6cb588e8..6f05b042dba 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 69c01cf8a45..070c0e5d986 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 5c89dfb974d..8376fa52882 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<Item> {
+            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 69092618da2..dd52058be8a 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)