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
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//! `Visit` trait for AST types that can be visited.
use syntax;
use syntax::ast::*;
use syntax::visit::Visitor;

/// A trait for AST nodes that can accept a `Visitor`.
pub trait Visit {
    fn visit<'ast, V: Visitor<'ast>>(&'ast self, v: &mut V);
}

// There's no `visit_crate` method in `Visitor`, for some reason.
impl Visit for Crate {
    fn visit<'ast, V: Visitor<'ast>>(&'ast self, v: &mut V) {
        syntax::visit::walk_crate(v, self);
    }
}

// This macro takes as input the definition of `syntax::visit::Visitor` as it appears the libsyntax
// docs, and emits a `Visit` impl for each method it finds.
macro_rules! gen_visit_impls {
    (
        pub trait Visitor<'ast>: Sized {
            $(
                fn $visit_fn:ident (&mut self, $arg:ident : &'ast $ArgTy:ty) { ... }
            )*
        }
    ) => {
        $(
            impl Visit for $ArgTy {
                fn visit<'ast, V: Visitor<'ast>>(&'ast self, v: &mut V) {
                    v.$visit_fn(self)
                }
            }
        )*
    };
}

gen_visit_impls! {
    // Copy-pasted from the syntax::visit::Visitor docs.  Some methods take multiple arguments, so
    // they are commented out in this copy.
    pub trait Visitor<'ast>: Sized {
        //fn visit_name(&mut self, _span: Span, _name: Name) { ... }
        //fn visit_ident(&mut self, span: Span, ident: Ident) { ... }
        //fn visit_mod(&mut self, m: &'ast Mod, _s: Span, _n: NodeId) { ... }
        fn visit_foreign_item(&mut self, i: &'ast ForeignItem) { ... }
        fn visit_global_asm(&mut self, ga: &'ast GlobalAsm) { ... }
        fn visit_item(&mut self, i: &'ast Item) { ... }
        fn visit_local(&mut self, l: &'ast Local) { ... }
        fn visit_block(&mut self, b: &'ast Block) { ... }
        fn visit_stmt(&mut self, s: &'ast Stmt) { ... }
        fn visit_arm(&mut self, a: &'ast Arm) { ... }
        fn visit_pat(&mut self, p: &'ast Pat) { ... }
        fn visit_anon_const(&mut self, c: &'ast AnonConst) { ... }
        fn visit_expr(&mut self, ex: &'ast Expr) { ... }
        // This is a second visit method for `Expr`
        //fn visit_expr_post(&mut self, _ex: &'ast Expr) { ... }
        fn visit_ty(&mut self, t: &'ast Ty) { ... }
        fn visit_generic_param(&mut self, param: &'ast GenericParam) { ... }
        fn visit_generics(&mut self, g: &'ast Generics) { ... }
        fn visit_where_predicate(&mut self, p: &'ast WherePredicate) { ... }
        //fn visit_fn(
        //    &mut self,
        //    fk: FnKind<'ast>,
        //    fd: &'ast FnDecl,
        //    s: Span,
        //    _: NodeId
        //) { ... }
        fn visit_trait_item(&mut self, ti: &'ast TraitItem) { ... }
        fn visit_impl_item(&mut self, ii: &'ast ImplItem) { ... }
        fn visit_trait_ref(&mut self, t: &'ast TraitRef) { ... }
        fn visit_param_bound(&mut self, bounds: &'ast GenericBound) { ... }
        //fn visit_poly_trait_ref(
        //    &mut self,
        //    t: &'ast PolyTraitRef,
        //    m: &'ast TraitBoundModifier
        //) { ... }
        //fn visit_variant_data(
        //    &mut self,
        //    s: &'ast VariantData,
        //    _: Ident,
        //    _: &'ast Generics,
        //    _: NodeId,
        //    _: Span
        //) { ... }
        fn visit_struct_field(&mut self, s: &'ast StructField) { ... }
        //fn visit_enum_def(
        //    &mut self,
        //    enum_definition: &'ast EnumDef,
        //    generics: &'ast Generics,
        //    item_id: NodeId,
        //    _: Span
        //) { ... }
        //fn visit_variant(
        //    &mut self,
        //    v: &'ast Variant,
        //    g: &'ast Generics,
        //    item_id: NodeId
        //) { ... }
        fn visit_label(&mut self, label: &'ast Label) { ... }
        fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) { ... }
        fn visit_mac(&mut self, mac: &'ast Mac) { ... }
        //fn visit_mac_def(&mut self, _mac: &'ast MacroDef, _id: NodeId) { ... }
        //fn visit_path(&mut self, path: &'ast Path, _id: NodeId) { ... }
        //fn visit_use_tree(&mut self, use_tree: &'ast UseTree, id: NodeId, _nested: bool) { ... }
        //fn visit_path_segment(
        //    &mut self,
        //    path_span: Span,
        //    path_segment: &'ast PathSegment
        //) { ... }
        //fn visit_generic_args(
        //    &mut self,
        //    path_span: Span,
        //    generic_args: &'ast GenericArgs
        //) { ... }
        fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) { ... }
        fn visit_assoc_type_binding(&mut self, type_binding: &'ast TypeBinding) { ... }
        fn visit_attribute(&mut self, _attr: &'ast Attribute) { ... }
        //fn visit_tt(&mut self, tt: TokenTree) { ... }
        //fn visit_tts(&mut self, tts: TokenStream) { ... }
        //fn visit_token(&mut self, _t: Token) { ... }
        fn visit_vis(&mut self, vis: &'ast Visibility) { ... }
        fn visit_fn_ret_ty(&mut self, ret_ty: &'ast FunctionRetTy) { ... }
    }
}