Skip to content

Commit 54151a6

Browse files
authored
Rollup merge of rust-lang#77897 - GuillaumeGomez:cleanup-passes-mod, r=jyn514
Move `Strip` into a separate rustdoc pass Just something which was bothering me lately. :) r? @jyn514
2 parents ed34f82 + 7beeb07 commit 54151a6

File tree

2 files changed

+176
-170
lines changed

2 files changed

+176
-170
lines changed

src/librustdoc/passes/mod.rs

+4-170
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
//! Contains information about "passes", used to modify crate information during the documentation
22
//! process.
33
4-
use rustc_hir::def_id::{DefId, DefIdSet};
5-
use rustc_middle::middle::privacy::AccessLevels;
64
use rustc_span::{InnerSpan, Span, DUMMY_SP};
7-
use std::mem;
85
use std::ops::Range;
96

107
use self::Condition::*;
11-
use crate::clean::{self, DocFragmentKind, GetDefId, Item};
8+
use crate::clean::{self, DocFragmentKind};
129
use crate::core::DocContext;
13-
use crate::fold::{DocFolder, StripItem};
10+
11+
mod stripper;
12+
pub use stripper::*;
1413

1514
mod collapse_docs;
1615
pub use self::collapse_docs::COLLAPSE_DOCS;
@@ -149,171 +148,6 @@ pub fn find_pass(pass_name: &str) -> Option<Pass> {
149148
PASSES.iter().find(|p| p.name == pass_name).copied()
150149
}
151150

