1use super::*;
2
3pub trait Visitor {
4 fn visit_source_unit(&mut self, _source_unit: &SourceUnit) {}
5 fn visit_import_directive(&mut self, _directive: &ImportDirective) {}
6 fn visit_pragma_directive(&mut self, _directive: &PragmaDirective) {}
7 fn visit_block(&mut self, _block: &Block) {}
8 fn visit_statement(&mut self, _statement: &Statement) {}
9 fn visit_expression(&mut self, _expression: &Expression) {}
10 fn visit_function_call(&mut self, _function_call: &FunctionCall) {}
11 fn visit_user_defined_type_name(&mut self, _type_name: &UserDefinedTypeName) {}
12 fn visit_identifier_path(&mut self, _identifier_path: &IdentifierPath) {}
13 fn visit_type_name(&mut self, _type_name: &TypeName) {}
14 fn visit_parameter_list(&mut self, _parameter_list: &ParameterList) {}
15 fn visit_function_definition(&mut self, _definition: &FunctionDefinition) {}
16 fn visit_enum_definition(&mut self, _definition: &EnumDefinition) {}
17 fn visit_error_definition(&mut self, _definition: &ErrorDefinition) {}
18 fn visit_event_definition(&mut self, _definition: &EventDefinition) {}
19 fn visit_struct_definition(&mut self, _definition: &StructDefinition) {}
20 fn visit_modifier_definition(&mut self, _definition: &ModifierDefinition) {}
21 fn visit_variable_declaration(&mut self, _declaration: &VariableDeclaration) {}
22 fn visit_overrides(&mut self, _specifier: &OverrideSpecifier) {}
23 fn visit_user_defined_value_type(&mut self, _value_type: &UserDefinedValueTypeDefinition) {}
24 fn visit_contract_definition(&mut self, _definition: &ContractDefinition) {}
25 fn visit_using_for(&mut self, _directive: &UsingForDirective) {}
26 fn visit_unary_operation(&mut self, _unary_op: &UnaryOperation) {}
27 fn visit_binary_operation(&mut self, _binary_op: &BinaryOperation) {}
28 fn visit_conditional(&mut self, _conditional: &Conditional) {}
29 fn visit_tuple_expression(&mut self, _tuple_expression: &TupleExpression) {}
30 fn visit_new_expression(&mut self, _new_expression: &NewExpression) {}
31 fn visit_assignment(&mut self, _assignment: &Assignment) {}
32 fn visit_identifier(&mut self, _identifier: &Identifier) {}
33 fn visit_index_access(&mut self, _index_access: &IndexAccess) {}
34 fn visit_index_range_access(&mut self, _index_range_access: &IndexRangeAccess) {}
35 fn visit_while_statement(&mut self, _while_statement: &WhileStatement) {}
36 fn visit_for_statement(&mut self, _for_statement: &ForStatement) {}
37 fn visit_if_statement(&mut self, _if_statement: &IfStatement) {}
38 fn visit_do_while_statement(&mut self, _do_while_statement: &DoWhileStatement) {}
39 fn visit_emit_statement(&mut self, _emit_statement: &EmitStatement) {}
40 fn visit_unchecked_block(&mut self, _unchecked_block: &UncheckedBlock) {}
41 fn visit_try_statement(&mut self, _try_statement: &TryStatement) {}
42 fn visit_revert_statement(&mut self, _revert_statement: &RevertStatement) {}
43 fn visit_member_access(&mut self, _member_access: &MemberAccess) {}
44 fn visit_mapping(&mut self, _mapping: &Mapping) {}
45 fn visit_elementary_type_name(&mut self, _elementary_type_name: &ElementaryTypeName) {}
46 fn visit_literal(&mut self, _literal: &Literal) {}
47 fn visit_function_type_name(&mut self, _function_type_name: &FunctionTypeName) {}
48 fn visit_array_type_name(&mut self, _array_type_name: &ArrayTypeName) {}
49 fn visit_function_call_options(&mut self, _function_call: &FunctionCallOptions) {}
50 fn visit_return(&mut self, _return: &Return) {}
51 fn visit_inheritance_specifier(&mut self, _specifier: &InheritanceSpecifier) {}
52 fn visit_modifier_invocation(&mut self, _invocation: &ModifierInvocation) {}
53 fn visit_inline_assembly(&mut self, _assembly: &InlineAssembly) {}
54 fn visit_external_assembly_reference(&mut self, _ref: &ExternalInlineAssemblyReference) {}
55}
56
57pub trait Walk {
58 fn walk(&self, visitor: &mut dyn Visitor);
59}
60
61macro_rules! impl_walk {
62 ($ty:ty, | $val:ident, $visitor:ident | $e:expr) => {
64 impl Walk for $ty {
65 fn walk(&self, visitor: &mut dyn Visitor) {
66 let $val = self;
67 let $visitor = visitor;
68 $e
69 }
70 }
71 };
72 ($ty:ty, $func:ident) => {
73 impl_walk!($ty, |obj, visitor| {
74 visitor.$func(obj);
75 });
76 };
77 ($ty:ty, $func:ident, | $val:ident, $visitor:ident | $e:expr) => {
78 impl_walk!($ty, |$val, $visitor| {
79 $visitor.$func($val);
80 $e
81 });
82 };
83}
84
85impl_walk!(SourceUnit, visit_source_unit, |source_unit, visitor| {
86 source_unit.nodes.iter().for_each(|part| {
87 part.walk(visitor);
88 });
89});
90
91impl_walk!(SourceUnitPart, |part, visitor| {
92 match part {
93 SourceUnitPart::ContractDefinition(contract) => {
94 contract.walk(visitor);
95 }
96 SourceUnitPart::UsingForDirective(directive) => {
97 directive.walk(visitor);
98 }
99 SourceUnitPart::ErrorDefinition(error) => {
100 error.walk(visitor);
101 }
102 SourceUnitPart::EventDefinition(event) => {
103 event.walk(visitor);
104 }
105 SourceUnitPart::StructDefinition(struct_) => {
106 struct_.walk(visitor);
107 }
108 SourceUnitPart::VariableDeclaration(declaration) => {
109 declaration.walk(visitor);
110 }
111 SourceUnitPart::FunctionDefinition(function) => {
112 function.walk(visitor);
113 }
114 SourceUnitPart::UserDefinedValueTypeDefinition(value_type) => {
115 value_type.walk(visitor);
116 }
117 SourceUnitPart::ImportDirective(directive) => {
118 directive.walk(visitor);
119 }
120 SourceUnitPart::EnumDefinition(enum_) => {
121 enum_.walk(visitor);
122 }
123 SourceUnitPart::PragmaDirective(directive) => {
124 directive.walk(visitor);
125 }
126 }
127});
128
129impl_walk!(ContractDefinition, visit_contract_definition, |contract, visitor| {
130 contract.base_contracts.iter().for_each(|base_contract| {
131 base_contract.walk(visitor);
132 });
133
134 for part in &contract.nodes {
135 match part {
136 ContractDefinitionPart::FunctionDefinition(function) => {
137 function.walk(visitor);
138 }
139 ContractDefinitionPart::ErrorDefinition(error) => {
140 error.walk(visitor);
141 }
142 ContractDefinitionPart::EventDefinition(event) => {
143 event.walk(visitor);
144 }
145 ContractDefinitionPart::StructDefinition(struct_) => {
146 struct_.walk(visitor);
147 }
148 ContractDefinitionPart::VariableDeclaration(declaration) => {
149 declaration.walk(visitor);
150 }
151 ContractDefinitionPart::ModifierDefinition(modifier) => {
152 modifier.walk(visitor);
153 }
154 ContractDefinitionPart::UserDefinedValueTypeDefinition(definition) => {
155 definition.walk(visitor);
156 }
157 ContractDefinitionPart::UsingForDirective(directive) => {
158 directive.walk(visitor);
159 }
160 ContractDefinitionPart::EnumDefinition(enum_) => {
161 enum_.walk(visitor);
162 }
163 }
164 }
165});
166
167impl_walk!(Expression, visit_expression, |expr, visitor| {
168 match expr {
169 Expression::FunctionCall(expression) => {
170 expression.walk(visitor);
171 }
172 Expression::MemberAccess(member_access) => {
173 member_access.walk(visitor);
174 }
175 Expression::IndexAccess(index_access) => {
176 index_access.walk(visitor);
177 }
178 Expression::UnaryOperation(unary_op) => {
179 unary_op.walk(visitor);
180 }
181 Expression::BinaryOperation(expression) => {
182 expression.walk(visitor);
183 }
184 Expression::Conditional(expression) => {
185 expression.walk(visitor);
186 }
187 Expression::TupleExpression(tuple) => {
188 tuple.walk(visitor);
189 }
190 Expression::NewExpression(expression) => {
191 expression.walk(visitor);
192 }
193 Expression::Assignment(expression) => {
194 expression.walk(visitor);
195 }
196 Expression::Identifier(identifier) => {
197 identifier.walk(visitor);
198 }
199 Expression::FunctionCallOptions(function_call) => {
200 function_call.walk(visitor);
201 }
202 Expression::IndexRangeAccess(range_access) => {
203 range_access.walk(visitor);
204 }
205 Expression::Literal(literal) => {
206 literal.walk(visitor);
207 }
208 Expression::ElementaryTypeNameExpression(type_name) => {
209 type_name.walk(visitor);
210 }
211 }
212});
213
214impl_walk!(Statement, visit_statement, |statement, visitor| {
215 match statement {
216 Statement::Block(block) => {
217 block.walk(visitor);
218 }
219 Statement::WhileStatement(statement) => {
220 statement.walk(visitor);
221 }
222 Statement::ForStatement(statement) => {
223 statement.walk(visitor);
224 }
225 Statement::IfStatement(statement) => {
226 statement.walk(visitor);
227 }
228 Statement::DoWhileStatement(statement) => {
229 statement.walk(visitor);
230 }
231 Statement::EmitStatement(statement) => {
232 statement.walk(visitor);
233 }
234 Statement::VariableDeclarationStatement(statement) => {
235 statement.walk(visitor);
236 }
237 Statement::ExpressionStatement(statement) => {
238 statement.walk(visitor);
239 }
240 Statement::UncheckedBlock(statement) => {
241 statement.walk(visitor);
242 }
243 Statement::TryStatement(statement) => {
244 statement.walk(visitor);
245 }
246 Statement::RevertStatement(statement) => {
247 statement.walk(visitor);
248 }
249 Statement::Return(statement) => {
250 statement.walk(visitor);
251 }
252 Statement::InlineAssembly(assembly) => {
253 assembly.walk(visitor);
254 }
255 Statement::Break(_) | Statement::Continue(_) | Statement::PlaceholderStatement(_) => {}
256 }
257});
258
259impl_walk!(FunctionDefinition, visit_function_definition, |function, visitor| {
260 function.parameters.walk(visitor);
261 function.return_parameters.walk(visitor);
262
263 if let Some(overrides) = &function.overrides {
264 overrides.walk(visitor);
265 }
266
267 if let Some(body) = &function.body {
268 body.walk(visitor);
269 }
270
271 function.modifiers.iter().for_each(|m| m.walk(visitor));
272});
273
274impl_walk!(ErrorDefinition, visit_error_definition, |error, visitor| {
275 error.parameters.walk(visitor);
276});
277
278impl_walk!(EventDefinition, visit_event_definition, |event, visitor| {
279 event.parameters.walk(visitor);
280});
281
282impl_walk!(StructDefinition, visit_struct_definition, |struct_, visitor| {
283 struct_.members.iter().for_each(|member| member.walk(visitor));
284});
285
286impl_walk!(ModifierDefinition, visit_modifier_definition, |modifier, visitor| {
287 if let Some(body) = &modifier.body {
288 body.walk(visitor);
289 }
290 if let Some(override_) = &modifier.overrides {
291 override_.walk(visitor);
292 }
293 modifier.parameters.walk(visitor);
294});
295
296impl_walk!(VariableDeclaration, visit_variable_declaration, |declaration, visitor| {
297 if let Some(value) = &declaration.value {
298 value.walk(visitor);
299 }
300
301 if let Some(type_name) = &declaration.type_name {
302 type_name.walk(visitor);
303 }
304});
305
306impl_walk!(OverrideSpecifier, visit_overrides, |override_, visitor| {
307 override_.overrides.iter().for_each(|type_name| {
308 type_name.walk(visitor);
309 });
310});
311
312impl_walk!(UserDefinedValueTypeDefinition, visit_user_defined_value_type, |value_type, visitor| {
313 value_type.underlying_type.walk(visitor);
314});
315
316impl_walk!(FunctionCallOptions, visit_function_call_options, |function_call, visitor| {
317 function_call.expression.walk(visitor);
318 function_call.options.iter().for_each(|option| {
319 option.walk(visitor);
320 });
321});
322
323impl_walk!(Return, visit_return, |return_, visitor| {
324 if let Some(expr) = return_.expression.as_ref() {
325 expr.walk(visitor);
326 }
327});
328
329impl_walk!(UsingForDirective, visit_using_for, |directive, visitor| {
330 if let Some(type_name) = &directive.type_name {
331 type_name.walk(visitor);
332 }
333 if let Some(library_name) = &directive.library_name {
334 library_name.walk(visitor);
335 }
336 for function in &directive.function_list {
337 function.walk(visitor);
338 }
339});
340
341impl_walk!(UnaryOperation, visit_unary_operation, |unary_op, visitor| {
342 unary_op.sub_expression.walk(visitor);
343});
344
345impl_walk!(BinaryOperation, visit_binary_operation, |binary_op, visitor| {
346 binary_op.lhs.walk(visitor);
347 binary_op.rhs.walk(visitor);
348});
349
350impl_walk!(Conditional, visit_conditional, |conditional, visitor| {
351 conditional.condition.walk(visitor);
352 conditional.true_expression.walk(visitor);
353 conditional.false_expression.walk(visitor);
354});
355
356impl_walk!(TupleExpression, visit_tuple_expression, |tuple_expression, visitor| {
357 tuple_expression.components.iter().filter_map(|component| component.as_ref()).for_each(
358 |component| {
359 component.walk(visitor);
360 },
361 );
362});
363
364impl_walk!(NewExpression, visit_new_expression, |new_expression, visitor| {
365 new_expression.type_name.walk(visitor);
366});
367
368impl_walk!(Assignment, visit_assignment, |assignment, visitor| {
369 assignment.lhs.walk(visitor);
370 assignment.rhs.walk(visitor);
371});
372impl_walk!(IfStatement, visit_if_statement, |if_statement, visitor| {
373 if_statement.condition.walk(visitor);
374 if_statement.true_body.walk(visitor);
375
376 if let Some(false_body) = &if_statement.false_body {
377 false_body.walk(visitor);
378 }
379});
380
381impl_walk!(IndexAccess, visit_index_access, |index_access, visitor| {
382 index_access.base_expression.walk(visitor);
383 if let Some(index_expression) = &index_access.index_expression {
384 index_expression.walk(visitor);
385 }
386});
387
388impl_walk!(IndexRangeAccess, visit_index_range_access, |index_range_access, visitor| {
389 index_range_access.base_expression.walk(visitor);
390 if let Some(start_expression) = &index_range_access.start_expression {
391 start_expression.walk(visitor);
392 }
393 if let Some(end_expression) = &index_range_access.end_expression {
394 end_expression.walk(visitor);
395 }
396});
397
398impl_walk!(WhileStatement, visit_while_statement, |while_statement, visitor| {
399 while_statement.condition.walk(visitor);
400 while_statement.body.walk(visitor);
401});
402
403impl_walk!(ForStatement, visit_for_statement, |for_statement, visitor| {
404 for_statement.body.walk(visitor);
405 if let Some(condition) = &for_statement.condition {
406 condition.walk(visitor);
407 }
408
409 if let Some(loop_expression) = &for_statement.loop_expression {
410 loop_expression.walk(visitor);
411 }
412
413 if let Some(initialization_expr) = &for_statement.initialization_expression {
414 initialization_expr.walk(visitor);
415 }
416});
417
418impl_walk!(DoWhileStatement, visit_do_while_statement, |do_while_statement, visitor| {
419 do_while_statement.body.walk(visitor);
420 do_while_statement.condition.walk(visitor);
421});
422
423impl_walk!(EmitStatement, visit_emit_statement, |emit_statement, visitor| {
424 emit_statement.event_call.walk(visitor);
425});
426
427impl_walk!(VariableDeclarationStatement, |stmt, visitor| {
428 stmt.declarations.iter().filter_map(|d| d.as_ref()).for_each(|declaration| {
429 declaration.walk(visitor);
430 });
431 if let Some(initial_value) = &stmt.initial_value {
432 initial_value.walk(visitor);
433 }
434});
435
436impl_walk!(UncheckedBlock, visit_unchecked_block, |unchecked_block, visitor| {
437 unchecked_block.statements.iter().for_each(|statement| {
438 statement.walk(visitor);
439 });
440});
441
442impl_walk!(TryStatement, visit_try_statement, |try_statement, visitor| {
443 try_statement.clauses.iter().for_each(|clause| {
444 clause.block.walk(visitor);
445
446 if let Some(parameter_list) = &clause.parameters {
447 parameter_list.walk(visitor);
448 }
449 });
450
451 try_statement.external_call.walk(visitor);
452});
453
454impl_walk!(RevertStatement, visit_revert_statement, |revert_statement, visitor| {
455 revert_statement.error_call.walk(visitor);
456});
457
458impl_walk!(MemberAccess, visit_member_access, |member_access, visitor| {
459 member_access.expression.walk(visitor);
460});
461
462impl_walk!(FunctionCall, visit_function_call, |function_call, visitor| {
463 function_call.expression.walk(visitor);
464 function_call.arguments.iter().for_each(|argument| {
465 argument.walk(visitor);
466 });
467});
468
469impl_walk!(Block, visit_block, |block, visitor| {
470 block.statements.iter().for_each(|statement| {
471 statement.walk(visitor);
472 });
473});
474
475impl_walk!(UserDefinedTypeName, visit_user_defined_type_name, |type_name, visitor| {
476 if let Some(path_node) = &type_name.path_node {
477 path_node.walk(visitor);
478 }
479});
480
481impl_walk!(TypeName, visit_type_name, |type_name, visitor| {
482 match type_name {
483 TypeName::ElementaryTypeName(type_name) => {
484 type_name.walk(visitor);
485 }
486 TypeName::UserDefinedTypeName(type_name) => {
487 type_name.walk(visitor);
488 }
489 TypeName::Mapping(mapping) => {
490 mapping.walk(visitor);
491 }
492 TypeName::ArrayTypeName(array) => {
493 array.walk(visitor);
494 }
495 TypeName::FunctionTypeName(function) => {
496 function.walk(visitor);
497 }
498 }
499});
500
501impl_walk!(FunctionTypeName, visit_function_type_name, |function, visitor| {
502 function.parameter_types.walk(visitor);
503 function.return_parameter_types.walk(visitor);
504});
505
506impl_walk!(ParameterList, visit_parameter_list, |parameter_list, visitor| {
507 parameter_list.parameters.iter().for_each(|parameter| {
508 parameter.walk(visitor);
509 });
510});
511
512impl_walk!(Mapping, visit_mapping, |mapping, visitor| {
513 mapping.key_type.walk(visitor);
514 mapping.value_type.walk(visitor);
515});
516
517impl_walk!(ArrayTypeName, visit_array_type_name, |array, visitor| {
518 array.base_type.walk(visitor);
519 if let Some(length) = &array.length {
520 length.walk(visitor);
521 }
522});
523
524impl_walk!(InheritanceSpecifier, visit_inheritance_specifier, |specifier, visitor| {
525 specifier.base_name.walk(visitor);
526 specifier.arguments.iter().for_each(|arg| {
527 arg.walk(visitor);
528 });
529});
530
531impl_walk!(ModifierInvocation, visit_modifier_invocation, |invocation, visitor| {
532 invocation.arguments.iter().for_each(|arg| arg.walk(visitor));
533 invocation.modifier_name.walk(visitor);
534});
535
536impl_walk!(InlineAssembly, visit_inline_assembly, |assembly, visitor| {
537 assembly.external_references.iter().for_each(|reference| {
538 reference.walk(visitor);
539 });
540});
541
542impl_walk!(ExternalInlineAssemblyReference, visit_external_assembly_reference);
543
544impl_walk!(ElementaryTypeName, visit_elementary_type_name);
545impl_walk!(Literal, visit_literal);
546impl_walk!(ImportDirective, visit_import_directive);
547impl_walk!(PragmaDirective, visit_pragma_directive);
548impl_walk!(IdentifierPath, visit_identifier_path);
549impl_walk!(EnumDefinition, visit_enum_definition);
550impl_walk!(Identifier, visit_identifier);
551
552impl_walk!(UserDefinedTypeNameOrIdentifierPath, |type_name, visitor| {
553 match type_name {
554 UserDefinedTypeNameOrIdentifierPath::UserDefinedTypeName(type_name) => {
555 type_name.walk(visitor);
556 }
557 UserDefinedTypeNameOrIdentifierPath::IdentifierPath(identifier_path) => {
558 identifier_path.walk(visitor);
559 }
560 }
561});
562
563impl_walk!(BlockOrStatement, |block_or_statement, visitor| {
564 match block_or_statement {
565 BlockOrStatement::Block(block) => {
566 block.walk(visitor);
567 }
568 BlockOrStatement::Statement(statement) => {
569 statement.walk(visitor);
570 }
571 }
572});
573
574impl_walk!(ExpressionOrVariableDeclarationStatement, |val, visitor| {
575 match val {
576 ExpressionOrVariableDeclarationStatement::ExpressionStatement(expression) => {
577 expression.walk(visitor);
578 }
579 ExpressionOrVariableDeclarationStatement::VariableDeclarationStatement(stmt) => {
580 stmt.walk(visitor);
581 }
582 }
583});
584
585impl_walk!(IdentifierOrIdentifierPath, |val, visitor| {
586 match val {
587 IdentifierOrIdentifierPath::Identifier(ident) => {
588 ident.walk(visitor);
589 }
590 IdentifierOrIdentifierPath::IdentifierPath(path) => {
591 path.walk(visitor);
592 }
593 }
594});
595
596impl_walk!(ExpressionStatement, |expression_statement, visitor| {
597 expression_statement.expression.walk(visitor);
598});
599
600impl_walk!(ElementaryTypeNameExpression, |type_name, visitor| {
601 type_name.type_name.walk(visitor);
602});
603
604impl_walk!(ElementaryOrRawTypeName, |type_name, visitor| {
605 match type_name {
606 ElementaryOrRawTypeName::ElementaryTypeName(type_name) => {
607 type_name.walk(visitor);
608 }
609 ElementaryOrRawTypeName::Raw(_) => {}
610 }
611});
612
613impl_walk!(UsingForFunctionItem, |item, visitor| {
614 match item {
615 UsingForFunctionItem::Function(func) => {
616 func.function.walk(visitor);
617 }
618 UsingForFunctionItem::OverloadedOperator(operator) => {
619 operator.walk(visitor);
620 }
621 }
622});
623
624impl_walk!(OverloadedOperator, |operator, visitor| {
625 operator.definition.walk(visitor);
626});