Skip to content

Commit c838351

Browse files
committed
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
1 parent acab4a8 commit c838351

File tree

5 files changed

+91
-5
lines changed

5 files changed

+91
-5
lines changed

src/librustdoc/clean.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use its = syntax::parse::token::ident_to_str;
1515

1616
use syntax;
1717
use syntax::ast;
18+
use syntax::ast_util;
1819
use syntax::attr::AttributeMethods;
1920

2021
use std;
@@ -283,7 +284,7 @@ impl Clean<Item> for ast::method {
283284
attrs: self.attrs.clean(),
284285
source: self.span.clean(),
285286
id: self.self_id.clone(),
286-
visibility: None,
287+
visibility: self.vis.clean(),
287288
inner: MethodItem(Method {
288289
generics: self.generics.clean(),
289290
self_: self.explicit_self.clean(),

src/librustdoc/html/format.rs

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use std::local_data;
1313
use std::rt::io;
1414

1515
use syntax::ast;
16+
use syntax::ast_util;
1617

1718
use clean;
1819
use html::render::{cache_key, current_location_key};

src/librustdoc/html/render.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -615,13 +615,21 @@ fn document(w: &mut io::Writer, item: &clean::Item) {
615615
fn item_module(w: &mut io::Writer, cx: &Context,
616616
item: &clean::Item, items: &[clean::Item]) {
617617
document(w, item);
618+
debug2!("{:?}", items);
618619
let mut indices = vec::from_fn(items.len(), |i| i);
619620

620-
fn lt(i1: &clean::Item, i2: &clean::Item) -> bool {
621+
fn lt(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> bool {
621622
if shortty(i1) == shortty(i2) {
622623
return i1.name < i2.name;
623624
}
624625
match (&i1.inner, &i2.inner) {
626+
(&clean::ViewItemItem(ref a), &clean::ViewItemItem(ref b)) => {
627+
match (&a.inner, &b.inner) {
628+
(&clean::ExternMod(*), _) => true,
629+
(_, &clean::ExternMod(*)) => false,
630+
_ => idx1 < idx2,
631+
}
632+
}
625633
(&clean::ViewItemItem(*), _) => true,
626634
(_, &clean::ViewItemItem(*)) => false,
627635
(&clean::ModuleItem(*), _) => true,
@@ -638,18 +646,19 @@ fn item_module(w: &mut io::Writer, cx: &Context,
638646
(_, &clean::FunctionItem(*)) => false,
639647
(&clean::TypedefItem(*), _) => true,
640648
(_, &clean::TypedefItem(*)) => false,
641-
_ => false,
649+
_ => idx1 < idx2,
642650
}
643651
}
644652

653+
debug2!("{:?}", indices);
645654
do sort::quick_sort(indices) |&i1, &i2| {
646-
lt(&items[i1], &items[i2])
655+
lt(&items[i1], &items[i2], i1, i2)
647656
}
648657

658+
debug2!("{:?}", indices);
649659
let mut curty = "";
650660
for &idx in indices.iter() {
651661
let myitem = &items[idx];
652-
if myitem.name.is_none() { loop }
653662

654663
let myty = shortty(myitem);
655664
if myty != curty {

src/librustdoc/passes.rs

+72
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,78 @@ pub fn strip_hidden(crate: clean::Crate) -> plugins::PluginResult {
4646
(crate, None)
4747
}
4848

49+
/// Strip private items from the point of view of a crate or externally from a
50+
/// crate, specified by the `xcrate` flag.
51+
pub fn strip_private(crate: clean::Crate) -> plugins::PluginResult {
52+
struct Stripper;
53+
impl fold::DocFolder for Stripper {
54+
fn fold_item(&mut self, i: Item) -> Option<Item> {
55+
match i.inner {
56+
// These items can all get re-exported
57+
clean::TypedefItem(*) | clean::StaticItem(*) |
58+
clean::StructItem(*) | clean::EnumItem(*) |
59+
clean::TraitItem(*) | clean::FunctionItem(*) |
60+
clean::ViewItemItem(*) | clean::MethodItem(*) => {
61+
// XXX: re-exported items should get surfaced in the docs as
62+
// well (using the output of resolve analysis)
63+
if i.visibility != Some(ast::public) {
64+
return None;
65+
}
66+
}
67+
68+
// These are public-by-default (if the enum was public)
69+
clean::VariantItem(*) => {
70+
if i.visibility == Some(ast::private) {
71+
return None;
72+
}
73+
}
74+
75+
// We show these regardless of whether they're public/private
76+
// because it's useful to see sometimes
77+
clean::StructFieldItem(*) => {}
78+
79+
// handled below
80+
clean::ModuleItem(*) => {}
81+
82+
// impls/tymethods have no control over privacy
83+
clean::ImplItem(*) | clean::TyMethodItem(*) => {}
84+
}
85+
86+
let fastreturn = match i.inner {
87+
// nothing left to do for traits (don't want to filter their
88+
// methods out, visibility controlled by the trait)
89+
clean::TraitItem(*) => true,
90+
91+
// implementations of traits are always public.
92+
clean::ImplItem(ref imp) if imp.trait_.is_some() => true,
93+
94+
_ => false,
95+
};
96+
97+
let i = if fastreturn {
98+
return Some(i);
99+
} else {
100+
self.fold_item_recur(i)
101+
};
102+
103+
match i {
104+
Some(i) => {
105+
match i.inner {
106+
// emptied modules/impls have no need to exist
107+
clean::ModuleItem(ref m) if m.items.len() == 0 => None,
108+
clean::ImplItem(ref i) if i.methods.len() == 0 => None,
109+
_ => Some(i),
110+
}
111+
}
112+
None => None,
113+
}
114+
}
115+
}
116+
let mut stripper = Stripper;
117+
let crate = stripper.fold_crate(crate);
118+
(crate, None)
119+
}
120+
49121
pub fn unindent_comments(crate: clean::Crate) -> plugins::PluginResult {
50122
struct CommentCleaner;
51123
impl fold::DocFolder for CommentCleaner {

src/librustdoc/rustdoc.rs

+3
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,14 @@ static PASSES: &'static [Pass] = &[
5656
"removes excess indentation on comments in order for markdown to like it"),
5757
("collapse-docs", passes::collapse_docs,
5858
"concatenates all document attributes into one document attribute"),
59+
("strip-private", passes::strip_private,
60+
"strips all private items from a crate which cannot be seen externally"),
5961
];
6062

6163
static DEFAULT_PASSES: &'static [&'static str] = &[
6264
"unindent-comments",
6365
"collapse-docs",
66+
"strip-private",
6467
];
6568

6669
local_data_key!(pub ctxtkey: @core::DocContext)

0 commit comments

Comments
 (0)