Skip to content

Commit

Permalink
rustdoc: Implement stripping based on privacy
Browse files Browse the repository at this point in the history
This will probably need to get tweaked once the privacy rules have been fully
agreed on, but for now this has all of the infrastructure necessary for
filtering out private items.

Closes #9410
  • Loading branch information
alexcrichton committed Sep 25, 2013
1 parent acab4a8 commit c838351
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/librustdoc/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(),
Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
17 changes: 13 additions & 4 deletions src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 {
Expand Down
72 changes: 72 additions & 0 deletions src/librustdoc/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
3 changes: 3 additions & 0 deletions src/librustdoc/rustdoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit c838351

Please sign in to comment.