|
9 | 9 | // except according to those terms.
|
10 | 10 |
|
11 | 11 | use std::num;
|
| 12 | +use std::cell::Cell; |
12 | 13 | use std::uint;
|
13 | 14 | use std::hashmap::HashSet;
|
| 15 | +use std::local_data; |
14 | 16 |
|
15 | 17 | use syntax::ast;
|
16 | 18 |
|
| 19 | +use core; |
17 | 20 | use clean;
|
18 | 21 | use clean::Item;
|
19 | 22 | use plugins;
|
@@ -51,110 +54,157 @@ pub fn strip_hidden(crate: clean::Crate) -> plugins::PluginResult {
|
51 | 54 |
|
52 | 55 | /// Strip private items from the point of view of a crate or externally from a
|
53 | 56 | /// crate, specified by the `xcrate` flag.
|
54 |
| -pub fn strip_private(mut crate: clean::Crate) -> plugins::PluginResult { |
| 57 | +pub fn strip_private(crate: clean::Crate) -> plugins::PluginResult { |
55 | 58 | // This stripper collects all *retained* nodes.
|
56 |
| - struct Stripper<'self>(&'self mut HashSet<ast::NodeId>); |
57 |
| - impl<'self> fold::DocFolder for Stripper<'self> { |
58 |
| - fn fold_item(&mut self, i: Item) -> Option<Item> { |
59 |
| - match i.inner { |
60 |
| - // These items can all get re-exported |
61 |
| - clean::TypedefItem(*) | clean::StaticItem(*) | |
62 |
| - clean::StructItem(*) | clean::EnumItem(*) | |
63 |
| - clean::TraitItem(*) | clean::FunctionItem(*) | |
64 |
| - clean::ViewItemItem(*) | clean::MethodItem(*) | |
65 |
| - clean::ForeignFunctionItem(*) | clean::ForeignStaticItem(*) => { |
66 |
| - // XXX: re-exported items should get surfaced in the docs as |
67 |
| - // well (using the output of resolve analysis) |
68 |
| - if i.visibility != Some(ast::public) { |
69 |
| - return None; |
70 |
| - } |
71 |
| - } |
| 59 | + let mut retained = HashSet::new(); |
| 60 | + let crate = Cell::new(crate); |
| 61 | + let exported_items = do local_data::get(super::analysiskey) |analysis| { |
| 62 | + let analysis = analysis.unwrap(); |
| 63 | + let mut exported_items = analysis.exported_items.clone(); |
| 64 | + { |
| 65 | + let mut finder = ExportedItemsFinder { |
| 66 | + exported_items: &mut exported_items, |
| 67 | + analysis: analysis, |
| 68 | + }; |
| 69 | + let c = finder.fold_crate(crate.take()); |
| 70 | + crate.put_back(c); |
| 71 | + } |
| 72 | + exported_items |
| 73 | + }; |
| 74 | + let mut crate = crate.take(); |
72 | 75 |
|
73 |
| - // These are public-by-default (if the enum/struct was public) |
74 |
| - clean::VariantItem(*) | clean::StructFieldItem(*) => { |
75 |
| - if i.visibility == Some(ast::private) { |
76 |
| - return None; |
| 76 | + // strip all private items |
| 77 | + { |
| 78 | + let mut stripper = Stripper { |
| 79 | + retained: &mut retained, |
| 80 | + exported_items: &exported_items, |
| 81 | + }; |
| 82 | + crate = stripper.fold_crate(crate); |
| 83 | + } |
| 84 | + |
| 85 | + // strip all private implementations of traits |
| 86 | + { |
| 87 | + let mut stripper = ImplStripper(&retained); |
| 88 | + crate = stripper.fold_crate(crate); |
| 89 | + } |
| 90 | + (crate, None) |
| 91 | +} |
| 92 | + |
| 93 | +struct ExportedItemsFinder<'self> { |
| 94 | + exported_items: &'self mut HashSet<ast::NodeId>, |
| 95 | + analysis: &'self core::CrateAnalysis, |
| 96 | +} |
| 97 | + |
| 98 | +impl<'self> fold::DocFolder for ExportedItemsFinder<'self> { |
| 99 | + fn fold_item(&mut self, i: Item) -> Option<Item> { |
| 100 | + match i.inner { |
| 101 | + clean::ModuleItem(*) => { |
| 102 | + if self.analysis.exported_items.contains(&i.id) { |
| 103 | + match self.analysis.reexports.find(&i.id) { |
| 104 | + Some(l) => { |
| 105 | + for &id in l.iter() { |
| 106 | + self.exported_items.insert(id); |
| 107 | + } |
| 108 | + } |
| 109 | + None => {} |
77 | 110 | }
|
78 | 111 | }
|
| 112 | + } |
| 113 | + _ => {} |
| 114 | + } |
| 115 | + return self.fold_item_recur(i); |
| 116 | + } |
| 117 | +} |
| 118 | + |
| 119 | +struct Stripper<'self> { |
| 120 | + retained: &'self mut HashSet<ast::NodeId>, |
| 121 | + exported_items: &'self HashSet<ast::NodeId>, |
| 122 | +} |
79 | 123 |
|
80 |
| - // handled below |
81 |
| - clean::ModuleItem(*) => {} |
| 124 | +impl<'self> fold::DocFolder for Stripper<'self> { |
| 125 | + fn fold_item(&mut self, i: Item) -> Option<Item> { |
| 126 | + match i.inner { |
| 127 | + // These items can all get re-exported |
| 128 | + clean::TypedefItem(*) | clean::StaticItem(*) | |
| 129 | + clean::StructItem(*) | clean::EnumItem(*) | |
| 130 | + clean::TraitItem(*) | clean::FunctionItem(*) | |
| 131 | + clean::VariantItem(*) | clean::MethodItem(*) | |
| 132 | + clean::ForeignFunctionItem(*) | clean::ForeignStaticItem(*) => { |
| 133 | + if !self.exported_items.contains(&i.id) { |
| 134 | + return None; |
| 135 | + } |
| 136 | + } |
82 | 137 |
|
83 |
| - // impls/tymethods have no control over privacy |
84 |
| - clean::ImplItem(*) | clean::TyMethodItem(*) => {} |
| 138 | + clean::ViewItemItem(*) | clean::StructFieldItem(*) => { |
| 139 | + if i.visibility != Some(ast::public) { |
| 140 | + return None; |
| 141 | + } |
85 | 142 | }
|
86 | 143 |
|
87 |
| - let fastreturn = match i.inner { |
88 |
| - // nothing left to do for traits (don't want to filter their |
89 |
| - // methods out, visibility controlled by the trait) |
90 |
| - clean::TraitItem(*) => true, |
| 144 | + // handled below |
| 145 | + clean::ModuleItem(*) => {} |
91 | 146 |
|
92 |
| - // implementations of traits are always public. |
93 |
| - clean::ImplItem(ref imp) if imp.trait_.is_some() => true, |
| 147 | + // impls/tymethods have no control over privacy |
| 148 | + clean::ImplItem(*) | clean::TyMethodItem(*) => {} |
| 149 | + } |
94 | 150 |
|
95 |
| - _ => false, |
96 |
| - }; |
| 151 | + let fastreturn = match i.inner { |
| 152 | + // nothing left to do for traits (don't want to filter their |
| 153 | + // methods out, visibility controlled by the trait) |
| 154 | + clean::TraitItem(*) => true, |
97 | 155 |
|
98 |
| - let i = if fastreturn { |
99 |
| - self.insert(i.id); |
100 |
| - return Some(i); |
101 |
| - } else { |
102 |
| - self.fold_item_recur(i) |
103 |
| - }; |
| 156 | + // implementations of traits are always public. |
| 157 | + clean::ImplItem(ref imp) if imp.trait_.is_some() => true, |
104 | 158 |
|
105 |
| - match i { |
106 |
| - Some(i) => { |
107 |
| - match i.inner { |
108 |
| - // emptied modules/impls have no need to exist |
109 |
| - clean::ModuleItem(ref m) if m.items.len() == 0 => None, |
110 |
| - clean::ImplItem(ref i) if i.methods.len() == 0 => None, |
111 |
| - _ => { |
112 |
| - self.insert(i.id); |
113 |
| - Some(i) |
114 |
| - } |
| 159 | + _ => false, |
| 160 | + }; |
| 161 | + |
| 162 | + let i = if fastreturn { |
| 163 | + self.retained.insert(i.id); |
| 164 | + return Some(i); |
| 165 | + } else { |
| 166 | + self.fold_item_recur(i) |
| 167 | + }; |
| 168 | + |
| 169 | + match i { |
| 170 | + Some(i) => { |
| 171 | + match i.inner { |
| 172 | + // emptied modules/impls have no need to exist |
| 173 | + clean::ModuleItem(ref m) if m.items.len() == 0 => None, |
| 174 | + clean::ImplItem(ref i) if i.methods.len() == 0 => None, |
| 175 | + _ => { |
| 176 | + self.retained.insert(i.id); |
| 177 | + Some(i) |
115 | 178 | }
|
116 | 179 | }
|
117 |
| - None => None, |
118 | 180 | }
|
| 181 | + None => None, |
119 | 182 | }
|
120 | 183 | }
|
| 184 | +} |
121 | 185 |
|
122 |
| - // This stripper discards all private impls of traits |
123 |
| - struct ImplStripper<'self>(&'self HashSet<ast::NodeId>); |
124 |
| - impl<'self> fold::DocFolder for ImplStripper<'self> { |
125 |
| - fn fold_item(&mut self, i: Item) -> Option<Item> { |
126 |
| - match i.inner { |
127 |
| - clean::ImplItem(ref imp) => { |
128 |
| - match imp.trait_ { |
129 |
| - Some(clean::ResolvedPath{ id, _ }) => { |
130 |
| - if !self.contains(&id) { |
131 |
| - return None; |
132 |
| - } |
| 186 | +// This stripper discards all private impls of traits |
| 187 | +struct ImplStripper<'self>(&'self HashSet<ast::NodeId>); |
| 188 | +impl<'self> fold::DocFolder for ImplStripper<'self> { |
| 189 | + fn fold_item(&mut self, i: Item) -> Option<Item> { |
| 190 | + match i.inner { |
| 191 | + clean::ImplItem(ref imp) => { |
| 192 | + match imp.trait_ { |
| 193 | + Some(clean::ResolvedPath{ id, _ }) => { |
| 194 | + if !self.contains(&id) { |
| 195 | + return None; |
133 | 196 | }
|
134 |
| - Some(*) | None => {} |
135 | 197 | }
|
| 198 | + Some(*) | None => {} |
136 | 199 | }
|
137 |
| - _ => {} |
138 | 200 | }
|
139 |
| - self.fold_item_recur(i) |
| 201 | + _ => {} |
140 | 202 | }
|
| 203 | + self.fold_item_recur(i) |
141 | 204 | }
|
142 |
| - |
143 |
| - let mut retained = HashSet::new(); |
144 |
| - // First, strip all private items |
145 |
| - { |
146 |
| - let mut stripper = Stripper(&mut retained); |
147 |
| - crate = stripper.fold_crate(crate); |
148 |
| - } |
149 |
| - |
150 |
| - // Next, strip all private implementations of traits |
151 |
| - { |
152 |
| - let mut stripper = ImplStripper(&retained); |
153 |
| - crate = stripper.fold_crate(crate); |
154 |
| - } |
155 |
| - (crate, None) |
156 | 205 | }
|
157 | 206 |
|
| 207 | + |
158 | 208 | pub fn unindent_comments(crate: clean::Crate) -> plugins::PluginResult {
|
159 | 209 | struct CommentCleaner;
|
160 | 210 | impl fold::DocFolder for CommentCleaner {
|
|
0 commit comments