Skip to main content

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