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            | AttributeItem => {}
54        }
55    }
56
57    /// Don't override!
58    fn visit_item_recur(&mut self, item: &'a Item) {
59        match &item.kind {
60            StrippedItem(i) => self.visit_inner_recur(i),
61            _ => self.visit_inner_recur(&item.kind),
62        }
63    }
64
65    fn visit_mod(&mut self, m: &'a Module) {
66        m.items.iter().for_each(|i| self.visit_item(i))
67    }
68
69    /// This is the main entrypoint of [`DocVisitor`].
70    fn visit_crate(&mut self, c: &'a Crate) {
71        self.visit_item(&c.module);
72
73        for trait_ in c.external_traits.values() {
74            trait_.items.iter().for_each(|i| self.visit_item(i));
75        }
76    }
77}