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::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                    // nothing to do
524                }
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
734/// The default node visitor.
735pub 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}