Skip to main content

darklua_core/process/
visitors.rs

1use crate::nodes::*;
2use crate::process::NodeProcessor;
3
4use std::marker::PhantomData;
5
6/// A trait that defines method that iterates on nodes and process them using a NodeProcessor.
7pub 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                    // nothing to do
542                }
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
752/// The default node visitor.
753pub 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}