python_syntax/
visitor.rs

1use crate::ast;
2
3#[allow(unused_variables)]
4trait Visitor: Sized {
5    fn visit_module(&mut self, node: &ast::Module) {
6        for e in &node.body {
7            e.accept(self)
8        }
9    }
10
11    fn visit_interactive(&mut self, node: &ast::Interactive) {
12        for e in &node.body {
13            e.accept(self)
14        }
15    }
16
17    fn visit_eval(&mut self, node: &ast::Eval) {
18        node.body.accept(self)
19    }
20
21    fn visit_function_def(&mut self, node: &ast::FunctionDef) {
22        walk_arguments(self, &node.args);
23        for e in &node.body {
24            e.accept(self)
25        }
26        for e in &node.decorator_list {
27            e.accept(self)
28        }
29        if let Some(e) = &node.returns {
30            e.accept(self)
31        }
32    }
33
34    fn visit_async_function_def(&mut self, node: &ast::AsyncFunctionDef) {
35        self.visit_function_def(node)
36    }
37
38    fn visit_class_def(&mut self, node: &ast::ClassDef) {
39        for e in &node.bases {
40            e.accept(self)
41        }
42        for e in &node.keywords {
43            walk_keyword(self, e)
44        }
45        for e in &node.body {
46            e.accept(self)
47        }
48        for e in &node.decorator_list {
49            e.accept(self)
50        }
51    }
52
53    fn visit_return(&mut self, node: &ast::Return) {
54        if let Some(e) = &node.value {
55            e.accept(self)
56        }
57    }
58
59    fn visit_delete(&mut self, node: &ast::Delete) {
60        for e in &node.targets {
61            e.accept(self)
62        }
63    }
64
65    fn visit_assign(&mut self, node: &ast::Assign) {
66        for e in &node.targets {
67            e.accept(self)
68        }
69        node.value.accept(self)
70    }
71
72    fn visit_aug_assign(&mut self, node: &ast::AugAssign) {
73        node.target.accept(self);
74        node.value.accept(self)
75    }
76
77    fn visit_ann_assign(&mut self, node: &ast::AnnAssign) {
78        node.target.accept(self);
79        node.annotation.accept(self);
80        if let Some(e) = &node.value {
81            e.accept(self)
82        }
83    }
84
85    fn visit_for(&mut self, node: &ast::For) {
86        node.target.accept(self);
87        node.iter.accept(self);
88        for e in &node.body {
89            e.accept(self)
90        }
91        for e in &node.orelse {
92            e.accept(self)
93        }
94    }
95
96    fn visit_async_for(&mut self, node: &ast::AsyncFor) {
97        self.visit_for(node)
98    }
99
100    fn visit_while(&mut self, node: &ast::While) {
101        node.test.accept(self);
102        for e in &node.body {
103            e.accept(self)
104        }
105        for e in &node.orelse {
106            e.accept(self)
107        }
108    }
109
110    fn visit_if(&mut self, node: &ast::If) {
111        node.test.accept(self);
112        for e in &node.body {
113            e.accept(self)
114        }
115        for e in &node.orelse {
116            e.accept(self)
117        }
118    }
119
120    fn visit_with(&mut self, node: &ast::With) {
121        for e in &node.items {
122            e.context_expr.accept(self);
123            if let Some(e) = &e.optional_vars {
124                e.accept(self)
125            }
126        }
127        for e in &node.body {
128            e.accept(self)
129        }
130    }
131
132    fn visit_async_with(&mut self, node: &ast::AsyncWith) {
133        self.visit_with(node)
134    }
135
136    fn visit_raise(&mut self, node: &ast::Raise) {
137        if let Some(e) = &node.exc {
138            e.accept(self)
139        }
140        if let Some(e) = &node.cause {
141            e.accept(self)
142        }
143    }
144
145    fn visit_try(&mut self, node: &ast::Try) {
146        for e in &node.body {
147            e.accept(self)
148        }
149        for hdl in &node.handlers {
150            if let Some(e) = &hdl.typ {
151                e.accept(self)
152            }
153            for e in &hdl.body {
154                e.accept(self)
155            }
156        }
157        for e in &node.orelse {
158            e.accept(self)
159        }
160        for e in &node.finalbody {
161            e.accept(self)
162        }
163    }
164
165    fn visit_assert(&mut self, node: &ast::Assert) {
166        node.test.accept(self);
167        if let Some(e) = &node.msg {
168            e.accept(self)
169        }
170    }
171
172    fn visit_import(&mut self, node: &ast::Import) {}
173
174    fn visit_import_from(&mut self, node: &ast::ImportFrom) {}
175
176    fn visit_global(&mut self, node: &ast::Global) {}
177
178    fn visit_nonlocal(&mut self, node: &ast::Nonlocal) {}
179
180    fn visit_expr(&mut self, node: &ast::Expr) {
181        node.value.accept(self)
182    }
183
184    fn visit_pass(&mut self, node: &ast::Pass) {}
185
186    fn visit_break(&mut self, node: &ast::Break) {}
187
188    fn visit_continue(&mut self, node: &ast::Continue) {}
189
190    fn visit_bool_op(&mut self, node: &ast::BoolOp) {
191        node.left.accept(self);
192        node.right.accept(self);
193    }
194
195    fn visit_bin_op(&mut self, node: &ast::BinOp) {
196        node.left.accept(self);
197        node.right.accept(self);
198    }
199
200    fn visit_unary_op(&mut self, node: &ast::UnaryOp) {
201        node.operand.accept(self);
202    }
203
204    fn visit_lambda(&mut self, node: &ast::Lambda) {
205        walk_arguments(self, &node.args);
206        node.body.accept(self);
207    }
208
209    fn visit_if_exp(&mut self, node: &ast::IfExp) {
210        node.test.accept(self);
211        node.body.accept(self);
212        node.orelse.accept(self);
213    }
214
215    fn visit_dict(&mut self, node: &ast::Dict) {
216        for e in &node.keys {
217            if let Some(e) = e {
218                e.accept(self)
219            }
220        }
221        for e in &node.values {
222            e.accept(self)
223        }
224    }
225
226    fn visit_set(&mut self, node: &ast::Set) {
227        for e in &node.elts {
228            e.accept(self)
229        }
230    }
231
232    fn visit_list_comp(&mut self, node: &ast::ListComp) {
233        node.elt.accept(self);
234        for e in &node.generators {
235            walk_comprehension(self, e)
236        }
237    }
238
239    fn visit_set_comp(&mut self, node: &ast::SetComp) {
240        node.elt.accept(self);
241        for e in &node.generators {
242            walk_comprehension(self, e)
243        }
244    }
245
246    fn visit_dict_comp(&mut self, node: &ast::DictComp) {
247        node.key.accept(self);
248        node.value.accept(self);
249        for e in &node.generators {
250            walk_comprehension(self, e)
251        }
252    }
253
254    fn visit_generator_exp(&mut self, node: &ast::GeneratorExp) {
255        node.elt.accept(self);
256        for e in &node.generators {
257            walk_comprehension(self, e)
258        }
259    }
260
261    fn visit_await(&mut self, node: &ast::Await) {
262        node.value.accept(self);
263    }
264
265    fn visit_yield(&mut self, node: &ast::Yield) {
266        if let Some(e) = &node.value {
267            e.accept(self)
268        }
269    }
270
271    fn visit_yield_from(&mut self, node: &ast::YieldFrom) {
272        node.value.accept(self);
273    }
274
275    fn visit_compare(&mut self, node: &ast::Compare) {
276        node.left.accept(self);
277        for e in &node.comparators {
278            e.accept(self)
279        }
280    }
281
282    fn visit_call(&mut self, node: &ast::Call) {
283        node.func.accept(self);
284        for e in &node.args {
285            e.accept(self)
286        }
287        for e in &node.keywords {
288            walk_keyword(self, e)
289        }
290    }
291
292    fn visit_num(&mut self, node: &ast::Num) {}
293
294    fn visit_str(&mut self, node: &ast::Str) {}
295
296    fn visit_formatted_value(&mut self, node: &ast::FormattedValue) {
297        node.value.accept(self);
298        node.format_spec.accept(self);
299    }
300
301    fn visit_joined_str(&mut self, node: &ast::JoinedStr) {
302        for e in &node.values {
303            e.accept(self)
304        }
305    }
306
307    fn visit_bytes(&mut self, node: &ast::Bytes) {}
308
309    fn visit_name_constant(&mut self, node: &ast::NameConstant) {}
310
311    fn visit_ellipsis(&mut self, node: &ast::Ellipsis) {}
312
313    fn visit_attribute(&mut self, node: &ast::Attribute) {
314        node.value.accept(self);
315    }
316
317    fn visit_subscript(&mut self, node: &ast::Subscript) {
318        node.value.accept(self);
319    }
320
321    fn visit_starred(&mut self, node: &ast::Starred) {
322        node.value.accept(self);
323    }
324
325    fn visit_name(&mut self, node: &ast::Name) {}
326
327    fn visit_list(&mut self, node: &ast::List) {
328        for e in &node.elts {
329            e.accept(self)
330        }
331    }
332
333    fn visit_tuple(&mut self, node: &ast::Tuple) {
334        for e in &node.elts {
335            e.accept(self)
336        }
337    }
338}
339
340fn walk_arguments<V: Visitor>(visitor: &mut V, node: &ast::Arguments) {
341    node.args
342        .iter()
343        .chain(&node.vararg)
344        .chain(&node.kwonlyargs)
345        .chain(&node.kwarg)
346        .for_each(|arg| walk_arg(visitor, &arg))
347}
348
349fn walk_arg<V: Visitor>(visitor: &mut V, node: &ast::Arg) {
350    if let Some(e) = &node.annotation {
351        e.accept(visitor)
352    }
353    if let ast::ArgKind::Optional(e) = &node.kind {
354        e.accept(visitor)
355    }
356}
357
358fn walk_keyword<V: Visitor>(visitor: &mut V, node: &ast::Keyword) {
359    node.value.accept(visitor)
360}
361
362fn walk_comprehension<V: Visitor>(visitor: &mut V, node: &ast::Comprehension) {
363    node.target.accept(visitor);
364    node.iter.accept(visitor);
365    for e in &node.ifs {
366        e.accept(visitor)
367    }
368}
369
370trait Visitable {
371    fn accept<V: Visitor>(&self, visitor: &mut V);
372}
373
374impl Visitable for ast::Program {
375    fn accept<V: Visitor>(&self, visitor: &mut V) {
376        match self {
377            ast::Program::Module(x) => visitor.visit_module(x),
378            ast::Program::Interactive(x) => visitor.visit_interactive(x),
379            ast::Program::Eval(x) => visitor.visit_eval(x),
380        }
381    }
382}
383
384impl Visitable for ast::Statement {
385    fn accept<V: Visitor>(&self, visitor: &mut V) {
386        match self {
387            ast::Statement::FunctionDef(x) => visitor.visit_function_def(x),
388            ast::Statement::AsyncFunctionDef(x) => visitor.visit_async_function_def(x),
389            ast::Statement::ClassDef(x) => visitor.visit_class_def(x),
390            ast::Statement::Return(x) => visitor.visit_return(x),
391            ast::Statement::Delete(x) => visitor.visit_delete(x),
392            ast::Statement::Assign(x) => visitor.visit_assign(x),
393            ast::Statement::AugAssign(x) => visitor.visit_aug_assign(x),
394            ast::Statement::AnnAssign(x) => visitor.visit_ann_assign(x),
395            ast::Statement::For(x) => visitor.visit_for(x),
396            ast::Statement::AsyncFor(x) => visitor.visit_async_for(x),
397            ast::Statement::While(x) => visitor.visit_while(x),
398            ast::Statement::If(x) => visitor.visit_if(x),
399            ast::Statement::With(x) => visitor.visit_with(x),
400            ast::Statement::AsyncWith(x) => visitor.visit_async_with(x),
401            ast::Statement::Raise(x) => visitor.visit_raise(x),
402            ast::Statement::Try(x) => visitor.visit_try(x),
403            ast::Statement::Assert(x) => visitor.visit_assert(x),
404            ast::Statement::Import(x) => visitor.visit_import(x),
405            ast::Statement::ImportFrom(x) => visitor.visit_import_from(x),
406            ast::Statement::Global(x) => visitor.visit_global(x),
407            ast::Statement::Nonlocal(x) => visitor.visit_nonlocal(x),
408            ast::Statement::Expr(x) => visitor.visit_expr(x),
409            ast::Statement::Pass(x) => visitor.visit_pass(x),
410            ast::Statement::Break(x) => visitor.visit_break(x),
411            ast::Statement::Continue(x) => visitor.visit_continue(x),
412        }
413    }
414}
415
416impl Visitable for ast::Expression {
417    fn accept<V: Visitor>(&self, visitor: &mut V) {
418        match self {
419            ast::Expression::BoolOp(x) => visitor.visit_bool_op(x),
420            ast::Expression::BinOp(x) => visitor.visit_bin_op(x),
421            ast::Expression::UnaryOp(x) => visitor.visit_unary_op(x),
422            ast::Expression::Lambda(x) => visitor.visit_lambda(x),
423            ast::Expression::IfExp(x) => visitor.visit_if_exp(x),
424            ast::Expression::Dict(x) => visitor.visit_dict(x),
425            ast::Expression::Set(x) => visitor.visit_set(x),
426            ast::Expression::ListComp(x) => visitor.visit_list_comp(x),
427            ast::Expression::SetComp(x) => visitor.visit_set_comp(x),
428            ast::Expression::DictComp(x) => visitor.visit_dict_comp(x),
429            ast::Expression::GeneratorExp(x) => visitor.visit_generator_exp(x),
430            ast::Expression::Await(x) => visitor.visit_await(x),
431            ast::Expression::Yield(x) => visitor.visit_yield(x),
432            ast::Expression::YieldFrom(x) => visitor.visit_yield_from(x),
433            ast::Expression::Compare(x) => visitor.visit_compare(x),
434            ast::Expression::Call(x) => visitor.visit_call(x),
435            ast::Expression::Num(x) => visitor.visit_num(x),
436            ast::Expression::Str(x) => visitor.visit_str(x),
437            ast::Expression::FormattedValue(x) => visitor.visit_formatted_value(x),
438            ast::Expression::JoinedStr(x) => visitor.visit_joined_str(x),
439            ast::Expression::Bytes(x) => visitor.visit_bytes(x),
440            ast::Expression::NameConstant(x) => visitor.visit_name_constant(x),
441            ast::Expression::Ellipsis(x) => visitor.visit_ellipsis(x),
442            ast::Expression::Attribute(x) => visitor.visit_attribute(x),
443            ast::Expression::Subscript(x) => visitor.visit_subscript(x),
444            ast::Expression::Starred(x) => visitor.visit_starred(x),
445            ast::Expression::Name(x) => visitor.visit_name(x),
446            ast::Expression::List(x) => visitor.visit_list(x),
447            ast::Expression::Tuple(x) => visitor.visit_tuple(x),
448        }
449    }
450}