1use crate::nodes::*;
2use crate::process::NodeProcessor;
3
4use std::marker::PhantomData;
5
6pub trait NodeVisitor<T: NodeProcessor> {
8 fn visit_block(block: &mut Block, processor: &mut T) {
9 processor.process_block(block);
10
11 block
12 .iter_mut_statements()
13 .for_each(|statement| Self::visit_statement(statement, processor));
14
15 if let Some(last_statement) = block.mutate_last_statement() {
16 Self::visit_last_statement(last_statement, processor);
17 };
18 }
19
20 fn visit_statement(statement: &mut Statement, processor: &mut T) {
21 processor.process_statement(statement);
22
23 match statement {
24 Statement::Assign(statement) => Self::visit_assign_statement(statement, processor),
25 Statement::Do(statement) => Self::visit_do_statement(statement, processor),
26 Statement::Call(statement) => Self::visit_function_call(statement, processor),
27 Statement::CompoundAssign(statement) => {
28 Self::visit_compound_assign(statement, processor)
29 }
30 Statement::Function(statement) => Self::visit_function_statement(statement, processor),
31 Statement::GenericFor(statement) => Self::visit_generic_for(statement, processor),
32 Statement::If(statement) => Self::visit_if_statement(statement, processor),
33 Statement::LocalAssign(statement) => Self::visit_local_assign(statement, processor),
34 Statement::LocalFunction(statement) => Self::visit_local_function(statement, processor),
35 Statement::NumericFor(statement) => Self::visit_numeric_for(statement, processor),
36 Statement::Repeat(statement) => Self::visit_repeat_statement(statement, processor),
37 Statement::While(statement) => Self::visit_while_statement(statement, processor),
38 Statement::TypeDeclaration(statement) => {
39 Self::visit_type_declaration(statement, processor)
40 }
41 Statement::TypeFunction(statement) => Self::visit_type_function(statement, processor),
42 };
43 }
44
45 fn visit_last_statement(last_statement: &mut LastStatement, processor: &mut T) {
46 processor.process_last_statement(last_statement);
47
48 if let LastStatement::Return(expressions) = last_statement {
49 expressions
50 .iter_mut_expressions()
51 .for_each(|expression| Self::visit_expression(expression, processor));
52 };
53 }
54
55 fn visit_expression(expression: &mut Expression, processor: &mut T) {
56 processor.process_expression(expression);
57
58 match expression {
59 Expression::Binary(expression) => {
60 Self::visit_binary_expression(expression, processor);
61 }
62 Expression::Call(expression) => Self::visit_function_call(expression, processor),
63 Expression::Field(field) => Self::visit_field_expression(field, processor),
64 Expression::Function(function) => Self::visit_function_expression(function, processor),
65 Expression::Identifier(identifier) => Self::visit_identifier(identifier, processor),
66 Expression::If(if_expression) => Self::visit_if_expression(if_expression, processor),
67 Expression::Index(index) => Self::visit_index_expression(index, processor),
68 Expression::Number(number) => Self::visit_number_expression(number, processor),
69 Expression::Parenthese(expression) => {
70 Self::visit_parenthese_expression(expression, processor);
71 }
72 Expression::String(string) => {
73 Self::visit_string_expression(string, processor);
74 }
75 Expression::InterpolatedString(interpolated_string) => {
76 Self::visit_interpolated_string_expression(interpolated_string, processor);
77 }
78 Expression::Table(table) => Self::visit_table(table, processor),
79 Expression::Unary(unary) => {
80 Self::visit_unary_expression(unary, processor);
81 }
82 Expression::TypeCast(type_cast) => {
83 Self::visit_type_cast_expression(type_cast, processor);
84 }
85 Expression::TypeInstantiation(type_instantiation) => {
86 Self::visit_type_instantiation(type_instantiation, processor);
87 }
88 Expression::False(_)
89 | Expression::Nil(_)
90 | Expression::True(_)
91 | Expression::VariableArguments(_) => {}
92 }
93 }
94
95 fn visit_binary_expression(binary: &mut BinaryExpression, processor: &mut T) {
96 processor.process_binary_expression(binary);
97 Self::visit_expression(binary.mutate_left(), processor);
98 Self::visit_expression(binary.mutate_right(), processor);
99 }
100
101 fn visit_number_expression(number: &mut NumberExpression, processor: &mut T) {
102 processor.process_number_expression(number);
103 }
104
105 fn visit_parenthese_expression(parenthese: &mut ParentheseExpression, processor: &mut T) {
106 processor.process_parenthese_expression(parenthese);
107 Self::visit_expression(parenthese.mutate_inner_expression(), processor)
108 }
109
110 fn visit_string_expression(string: &mut StringExpression, processor: &mut T) {
111 processor.process_string_expression(string);
112 }
113
114 fn visit_interpolated_string_expression(
115 interpolated_string: &mut InterpolatedStringExpression,
116 processor: &mut T,
117 ) {
118 processor.process_interpolated_string_expression(interpolated_string);
119
120 for segment in interpolated_string.iter_mut_segments() {
121 match segment {
122 InterpolationSegment::String(_) => {}
123 InterpolationSegment::Value(value) => {
124 Self::visit_expression(value.mutate_expression(), processor)
125 }
126 }
127 }
128 }
129
130 fn visit_unary_expression(unary: &mut UnaryExpression, processor: &mut T) {
131 processor.process_unary_expression(unary);
132 Self::visit_expression(unary.mutate_expression(), processor);
133 }
134
135 fn visit_type_cast_expression(type_cast: &mut TypeCastExpression, processor: &mut T) {
136 processor.process_type_cast_expression(type_cast);
137
138 Self::visit_expression(type_cast.mutate_expression(), processor);
139 Self::visit_type(type_cast.mutate_type(), processor);
140 }
141
142 fn visit_type_instantiation(
143 type_instantiation: &mut TypeInstantiationExpression,
144 processor: &mut T,
145 ) {
146 processor.process_type_instantiation(type_instantiation);
147
148 Self::visit_prefix_expression(type_instantiation.mutate_prefix(), processor);
149 for r#type in type_instantiation.iter_mut_types() {
150 Self::visit_type(r#type, processor);
151 }
152 }
153
154 fn visit_function_expression(function: &mut FunctionExpression, processor: &mut T) {
155 processor.process_function_expression(function);
156 Self::visit_attributes(function.mutate_attributes(), processor);
157
158 processor.process_scope(function.mutate_block(), None);
159
160 Self::visit_block(function.mutate_block(), processor);
161
162 for r#type in function
163 .iter_mut_parameters()
164 .filter_map(TypedIdentifier::mutate_type)
165 {
166 Self::visit_type(r#type, processor);
167 }
168
169 if let Some(variadic_type) = function.mutate_variadic_type() {
170 Self::visit_function_variadic_type(variadic_type, processor);
171 }
172
173 if let Some(return_type) = function.mutate_return_type() {
174 Self::visit_function_return_type(return_type, processor);
175 }
176 }
177
178 fn visit_assign_statement(statement: &mut AssignStatement, processor: &mut T) {
179 processor.process_assign_statement(statement);
180
181 statement
182 .mutate_variables()
183 .iter_mut()
184 .for_each(|variable| Self::visit_variable(variable, processor));
185
186 statement
187 .iter_mut_values()
188 .for_each(|expression| Self::visit_expression(expression, processor));
189 }
190
191 fn visit_do_statement(statement: &mut DoStatement, processor: &mut T) {
192 processor.process_do_statement(statement);
193 processor.process_scope(statement.mutate_block(), None);
194 Self::visit_block(statement.mutate_block(), processor);
195 }
196
197 fn visit_compound_assign(statement: &mut CompoundAssignStatement, processor: &mut T) {
198 processor.process_compound_assign_statement(statement);
199 Self::visit_variable(statement.mutate_variable(), processor);
200 Self::visit_expression(statement.mutate_value(), processor);
201 }
202
203 fn visit_function_statement(statement: &mut FunctionStatement, processor: &mut T) {
204 processor.process_function_statement(statement);
205 Self::visit_attributes(statement.mutate_attributes(), processor);
206
207 Self::visit_identifier(
208 statement.mutate_function_name().mutate_identifier(),
209 processor,
210 );
211
212 processor.process_scope(statement.mutate_block(), None);
213 Self::visit_block(statement.mutate_block(), processor);
214
215 for r#type in statement
216 .iter_mut_parameters()
217 .filter_map(TypedIdentifier::mutate_type)
218 {
219 Self::visit_type(r#type, processor);
220 }
221
222 if let Some(variadic_type) = statement.mutate_variadic_type() {
223 Self::visit_function_variadic_type(variadic_type, processor);
224 }
225
226 if let Some(return_type) = statement.mutate_return_type() {
227 Self::visit_function_return_type(return_type, processor);
228 }
229 }
230
231 fn visit_generic_for(statement: &mut GenericForStatement, processor: &mut T) {
232 processor.process_generic_for_statement(statement);
233
234 statement
235 .iter_mut_expressions()
236 .for_each(|expression| Self::visit_expression(expression, processor));
237
238 processor.process_scope(statement.mutate_block(), None);
239 Self::visit_block(statement.mutate_block(), processor);
240
241 for r#type in statement
242 .iter_mut_identifiers()
243 .filter_map(TypedIdentifier::mutate_type)
244 {
245 Self::visit_type(r#type, processor);
246 }
247 }
248
249 fn visit_if_statement(statement: &mut IfStatement, processor: &mut T) {
250 processor.process_if_statement(statement);
251
252 statement.mutate_branches().iter_mut().for_each(|branch| {
253 Self::visit_expression(branch.mutate_condition(), processor);
254 processor.process_scope(branch.mutate_block(), None);
255 Self::visit_block(branch.mutate_block(), processor);
256 });
257
258 if let Some(block) = statement.mutate_else_block() {
259 processor.process_scope(block, None);
260 Self::visit_block(block, processor);
261 }
262 }
263
264 fn visit_local_assign(statement: &mut VariableAssignment, processor: &mut T) {
265 processor.process_local_assign_statement(statement);
266
267 statement
268 .iter_mut_values()
269 .for_each(|value| Self::visit_expression(value, processor));
270
271 for r#type in statement
272 .iter_mut_variables()
273 .filter_map(TypedIdentifier::mutate_type)
274 {
275 Self::visit_type(r#type, processor);
276 }
277 }
278
279 fn visit_local_function(statement: &mut FunctionAssignment, processor: &mut T) {
280 processor.process_local_function_statement(statement);
281 Self::visit_attributes(statement.mutate_attributes(), processor);
282
283 processor.process_scope(statement.mutate_block(), None);
284 Self::visit_block(statement.mutate_block(), processor);
285
286 for r#type in statement
287 .iter_mut_parameters()
288 .filter_map(TypedIdentifier::mutate_type)
289 {
290 Self::visit_type(r#type, processor);
291 }
292
293 if let Some(variadic_type) = statement.mutate_variadic_type() {
294 Self::visit_function_variadic_type(variadic_type, processor);
295 }
296
297 if let Some(return_type) = statement.mutate_return_type() {
298 Self::visit_function_return_type(return_type, processor);
299 }
300 }
301
302 fn visit_function_variadic_type(variadic_type: &mut FunctionVariadicType, processor: &mut T) {
303 match variadic_type {
304 FunctionVariadicType::Type(r#type) => {
305 Self::visit_type(r#type, processor);
306 }
307 FunctionVariadicType::GenericTypePack(generic) => {
308 Self::visit_generic_type_pack(generic, processor);
309 }
310 }
311 }
312
313 fn visit_generic_type_pack(generic: &mut GenericTypePack, processor: &mut T) {
314 processor.process_generic_type_pack(generic);
315 }
316
317 fn visit_numeric_for(statement: &mut NumericForStatement, processor: &mut T) {
318 processor.process_numeric_for_statement(statement);
319
320 Self::visit_expression(statement.mutate_start(), processor);
321 Self::visit_expression(statement.mutate_end(), processor);
322
323 if let Some(step) = statement.mutate_step() {
324 Self::visit_expression(step, processor);
325 };
326
327 processor.process_scope(statement.mutate_block(), None);
328 Self::visit_block(statement.mutate_block(), processor);
329
330 if let Some(r#type) = statement.mutate_identifier().mutate_type() {
331 Self::visit_type(r#type, processor);
332 }
333 }
334
335 fn visit_repeat_statement(statement: &mut RepeatStatement, processor: &mut T) {
336 processor.process_repeat_statement(statement);
337
338 let (block, condition) = statement.mutate_block_and_condition();
339 processor.process_scope(block, Some(condition));
340
341 Self::visit_expression(statement.mutate_condition(), processor);
342 Self::visit_block(statement.mutate_block(), processor);
343 }
344
345 fn visit_while_statement(statement: &mut WhileStatement, processor: &mut T) {
346 processor.process_while_statement(statement);
347
348 Self::visit_expression(statement.mutate_condition(), processor);
349
350 processor.process_scope(statement.mutate_block(), None);
351 Self::visit_block(statement.mutate_block(), processor);
352 }
353
354 fn visit_type_declaration(statement: &mut TypeDeclarationStatement, processor: &mut T) {
355 processor.process_type_declaration(statement);
356
357 if let Some(generic_parameters) = statement.mutate_generic_parameters() {
358 for parameter in generic_parameters {
359 match parameter {
360 GenericParameterMutRef::TypeVariable(_) => {}
361 GenericParameterMutRef::TypeVariableWithDefault(type_variable) => {
362 Self::visit_type(type_variable.mutate_default_type(), processor);
363 }
364 GenericParameterMutRef::GenericTypePack(generic_type_pack) => {
365 Self::visit_generic_type_pack(generic_type_pack, processor);
366 }
367 GenericParameterMutRef::GenericTypePackWithDefault(
368 generic_type_pack_with_default,
369 ) => {
370 Self::visit_generic_type_pack(
371 generic_type_pack_with_default.mutate_generic_type_pack(),
372 processor,
373 );
374
375 match generic_type_pack_with_default.mutate_default_type() {
376 GenericTypePackDefault::TypePack(type_pack) => {
377 Self::visit_type_pack(type_pack, processor);
378 }
379 GenericTypePackDefault::VariadicTypePack(variadic_type_pack) => {
380 Self::visit_variadic_type_pack(variadic_type_pack, processor);
381 }
382 GenericTypePackDefault::GenericTypePack(generic_type_pack) => {
383 Self::visit_generic_type_pack(generic_type_pack, processor);
384 }
385 }
386 }
387 }
388 }
389 }
390
391 Self::visit_type(statement.mutate_type(), processor);
392 }
393
394 fn visit_type_function(statement: &mut TypeFunctionStatement, processor: &mut T) {
395 processor.process_type_function(statement);
396 processor.process_scope(statement.mutate_block(), None);
397 Self::visit_block(statement.mutate_block(), processor);
398
399 for r#type in statement
400 .iter_mut_parameters()
401 .filter_map(TypedIdentifier::mutate_type)
402 {
403 Self::visit_type(r#type, processor);
404 }
405
406 if let Some(variadic_type) = statement.mutate_variadic_type() {
407 Self::visit_function_variadic_type(variadic_type, processor);
408 }
409
410 if let Some(return_type) = statement.mutate_return_type() {
411 Self::visit_function_return_type(return_type, processor);
412 }
413 }
414
415 fn visit_variable(variable: &mut Variable, processor: &mut T) {
416 processor.process_variable(variable);
417
418 match variable {
419 Variable::Identifier(identifier) => Self::visit_identifier(identifier, processor),
420 Variable::Field(field) => Self::visit_field_expression(field, processor),
421 Variable::Index(index) => Self::visit_index_expression(index, processor),
422 }
423 }
424
425 fn visit_identifier(identifier: &mut Identifier, processor: &mut T) {
426 processor.process_variable_expression(identifier);
427 }
428
429 fn visit_if_expression(if_expression: &mut IfExpression, processor: &mut T) {
430 processor.process_if_expression(if_expression);
431
432 Self::visit_expression(if_expression.mutate_condition(), processor);
433 Self::visit_expression(if_expression.mutate_result(), processor);
434
435 for branch in if_expression.iter_mut_branches() {
436 Self::visit_expression(branch.mutate_condition(), processor);
437 Self::visit_expression(branch.mutate_result(), processor);
438 }
439
440 Self::visit_expression(if_expression.mutate_else_result(), processor);
441 }
442
443 fn visit_field_expression(field: &mut FieldExpression, processor: &mut T) {
444 processor.process_field_expression(field);
445
446 Self::visit_prefix_expression(field.mutate_prefix(), processor);
447 }
448
449 fn visit_index_expression(index: &mut IndexExpression, processor: &mut T) {
450 processor.process_index_expression(index);
451
452 Self::visit_prefix_expression(index.mutate_prefix(), processor);
453 Self::visit_expression(index.mutate_index(), processor);
454 }
455
456 fn visit_function_call(call: &mut FunctionCall, processor: &mut T) {
457 processor.process_function_call(call);
458
459 Self::visit_prefix_expression(call.mutate_prefix(), processor);
460 Self::visit_arguments(call.mutate_arguments(), processor);
461 }
462
463 fn visit_arguments(arguments: &mut Arguments, processor: &mut T) {
464 match arguments {
465 Arguments::String(string) => Self::visit_string_expression(string, processor),
466 Arguments::Table(table) => Self::visit_table(table, processor),
467 Arguments::Tuple(expressions) => expressions
468 .iter_mut_values()
469 .for_each(|expression| Self::visit_expression(expression, processor)),
470 }
471 }
472
473 fn visit_table(table: &mut TableExpression, processor: &mut T) {
474 processor.process_table_expression(table);
475
476 table.iter_mut_entries().for_each(|entry| match entry {
477 TableEntry::Field(entry) => Self::visit_expression(entry.mutate_value(), processor),
478 TableEntry::Index(entry) => {
479 Self::visit_expression(entry.mutate_key(), processor);
480 Self::visit_expression(entry.mutate_value(), processor);
481 }
482 TableEntry::Value(value) => Self::visit_expression(value, processor),
483 });
484 }
485
486 fn visit_prefix_expression(prefix: &mut Prefix, processor: &mut T) {
487 processor.process_prefix_expression(prefix);
488
489 match prefix {
490 Prefix::Call(call) => Self::visit_function_call(call, processor),
491 Prefix::Field(field) => Self::visit_field_expression(field, processor),
492 Prefix::Identifier(identifier) => Self::visit_identifier(identifier, processor),
493 Prefix::Index(index) => Self::visit_index_expression(index, processor),
494 Prefix::Parenthese(expression) => {
495 Self::visit_parenthese_expression(expression, processor)
496 }
497 Prefix::TypeInstantiation(type_instantiation) => {
498 Self::visit_type_instantiation(type_instantiation, processor);
499 }
500 };
501 }
502
503 fn visit_attributes(attributes: &mut Attributes, processor: &mut T) {
504 processor.process_attributes(attributes);
505 for attribute in attributes.iter_mut_attributes() {
506 match attribute {
507 Attribute::Group(group) => {
508 for arguments in group
509 .iter_mut_attributes()
510 .flat_map(AttributeGroupElement::mutate_arguments)
511 {
512 match arguments {
513 AttributeArguments::Tuple(arguments) => {
514 for value in arguments.iter_mut_values() {
515 match value {
516 LiteralExpression::True(_)
517 | LiteralExpression::False(_)
518 | LiteralExpression::Nil(_) => {}
519 LiteralExpression::Number(number) => {
520 Self::visit_number_expression(number, processor);
521 }
522 LiteralExpression::String(string) => {
523 Self::visit_string_expression(string, processor);
524 }
525 LiteralExpression::Table(table) => {
526 Self::visit_literal_table(table, processor);
527 }
528 }
529 }
530 }
531 AttributeArguments::String(string) => {
532 Self::visit_string_expression(string, processor);
533 }
534 AttributeArguments::Table(table) => {
535 Self::visit_literal_table(table, processor);
536 }
537 }
538 }
539 }
540 Attribute::Name(_) => {
541 }
543 }
544 }
545 }
546
547 fn visit_literal_table(table: &mut LiteralTable, processor: &mut T) {
548 processor.process_literal_table(table);
549
550 for entry in table.iter_mut_entries() {
551 match entry {
552 LiteralTableEntry::Field(field) => {
553 Self::visit_literal_expression(field.mutate_value(), processor);
554 }
555 LiteralTableEntry::Value(value) => {
556 Self::visit_literal_expression(value, processor);
557 }
558 }
559 }
560 }
561
562 fn visit_literal_expression(expression: &mut LiteralExpression, processor: &mut T) {
563 processor.process_literal_expression(expression);
564
565 match expression {
566 LiteralExpression::Number(number) => {
567 Self::visit_number_expression(number, processor);
568 }
569 LiteralExpression::String(string) => {
570 Self::visit_string_expression(string, processor);
571 }
572 LiteralExpression::Table(table) => {
573 Self::visit_literal_table(table, processor);
574 }
575 LiteralExpression::True(_)
576 | LiteralExpression::False(_)
577 | LiteralExpression::Nil(_) => {}
578 }
579 }
580
581 fn visit_type(r#type: &mut Type, processor: &mut T) {
582 processor.process_type(r#type);
583
584 match r#type {
585 Type::Name(type_name) => Self::visit_type_name(type_name, processor),
586 Type::Field(type_field) => Self::visit_type_field(type_field, processor),
587 Type::Array(array) => Self::visit_array_type(array, processor),
588 Type::Table(table) => Self::visit_table_type(table, processor),
589 Type::TypeOf(expression_type) => {
590 Self::visit_expression_type(expression_type, processor)
591 }
592 Type::Parenthese(parenthese) => Self::visit_parenthese_type(parenthese, processor),
593 Type::Function(function) => Self::visit_function_type(function, processor),
594 Type::Optional(optional) => Self::visit_optional_type(optional, processor),
595 Type::Intersection(intersection) => {
596 Self::visit_intersection_type(intersection, processor)
597 }
598 Type::Union(union) => Self::visit_union_type(union, processor),
599 Type::String(string) => Self::visit_string_type(string, processor),
600 Type::True(_) | Type::False(_) | Type::Nil(_) => {}
601 }
602 }
603
604 fn visit_type_name(type_name: &mut TypeName, processor: &mut T) {
605 processor.process_type_name(type_name);
606
607 if let Some(type_parameters) = type_name.mutate_type_parameters() {
608 for type_parameter in type_parameters {
609 match type_parameter {
610 TypeParameter::Type(next_type) => {
611 Self::visit_type(next_type, processor);
612 }
613 TypeParameter::TypePack(type_pack) => {
614 Self::visit_type_pack(type_pack, processor);
615 }
616 TypeParameter::VariadicTypePack(variadic_type_pack) => {
617 Self::visit_variadic_type_pack(variadic_type_pack, processor);
618 }
619 TypeParameter::GenericTypePack(generic_type_pack) => {
620 Self::visit_generic_type_pack(generic_type_pack, processor);
621 }
622 }
623 }
624 }
625 }
626
627 fn visit_type_field(type_field: &mut TypeField, processor: &mut T) {
628 processor.process_type_field(type_field);
629 Self::visit_type_name(type_field.mutate_type_name(), processor);
630 }
631
632 fn visit_array_type(array: &mut ArrayType, processor: &mut T) {
633 processor.process_array_type(array);
634 Self::visit_type(array.mutate_element_type(), processor);
635 }
636
637 fn visit_table_type(table: &mut TableType, processor: &mut T) {
638 processor.process_table_type(table);
639
640 for entry in table.iter_mut_entries() {
641 match entry {
642 TableEntryType::Property(property) => {
643 Self::visit_type(property.mutate_type(), processor);
644 }
645 TableEntryType::Literal(property) => {
646 Self::visit_string_type(property.mutate_string(), processor);
647 Self::visit_type(property.mutate_type(), processor);
648 }
649 TableEntryType::Indexer(indexer) => {
650 Self::visit_type(indexer.mutate_key_type(), processor);
651 Self::visit_type(indexer.mutate_value_type(), processor);
652 }
653 }
654 }
655 }
656
657 fn visit_expression_type(expression_type: &mut ExpressionType, processor: &mut T) {
658 processor.process_expression_type(expression_type);
659 Self::visit_expression(expression_type.mutate_expression(), processor);
660 }
661
662 fn visit_parenthese_type(parenthese: &mut ParentheseType, processor: &mut T) {
663 processor.process_parenthese_type(parenthese);
664 Self::visit_type(parenthese.mutate_inner_type(), processor);
665 }
666
667 fn visit_function_type(function: &mut FunctionType, processor: &mut T) {
668 processor.process_function_type(function);
669
670 for argument in function.iter_mut_arguments() {
671 Self::visit_type(argument.mutate_type(), processor);
672 }
673
674 if let Some(variadic_type) = function.mutate_variadic_argument_type() {
675 Self::visit_variadic_argument_type(variadic_type, processor);
676 }
677
678 Self::visit_function_return_type(function.mutate_return_type(), processor);
679 }
680
681 fn visit_optional_type(optional: &mut OptionalType, processor: &mut T) {
682 processor.process_optional_type(optional);
683 Self::visit_type(optional.mutate_inner_type(), processor);
684 }
685
686 fn visit_intersection_type(intersection: &mut IntersectionType, processor: &mut T) {
687 processor.process_intersection_type(intersection);
688
689 for r#type in intersection.iter_mut_types() {
690 Self::visit_type(r#type, processor);
691 }
692 }
693
694 fn visit_union_type(union: &mut UnionType, processor: &mut T) {
695 processor.process_union_type(union);
696
697 for r#type in union.iter_mut_types() {
698 Self::visit_type(r#type, processor);
699 }
700 }
701
702 fn visit_string_type(string: &mut StringType, processor: &mut T) {
703 processor.process_string_type(string);
704 }
705
706 fn visit_type_pack(type_pack: &mut TypePack, processor: &mut T) {
707 processor.process_type_pack(type_pack);
708
709 for next_type in type_pack.into_iter() {
710 Self::visit_type(next_type, processor)
711 }
712 if let Some(variadic_type) = type_pack.mutate_variadic_type() {
713 Self::visit_variadic_argument_type(variadic_type, processor);
714 }
715 }
716
717 fn visit_variadic_type_pack(variadic_type_pack: &mut VariadicTypePack, processor: &mut T) {
718 processor.process_variadic_type_pack(variadic_type_pack);
719 Self::visit_type(variadic_type_pack.mutate_type(), processor);
720 }
721
722 fn visit_variadic_argument_type(variadic_type: &mut VariadicArgumentType, processor: &mut T) {
723 match variadic_type {
724 VariadicArgumentType::VariadicTypePack(variadic_type_pack) => {
725 Self::visit_variadic_type_pack(variadic_type_pack, processor);
726 }
727 VariadicArgumentType::GenericTypePack(generic_type_pack) => {
728 Self::visit_generic_type_pack(generic_type_pack, processor);
729 }
730 }
731 }
732
733 fn visit_function_return_type(
734 function_return_type: &mut FunctionReturnType,
735 processor: &mut T,
736 ) {
737 match function_return_type {
738 FunctionReturnType::Type(next_type) => {
739 Self::visit_type(next_type, processor);
740 }
741 FunctionReturnType::TypePack(type_pack) => Self::visit_type_pack(type_pack, processor),
742 FunctionReturnType::VariadicTypePack(variadic_type_pack) => {
743 Self::visit_variadic_type_pack(variadic_type_pack, processor);
744 }
745 FunctionReturnType::GenericTypePack(generic_type_pack) => {
746 Self::visit_generic_type_pack(generic_type_pack, processor);
747 }
748 }
749 }
750}
751
752pub struct DefaultVisitor<T> {
754 _phantom: PhantomData<T>,
755}
756
757impl<T: NodeProcessor> NodeVisitor<T> for DefaultVisitor<T> {}
758
759#[cfg(test)]
760mod test {
761 use super::*;
762 use crate::process::NodeCounter;
763
764 #[test]
765 fn visit_do_statement() {
766 let mut counter = NodeCounter::new();
767 let mut block = Block::default().with_statement(DoStatement::default());
768
769 DefaultVisitor::visit_block(&mut block, &mut counter);
770
771 assert_eq!(counter.block_count, 2);
772 assert_eq!(counter.do_count, 1);
773 }
774
775 #[test]
776 fn visit_numeric_for_statement() {
777 let mut counter = NodeCounter::new();
778 let mut block = Block::default().with_statement(NumericForStatement::new(
779 "i".to_owned(),
780 Expression::from(true),
781 Expression::from(true),
782 None,
783 Block::default(),
784 ));
785
786 DefaultVisitor::visit_block(&mut block, &mut counter);
787
788 assert_eq!(counter.block_count, 2);
789 assert_eq!(counter.expression_count, 2);
790 assert_eq!(counter.numeric_for_count, 1);
791 }
792
793 #[test]
794 fn visit_generic_for_statement() {
795 let mut counter = NodeCounter::new();
796 let mut block = Block::default().with_statement(GenericForStatement::new(
797 vec!["k".into()],
798 vec![Expression::from(true)],
799 Block::default(),
800 ));
801
802 DefaultVisitor::visit_block(&mut block, &mut counter);
803
804 assert_eq!(counter.block_count, 2);
805 assert_eq!(counter.expression_count, 1);
806 assert_eq!(counter.generic_for_count, 1);
807 }
808
809 #[test]
810 fn visit_repeat_statement() {
811 let mut counter = NodeCounter::new();
812 let mut block =
813 Block::default().with_statement(RepeatStatement::new(Block::default(), true));
814
815 DefaultVisitor::visit_block(&mut block, &mut counter);
816
817 assert_eq!(counter.block_count, 2);
818 assert_eq!(counter.expression_count, 1);
819 assert_eq!(counter.repeat_count, 1);
820 }
821
822 #[test]
823 fn visit_while_statement() {
824 let mut counter = NodeCounter::new();
825 let mut block =
826 Block::default().with_statement(WhileStatement::new(Block::default(), true));
827
828 DefaultVisitor::visit_block(&mut block, &mut counter);
829
830 assert_eq!(counter.block_count, 2);
831 assert_eq!(counter.expression_count, 1);
832 assert_eq!(counter.while_count, 1);
833 }
834
835 #[test]
836 fn visit_if_statement() {
837 let mut counter = NodeCounter::new();
838 let mut block =
839 Block::default().with_statement(IfStatement::create(true, Block::default()));
840
841 DefaultVisitor::visit_block(&mut block, &mut counter);
842
843 assert_eq!(counter.block_count, 2);
844 assert_eq!(counter.expression_count, 1);
845 assert_eq!(counter.if_count, 1);
846 }
847
848 #[test]
849 fn visit_if_statement_with_else() {
850 let mut counter = NodeCounter::new();
851 let if_statement =
852 IfStatement::create(true, Block::default()).with_else_block(Block::default());
853
854 let mut block = Block::default().with_statement(if_statement);
855
856 DefaultVisitor::visit_block(&mut block, &mut counter);
857
858 assert_eq!(counter.block_count, 3);
859 assert_eq!(counter.expression_count, 1);
860 assert_eq!(counter.if_count, 1);
861 }
862
863 #[test]
864 fn visit_if_statement_with_elseif_and_else() {
865 let mut counter = NodeCounter::new();
866 let if_statement = IfStatement::create(true, Block::default())
867 .with_new_branch(false, Block::default())
868 .with_else_block(Block::default());
869
870 let mut block = Block::default().with_statement(if_statement);
871
872 DefaultVisitor::visit_block(&mut block, &mut counter);
873
874 assert_eq!(counter.block_count, 4);
875 assert_eq!(counter.expression_count, 2);
876 assert_eq!(counter.if_count, 1);
877 }
878
879 #[test]
880 fn visit_compound_assign_statement() {
881 let mut counter = NodeCounter::new();
882 let statement =
883 CompoundAssignStatement::new(CompoundOperator::Plus, Variable::new("var"), 1_f64);
884
885 let mut block = statement.into();
886
887 DefaultVisitor::visit_block(&mut block, &mut counter);
888
889 assert_eq!(counter.compound_assign, 1);
890 assert_eq!(counter.expression_count, 1);
891 assert_eq!(counter.variable_count, 1);
892 }
893
894 #[test]
895 fn visit_interpolated_string() {
896 let mut counter = NodeCounter::new();
897 let statement = VariableAssignment::from_variable("value")
898 .with_value(InterpolatedStringExpression::empty().with_segment(Expression::from(true)));
899
900 let mut block = statement.into();
901
902 DefaultVisitor::visit_block(&mut block, &mut counter);
903
904 assert_eq!(counter.interpolated_string_count, 1);
905 assert_eq!(counter.expression_count, 2);
906 }
907}