]> git.lizzy.rs Git - rust.git/blob - src/librustdoc/passes/strip_hidden.rs
Fix remaining bugs
[rust.git] / src / librustdoc / passes / strip_hidden.rs
1 use rustc_span::symbol::sym;
2 use std::mem;
3
4 use crate::clean;
5 use crate::clean::{Item, ItemIdSet, NestedAttributesExt};
6 use crate::core::DocContext;
7 use crate::fold::{strip_item, DocFolder};
8 use crate::passes::{ImplStripper, Pass};
9
10 crate const STRIP_HIDDEN: Pass = Pass {
11     name: "strip-hidden",
12     run: strip_hidden,
13     description: "strips all `#[doc(hidden)]` items from the output",
14 };
15
16 /// Strip items marked `#[doc(hidden)]`
17 crate fn strip_hidden(krate: clean::Crate, _: &mut DocContext<'_>) -> clean::Crate {
18     let mut retained = ItemIdSet::default();
19
20     // strip all #[doc(hidden)] items
21     let krate = {
22         let mut stripper = Stripper { retained: &mut retained, update_retained: true };
23         stripper.fold_crate(krate)
24     };
25
26     // strip all impls referencing stripped items
27     let mut stripper = ImplStripper { retained: &retained };
28     stripper.fold_crate(krate)
29 }
30
31 struct Stripper<'a> {
32     retained: &'a mut ItemIdSet,
33     update_retained: bool,
34 }
35
36 impl<'a> DocFolder for Stripper<'a> {
37     fn fold_item(&mut self, i: Item) -> Option<Item> {
38         if i.attrs.lists(sym::doc).has_word(sym::hidden) {
39             debug!("strip_hidden: stripping {:?} {:?}", i.type_(), i.name);
40             // use a dedicated hidden item for given item type if any
41             match *i.kind {
42                 clean::StructFieldItem(..) | clean::ModuleItem(..) => {
43                     // We need to recurse into stripped modules to
44                     // strip things like impl methods but when doing so
45                     // we must not add any items to the `retained` set.
46                     let old = mem::replace(&mut self.update_retained, false);
47                     let ret = strip_item(self.fold_item_recur(i));
48                     self.update_retained = old;
49                     return Some(ret);
50                 }
51                 _ => return None,
52             }
53         } else {
54             if self.update_retained {
55                 self.retained.insert(i.def_id);
56             }
57         }
58         Some(self.fold_item_recur(i))
59     }
60 }