]>
Commit | Line | Data |
---|---|---|
9e0c209e SL |
1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | use rustc::hir::def_id::DefId; | |
12 | use rustc::middle::privacy::AccessLevels; | |
13 | use rustc::util::nodemap::DefIdSet; | |
14 | use std::mem; | |
15 | ||
16 | use clean::{self, GetDefId, Item}; | |
17 | use fold; | |
18 | use fold::FoldItem::Strip; | |
19 | use plugins; | |
20 | ||
21 | mod collapse_docs; | |
22 | pub use self::collapse_docs::collapse_docs; | |
23 | ||
24 | mod strip_hidden; | |
25 | pub use self::strip_hidden::strip_hidden; | |
26 | ||
27 | mod strip_private; | |
28 | pub use self::strip_private::strip_private; | |
29 | ||
30 | mod strip_priv_imports; | |
31 | pub use self::strip_priv_imports::strip_priv_imports; | |
32 | ||
33 | mod unindent_comments; | |
34 | pub use self::unindent_comments::unindent_comments; | |
35 | ||
3b2f2976 XL |
36 | mod propagate_doc_cfg; |
37 | pub use self::propagate_doc_cfg::propagate_doc_cfg; | |
38 | ||
9e0c209e SL |
39 | type Pass = (&'static str, // name |
40 | fn(clean::Crate) -> plugins::PluginResult, // fn | |
41 | &'static str); // description | |
42 | ||
43 | pub const PASSES: &'static [Pass] = &[ | |
44 | ("strip-hidden", strip_hidden, | |
45 | "strips all doc(hidden) items from the output"), | |
46 | ("unindent-comments", unindent_comments, | |
47 | "removes excess indentation on comments in order for markdown to like it"), | |
48 | ("collapse-docs", collapse_docs, | |
49 | "concatenates all document attributes into one document attribute"), | |
50 | ("strip-private", strip_private, | |
51 | "strips all private items from a crate which cannot be seen externally, \ | |
52 | implies strip-priv-imports"), | |
53 | ("strip-priv-imports", strip_priv_imports, | |
54 | "strips all private import statements (`use`, `extern crate`) from a crate"), | |
3b2f2976 XL |
55 | ("propagate-doc-cfg", propagate_doc_cfg, |
56 | "propagates `#[doc(cfg(...))]` to child items"), | |
9e0c209e SL |
57 | ]; |
58 | ||
59 | pub const DEFAULT_PASSES: &'static [&'static str] = &[ | |
60 | "strip-hidden", | |
61 | "strip-private", | |
62 | "collapse-docs", | |
63 | "unindent-comments", | |
3b2f2976 | 64 | "propagate-doc-cfg", |
9e0c209e SL |
65 | ]; |
66 | ||
67 | ||
68 | struct Stripper<'a> { | |
69 | retained: &'a mut DefIdSet, | |
70 | access_levels: &'a AccessLevels<DefId>, | |
71 | update_retained: bool, | |
72 | } | |
73 | ||
74 | impl<'a> fold::DocFolder for Stripper<'a> { | |
75 | fn fold_item(&mut self, i: Item) -> Option<Item> { | |
76 | match i.inner { | |
77 | clean::StrippedItem(..) => { | |
78 | // We need to recurse into stripped modules to strip things | |
79 | // like impl methods but when doing so we must not add any | |
80 | // items to the `retained` set. | |
81 | let old = mem::replace(&mut self.update_retained, false); | |
82 | let ret = self.fold_item_recur(i); | |
83 | self.update_retained = old; | |
84 | return ret; | |
85 | } | |
86 | // These items can all get re-exported | |
87 | clean::TypedefItem(..) | clean::StaticItem(..) | | |
88 | clean::StructItem(..) | clean::EnumItem(..) | | |
89 | clean::TraitItem(..) | clean::FunctionItem(..) | | |
90 | clean::VariantItem(..) | clean::MethodItem(..) | | |
91 | clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) | | |
041b39d2 | 92 | clean::ConstantItem(..) | clean::UnionItem(..) | |
abe05a73 | 93 | clean::AssociatedConstItem(..) | clean::ForeignTypeItem => { |
9e0c209e SL |
94 | if i.def_id.is_local() { |
95 | if !self.access_levels.is_exported(i.def_id) { | |
96 | return None; | |
97 | } | |
98 | } | |
99 | } | |
100 | ||
101 | clean::StructFieldItem(..) => { | |
102 | if i.visibility != Some(clean::Public) { | |
103 | return Strip(i).fold(); | |
104 | } | |
105 | } | |
106 | ||
107 | clean::ModuleItem(..) => { | |
108 | if i.def_id.is_local() && i.visibility != Some(clean::Public) { | |
109 | let old = mem::replace(&mut self.update_retained, false); | |
110 | let ret = Strip(self.fold_item_recur(i).unwrap()).fold(); | |
111 | self.update_retained = old; | |
112 | return ret; | |
113 | } | |
114 | } | |
115 | ||
116 | // handled in the `strip-priv-imports` pass | |
117 | clean::ExternCrateItem(..) | clean::ImportItem(..) => {} | |
118 | ||
abe05a73 | 119 | clean::AutoImplItem(..) | clean::ImplItem(..) => {} |
9e0c209e SL |
120 | |
121 | // tymethods/macros have no control over privacy | |
122 | clean::MacroItem(..) | clean::TyMethodItem(..) => {} | |
123 | ||
124 | // Primitives are never stripped | |
125 | clean::PrimitiveItem(..) => {} | |
126 | ||
041b39d2 | 127 | // Associated types are never stripped |
9e0c209e SL |
128 | clean::AssociatedTypeItem(..) => {} |
129 | } | |
130 | ||
131 | let fastreturn = match i.inner { | |
132 | // nothing left to do for traits (don't want to filter their | |
133 | // methods out, visibility controlled by the trait) | |
134 | clean::TraitItem(..) => true, | |
135 | ||
136 | // implementations of traits are always public. | |
137 | clean::ImplItem(ref imp) if imp.trait_.is_some() => true, | |
138 | // Struct variant fields have inherited visibility | |
139 | clean::VariantItem(clean::Variant { | |
c30ab7b3 | 140 | kind: clean::VariantKind::Struct(..) |
9e0c209e SL |
141 | }) => true, |
142 | _ => false, | |
143 | }; | |
144 | ||
145 | let i = if fastreturn { | |
146 | if self.update_retained { | |
147 | self.retained.insert(i.def_id); | |
148 | } | |
149 | return Some(i); | |
150 | } else { | |
151 | self.fold_item_recur(i) | |
152 | }; | |
153 | ||
041b39d2 XL |
154 | if let Some(ref i) = i { |
155 | if self.update_retained { | |
156 | self.retained.insert(i.def_id); | |
9e0c209e | 157 | } |
041b39d2 XL |
158 | } |
159 | i | |
9e0c209e SL |
160 | } |
161 | } | |
162 | ||
163 | // This stripper discards all impls which reference stripped items | |
164 | struct ImplStripper<'a> { | |
165 | retained: &'a DefIdSet | |
166 | } | |
167 | ||
168 | impl<'a> fold::DocFolder for ImplStripper<'a> { | |
169 | fn fold_item(&mut self, i: Item) -> Option<Item> { | |
170 | if let clean::ImplItem(ref imp) = i.inner { | |
171 | // emptied none trait impls can be stripped | |
172 | if imp.trait_.is_none() && imp.items.is_empty() { | |
173 | return None; | |
174 | } | |
175 | if let Some(did) = imp.for_.def_id() { | |
176 | if did.is_local() && !imp.for_.is_generic() && | |
177 | !self.retained.contains(&did) | |
178 | { | |
179 | return None; | |
180 | } | |
181 | } | |
182 | if let Some(did) = imp.trait_.def_id() { | |
183 | if did.is_local() && !self.retained.contains(&did) { | |
184 | return None; | |
185 | } | |
186 | } | |
187 | } | |
188 | self.fold_item_recur(i) | |
189 | } | |
190 | } | |
191 | ||
192 | // This stripper discards all private import statements (`use`, `extern crate`) | |
193 | struct ImportStripper; | |
194 | impl fold::DocFolder for ImportStripper { | |
195 | fn fold_item(&mut self, i: Item) -> Option<Item> { | |
196 | match i.inner { | |
197 | clean::ExternCrateItem(..) | | |
198 | clean::ImportItem(..) if i.visibility != Some(clean::Public) => None, | |
199 | _ => self.fold_item_recur(i) | |
200 | } | |
201 | } | |
202 | } |