darklua_core/generator/
mod.rs

1//! A module that contains the main [LuaGenerator](trait.LuaGenerator.html) trait
2//! and its implementations.
3
4mod dense;
5mod readable;
6mod token_based;
7pub(crate) mod utils;
8
9pub use dense::DenseLuaGenerator;
10pub use readable::ReadableLuaGenerator;
11pub use token_based::TokenBasedLuaGenerator;
12
13use crate::nodes;
14
15/// A trait to let its implementation define how the Lua code is generated. See
16/// [ReadableLuaGenerator](struct.ReadableLuaGenerator.html) and
17/// [DenseLuaGenerator](struct.DenseLuaGenerator.html) for implementations.
18pub trait LuaGenerator {
19    /// Consumes the LuaGenerator and produce a String object.
20    fn into_string(self) -> String;
21
22    fn write_block(&mut self, block: &nodes::Block);
23
24    fn write_statement(&mut self, statement: &nodes::Statement) {
25        use nodes::Statement::*;
26        match statement {
27            Assign(statement) => self.write_assign_statement(statement),
28            Do(statement) => self.write_do_statement(statement),
29            Call(statement) => self.write_function_call(statement),
30            CompoundAssign(statement) => self.write_compound_assign(statement),
31            Function(statement) => self.write_function_statement(statement),
32            GenericFor(statement) => self.write_generic_for(statement),
33            If(statement) => self.write_if_statement(statement),
34            LocalAssign(statement) => self.write_local_assign(statement),
35            LocalFunction(statement) => self.write_local_function(statement),
36            NumericFor(statement) => self.write_numeric_for(statement),
37            Repeat(statement) => self.write_repeat_statement(statement),
38            While(statement) => self.write_while_statement(statement),
39            TypeDeclaration(statement) => self.write_type_declaration_statement(statement),
40        }
41    }
42
43    fn write_assign_statement(&mut self, assign: &nodes::AssignStatement);
44    fn write_do_statement(&mut self, do_statement: &nodes::DoStatement);
45    fn write_compound_assign(&mut self, assign: &nodes::CompoundAssignStatement);
46    fn write_generic_for(&mut self, generic_for: &nodes::GenericForStatement);
47    fn write_if_statement(&mut self, if_statement: &nodes::IfStatement);
48    fn write_function_statement(&mut self, function: &nodes::FunctionStatement);
49    fn write_last_statement(&mut self, statement: &nodes::LastStatement);
50    fn write_local_assign(&mut self, assign: &nodes::LocalAssignStatement);
51    fn write_local_function(&mut self, function: &nodes::LocalFunctionStatement);
52    fn write_numeric_for(&mut self, numeric_for: &nodes::NumericForStatement);
53    fn write_repeat_statement(&mut self, repeat: &nodes::RepeatStatement);
54    fn write_while_statement(&mut self, while_statement: &nodes::WhileStatement);
55    fn write_type_declaration_statement(&mut self, statement: &nodes::TypeDeclarationStatement);
56
57    fn write_variable(&mut self, variable: &nodes::Variable) {
58        use nodes::Variable::*;
59        match variable {
60            Identifier(identifier) => self.write_identifier(identifier),
61            Field(field) => self.write_field(field),
62            Index(index) => self.write_index(index),
63        }
64    }
65
66    fn write_expression(&mut self, expression: &nodes::Expression) {
67        use nodes::Expression::*;
68        match expression {
69            Binary(binary) => self.write_binary_expression(binary),
70            Call(call) => self.write_function_call(call),
71            False(token) => self.write_false_expression(token),
72            Field(field) => self.write_field(field),
73            Function(function) => self.write_function(function),
74            Identifier(identifier) => self.write_identifier(identifier),
75            If(if_expression) => self.write_if_expression(if_expression),
76            Index(index) => self.write_index(index),
77            Nil(token) => self.write_nil_expression(token),
78            Number(number) => self.write_number(number),
79            Parenthese(parenthese) => self.write_parenthese(parenthese),
80            String(string) => self.write_string(string),
81            InterpolatedString(string) => self.write_interpolated_string(string),
82            Table(table) => self.write_table(table),
83            True(token) => self.write_true_expression(token),
84            Unary(unary) => self.write_unary_expression(unary),
85            VariableArguments(token) => self.write_variable_arguments_expression(token),
86            TypeCast(type_cast) => self.write_type_cast(type_cast),
87        }
88    }
89
90    fn write_identifier(&mut self, identifier: &nodes::Identifier);
91    fn write_binary_expression(&mut self, binary: &nodes::BinaryExpression);
92    fn write_if_expression(&mut self, if_expression: &nodes::IfExpression);
93    fn write_unary_expression(&mut self, unary: &nodes::UnaryExpression);
94    fn write_function(&mut self, function: &nodes::FunctionExpression);
95    fn write_function_call(&mut self, call: &nodes::FunctionCall);
96    fn write_field(&mut self, field: &nodes::FieldExpression);
97    fn write_index(&mut self, index: &nodes::IndexExpression);
98    fn write_parenthese(&mut self, parenthese: &nodes::ParentheseExpression);
99    fn write_type_cast(&mut self, type_cast: &nodes::TypeCastExpression);
100
101    fn write_false_expression(&mut self, token: &Option<nodes::Token>);
102    fn write_true_expression(&mut self, token: &Option<nodes::Token>);
103    fn write_nil_expression(&mut self, token: &Option<nodes::Token>);
104    fn write_variable_arguments_expression(&mut self, token: &Option<nodes::Token>);
105
106    fn write_prefix(&mut self, prefix: &nodes::Prefix) {
107        use nodes::Prefix::*;
108        match prefix {
109            Call(call) => self.write_function_call(call),
110            Field(field) => self.write_field(field),
111            Identifier(identifier) => self.write_identifier(identifier),
112            Index(index) => self.write_index(index),
113            Parenthese(parenthese) => self.write_parenthese(parenthese),
114        }
115    }
116
117    fn write_table(&mut self, table: &nodes::TableExpression);
118    fn write_table_entry(&mut self, entry: &nodes::TableEntry);
119    fn write_number(&mut self, number: &nodes::NumberExpression);
120
121    fn write_arguments(&mut self, arguments: &nodes::Arguments) {
122        use nodes::Arguments::*;
123        match arguments {
124            String(string) => self.write_string(string),
125            Table(table) => self.write_table(table),
126            Tuple(tuple) => self.write_tuple_arguments(tuple),
127        }
128    }
129
130    fn write_tuple_arguments(&mut self, arguments: &nodes::TupleArguments);
131
132    fn write_string(&mut self, string: &nodes::StringExpression);
133
134    fn write_interpolated_string(&mut self, string: &nodes::InterpolatedStringExpression);
135
136    fn write_type(&mut self, r#type: &nodes::Type) {
137        match r#type {
138            nodes::Type::Name(type_name) => self.write_type_name(type_name),
139            nodes::Type::Field(type_field) => self.write_type_field(type_field),
140            nodes::Type::True(token) => self.write_true_type(token),
141            nodes::Type::False(token) => self.write_false_type(token),
142            nodes::Type::Nil(token) => self.write_nil_type(token),
143            nodes::Type::String(string_type) => self.write_string_type(string_type),
144            nodes::Type::Array(array_type) => self.write_array_type(array_type),
145            nodes::Type::Table(table_type) => self.write_table_type(table_type),
146            nodes::Type::TypeOf(expression_type) => self.write_expression_type(expression_type),
147            nodes::Type::Parenthese(parenthese_type) => self.write_parenthese_type(parenthese_type),
148            nodes::Type::Function(function_type) => self.write_function_type(function_type),
149            nodes::Type::Optional(optional_type) => self.write_optional_type(optional_type),
150            nodes::Type::Intersection(intersection_type) => {
151                self.write_intersection_type(intersection_type)
152            }
153            nodes::Type::Union(union_type) => self.write_union_type(union_type),
154        }
155    }
156    fn write_type_name(&mut self, type_name: &nodes::TypeName);
157    fn write_type_field(&mut self, type_field: &nodes::TypeField);
158    fn write_true_type(&mut self, token: &Option<nodes::Token>);
159    fn write_false_type(&mut self, token: &Option<nodes::Token>);
160    fn write_nil_type(&mut self, token: &Option<nodes::Token>);
161    fn write_string_type(&mut self, string_type: &nodes::StringType);
162    fn write_array_type(&mut self, array_type: &nodes::ArrayType);
163    fn write_table_type(&mut self, table_type: &nodes::TableType);
164    fn write_expression_type(&mut self, expression_type: &nodes::ExpressionType);
165    fn write_parenthese_type(&mut self, parenthese_type: &nodes::ParentheseType);
166    fn write_function_type(&mut self, function_type: &nodes::FunctionType);
167    fn write_optional_type(&mut self, optional_type: &nodes::OptionalType);
168    fn write_intersection_type(&mut self, intersection_type: &nodes::IntersectionType);
169    fn write_union_type(&mut self, union_type: &nodes::UnionType);
170
171    fn write_type_pack(&mut self, type_pack: &nodes::TypePack);
172    fn write_variadic_type_pack(&mut self, variadic_type_pack: &nodes::VariadicTypePack);
173    fn write_generic_type_pack(&mut self, generic_type_pack: &nodes::GenericTypePack);
174
175    fn write_function_return_type(&mut self, return_type: &nodes::FunctionReturnType) {
176        match return_type {
177            nodes::FunctionReturnType::Type(r#type) => {
178                self.write_type(r#type);
179            }
180            nodes::FunctionReturnType::TypePack(type_pack) => {
181                self.write_type_pack(type_pack);
182            }
183            nodes::FunctionReturnType::VariadicTypePack(variadic_type_pack) => {
184                self.write_variadic_type_pack(variadic_type_pack);
185            }
186            nodes::FunctionReturnType::GenericTypePack(generic_type_pack) => {
187                self.write_generic_type_pack(generic_type_pack);
188            }
189        }
190    }
191
192    fn write_variadic_argument_type(
193        &mut self,
194        variadic_argument_type: &nodes::VariadicArgumentType,
195    ) {
196        match variadic_argument_type {
197            nodes::VariadicArgumentType::GenericTypePack(generic_type_pack) => {
198                self.write_generic_type_pack(generic_type_pack);
199            }
200            nodes::VariadicArgumentType::VariadicTypePack(variadic_type_pack) => {
201                self.write_variadic_type_pack(variadic_type_pack);
202            }
203        }
204    }
205
206    fn write_function_variadic_type(&mut self, variadic_type: &nodes::FunctionVariadicType) {
207        match variadic_type {
208            nodes::FunctionVariadicType::Type(r#type) => {
209                self.write_type(r#type);
210            }
211            nodes::FunctionVariadicType::GenericTypePack(generic_pack) => {
212                self.write_generic_type_pack(generic_pack);
213            }
214        }
215    }
216
217    fn write_type_parameter(&mut self, type_parameter: &nodes::TypeParameter) {
218        match type_parameter {
219            nodes::TypeParameter::Type(r#type) => self.write_type(r#type),
220            nodes::TypeParameter::TypePack(type_pack) => self.write_type_pack(type_pack),
221            nodes::TypeParameter::VariadicTypePack(variadic_type_pack) => {
222                self.write_variadic_type_pack(variadic_type_pack);
223            }
224            nodes::TypeParameter::GenericTypePack(generic_type_pack) => {
225                self.write_generic_type_pack(generic_type_pack);
226            }
227        }
228    }
229
230    fn write_generic_type_pack_default(
231        &mut self,
232        generic_type_pack_default: &nodes::GenericTypePackDefault,
233    ) {
234        match generic_type_pack_default {
235            nodes::GenericTypePackDefault::TypePack(type_pack) => self.write_type_pack(type_pack),
236            nodes::GenericTypePackDefault::VariadicTypePack(variadic_type_pack) => {
237                self.write_variadic_type_pack(variadic_type_pack);
238            }
239            nodes::GenericTypePackDefault::GenericTypePack(generic_type_pack) => {
240                self.write_generic_type_pack(generic_type_pack);
241            }
242        }
243    }
244}
245
246#[cfg(test)]
247mod test {
248    use super::*;
249    use crate::generator::{DenseLuaGenerator, ReadableLuaGenerator};
250
251    macro_rules! rewrite_block {
252        (
253            $generator_name:ident, $generator:expr, $preserve_tokens:expr, $($name:ident => $code:literal),+ $(,)?,
254        ) => {
255            $(
256                #[test]
257                fn $name() {
258                    let mut parser = $crate::Parser::default();
259
260                    if $preserve_tokens {
261                        parser = parser.preserve_tokens();
262                    }
263
264                    let input_block = parser.parse($code)
265                        .expect(&format!("unable to parse `{}`", $code));
266
267                    let mut generator = ($generator)($code);
268                    generator.write_block(&input_block);
269                    let generated_code = generator.into_string();
270
271                    let snapshot_name = concat!(
272                        stringify!($generator_name),
273                        "_",
274                        stringify!($name),
275                    );
276
277                    insta::assert_snapshot!(
278                        snapshot_name,
279                        generated_code
280                    );
281                }
282            )*
283        };
284    }
285
286    macro_rules! snapshot_node {
287        (
288            $generator_name:ident, $generator:expr, $node_name:ident, $write_name:ident => (
289                $($test_name:ident => $item:expr),+,
290            )
291        ) => {
292            mod $node_name {
293                use super::*;
294
295                $(
296                    #[test]
297                    fn $test_name() {
298                        let statement = $item;
299
300                        let mut generator = ($generator)("");
301                        generator.$write_name(&statement.into());
302
303                        let snapshot_name = concat!(
304                            stringify!($generator_name),
305                            "_",
306                            stringify!($node_name),
307                            "_",
308                            stringify!($test_name),
309                        );
310
311                        insta::assert_snapshot!(
312                            snapshot_name,
313                            generator.into_string()
314                        );
315                    }
316                )*
317            }
318        }
319    }
320
321    macro_rules! test_numbers {
322        (
323            $generator:expr => (
324                $($name:ident => $value:expr),+,
325            )
326        ) => {
327            $(
328                #[test]
329                fn $name() {
330                    use std::str::FromStr;
331                    let number = $crate::nodes::NumberExpression::from_str($value).unwrap();
332
333                    let mut generator = ($generator)("");
334                    generator.write_expression(&number.into());
335
336                    assert_eq!(generator.into_string(), $value);
337                }
338            )*
339        };
340    }
341
342    macro_rules! blocks_consistency {
343        (
344            $generator:expr => (
345                $($name:ident => $code:literal),+,
346            )
347        ) => {
348            $(
349                #[test]
350                fn $name() {
351                    let parser = $crate::Parser::default();
352
353                    let expected_block = parser.parse($code)
354                        .expect(&format!("unable to parse `{}`", $code));
355
356                    let mut generator = ($generator)($code);
357                    generator.write_block(&expected_block);
358                    let generated_code = generator.into_string();
359
360                    let generated_block = parser.parse(&generated_code)
361                        .expect(&format!("unable to parse generated code `{}`", &generated_code));
362
363                    assert_eq!(expected_block, generated_block);
364                }
365            )*
366        };
367    }
368
369    macro_rules! binary_precedence {
370        (
371            $generator:expr => (
372                $($name:ident($input:expr) => $expected:literal),+,
373            )
374        ) => {
375            $(
376                #[test]
377                fn $name() {
378                    let parser = $crate::Parser::default();
379
380                    let expected_block = parser.parse(&format!("return {}", $expected))
381                        .unwrap();
382                    let expected_return = expected_block.get_last_statement()
383                        .expect("it should have a return statement");
384
385                    let expected = match expected_return {
386                        LastStatement::Return(statement) => statement.iter_expressions()
387                            .next()
388                            .unwrap(),
389                        _ => panic!("return statement expected"),
390                    };
391
392                    let mut generator = ($generator)("");
393                    generator.write_expression(&$input.into());
394
395                    let generated_code = format!("return {}", generator.into_string());
396                    let parsed_block = parser.parse(&generated_code)
397                        .expect(&format!("unable to parse generated code: `{}`", &generated_code));
398
399                    let parsed_return = parsed_block.get_last_statement()
400                        .expect("it should have a return statement");
401
402                    let parsed = match parsed_return {
403                        LastStatement::Return(statement) => {
404                            if statement.len() != 1 {
405                                panic!("return statement has more than one expression")
406                            }
407                            statement.iter_expressions().next().unwrap()
408                        },
409                        _ => panic!("return statement expected"),
410                    };
411
412                    pretty_assertions::assert_eq!(parsed, expected);
413                }
414            )*
415        };
416    }
417
418    macro_rules! snapshot_generator {
419        ($mod_name:ident, $generator:expr, $preserve_tokens:expr) => {
420
421mod $mod_name {
422    use super::*;
423    use $crate::nodes::*;
424
425    mod edge_cases {
426        use super::*;
427
428        blocks_consistency!($generator => (
429            index_with_bracket_string => "return ok[ [[field]]]",
430            call_with_bracket_string => "return ok[[ [field] ]]",
431            concat_numbers => "return 9 .. 3",
432            concat_float_numbers => "return 9. .. 3",
433            concat_number_with_variable_arguments => "return 9 .. ...",
434            concat_variable_arguments_with_number => "return ... ..1",
435            double_unary_minus => "return - -10",
436            binary_minus_with_unary_minus => "return 100- -10",
437        ));
438    }
439
440    mod numbers {
441        use super::*;
442
443        test_numbers!($generator => (
444            zero => "0",
445            one => "1",
446            integer => "123",
447            hex_number => "0x12",
448            hex_number_with_letter => "0x12a",
449            hex_with_exponent => "0x12p4",
450        ));
451    }
452
453    mod binary {
454        use super::*;
455
456        binary_precedence!($generator => (
457            left_associative_wraps_left_operand_if_has_lower_precedence(
458                BinaryExpression::new(
459                    BinaryOperator::Asterisk,
460                    DecimalNumber::new(2.0),
461                    BinaryExpression::new(
462                        BinaryOperator::Plus,
463                        DecimalNumber::new(1.0),
464                        DecimalNumber::new(3.0),
465                    )
466                )
467            ) => "2 * (1 + 3)",
468            left_associative_wraps_right_operand_if_has_lower_precedence(
469                BinaryExpression::new(
470                    BinaryOperator::And,
471                    false,
472                    BinaryExpression::new(
473                        BinaryOperator::Or,
474                        false,
475                        true,
476                    ),
477                )
478            ) => "false and (false or true)",
479            left_associative_wraps_right_operand_if_has_same_precedence(
480                BinaryExpression::new(
481                    BinaryOperator::Equal,
482                    true,
483                    BinaryExpression::new(
484                        BinaryOperator::LowerThan,
485                        DecimalNumber::new(1.0),
486                        DecimalNumber::new(2.0),
487                    ),
488                )
489            ) => "true == (1 < 2)",
490            right_associative_wrap_unary_left_operand_if_has_lower_precedence(
491                BinaryExpression::new(
492                    BinaryOperator::Caret,
493                    UnaryExpression::new(
494                        UnaryOperator::Minus,
495                        DecimalNumber::new(2.0),
496                    ),
497                    DecimalNumber::new(2.0),
498                )
499            ) => "(-2) ^ 2",
500            right_associative_wraps_left_operand_if_has_lower_precedence(
501                BinaryExpression::new(
502                    BinaryOperator::Caret,
503                    BinaryExpression::new(
504                        BinaryOperator::Plus,
505                        DecimalNumber::new(1.0),
506                        DecimalNumber::new(2.0),
507                    ),
508                    DecimalNumber::new(3.0),
509                )
510            ) => "(1 + 2) ^ 3",
511            right_associative_wraps_left_operand_if_has_same_precedence(
512                BinaryExpression::new(
513                    BinaryOperator::Caret,
514                    BinaryExpression::new(
515                        BinaryOperator::Caret,
516                        DecimalNumber::new(2.0),
517                        DecimalNumber::new(2.0),
518                    ),
519                    DecimalNumber::new(3.0),
520                )
521            ) => "(2 ^ 2) ^ 3",
522            right_associative_does_not_wrap_right_operand_if_unary(
523                BinaryExpression::new(
524                    BinaryOperator::Caret,
525                    DecimalNumber::new(2.0),
526                    UnaryExpression::new(
527                        UnaryOperator::Minus,
528                        DecimalNumber::new(2.0),
529                    ),
530                )
531            ) => "2 ^ -2",
532            right_associative_does_not_wrap_right_operand_if_has_same_precedence(
533                BinaryExpression::new(
534                    BinaryOperator::Caret,
535                    DecimalNumber::new(2.0),
536                    BinaryExpression::new(
537                        BinaryOperator::Caret,
538                        DecimalNumber::new(2.0),
539                        DecimalNumber::new(3.0),
540                    ),
541                )
542            ) => "2 ^ 2 ^ 3",
543            right_associative_does_not_wrap_right_operand_if_has_higher_precedence(
544                BinaryExpression::new(
545                    BinaryOperator::Concat,
546                    DecimalNumber::new(3.0),
547                    BinaryExpression::new(
548                        BinaryOperator::Plus,
549                        DecimalNumber::new(9.0),
550                        DecimalNumber::new(3.0),
551                    ),
552                )
553            ) => "3 .. 9 + 3",
554            if_does_not_wrap_else(
555                IfExpression::new(
556                    Expression::identifier("condition"),
557                    10.0,
558                    BinaryExpression::new(
559                        BinaryOperator::Percent,
560                        9.0,
561                        2.0,
562                    ),
563                )
564
565            ) => "if condition then 10 else 9 % 2",
566            binary_expression_wraps_if(
567                BinaryExpression::new(
568                    BinaryOperator::Percent,
569                    IfExpression::new(Expression::identifier("condition"), 10.0, 9.0),
570                    2.0,
571                )
572            ) => "(if condition then 10 else 9) % 2",
573            unary_does_not_wrap_if_with_binary_in_else_result(
574                UnaryExpression::new(
575                    UnaryOperator::Not,
576                    IfExpression::new(
577                        Expression::identifier("condition"),
578                        true,
579                        BinaryExpression::new(
580                            BinaryOperator::And,
581                            false,
582                            StringExpression::from_value("ok"),
583                        )
584                    ),
585                )
586            ) => "not if condition then true else false and 'ok'",
587            binary_wraps_unary_containing_an_if_expression(
588                BinaryExpression::new(
589                    BinaryOperator::And,
590                    UnaryExpression::new(
591                        UnaryOperator::Not,
592                        IfExpression::new(Expression::identifier("condition"), true, false),
593                    ),
594                    StringExpression::from_value("ok"),
595                )
596            ) => "(not if condition then true else false) and 'ok'",
597        ));
598    }
599
600    mod snapshots {
601        use super::*;
602
603        snapshot_node!($mod_name, $generator, block, write_block => (
604            ambiguous_function_call_from_assign => Block::default()
605                .with_statement(
606                    AssignStatement::from_variable(Variable::new("name"), Expression::identifier("variable"))
607                )
608                .with_statement(
609                    AssignStatement::from_variable(
610                        FieldExpression::new(ParentheseExpression::new(Expression::identifier("t")), "field"),
611                        false
612                    )
613                ),
614            ambiguous_function_call_from_compound_assign => Block::default()
615                .with_statement(
616                    CompoundAssignStatement::new(
617                        CompoundOperator::Plus,
618                        Variable::new("name"),
619                        BinaryExpression::new(
620                            BinaryOperator::Plus,
621                            Expression::identifier("variable"),
622                            Expression::identifier("value"),
623                        )
624                    )
625                )
626                .with_statement(
627                    AssignStatement::from_variable(
628                        IndexExpression::new(
629                            ParentheseExpression::new(Expression::identifier("t")),
630                            Expression::identifier("field"),
631                        ),
632                        false
633                    )
634                ),
635            ambiguous_function_call_from_local_assign => Block::default()
636                .with_statement(
637                    LocalAssignStatement::from_variable("name")
638                        .with_value(
639                            IfExpression::new(
640                                Expression::identifier("condition"),
641                                true,
642                                FunctionCall::from_name("fn")
643                            )
644                        )
645                )
646                .with_statement(
647                    FunctionCall::from_prefix(ParentheseExpression::new(Expression::identifier("fn")))
648                ),
649            ambiguous_function_call_from_function_call => Block::default()
650                .with_statement(
651                    FunctionCall::from_name("fn")
652                )
653                .with_statement(
654                    CompoundAssignStatement::new(
655                        CompoundOperator::Plus,
656                        IndexExpression::new(ParentheseExpression::new(
657                            Expression::identifier("t")),
658                            Expression::identifier("field"),
659                        ),
660                        1
661                    )
662                ),
663            ambiguous_function_call_from_repeat => Block::default()
664                .with_statement(
665                    RepeatStatement::new(
666                        Block::default(),
667                        UnaryExpression::new(UnaryOperator::Not, Expression::identifier("variable"))
668                    )
669                )
670                .with_statement(
671                    CompoundAssignStatement::new(
672                        CompoundOperator::Plus,
673                        FieldExpression::new(ParentheseExpression::new(Expression::identifier("t")), "field"),
674                        1
675                    )
676                ),
677        ));
678
679        snapshot_node!($mod_name, $generator, expression, write_expression => (
680            false_value => false,
681            true_value => true,
682            nil_value => Expression::nil(),
683            variable_arguments => Expression::variable_arguments(),
684            true_in_parenthese => Expression::from(true).in_parentheses(),
685        ));
686
687        snapshot_node!($mod_name, $generator, assign, write_statement => (
688            variable_with_one_value => AssignStatement::new(
689                vec![Variable::new("var")],
690                vec![Expression::from(false)],
691            ),
692            two_variables_with_one_value => AssignStatement::new(
693                vec![Variable::new("foo"), Variable::new("var")],
694                vec![Expression::from(false)],
695            ),
696            two_variables_with_two_values => AssignStatement::new(
697                vec![Variable::new("foo"), Variable::new("var")],
698                vec![Expression::nil(), Expression::from(false)],
699            ),
700        ));
701
702        snapshot_node!($mod_name, $generator, do_statement, write_statement => (
703            empty => DoStatement::default(),
704            nested_do => DoStatement::new(
705                Block::default().with_statement(DoStatement::default())
706            ),
707        ));
708
709        snapshot_node!($mod_name, $generator, compound_assign_statement, write_statement => (
710            increment_var_by_one => CompoundAssignStatement::new(
711                CompoundOperator::Plus,
712                Variable::new("var"),
713                1_f64,
714            ),
715        ));
716
717        snapshot_node!($mod_name, $generator, function_statement, write_statement => (
718            empty => FunctionStatement::from_name("foo", Block::default()),
719            empty_with_field =>  FunctionStatement::new(
720                FunctionName::from_name("foo").with_fields(vec!["bar".into()]),
721                Block::default(),
722                Vec::new(),
723                false
724            ),
725            empty_with_name_ending_with_number_with_field =>  FunctionStatement::new(
726                FunctionName::from_name("fn1").with_fields(vec!["bar".into()]),
727                Block::default(),
728                Vec::new(),
729                false
730            ),
731            empty_with_one_typed_parameter => FunctionStatement::from_name("fn", Block::default())
732                .with_parameter(Identifier::new("a").with_type(TypeName::new("string"))),
733            empty_with_two_typed_parameters => FunctionStatement::from_name("fn", Block::default())
734                .with_parameter(Identifier::new("a").with_type(TypeName::new("string")))
735                .with_parameter(Identifier::new("b").with_type(TypeName::new("bool"))),
736            empty_variadic_with_one_typed_parameter => FunctionStatement::from_name("fn", Block::default())
737                .variadic()
738                .with_parameter(Identifier::new("a").with_type(TypeName::new("string"))),
739            empty_variadic_typed_with_one_typed_parameter => FunctionStatement::from_name("fn", Block::default())
740                .with_variadic_type(TypeName::new("any"))
741                .with_parameter(Identifier::new("a").with_type(TypeName::new("string"))),
742            empty_with_string_return_type => FunctionStatement::from_name("fn", Block::default())
743                .with_return_type(TypeName::new("string")),
744            empty_with_void_return_type => FunctionStatement::from_name("fn", Block::default())
745                .with_return_type(TypePack::default()),
746            empty_with_generic_pack_return_type => FunctionStatement::from_name("fn", Block::default())
747                .with_return_type(GenericTypePack::new("T")),
748            empty_with_variadic_pack_return_type => FunctionStatement::from_name("fn", Block::default())
749                .with_return_type(
750                    VariadicTypePack::new(ParentheseType::new(
751                        UnionType::new(Type::from(true), Type::nil())
752                    ))
753                ),
754            empty_with_method => FunctionStatement::new(
755                FunctionName::from_name("foo").with_method("bar"),
756                Block::default(),
757                Vec::new(),
758                false
759            ),
760        ));
761
762        snapshot_node!($mod_name, $generator, generic_for, write_statement => (
763            empty => GenericForStatement::new(
764                vec!["var".into()],
765                vec![Expression::from(true)],
766                Block::default()
767            ),
768            empty_with_typed_var => GenericForStatement::new(
769                vec![Identifier::new("var").with_type(TypeName::new("string"))],
770                vec![Expression::from(true)],
771                Block::default()
772            ),
773            empty_with_two_typed_vars => GenericForStatement::new(
774                vec![
775                    Identifier::new("key").with_type(TypeName::new("string")),
776                    Identifier::new("value").with_type(TypeName::new("bool")),
777                ],
778                vec![Expression::from(true)],
779                Block::default()
780            ),
781        ));
782
783        snapshot_node!($mod_name, $generator, type_declaration, write_type_declaration_statement => (
784            string_alias => TypeDeclarationStatement::new("Str", TypeName::new("string")),
785            type_field => TypeDeclarationStatement::new("Object", TypeField::new("module", TypeName::new("Object"))),
786            type_field_with_name_ending_with_number
787                => TypeDeclarationStatement::new("Object", TypeField::new("module0", TypeName::new("Object"))),
788            exported_string_alias => TypeDeclarationStatement::new("Str", TypeName::new("string"))
789                .export(),
790            generic_array => TypeDeclarationStatement::new("Array", ArrayType::new(TypeName::new("T")))
791                .with_generic_parameters(
792                    GenericParametersWithDefaults::from_type_variable("T")
793                ),
794            generic_array_with_default
795                => TypeDeclarationStatement::new("Array", ArrayType::new(TypeName::new("T")))
796                    .with_generic_parameters(
797                        GenericParametersWithDefaults::from_type_variable_with_default(
798                            TypeVariableWithDefault::new("T", Type::nil())
799                        )
800                    ),
801            table_with_one_property => TypeDeclarationStatement::new(
802                "Obj",
803                TableType::default()
804                    .with_property(TablePropertyType::new("name", TypeName::new("string")))
805            ),
806            table_with_indexer_type => TypeDeclarationStatement::new(
807                "StringArray",
808                TableType::default()
809                    .with_indexer_type(TableIndexerType::new(TypeName::new("number"), TypeName::new("string")))
810            ),
811            table_with_one_property_and_indexer_type => TypeDeclarationStatement::new(
812                "PackedArray",
813                TableType::default()
814                    .with_property(TablePropertyType::new("n", TypeName::new("number")))
815                    .with_indexer_type(TableIndexerType::new(TypeName::new("number"), TypeName::new("string")))
816            ),
817            callback_with_variadic_type_is_string => TypeDeclarationStatement::new(
818                "Fn",
819                FunctionType::new(TypePack::default())
820                    .with_variadic_type(VariadicTypePack::new(TypeName::new("string")))
821            ),
822            callback_with_variadic_type_is_generic_pack => TypeDeclarationStatement::new(
823                "Fn",
824                FunctionType::new(TypePack::default())
825                    .with_variadic_type(GenericTypePack::new("T"))
826            ),
827            generic_fn_with_default_generic_pack
828                => TypeDeclarationStatement::new("Fn", FunctionType::new(GenericTypePack::new("R")))
829                    .with_generic_parameters(
830                        GenericParametersWithDefaults::from_generic_type_pack_with_default(
831                            GenericTypePackWithDefault::new(
832                                GenericTypePack::new("R"),
833                                GenericTypePack::new("T")
834                            )
835                        )
836                    ),
837            generic_fn_with_type_variable_and_default_generic_pack
838                => TypeDeclarationStatement::new(
839                    "Fn",
840                    FunctionType::new(GenericTypePack::new("R"))
841                        .with_argument(TypeName::new("T"))
842                )
843                    .with_generic_parameters(
844                        GenericParametersWithDefaults::from_type_variable("T")
845                        .with_generic_type_pack_with_default(
846                            GenericTypePackWithDefault::new(
847                                GenericTypePack::new("R"),
848                                VariadicTypePack::new(TypeName::new("string"))
849                            )
850                        )
851                    ),
852            generic_fn_with_type_variable_with_default_and_default_generic_pack
853                => TypeDeclarationStatement::new(
854                    "Fn",
855                    FunctionType::new(GenericTypePack::new("R"))
856                        .with_argument(TypeName::new("T"))
857                )
858                    .with_generic_parameters(
859                        GenericParametersWithDefaults::from_type_variable_with_default(
860                            TypeVariableWithDefault::new("T", TypeName::new("boolean"))
861                        )
862                        .with_generic_type_pack_with_default(
863                            GenericTypePackWithDefault::new(
864                                GenericTypePack::new("R"),
865                                VariadicTypePack::new(TypeName::new("string"))
866                            )
867                        )
868                    ),
869        ));
870
871        snapshot_node!($mod_name, $generator, if_statement, write_statement => (
872            empty => IfStatement::create(false, Block::default()),
873            empty_with_empty_else => IfStatement::create(false, Block::default())
874                .with_else_block(Block::default()),
875            empty_with_empty_multiple_branch => IfStatement::create(false, Block::default())
876                .with_new_branch(Expression::nil(), Block::default())
877                .with_new_branch(false, Block::default()),
878        ));
879
880        snapshot_node!($mod_name, $generator, intersection_type, write_intersection_type => (
881            single_type => IntersectionType::from(vec![Type::from(true)]),
882            two_types => IntersectionType::from(vec![Type::from(true), Type::from(false)]),
883            two_types_with_leading_token => IntersectionType::from(vec![Type::from(true), Type::from(false)])
884                .with_leading_token(),
885        ));
886
887        snapshot_node!($mod_name, $generator, union_type, write_union_type => (
888            single_type => UnionType::from(vec![Type::from(true)]),
889            two_types => UnionType::from(vec![Type::from(true), Type::from(false)]),
890            two_types_with_leading_token => UnionType::from(vec![Type::from(true), Type::from(false)])
891                .with_leading_token(),
892        ));
893
894        snapshot_node!($mod_name, $generator, local_assign, write_statement => (
895            foo_unassigned => LocalAssignStatement::from_variable("foo"),
896            foo_typed_unassigned => LocalAssignStatement::from_variable(
897                Identifier::new("foo").with_type(Type::from(true))
898            ),
899            foo_and_bar_unassigned => LocalAssignStatement::from_variable("foo")
900                .with_variable("bar"),
901            foo_and_bar_typed_unassigned => LocalAssignStatement::from_variable("foo")
902                .with_variable(Identifier::new("bar").with_type(Type::from(false))),
903            var_assign_to_false => LocalAssignStatement::from_variable("var")
904                .with_value(false),
905            typed_generic_var_break_equal_sign => LocalAssignStatement::from_variable(
906                Identifier::new("var").with_type(
907                    TypeName::new("List").with_type_parameter(TypeName::new("string"))
908                )
909            ).with_value(false),
910        ));
911
912        snapshot_node!($mod_name, $generator, local_function, write_statement => (
913            empty => LocalFunctionStatement::from_name("foo", Block::default()),
914            empty_variadic => LocalFunctionStatement::from_name("foo", Block::default())
915                .variadic(),
916            empty_with_one_parameter => LocalFunctionStatement::from_name("foo", Block::default())
917                .with_parameter("bar"),
918            empty_with_two_parameters => LocalFunctionStatement::from_name("foo", Block::default())
919                .with_parameter("bar")
920                .with_parameter("baz"),
921            empty_variadic_with_one_parameter => LocalFunctionStatement::from_name("foo", Block::default())
922                .with_parameter("bar")
923                .variadic(),
924            empty_with_generic_pack_return_type => LocalFunctionStatement::from_name("foo", Block::default())
925                .with_return_type(GenericTypePack::new("R")),
926        ));
927
928        snapshot_node!($mod_name, $generator, numeric_for, write_statement => (
929            empty_without_step => NumericForStatement::new(
930                "i",
931                Expression::identifier("start"),
932                Expression::identifier("max"),
933                None,
934                Block::default()
935            ),
936            empty_typed_without_step => NumericForStatement::new(
937                Identifier::new("i").with_type(TypeName::new("number")),
938                Expression::identifier("start"),
939                Expression::identifier("max"),
940                None,
941                Block::default()
942            ),
943            empty_with_step => NumericForStatement::new(
944                "i",
945                Expression::identifier("start"),
946                Expression::identifier("max"),
947                Some(Expression::identifier("step")),
948                Block::default()
949            ),
950            empty_typed_with_step => NumericForStatement::new(
951                Identifier::new("i").with_type(TypeName::new("number")),
952                Expression::identifier("start"),
953                Expression::identifier("max"),
954                Some(Expression::identifier("step")),
955                Block::default()
956            ),
957        ));
958
959        snapshot_node!($mod_name, $generator, repeat, write_statement => (
960            empty => RepeatStatement::new(
961                Block::default(),
962                false
963            ),
964        ));
965
966        snapshot_node!($mod_name, $generator, while_statement, write_statement => (
967            empty => WhileStatement::new(
968                Block::default(),
969                false
970            ),
971        ));
972
973        snapshot_node!($mod_name, $generator, last, write_last_statement => (
974            break_statement => LastStatement::new_break(),
975            continue_statement => LastStatement::new_continue(),
976            return_without_values => ReturnStatement::default(),
977            return_one_expression => ReturnStatement::one(Expression::from(true)),
978            return_two_expressions => ReturnStatement::one(Expression::from(true))
979                .with_expression(Expression::nil()),
980            return_parentheses => ReturnStatement::one(Expression::from(true).in_parentheses()),
981        ));
982
983        snapshot_node!($mod_name, $generator, binary, write_expression => (
984            true_and_false => BinaryExpression::new(
985                BinaryOperator::And,
986                Expression::from(true),
987                Expression::from(false)
988            ),
989            true_equal_false => BinaryExpression::new(
990                BinaryOperator::Equal,
991                Expression::from(true),
992                Expression::from(false)
993            ),
994            type_cast_break_type_parameters => BinaryExpression::new(
995                BinaryOperator::Equal,
996                TypeCastExpression::new(
997                    true,
998                    TypeName::new("Array").with_type_parameter(TypeName::new("string"))
999                ),
1000                Expression::from(false)
1001            ),
1002            wrap_left_to_break_type_name_parameters => BinaryExpression::new(
1003                BinaryOperator::LowerThan,
1004                TypeCastExpression::new(true, TypeName::new("Array")),
1005                Expression::from(false)
1006            ),
1007            wrap_left_to_break_type_field_parameters => BinaryExpression::new(
1008                BinaryOperator::LowerThan,
1009                TypeCastExpression::new(
1010                    true,
1011                    TypeField::new("Collections", TypeName::new("Array"))
1012                ),
1013                Expression::from(false)
1014            ),
1015        ));
1016
1017        snapshot_node!($mod_name, $generator, field, write_expression => (
1018            identifier_prefix => FieldExpression::new(Prefix::from_name("foo"), "bar"),
1019            identifier_ending_with_number_prefix => FieldExpression::new(Prefix::from_name("oof0"), "field"),
1020        ));
1021
1022        snapshot_node!($mod_name, $generator, index, write_expression => (
1023            identifier_prefix_with_identifier_value => IndexExpression::new(
1024                Prefix::from_name("foo"),
1025                Prefix::from_name("bar"),
1026            ),
1027        ));
1028
1029        snapshot_node!($mod_name, $generator, function_expr, write_expression => (
1030            empty => FunctionExpression::default(),
1031            empty_variadic => FunctionExpression::default().variadic(),
1032            empty_variadic_with_one_parameter => FunctionExpression::default()
1033                .with_parameter("a")
1034                .variadic(),
1035            empty_variadic_with_two_parameter => FunctionExpression::default()
1036                .with_parameter("a")
1037                .with_parameter("b")
1038                .variadic(),
1039            empty_with_two_parameter => FunctionExpression::default()
1040                .with_parameter("a")
1041                .with_parameter("b"),
1042            empty_with_generic_pack_return_type => FunctionExpression::default()
1043                .with_return_type(GenericTypePack::new("R")),
1044        ));
1045
1046        snapshot_node!($mod_name, $generator, prefix, write_prefix => (
1047            identifier => Prefix::from_name("foo"),
1048            identifier_in_parenthese => Prefix::from(ParentheseExpression::new(Expression::identifier("foo"))),
1049        ));
1050
1051        snapshot_node!($mod_name, $generator, string, write_expression => (
1052            only_letters => StringExpression::from_value("hello"),
1053            with_single_quotes => StringExpression::from_value("I'm cool"),
1054            with_double_quotes => StringExpression::from_value(r#"Say: "Hi""#),
1055            with_single_and_double_quotes => StringExpression::from_value(r#"Say: "Don't""#),
1056        ));
1057
1058        snapshot_node!($mod_name, $generator, interpolated_string, write_expression => (
1059            only_letters => InterpolatedStringExpression::empty()
1060                .with_segment("hello"),
1061            with_single_quotes => InterpolatedStringExpression::empty()
1062                .with_segment("I'm cool"),
1063            with_double_quotes => InterpolatedStringExpression::empty()
1064                .with_segment(r#"Say: "Hi""#),
1065            with_backticks => InterpolatedStringExpression::empty()
1066                .with_segment("Say: `Hi`"),
1067            with_single_and_double_quotes => InterpolatedStringExpression::empty()
1068                .with_segment(r#"Say: "Don't""#),
1069            with_true_value => InterpolatedStringExpression::empty()
1070                .with_segment(true),
1071            with_empty_table => InterpolatedStringExpression::empty()
1072                .with_segment(TableExpression::default()),
1073            with_empty_table_in_type_cast => InterpolatedStringExpression::empty()
1074                .with_segment(TypeCastExpression::new(TableExpression::default(), TypeName::new("any"))),
1075        ));
1076
1077        snapshot_node!($mod_name, $generator, number, write_expression => (
1078            number_1 => 1.0,
1079            number_0_5 => 0.5,
1080            number_123 => 123.0,
1081            number_0_005 => 0.005,
1082            number_nan => DecimalNumber::new(f64::NAN),
1083            number_positive_infinity => DecimalNumber::new(f64::INFINITY),
1084            number_negative_infinity => DecimalNumber::new(f64::NEG_INFINITY),
1085            number_1_2345e_minus50 => 1.2345e-50,
1086            number_thousand => 1000.0,
1087            number_1_2345e50 => 1.2345e50,
1088            number_100_25 => 100.25,
1089            number_2000_05 => 2000.05,
1090            binary_0b10101 => BinaryNumber::new(0b10101, false),
1091            number_4_6982573308436185e159 => "4.6982573308436185e159".parse::<NumberExpression>().ok(),
1092        ));
1093
1094        snapshot_node!($mod_name, $generator, table, write_expression => (
1095            empty => TableExpression::default(),
1096            list_with_single_value => TableExpression::new(vec![
1097                TableEntry::from_value(Expression::from(true)),
1098            ]),
1099            list_with_two_values => TableExpression::new(vec![
1100                TableEntry::from_value(Expression::from(true)),
1101                TableEntry::from_value(Expression::from(false)),
1102            ]),
1103            with_field_entry => TableExpression::new(vec![
1104                TableFieldEntry::new("field", true).into(),
1105            ]),
1106            with_index_entry => TableExpression::new(vec![
1107                TableIndexEntry::new(false, true).into(),
1108            ]),
1109            mixed_table => TableExpression::new(vec![
1110                TableEntry::from_value(Expression::from(true)),
1111                TableFieldEntry::new("field", true).into(),
1112                TableIndexEntry::new(false, true).into(),
1113            ]),
1114        ));
1115
1116        snapshot_node!($mod_name, $generator, unary, write_expression => (
1117            not_true => UnaryExpression::new(
1118                UnaryOperator::Not,
1119                true,
1120            ),
1121            two_unary_minus_breaks_between_them => UnaryExpression::new(
1122                UnaryOperator::Minus,
1123                UnaryExpression::new(
1124                    UnaryOperator::Minus,
1125                    Expression::identifier("a"),
1126                ),
1127            ),
1128            wraps_in_parens_if_an_inner_binary_has_lower_precedence => UnaryExpression::new(
1129                UnaryOperator::Not,
1130                BinaryExpression::new(
1131                    BinaryOperator::Or,
1132                    false,
1133                    true,
1134                ),
1135            ),
1136            does_not_wrap_in_parens_if_an_inner_binary_has_higher_precedence => UnaryExpression::new(
1137                UnaryOperator::Minus,
1138                BinaryExpression::new(
1139                    BinaryOperator::Caret,
1140                    DecimalNumber::new(2.0),
1141                    DecimalNumber::new(2.0),
1142                ),
1143            ),
1144        ));
1145
1146        snapshot_node!($mod_name, $generator, arguments, write_arguments => (
1147            empty_tuple => TupleArguments::default(),
1148            tuple_with_one_value => TupleArguments::new(vec![true.into()]),
1149            tuple_with_two_values => TupleArguments::new(vec![true.into(), false.into()]),
1150        ));
1151
1152        rewrite_block!(
1153            $mod_name,
1154            $generator,
1155            $preserve_tokens,
1156            table_type_with_final_comma => "type A = { field: number, }",
1157        );
1158    }
1159}
1160
1161        };
1162    }
1163
1164    snapshot_generator!(dense, |_| DenseLuaGenerator::default(), false);
1165    snapshot_generator!(readable, |_| ReadableLuaGenerator::default(), false);
1166    snapshot_generator!(token_based, |code| TokenBasedLuaGenerator::new(code), true);
1167}