Skip to content

Commit b1543a1

Browse files
committed
Make the rendering process less pass-aware
Instead of hardcoding knowledge about the strip-private pass into the rendering process we represent (some) stripped items as `ItemEnum::StrippedItem`. Rustdoc will, for example, generate redirect pages for public items contained in private modules which have been re-exported to somewhere externally reachable - this will now not only work for the `strip-private` pass, but for other passes as well, such as the `strip-hidden` pass.
1 parent 4583dc9 commit b1543a1

File tree

8 files changed

+244
-146
lines changed

8 files changed

+244
-146
lines changed

src/librustdoc/clean/mod.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ use std::env::current_dir;
5353
use core::DocContext;
5454
use doctree;
5555
use visit_ast;
56+
use html::item_type::ItemType;
5657

5758
/// A stable identifier to the particular version of JSON output.
5859
/// Increment this when the `Crate` and related structures change.
@@ -273,36 +274,40 @@ impl Item {
273274
}
274275
pub fn is_crate(&self) -> bool {
275276
match self.inner {
276-
ModuleItem(Module { items: _, is_crate: true }) => true,
277-
_ => false
277+
StrippedItem(box ModuleItem(Module { is_crate: true, ..})) |
278+
ModuleItem(Module { is_crate: true, ..}) => true,
279+
_ => false,
278280
}
279281
}
280282
pub fn is_mod(&self) -> bool {
281-
match self.inner { ModuleItem(..) => true, _ => false }
283+
ItemType::from_item(self) == ItemType::Module
282284
}
283285
pub fn is_trait(&self) -> bool {
284-
match self.inner { TraitItem(..) => true, _ => false }
286+
ItemType::from_item(self) == ItemType::Trait
285287
}
286288
pub fn is_struct(&self) -> bool {
287-
match self.inner { StructItem(..) => true, _ => false }
289+
ItemType::from_item(self) == ItemType::Struct
288290
}
289291
pub fn is_enum(&self) -> bool {
290-
match self.inner { EnumItem(..) => true, _ => false }
292+
ItemType::from_item(self) == ItemType::Module
291293
}
292294
pub fn is_fn(&self) -> bool {
293-
match self.inner { FunctionItem(..) => true, _ => false }
295+
ItemType::from_item(self) == ItemType::Function
294296
}
295297
pub fn is_associated_type(&self) -> bool {
296-
match self.inner { AssociatedTypeItem(..) => true, _ => false }
298+
ItemType::from_item(self) == ItemType::AssociatedType
297299
}
298300
pub fn is_associated_const(&self) -> bool {
299-
match self.inner { AssociatedConstItem(..) => true, _ => false }
301+
ItemType::from_item(self) == ItemType::AssociatedConst
300302
}
301303
pub fn is_method(&self) -> bool {
302-
match self.inner { MethodItem(..) => true, _ => false }
304+
ItemType::from_item(self) == ItemType::Method
303305
}
304306
pub fn is_ty_method(&self) -> bool {
305-
match self.inner { TyMethodItem(..) => true, _ => false }
307+
ItemType::from_item(self) == ItemType::TyMethod
308+
}
309+
pub fn is_stripped(&self) -> bool {
310+
match self.inner { StrippedItem(..) => true, _ => false }
306311
}
307312

308313
pub fn stability_class(&self) -> String {
@@ -352,6 +357,8 @@ pub enum ItemEnum {
352357
AssociatedConstItem(Type, Option<String>),
353358
AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
354359
DefaultImplItem(DefaultImpl),
360+
/// An item that has been stripped by a rustdoc pass
361+
StrippedItem(Box<ItemEnum>),
355362
}
356363

357364
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]

src/librustdoc/fold.rs

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,50 @@
1010

1111
use clean::*;
1212

