1mod 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
15pub trait LuaGenerator {
19 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}