]>
Commit | Line | Data |
---|---|---|
29967ef6 XL |
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 | ||
fc512014 XL |
8 | crate struct Stripper<'a> { |
9 | crate retained: &'a mut DefIdSet, | |
10 | crate access_levels: &'a AccessLevels<DefId>, | |
11 | crate update_retained: bool, | |
29967ef6 XL |
12 | } |
13 | ||
14 | impl<'a> DocFolder for Stripper<'a> { | |
15 | fn fold_item(&mut self, i: Item) -> Option<Item> { | |
5869c6ff | 16 | match *i.kind { |
29967ef6 XL |
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; | |
fc512014 | 25 | return Some(ret); |
29967ef6 XL |
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(..) => { | |
fc512014 | 53 | if !i.visibility.is_public() { |
5869c6ff | 54 | return Some(StripItem(i).strip()); |
29967ef6 XL |
55 | } |
56 | } | |
57 | ||
58 | clean::ModuleItem(..) => { | |
fc512014 | 59 | if i.def_id.is_local() && !i.visibility.is_public() { |
29967ef6 XL |
60 | debug!("Stripper: stripping module {:?}", i.name); |
61 | let old = mem::replace(&mut self.update_retained, false); | |
fc512014 | 62 | let ret = StripItem(self.fold_item_recur(i)).strip(); |
29967ef6 | 63 | self.update_retained = old; |
5869c6ff | 64 | return Some(ret); |
29967ef6 XL |
65 | } |
66 | } | |
67 | ||
68 | // handled in the `strip-priv-imports` pass | |
6a06907d | 69 | clean::ExternCrateItem { .. } | clean::ImportItem(..) => {} |
29967ef6 XL |
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 | ||
5869c6ff | 89 | let fastreturn = match *i.kind { |
29967ef6 XL |
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 | |
5869c6ff | 97 | clean::VariantItem(clean::Variant::Struct(..)) => true, |
29967ef6 XL |
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 | ||
fc512014 XL |
110 | if self.update_retained { |
111 | self.retained.insert(i.def_id); | |
29967ef6 | 112 | } |
fc512014 | 113 | Some(i) |
29967ef6 XL |
114 | } |
115 | } | |
116 | ||
117 | /// This stripper discards all impls which reference stripped items | |
fc512014 XL |
118 | crate struct ImplStripper<'a> { |
119 | crate retained: &'a DefIdSet, | |
29967ef6 XL |
120 | } |
121 | ||
122 | impl<'a> DocFolder for ImplStripper<'a> { | |
123 | fn fold_item(&mut self, i: Item) -> Option<Item> { | |
5869c6ff | 124 | if let clean::ImplItem(ref imp) = *i.kind { |
29967ef6 XL |
125 | // emptied none trait impls can be stripped |
126 | if imp.trait_.is_none() && imp.items.is_empty() { | |
127 | return None; | |
128 | } | |
129 | if let Some(did) = imp.for_.def_id() { | |
130 | if did.is_local() && !imp.for_.is_generic() && !self.retained.contains(&did) { | |
131 | debug!("ImplStripper: impl item for stripped type; removing"); | |
132 | return None; | |
133 | } | |
134 | } | |
135 | if let Some(did) = imp.trait_.def_id() { | |
136 | if did.is_local() && !self.retained.contains(&did) { | |
137 | debug!("ImplStripper: impl item for stripped trait; removing"); | |
138 | return None; | |
139 | } | |
140 | } | |
141 | if let Some(generics) = imp.trait_.as_ref().and_then(|t| t.generics()) { | |
142 | for typaram in generics { | |
143 | if let Some(did) = typaram.def_id() { | |
144 | if did.is_local() && !self.retained.contains(&did) { | |
145 | debug!( | |
146 | "ImplStripper: stripped item in trait's generics; removing impl" | |
147 | ); | |
148 | return None; | |
149 | } | |
150 | } | |
151 | } | |
152 | } | |
153 | } | |
fc512014 | 154 | Some(self.fold_item_recur(i)) |
29967ef6 XL |
155 | } |
156 | } | |
157 | ||
158 | /// This stripper discards all private import statements (`use`, `extern crate`) | |
fc512014 | 159 | crate struct ImportStripper; |
29967ef6 XL |
160 | |
161 | impl DocFolder for ImportStripper { | |
162 | fn fold_item(&mut self, i: Item) -> Option<Item> { | |
5869c6ff | 163 | match *i.kind { |
6a06907d XL |
164 | clean::ExternCrateItem { .. } | clean::ImportItem(..) if !i.visibility.is_public() => { |
165 | None | |
166 | } | |
fc512014 | 167 | _ => Some(self.fold_item_recur(i)), |
29967ef6 XL |
168 | } |
169 | } | |
170 | } |