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