13+
pub enum FoldItem {
14+
Retain(Item),
15+
Strip(Item),
16+
Erase,
17+
}
18+
19+
impl FoldItem {
20+
pub fn fold(self) -> Option<Item> {
21+
match self {
22+
FoldItem::Erase => None,
23+
FoldItem::Retain(i) => Some(i),
24+
FoldItem::Strip(item@ Item { inner: StrippedItem(..), .. } ) => Some(item),
25+
FoldItem::Strip(mut i) => {
26+
i.inner = StrippedItem(box i.inner);
27+
Some(i)
28+
}
29+
}
30+
}
31+
}
32+
1333
pub trait DocFolder : Sized {
1434
fn fold_item(&mut self, item: Item) -> Option<Item> {
1535
self.fold_item_recur(item)
1636
}
1737

1838
/// don't override!
19-
fn fold_item_recur(&mut self, item: Item) -> Option<Item> {
20-
let Item { attrs, name, source, visibility, def_id, inner, stability, deprecation } = item;
21-
let inner = match inner {
39+
fn fold_inner_recur(&mut self, inner: ItemEnum) -> ItemEnum {
40+
match inner {
41+
StrippedItem(..) => unreachable!(),
42+
ModuleItem(i) => {
43+
ModuleItem(self.fold_mod(i))
44+
},
2245
StructItem(mut i) => {
2346
let num_fields = i.fields.len();
2447
i.fields = i.fields.into_iter().filter_map(|x| self.fold_item(x)).collect();
25-
i.fields_stripped |= num_fields != i.fields.len();
48+
i.fields_stripped |= num_fields != i.fields.len() ||
49+
i.fields.iter().any(|f| f.is_stripped());
2650
StructItem(i)
2751
},
28-
ModuleItem(i) => {
29-
ModuleItem(self.fold_mod(i))
30-
},
3152
EnumItem(mut i) => {
3253
let num_variants = i.variants.len();
3354
i.variants = i.variants.into_iter().filter_map(|x| self.fold_item(x)).collect();
34-
i.variants_stripped |= num_variants != i.variants.len();
55+
i.variants_stripped |= num_variants != i.variants.len() ||
56+
i.variants.iter().any(|f| f.is_stripped());
3557
EnumItem(i)
3658
},
3759
TraitItem(mut i) => {
@@ -48,13 +70,24 @@ pub trait DocFolder : Sized {
4870
StructVariant(mut j) => {
4971
let num_fields = j.fields.len();
5072
j.fields = j.fields.into_iter().filter_map(|x| self.fold_item(x)).collect();
51-
j.fields_stripped |= num_fields != j.fields.len();
73+
j.fields_stripped |= num_fields != j.fields.len() ||
74+
j.fields.iter().any(|f| f.is_stripped());
5275
VariantItem(Variant {kind: StructVariant(j), ..i2})
5376
},
5477
_ => VariantItem(i2)
5578
}
5679
},
5780
x => x
81+
}
82+
}
83+
84+
/// don't override!
85+
fn fold_item_recur(&mut self, item: Item) -> Option<Item> {
86+
let Item { attrs, name, source, visibility, def_id, inner, stability, deprecation } = item;
87+
88+
let inner = match inner {
89+
StrippedItem(box i) => StrippedItem(box self.fold_inner_recur(i)),
90+
_ => self.fold_inner_recur(inner),
5891
};
5992

6093
Some(Item { attrs: attrs, name: name, source: source, inner: inner,
@@ -70,9 +103,8 @@ pub trait DocFolder : Sized {
70103
}
71104

72105
fn fold_crate(&mut self, mut c: Crate) -> Crate {
73-
c.module = c.module.and_then(|module| {
74-
self.fold_item(module)
75-
});
106+
c.module = c.module.and_then(|module| self.fold_item(module));
107+
76108
c.external_traits = c.external_traits.into_iter().map(|(k, mut v)| {
77109
v.items = v.items.into_iter().filter_map(|i| self.fold_item(i)).collect();
78110
(k, v)

src/librustdoc/html/item_type.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,12 @@ pub enum ItemType {
4444

4545
impl ItemType {
4646
pub fn from_item(item: &clean::Item) -> ItemType {
47-
match item.inner {
47+
let inner = match item.inner {
48+
clean::StrippedItem(box ref item) => item,
49+
ref inner@_ => inner,
50+
};
51+
52+
match *inner {
4853
clean::ModuleItem(..) => ItemType::Module,
4954
clean::ExternCrateItem(..) => ItemType::ExternCrate,
5055
clean::ImportItem(..) => ItemType::Import,
@@ -67,6 +72,7 @@ impl ItemType {
6772
clean::AssociatedConstItem(..) => ItemType::AssociatedConst,
6873
clean::AssociatedTypeItem(..) => ItemType::AssociatedType,
6974
clean::DefaultImplItem(..) => ItemType::Impl,
75+
clean::StrippedItem(..) => unreachable!(),
7076
}
7177
}
7278

0 commit comments

Comments
 (0)