rustdoc: Implement stripping based on privacy
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
This commit is contained in:
parent
acab4a8c8e
commit
c838351ba6
5 changed files with 91 additions and 5 deletions
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue