]> git.proxmox.com Git - rustc.git/blame - src/librustdoc/passes/mod.rs
New upstream version 1.23.0+dfsg1
[rustc.git] / src / librustdoc / passes / mod.rs
CommitLineData
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
11use rustc::hir::def_id::DefId;
12use rustc::middle::privacy::AccessLevels;
13use rustc::util::nodemap::DefIdSet;
14use std::mem;
15
16use clean::{self, GetDefId, Item};
17use fold;
18use fold::FoldItem::Strip;
19use plugins;
20
21mod collapse_docs;
22pub use self::collapse_docs::collapse_docs;
23
24mod strip_hidden;
25pub use self::strip_hidden::strip_hidden;
26
27mod strip_private;
28pub use self::strip_private::strip_private;
29
30mod strip_priv_imports;
31pub use self::strip_priv_imports::strip_priv_imports;
32
33mod unindent_comments;
34pub use self::unindent_comments::unindent_comments;
35
3b2f2976
XL
36mod propagate_doc_cfg;
37pub use self::propagate_doc_cfg::propagate_doc_cfg;
38
9e0c209e
SL
39type Pass = (&'static str, // name
40 fn(clean::Crate) -> plugins::PluginResult, // fn
41 &'static str); // description
42
43pub 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
59pub 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
68struct Stripper<'a> {
69 retained: &'a mut DefIdSet,
70 access_levels: &'a AccessLevels<DefId>,
71 update_retained: bool,
72}
73
74impl<'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
164struct ImplStripper<'a> {
165 retained: &'a DefIdSet
166}
167
168impl<'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`)
193struct ImportStripper;
194impl 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}