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