152-
struct Stripper<'a> {
153-
retained: &'a mut DefIdSet,
154-
access_levels: &'a AccessLevels<DefId>,
155-
update_retained: bool,
156-
}
157-
158-
impl<'a> DocFolder for Stripper<'a> {
159-
fn fold_item(&mut self, i: Item) -> Option<Item> {
160-
match i.inner {
161-
clean::StrippedItem(..) => {
162-
// We need to recurse into stripped modules to strip things
163-
// like impl methods but when doing so we must not add any
164-
// items to the `retained` set.
165-
debug!("Stripper: recursing into stripped {:?} {:?}", i.type_(), i.name);
166-
let old = mem::replace(&mut self.update_retained, false);
167-
let ret = self.fold_item_recur(i);
168-
self.update_retained = old;
169-
return ret;
170-
}
171-
// These items can all get re-exported
172-
clean::OpaqueTyItem(..)
173-
| clean::TypedefItem(..)
174-
| clean::StaticItem(..)
175-
| clean::StructItem(..)
176-
| clean::EnumItem(..)
177-
| clean::TraitItem(..)
178-
| clean::FunctionItem(..)
179-
| clean::VariantItem(..)
180-
| clean::MethodItem(..)
181-
| clean::ForeignFunctionItem(..)
182-
| clean::ForeignStaticItem(..)
183-
| clean::ConstantItem(..)
184-
| clean::UnionItem(..)
185-
| clean::AssocConstItem(..)
186-
| clean::TraitAliasItem(..)
187-
| clean::ForeignTypeItem => {
188-
if i.def_id.is_local() {
189-
if !self.access_levels.is_exported(i.def_id) {
190-
debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name);
191-
return None;
192-
}
193-
}
194-
}
195-
196-
clean::StructFieldItem(..) => {
197-
if i.visibility != clean::Public {
198-
return StripItem(i).strip();
199-
}
200-
}
201-
202-
clean::ModuleItem(..) => {
203-
if i.def_id.is_local() && i.visibility != clean::Public {
204-
debug!("Stripper: stripping module {:?}", i.name);
205-
let old = mem::replace(&mut self.update_retained, false);
206-
let ret = StripItem(self.fold_item_recur(i).unwrap()).strip();
207-
self.update_retained = old;
208-
return ret;
209-
}
210-
}
211-
212-
// handled in the `strip-priv-imports` pass
213-
clean::ExternCrateItem(..) | clean::ImportItem(..) => {}
214-
215-
clean::ImplItem(..) => {}
216-
217-
// tymethods/macros have no control over privacy
218-
clean::MacroItem(..) | clean::TyMethodItem(..) => {}
219-
220-
// Proc-macros are always public
221-
clean::ProcMacroItem(..) => {}
222-
223-
// Primitives are never stripped
224-
clean::PrimitiveItem(..) => {}
225-
226-
// Associated types are never stripped
227-
clean::AssocTypeItem(..) => {}
228-
229-
// Keywords are never stripped
230-
clean::KeywordItem(..) => {}
231-
}
232-
233-
let fastreturn = match i.inner {
234-
// nothing left to do for traits (don't want to filter their
235-
// methods out, visibility controlled by the trait)
236-
clean::TraitItem(..) => true,
237-
238-
// implementations of traits are always public.
239-
clean::ImplItem(ref imp) if imp.trait_.is_some() => true,
240-
// Struct variant fields have inherited visibility
241-
clean::VariantItem(clean::Variant { kind: clean::VariantKind::Struct(..) }) => true,
242-
_ => false,
243-
};
244-
245-
let i = if fastreturn {
246-
if self.update_retained {
247-
self.retained.insert(i.def_id);
248-
}
249-
return Some(i);
250-
} else {
251-
self.fold_item_recur(i)
252-
};
253-
254-
if let Some(ref i) = i {
255-
if self.update_retained {
256-
self.retained.insert(i.def_id);
257-
}
258-
}
259-
i
260-
}
261-
}
262-
263-
// This stripper discards all impls which reference stripped items
264-
struct ImplStripper<'a> {
265-
retained: &'a DefIdSet,
266-
}
267-
268-
impl<'a> DocFolder for ImplStripper<'a> {
269-
fn fold_item(&mut self, i: Item) -> Option<Item> {
270-
if let clean::ImplItem(ref imp) = i.inner {
271-
// emptied none trait impls can be stripped
272-
if imp.trait_.is_none() && imp.items.is_empty() {
273-
return None;
274-
}
275-
if let Some(did) = imp.for_.def_id() {
276-
if did.is_local() && !imp.for_.is_generic() && !self.retained.contains(&did) {
277-
debug!("ImplStripper: impl item for stripped type; removing");
278-
return None;
279-
}
280-
}
281-
if let Some(did) = imp.trait_.def_id() {
282-
if did.is_local() && !self.retained.contains(&did) {
283-
debug!("ImplStripper: impl item for stripped trait; removing");
284-
return None;
285-
}
286-
}
287-
if let Some(generics) = imp.trait_.as_ref().and_then(|t| t.generics()) {
288-
for typaram in generics {
289-
if let Some(did) = typaram.def_id() {
290-
if did.is_local() && !self.retained.contains(&did) {
291-
debug!(
292-
"ImplStripper: stripped item in trait's generics; removing impl"
293-
);
294-
return None;
295-
}
296-
}
297-
}
298-
}
299-
}
300-
self.fold_item_recur(i)
301-
}
302-
}
303-
304-
// This stripper discards all private import statements (`use`, `extern crate`)
305-
struct ImportStripper;
306-
impl DocFolder for ImportStripper {
307-
fn fold_item(&mut self, i: Item) -> Option<Item> {
308-
match i.inner {
309-
clean::ExternCrateItem(..) | clean::ImportItem(..) if i.visibility != clean::Public => {
310-
None
311-
}
312-
_ => self.fold_item_recur(i),
313-
}
314-
}
315-
}
316-
317151
/// Returns a span encompassing all the given attributes.
318152
crate fn span_of_attrs(attrs: &clean::Attributes) -> Option<Span> {
319153
if attrs.doc_strings.is_empty() {

src/librustdoc/passes/stripper.rs

+172
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
use rustc_hir::def_id::{DefId, DefIdSet};
2+
use rustc_middle::middle::privacy::AccessLevels;
3+
use std::mem;
4+
5+
use crate::clean::{self, GetDefId, Item};
6+
use crate::fold::{DocFolder, StripItem};
7+
8+
pub struct Stripper<'a> {
9+
pub retained: &'a mut DefIdSet,
10+
pub access_levels: &'a AccessLevels<DefId>,
11+
pub update_retained: bool,
12+
}
13+
14+
impl<'a> DocFolder for Stripper<'a> {
15+
fn fold_item(&mut self, i: Item) -> Option<Item> {
16+
match i.inner {
17+
clean::StrippedItem(..) => {
18+
// We need to recurse into stripped modules to strip things
19+
// like impl methods but when doing so we must not add any
20+
// items to the `retained` set.
21+
debug!("Stripper: recursing into stripped {:?} {:?}", i.type_(), i.name);
22+
let old = mem::replace(&mut self.update_retained, false);
23+
let ret = self.fold_item_recur(i);
24+
self.update_retained = old;
25+
return ret;
26+
}
27+
// These items can all get re-exported
28+
clean::OpaqueTyItem(..)
29+
| clean::TypedefItem(..)
30+
| clean::StaticItem(..)
31+
| clean::StructItem(..)
32+
| clean::EnumItem(..)
33+
| clean::TraitItem(..)
34+
| clean::FunctionItem(..)
35+
| clean::VariantItem(..)
36+
| clean::MethodItem(..)
37+
| clean::ForeignFunctionItem(..)
38+
| clean::ForeignStaticItem(..)
39+
| clean::ConstantItem(..)
40+
| clean::UnionItem(..)
41+
| clean::AssocConstItem(..)
42+
| clean::TraitAliasItem(..)
43+
| clean::ForeignTypeItem => {
44+
if i.def_id.is_local() {
45+
if !self.access_levels.is_exported(i.def_id) {
46+
debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name);
47+
return None;
48+
}
49+
}
50+
}
51+
52+
clean::StructFieldItem(..) => {
53+
if i.visibility != clean::Public {
54+
return StripItem(i).strip();
55+
}
56+
}
57+
58+
clean::ModuleItem(..) => {
59+
if i.def_id.is_local() && i.visibility != clean::Public {
60+
debug!("Stripper: stripping module {:?}", i.name);
61+
let old = mem::replace(&mut self.update_retained, false);
62+
let ret = StripItem(self.fold_item_recur(i).unwrap()).strip();
63+
self.update_retained = old;
64+
return ret;
65+
}
66+
}
67+
68+
// handled in the `strip-priv-imports` pass
69+
clean::ExternCrateItem(..) | clean::ImportItem(..) => {}
70+
71+
clean::ImplItem(..) => {}
72+
73+
// tymethods/macros have no control over privacy
74+
clean::MacroItem(..) | clean::TyMethodItem(..) => {}
75+
76+
// Proc-macros are always public
77+
clean::ProcMacroItem(..) => {}
78+
79+
// Primitives are never stripped
80+
clean::PrimitiveItem(..) => {}
81+
82+
// Associated types are never stripped
83+
clean::AssocTypeItem(..) => {}
84+
85+
// Keywords are never stripped
86+
clean::KeywordItem(..) => {}
87+
}
88+
89+
let fastreturn = match i.inner {
90+
// nothing left to do for traits (don't want to filter their
91+
// methods out, visibility controlled by the trait)
92+
clean::TraitItem(..) => true,
93+
94+
// implementations of traits are always public.
95+
clean::ImplItem(ref imp) if imp.trait_.is_some() => true,
96+
// Struct variant fields have inherited visibility
97+
clean::VariantItem(clean::Variant { kind: clean::VariantKind::Struct(..) }) => true,
98+
_ => false,
99+
};
100+
101+
let i = if fastreturn {
102+
if self.update_retained {
103+
self.retained.insert(i.def_id);
104+
}
105+
return Some(i);
106+
} else {
107+
self.fold_item_recur(i)
108+
};
109+
110+
if let Some(ref i) = i {
111+
if self.update_retained {
112+
self.retained.insert(i.def_id);
113+
}
114+
}
115+
i
116+
}
117+
}
118+
119+
/// This stripper discards all impls which reference stripped items
120+
pub struct ImplStripper<'a> {
121+
pub retained: &'a DefIdSet,
122+
}
123+
124+
impl<'a> DocFolder for ImplStripper<'a> {
125+
fn fold_item(&mut self, i: Item) -> Option<Item> {
126+
if let clean::ImplItem(ref imp) = i.inner {
127+
// emptied none trait impls can be stripped
128+
if imp.trait_.is_none() && imp.items.is_empty() {
129+
return None;
130+
}
131+
if let Some(did) = imp.for_.def_id() {
132+
if did.is_local() && !imp.for_.is_generic() && !self.retained.contains(&did) {
133+
debug!("ImplStripper: impl item for stripped type; removing");
134+
return None;
135+
}
136+
}
137+
if let Some(did) = imp.trait_.def_id() {
138+
if did.is_local() && !self.retained.contains(&did) {
139+
debug!("ImplStripper: impl item for stripped trait; removing");
140+
return None;
141+
}
142+
}
143+
if let Some(generics) = imp.trait_.as_ref().and_then(|t| t.generics()) {
144+
for typaram in generics {
145+
if let Some(did) = typaram.def_id() {
146+
if did.is_local() && !self.retained.contains(&did) {
147+
debug!(
148+
"ImplStripper: stripped item in trait's generics; removing impl"
149+
);
150+
return None;
151+
}
152+
}
153+
}
154+
}
155+
}
156+
self.fold_item_recur(i)
157+
}
158+
}
159+
160+
/// This stripper discards all private import statements (`use`, `extern crate`)
161+
pub struct ImportStripper;
162+
163+
impl DocFolder for ImportStripper {
164+
fn fold_item(&mut self, i: Item) -> Option<Item> {
165+
match i.inner {
166+
clean::ExternCrateItem(..) | clean::ImportItem(..) if i.visibility != clean::Public => {
167+
None
168+
}
169+
_ => self.fold_item_recur(i),
170+
}
171+
}
172+
}

0 commit comments

Comments
 (0)