rustdoc/
visit.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use crate::clean::*;

/// Allows a type to traverse the cleaned ast of a crate.
///
/// Note that like [`rustc_ast::visit::Visitor`], but
/// unlike [`rustc_lint::EarlyLintPass`], if you override a
/// `visit_*` method, you will need to manually recurse into
/// its contents.
pub(crate) trait DocVisitor<'a>: Sized {
    fn visit_item(&mut self, item: &'a Item) {
        self.visit_item_recur(item)
    }

    /// Don't override!
    fn visit_inner_recur(&mut self, kind: &'a ItemKind) {
        match kind {
            StrippedItem(..) => unreachable!(),
            ModuleItem(i) => {
                self.visit_mod(i);
            }
            StructItem(i) => i.fields.iter().for_each(|x| self.visit_item(x)),
            UnionItem(i) => i.fields.iter().for_each(|x| self.visit_item(x)),
            EnumItem(i) => i.variants.iter().for_each(|x| self.visit_item(x)),
            TraitItem(i) => i.items.iter().for_each(|x| self.visit_item(x)),
            ImplItem(i) => i.items.iter().for_each(|x| self.visit_item(x)),
            VariantItem(i) => match &i.kind {
                VariantKind::Struct(j) => j.fields.iter().for_each(|x| self.visit_item(x)),
                VariantKind::Tuple(fields) => fields.iter().for_each(|x| self.visit_item(x)),
                VariantKind::CLike => {}
            },
            ExternCrateItem { src: _ }
            | ImportItem(_)
            | FunctionItem(_)
            | TypeAliasItem(_)
            | StaticItem(_)
            | ConstantItem(..)
            | TraitAliasItem(_)
            | TyMethodItem(_)
            | MethodItem(_, _)
            | StructFieldItem(_)
            | ForeignFunctionItem(..)
            | ForeignStaticItem(..)
            | ForeignTypeItem
            | MacroItem(_)
            | ProcMacroItem(_)
            | PrimitiveItem(_)
            | TyAssocConstItem(..)
            | AssocConstItem(..)
            | TyAssocTypeItem(..)
            | AssocTypeItem(..)
            | KeywordItem => {}
        }
    }

    /// Don't override!
    fn visit_item_recur(&mut self, item: &'a Item) {
        match &item.kind {
            StrippedItem(i) => self.visit_inner_recur(&*i),
            _ => self.visit_inner_recur(&item.kind),
        }
    }

    fn visit_mod(&mut self, m: &'a Module) {
        m.items.iter().for_each(|i| self.visit_item(i))
    }

    /// This is the main entrypoint of [`DocVisitor`].
    fn visit_crate(&mut self, c: &'a Crate) {
        self.visit_item(&c.module);

        for trait_ in c.external_traits.values() {
            trait_.items.iter().for_each(|i| self.visit_item(i));
        }
    }
}