rust_visitor/
lib.rs

1use paste::paste;
2use ra_ap_syntax::{
3    ast::{self, AstNode},
4    SyntaxKind, SyntaxNode,
5};
6
7pub(crate) const INTERNAL_ERR: &'static str =
8    "Internal error message in rust-visitor. Please create an issue on https://github.com/automa-app/cargo-up";
9
10pub use ra_ap_syntax;
11
12#[derive(Default, Debug)]
13pub struct Options {
14    skip_children: bool,
15}
16
17macro_rules! visiting {
18    () => {};
19    ($($kind:ident,)*) => {
20        trait Visitable: Sized {
21            fn accept<T: Visitor>(&self, visitor: &mut T);
22        }
23
24        impl Visitable for SyntaxNode {
25            fn accept<T: Visitor>(&self, visitor: &mut T) {
26                let mut options = Options::default();
27
28                visitor.pre_visit(self);
29
30                paste! {
31                    match self.kind() {
32                        $(SyntaxKind::$kind => visitor.[<visit_ $kind:lower>](
33                            &ast::[<$kind:camel>]::cast((*self).clone()).expect(INTERNAL_ERR),
34                            &mut options,
35                        ),)*
36                        _ => {},
37                    };
38                };
39
40                if !options.skip_children {
41                    for child in self.children() {
42                        child.accept(visitor);
43                    }
44                }
45
46                visitor.post_visit(self);
47            }
48        }
49
50        pub trait Visitor: Sized {
51            /// Call this method to perform a in-order traversal on `node` and its children.
52            fn walk(&mut self, node: &SyntaxNode) {
53                node.accept(self);
54            }
55
56            /// This method is called before visiting a node.
57            fn pre_visit(&mut self, _node: &SyntaxNode) {}
58
59            /// This method is called after visiting a node.
60            fn post_visit(&mut self, _node: &SyntaxNode) {}
61
62            paste! {
63                $(
64                    #[doc = " This method is called when visiting a `" $kind "` node."]
65                    fn [<visit_ $kind:lower>](&mut self, _node: &ast::[<$kind:camel>], _options: &mut Options) {}
66                )*
67            }
68        }
69    };
70}
71
72visiting!(
73    SOURCE_FILE,
74    STRUCT,
75    UNION,
76    ENUM,
77    FN,
78    RET_TYPE,
79    EXTERN_CRATE,
80    MODULE,
81    USE,
82    STATIC,
83    CONST,
84    TRAIT,
85    IMPL,
86    TYPE_ALIAS,
87    MACRO_CALL,
88    MACRO_RULES,
89    TOKEN_TREE,
90    MACRO_DEF,
91    PAREN_TYPE,
92    TUPLE_TYPE,
93    MACRO_TYPE,
94    NEVER_TYPE,
95    PATH_TYPE,
96    PTR_TYPE,
97    ARRAY_TYPE,
98    SLICE_TYPE,
99    REF_TYPE,
100    INFER_TYPE,
101    FN_PTR_TYPE,
102    FOR_TYPE,
103    IMPL_TRAIT_TYPE,
104    DYN_TRAIT_TYPE,
105    OR_PAT,
106    PAREN_PAT,
107    REF_PAT,
108    BOX_PAT,
109    IDENT_PAT,
110    WILDCARD_PAT,
111    REST_PAT,
112    PATH_PAT,
113    RECORD_PAT,
114    RECORD_PAT_FIELD_LIST,
115    RECORD_PAT_FIELD,
116    TUPLE_STRUCT_PAT,
117    TUPLE_PAT,
118    SLICE_PAT,
119    RANGE_PAT,
120    LITERAL_PAT,
121    MACRO_PAT,
122    CONST_BLOCK_PAT,
123    TUPLE_EXPR,
124    ARRAY_EXPR,
125    PAREN_EXPR,
126    PATH_EXPR,
127    CLOSURE_EXPR,
128    IF_EXPR,
129    WHILE_EXPR,
130    CONDITION,
131    LOOP_EXPR,
132    FOR_EXPR,
133    CONTINUE_EXPR,
134    BREAK_EXPR,
135    LABEL,
136    BLOCK_EXPR,
137    STMT_LIST,
138    RETURN_EXPR,
139    YIELD_EXPR,
140    MATCH_EXPR,
141    MATCH_ARM_LIST,
142    MATCH_ARM,
143    MATCH_GUARD,
144    RECORD_EXPR,
145    RECORD_EXPR_FIELD_LIST,
146    RECORD_EXPR_FIELD,
147    BOX_EXPR,
148    CALL_EXPR,
149    INDEX_EXPR,
150    METHOD_CALL_EXPR,
151    FIELD_EXPR,
152    AWAIT_EXPR,
153    TRY_EXPR,
154    CAST_EXPR,
155    REF_EXPR,
156    PREFIX_EXPR,
157    RANGE_EXPR,
158    BIN_EXPR,
159    EXTERN_BLOCK,
160    EXTERN_ITEM_LIST,
161    VARIANT,
162    RECORD_FIELD_LIST,
163    RECORD_FIELD,
164    TUPLE_FIELD_LIST,
165    TUPLE_FIELD,
166    VARIANT_LIST,
167    ITEM_LIST,
168    ASSOC_ITEM_LIST,
169    ATTR,
170    META,
171    USE_TREE,
172    USE_TREE_LIST,
173    PATH,
174    PATH_SEGMENT,
175    LITERAL,
176    RENAME,
177    VISIBILITY,
178    WHERE_CLAUSE,
179    WHERE_PRED,
180    ABI,
181    NAME,
182    NAME_REF,
183    LET_STMT,
184    LET_ELSE,
185    EXPR_STMT,
186    GENERIC_PARAM_LIST,
187    GENERIC_PARAM,
188    LIFETIME_PARAM,
189    TYPE_PARAM,
190    CONST_PARAM,
191    GENERIC_ARG_LIST,
192    LIFETIME,
193    LIFETIME_ARG,
194    TYPE_ARG,
195    ASSOC_TYPE_ARG,
196    CONST_ARG,
197    PARAM_LIST,
198    PARAM,
199    SELF_PARAM,
200    ARG_LIST,
201    TYPE_BOUND,
202    TYPE_BOUND_LIST,
203    MACRO_ITEMS,
204    MACRO_STMTS,
205);