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