rustdoc/
visit.rs

1use crate::clean::*;
2
3/// Allows a type to traverse the cleaned ast of a crate.
4///
5/// Note that like [`rustc_ast::visit::Visitor`], but
6/// unlike [`rustc_lint::EarlyLintPass`], if you override a
7/// `visit_*` method, you will need to manually recurse into
8/// its contents.
9pub(crate) trait DocVisitor<'a>: Sized {
10    fn visit_item(&mut self, item: &'a Item) {
11        self.visit_item_recur(item)
12    }
13
14    /// Don't override!
15    fn visit_inner_recur(&mut self, kind: &'a ItemKind) {
16        match kind {
17            StrippedItem(..) => unreachable!(),
18            ModuleItem(i) => {
19                self.visit_mod(i);
20            }
21            StructItem(i) => i.fields.iter().for_each(|x| self.visit_item(x)),
22            UnionItem(i) => i.fields.iter().for_each(|x| self.visit_item(x)),
23            EnumItem(i) => i.variants.iter().for_each(|x| self.visit_item(x)),
24            TraitItem(i) => i.items.iter().for_each(|x| self.visit_item(x)),
25            ImplItem(i) => i.items.iter().for_each(|x| self.visit_item(x)),
26            VariantItem(i) => match &i.kind {
27                VariantKind::Struct(j) => j.fields.iter().for_each(|x| self.visit_item(x)),
28                VariantKind::Tuple(fields) => fields.iter().for_each(|x| self.visit_item(x)),
29                VariantKind::CLike => {}
30            },
31            ExternCrateItem { src: _ }
32            | ImportItem(_)
33            | FunctionItem(_)
34            | TypeAliasItem(_)
35            | StaticItem(_)
36            | ConstantItem(..)
37            | TraitAliasItem(_)
38            | RequiredMethodItem(_)
39            | MethodItem(_, _)
40            | StructFieldItem(_)
41            | ForeignFunctionItem(..)
42            | ForeignStaticItem(..)
43            | ForeignTypeItem
44            | MacroItem(_)
45            | ProcMacroItem(_)
46            | PrimitiveItem(_)
47            | RequiredAssocConstItem(..)
48            | ProvidedAssocConstItem(..)
49            | ImplAssocConstItem(..)
50            | RequiredAssocTypeItem(..)
51            | AssocTypeItem(..)
52            | KeywordItem => {}
53        }
54    }
55
56    /// Don't override!
57    fn visit_item_recur(&mut self, item: &'a Item) {
58        match &item.kind {
59            StrippedItem(i) => self.visit_inner_recur(i),
60            _ => self.visit_inner_recur(&item.kind),
61        }
62    }
63
64    fn visit_mod(&mut self, m: &'a Module) {
65        m.items.iter().for_each(|i| self.visit_item(i))
66    }
67
68    /// This is the main entrypoint of [`DocVisitor`].
69    fn visit_crate(&mut self, c: &'a Crate) {
70        self.visit_item(&c.module);
71
72        for trait_ in c.external_traits.values() {
73            trait_.items.iter().for_each(|i| self.visit_item(i));
74        }
75    }
76}