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.
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.
11 use rustc::hir::def_id::DefId;
12 use rustc::middle::privacy::AccessLevels;
13 use rustc::util::nodemap::DefIdSet;
16 use clean::{self, GetDefId, Item};
18 use fold::FoldItem::Strip;
21 pub use self::collapse_docs::collapse_docs;
24 pub use self::strip_hidden::strip_hidden;
27 pub use self::strip_private::strip_private;
29 mod strip_priv_imports;
30 pub use self::strip_priv_imports::strip_priv_imports;
32 mod unindent_comments;
33 pub use self::unindent_comments::unindent_comments;
35 mod propagate_doc_cfg;
36 pub use self::propagate_doc_cfg::propagate_doc_cfg;
38 type Pass = (&'static str, // name
39 fn(clean::Crate) -> clean::Crate, // fn
40 &'static str); // description
42 pub const PASSES: &'static [Pass] = &[
43 ("strip-hidden", strip_hidden,
44 "strips all doc(hidden) items from the output"),
45 ("unindent-comments", unindent_comments,
46 "removes excess indentation on comments in order for markdown to like it"),
47 ("collapse-docs", collapse_docs,
48 "concatenates all document attributes into one document attribute"),
49 ("strip-private", strip_private,
50 "strips all private items from a crate which cannot be seen externally, \
51 implies strip-priv-imports"),
52 ("strip-priv-imports", strip_priv_imports,
53 "strips all private import statements (`use`, `extern crate`) from a crate"),
54 ("propagate-doc-cfg", propagate_doc_cfg,
55 "propagates `#[doc(cfg(...))]` to child items"),
58 pub const DEFAULT_PASSES: &'static [&'static str] = &[
66 pub const DEFAULT_PRIVATE_PASSES: &'static [&'static str] = &[
73 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
74 pub enum DefaultPassOption {
80 pub fn defaults(default_set: DefaultPassOption) -> &'static [&'static str] {
82 DefaultPassOption::Default => {
85 DefaultPassOption::Private => {
86 DEFAULT_PRIVATE_PASSES
88 DefaultPassOption::None => {
95 retained: &'a mut DefIdSet,
96 access_levels: &'a AccessLevels<DefId>,
97 update_retained: bool,
100 impl<'a> fold::DocFolder for Stripper<'a> {
101 fn fold_item(&mut self, i: Item) -> Option<Item> {
103 clean::StrippedItem(..) => {
104 // We need to recurse into stripped modules to strip things
105 // like impl methods but when doing so we must not add any
106 // items to the `retained` set.
107 let old = mem::replace(&mut self.update_retained, false);
108 let ret = self.fold_item_recur(i);
109 self.update_retained = old;
112 // These items can all get re-exported
113 clean::ExistentialItem(..) |
114 clean::TypedefItem(..) | clean::StaticItem(..) |
115 clean::StructItem(..) | clean::EnumItem(..) |
116 clean::TraitItem(..) | clean::FunctionItem(..) |
117 clean::VariantItem(..) | clean::MethodItem(..) |
118 clean::ForeignFunctionItem(..) | clean::ForeignStaticItem(..) |
119 clean::ConstantItem(..) | clean::UnionItem(..) |
120 clean::AssociatedConstItem(..) | clean::ForeignTypeItem => {
121 if i.def_id.is_local() {
122 if !self.access_levels.is_exported(i.def_id) {
128 clean::StructFieldItem(..) => {
129 if i.visibility != Some(clean::Public) {
130 return Strip(i).fold();
134 clean::ModuleItem(..) => {
135 if i.def_id.is_local() && i.visibility != Some(clean::Public) {
136 let old = mem::replace(&mut self.update_retained, false);
137 let ret = Strip(self.fold_item_recur(i).unwrap()).fold();
138 self.update_retained = old;
143 // handled in the `strip-priv-imports` pass
144 clean::ExternCrateItem(..) | clean::ImportItem(..) => {}
146 clean::ImplItem(..) => {}
148 // tymethods/macros have no control over privacy
149 clean::MacroItem(..) | clean::TyMethodItem(..) => {}
151 // Primitives are never stripped
152 clean::PrimitiveItem(..) => {}
154 // Associated types are never stripped
155 clean::AssociatedTypeItem(..) => {}
157 // Keywords are never stripped
158 clean::KeywordItem(..) => {}
161 let fastreturn = match i.inner {
162 // nothing left to do for traits (don't want to filter their
163 // methods out, visibility controlled by the trait)
164 clean::TraitItem(..) => true,
166 // implementations of traits are always public.
167 clean::ImplItem(ref imp) if imp.trait_.is_some() => true,
168 // Struct variant fields have inherited visibility
169 clean::VariantItem(clean::Variant {
170 kind: clean::VariantKind::Struct(..)
175 let i = if fastreturn {
176 if self.update_retained {
177 self.retained.insert(i.def_id);
181 self.fold_item_recur(i)
184 if let Some(ref i) = i {
185 if self.update_retained {
186 self.retained.insert(i.def_id);
193 // This stripper discards all impls which reference stripped items
194 struct ImplStripper<'a> {
195 retained: &'a DefIdSet
198 impl<'a> fold::DocFolder for ImplStripper<'a> {
199 fn fold_item(&mut self, i: Item) -> Option<Item> {
200 if let clean::ImplItem(ref imp) = i.inner {
201 // emptied none trait impls can be stripped
202 if imp.trait_.is_none() && imp.items.is_empty() {
205 if let Some(did) = imp.for_.def_id() {
206 if did.is_local() && !imp.for_.is_generic() &&
207 !self.retained.contains(&did)
212 if let Some(did) = imp.trait_.def_id() {
213 if did.is_local() && !self.retained.contains(&did) {
217 if let Some(generics) = imp.trait_.as_ref().and_then(|t| t.generics()) {
218 for typaram in generics {
219 if let Some(did) = typaram.def_id() {
220 if did.is_local() && !self.retained.contains(&did) {
227 self.fold_item_recur(i)
231 // This stripper discards all private import statements (`use`, `extern crate`)
232 struct ImportStripper;
233 impl fold::DocFolder for ImportStripper {
234 fn fold_item(&mut self, i: Item) -> Option<Item> {
236 clean::ExternCrateItem(..) |
237 clean::ImportItem(..) if i.visibility != Some(clean::Public) => None,
238 _ => self.fold_item_recur(i)