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