提交 c838351b 编写于 作者: A Alex Crichton

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
上级 acab4a8c
......@@ -15,6 +15,7 @@
use syntax;
use syntax::ast;
use syntax::ast_util;
use syntax::attr::AttributeMethods;
use std;
......@@ -283,7 +284,7 @@ fn clean(&self) -> Item {
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::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 lt(i1: &clean::Item, i2: &clean::Item) -> bool {
(_, &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 @@ fn fold_item(&mut self, i: Item) -> Option<Item> {
(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 @@ pub mod html {
"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)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册