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}