1mod dense;
5mod readable;
6mod token_based;
7mod 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! snapshot_node {
252 (
253 $generator_name:ident, $generator:expr, $node_name:ident, $write_name:ident => (
254 $($test_name:ident => $item:expr),+,
255 )
256 ) => {
257 mod $node_name {
258 use super::*;
259
260 $(
261 #[test]
262 fn $test_name() {
263 let statement = $item;
264
265 let mut generator = $generator;
266 generator.$write_name(&statement.into());
267
268 let snapshot_name = concat!(
269 stringify!($generator_name),
270 "_",
271 stringify!($node_name),
272 "_",
273 stringify!($test_name),
274 );
275
276 insta::assert_snapshot!(
277 snapshot_name,
278 generator.into_string()
279 );
280 }
281 )*
282 }
283 }
284 }
285
286 macro_rules! test_numbers {
287 (
288 $generator:expr => (
289 $($name:ident => $value:expr),+,
290 )
291 ) => {
292 $(
293 #[test]
294 fn $name() {
295 use std::str::FromStr;
296 let number = $crate::nodes::NumberExpression::from_str($value).unwrap();
297
298 let mut generator = $generator;
299 generator.write_expression(&number.into());
300
301 assert_eq!(generator.into_string(), $value);
302 }
303 )*
304 };
305 }
306
307 macro_rules! blocks_consistency {
308 (
309 $generator:expr => (
310 $($name:ident => $code:literal),+,
311 )
312 ) => {
313 $(
314 #[test]
315 fn $name() {
316 let parser = $crate::Parser::default();
317
318 let expected_block = parser.parse($code)
319 .expect(&format!("unable to parse `{}`", $code));
320
321 let mut generator = $generator;
322 generator.write_block(&expected_block);
323 let generated_code = generator.into_string();
324
325 let generated_block = parser.parse(&generated_code)
326 .expect(&format!("unable to parse generated code `{}`", &generated_code));
327
328 assert_eq!(expected_block, generated_block);
329 }
330 )*
331 };
332 }
333
334 macro_rules! binary_precedence {
335 (
336 $generator:expr => (
337 $($name:ident($input:expr) => $expected:literal),+,
338 )
339 ) => {
340 $(
341 #[test]
342 fn $name() {
343 let parser = $crate::Parser::default();
344
345 let expected_block = parser.parse(&format!("return {}", $expected))
346 .unwrap();
347 let expected_return = expected_block.get_last_statement()
348 .expect("it should have a return statement");
349
350 let expected = match expected_return {
351 LastStatement::Return(statement) => statement.iter_expressions()
352 .next()
353 .unwrap(),
354 _ => panic!("return statement expected"),
355 };
356
357 let mut generator = $generator;
358 generator.write_expression(&$input.into());
359
360 let generated_code = format!("return {}", generator.into_string());
361 let parsed_block = parser.parse(&generated_code)
362 .expect(&format!("unable to parse generated code: `{}`", &generated_code));
363
364 let parsed_return = parsed_block.get_last_statement()
365 .expect("it should have a return statement");
366
367 let parsed = match parsed_return {
368 LastStatement::Return(statement) => {
369 if statement.len() != 1 {
370 panic!("return statement has more than one expression")
371 }
372 statement.iter_expressions().next().unwrap()
373 },
374 _ => panic!("return statement expected"),
375 };
376
377 pretty_assertions::assert_eq!(parsed, expected);
378 }
379 )*
380 };
381 }
382
383 macro_rules! snapshot_generator {
384 ($mod_name:ident, $generator:expr) => {
385
386mod $mod_name {
387 use super::*;
388 use $crate::nodes::*;
389
390 mod edge_cases {
391 use super::*;
392
393 blocks_consistency!($generator => (
394 index_with_bracket_string => "return ok[ [[field]]]",
395 call_with_bracket_string => "return ok[[ [field] ]]",
396 concat_numbers => "return 9 .. 3",
397 concat_float_numbers => "return 9. .. 3",
398 concat_number_with_variable_arguments => "return 9 .. ...",
399 concat_variable_arguments_with_number => "return ... ..1",
400 double_unary_minus => "return - -10",
401 binary_minus_with_unary_minus => "return 100- -10",
402 ));
403 }
404
405 mod numbers {
406 use super::*;
407
408 test_numbers!($generator => (
409 zero => "0",
410 one => "1",
411 integer => "123",
412 hex_number => "0x12",
413 hex_number_with_letter => "0x12a",
414 hex_with_exponent => "0x12p4",
415 ));
416 }
417
418 mod binary {
419 use super::*;
420
421 binary_precedence!($generator => (
422 left_associative_wraps_left_operand_if_has_lower_precedence(
423 BinaryExpression::new(
424 BinaryOperator::Asterisk,
425 DecimalNumber::new(2.0),
426 BinaryExpression::new(
427 BinaryOperator::Plus,
428 DecimalNumber::new(1.0),
429 DecimalNumber::new(3.0),
430 )
431 )
432 ) => "2 * (1 + 3)",
433 left_associative_wraps_right_operand_if_has_lower_precedence(
434 BinaryExpression::new(
435 BinaryOperator::And,
436 false,
437 BinaryExpression::new(
438 BinaryOperator::Or,
439 false,
440 true,
441 ),
442 )
443 ) => "false and (false or true)",
444 left_associative_wraps_right_operand_if_has_same_precedence(
445 BinaryExpression::new(
446 BinaryOperator::Equal,
447 true,
448 BinaryExpression::new(
449 BinaryOperator::LowerThan,
450 DecimalNumber::new(1.0),
451 DecimalNumber::new(2.0),
452 ),
453 )
454 ) => "true == (1 < 2)",
455 right_associative_wrap_unary_left_operand_if_has_lower_precedence(
456 BinaryExpression::new(
457 BinaryOperator::Caret,
458 UnaryExpression::new(
459 UnaryOperator::Minus,
460 DecimalNumber::new(2.0),
461 ),
462 DecimalNumber::new(2.0),
463 )
464 ) => "(-2) ^ 2",
465 right_associative_wraps_left_operand_if_has_lower_precedence(
466 BinaryExpression::new(
467 BinaryOperator::Caret,
468 BinaryExpression::new(
469 BinaryOperator::Plus,
470 DecimalNumber::new(1.0),
471 DecimalNumber::new(2.0),
472 ),
473 DecimalNumber::new(3.0),
474 )
475 ) => "(1 + 2) ^ 3",
476 right_associative_wraps_left_operand_if_has_same_precedence(
477 BinaryExpression::new(
478 BinaryOperator::Caret,
479 BinaryExpression::new(
480 BinaryOperator::Caret,
481 DecimalNumber::new(2.0),
482 DecimalNumber::new(2.0),
483 ),
484 DecimalNumber::new(3.0),
485 )
486 ) => "(2 ^ 2) ^ 3",
487 right_associative_does_not_wrap_right_operand_if_unary(
488 BinaryExpression::new(
489 BinaryOperator::Caret,
490 DecimalNumber::new(2.0),
491 UnaryExpression::new(
492 UnaryOperator::Minus,
493 DecimalNumber::new(2.0),
494 ),
495 )
496 ) => "2 ^ -2",
497 right_associative_does_not_wrap_right_operand_if_has_same_precedence(
498 BinaryExpression::new(
499 BinaryOperator::Caret,
500 DecimalNumber::new(2.0),
501 BinaryExpression::new(
502 BinaryOperator::Caret,
503 DecimalNumber::new(2.0),
504 DecimalNumber::new(3.0),
505 ),
506 )
507 ) => "2 ^ 2 ^ 3",
508 right_associative_does_not_wrap_right_operand_if_has_higher_precedence(
509 BinaryExpression::new(
510 BinaryOperator::Concat,
511 DecimalNumber::new(3.0),
512 BinaryExpression::new(
513 BinaryOperator::Plus,
514 DecimalNumber::new(9.0),
515 DecimalNumber::new(3.0),
516 ),
517 )
518 ) => "3 .. 9 + 3",
519 if_does_not_wrap_else(
520 IfExpression::new(
521 Expression::identifier("condition"),
522 10.0,
523 BinaryExpression::new(
524 BinaryOperator::Percent,
525 9.0,
526 2.0,
527 ),
528 )
529
530 ) => "if condition then 10 else 9 % 2",
531 binary_expression_wraps_if(
532 BinaryExpression::new(
533 BinaryOperator::Percent,
534 IfExpression::new(Expression::identifier("condition"), 10.0, 9.0),
535 2.0,
536 )
537 ) => "(if condition then 10 else 9) % 2",
538 unary_does_not_wrap_if_with_binary_in_else_result(
539 UnaryExpression::new(
540 UnaryOperator::Not,
541 IfExpression::new(
542 Expression::identifier("condition"),
543 true,
544 BinaryExpression::new(
545 BinaryOperator::And,
546 false,
547 StringExpression::from_value("ok"),
548 )
549 ),
550 )
551 ) => "not if condition then true else false and 'ok'",
552 binary_wraps_unary_containing_an_if_expression(
553 BinaryExpression::new(
554 BinaryOperator::And,
555 UnaryExpression::new(
556 UnaryOperator::Not,
557 IfExpression::new(Expression::identifier("condition"), true, false),
558 ),
559 StringExpression::from_value("ok"),
560 )
561 ) => "(not if condition then true else false) and 'ok'",
562 ));
563 }
564
565 mod snapshots {
566 use super::*;
567
568 snapshot_node!($mod_name, $generator, block, write_block => (
569 ambiguous_function_call_from_assign => Block::default()
570 .with_statement(
571 AssignStatement::from_variable(Variable::new("name"), Expression::identifier("variable"))
572 )
573 .with_statement(
574 AssignStatement::from_variable(
575 FieldExpression::new(ParentheseExpression::new(Expression::identifier("t")), "field"),
576 false
577 )
578 ),
579 ambiguous_function_call_from_compound_assign => Block::default()
580 .with_statement(
581 CompoundAssignStatement::new(
582 CompoundOperator::Plus,
583 Variable::new("name"),
584 BinaryExpression::new(
585 BinaryOperator::Plus,
586 Expression::identifier("variable"),
587 Expression::identifier("value"),
588 )
589 )
590 )
591 .with_statement(
592 AssignStatement::from_variable(
593 IndexExpression::new(
594 ParentheseExpression::new(Expression::identifier("t")),
595 Expression::identifier("field"),
596 ),
597 false
598 )
599 ),
600 ambiguous_function_call_from_local_assign => Block::default()
601 .with_statement(
602 LocalAssignStatement::from_variable("name")
603 .with_value(
604 IfExpression::new(
605 Expression::identifier("condition"),
606 true,
607 FunctionCall::from_name("fn")
608 )
609 )
610 )
611 .with_statement(
612 FunctionCall::from_prefix(ParentheseExpression::new(Expression::identifier("fn")))
613 ),
614 ambiguous_function_call_from_function_call => Block::default()
615 .with_statement(
616 FunctionCall::from_name("fn")
617 )
618 .with_statement(
619 CompoundAssignStatement::new(
620 CompoundOperator::Plus,
621 IndexExpression::new(ParentheseExpression::new(
622 Expression::identifier("t")),
623 Expression::identifier("field"),
624 ),
625 1
626 )
627 ),
628 ambiguous_function_call_from_repeat => Block::default()
629 .with_statement(
630 RepeatStatement::new(
631 Block::default(),
632 UnaryExpression::new(UnaryOperator::Not, Expression::identifier("variable"))
633 )
634 )
635 .with_statement(
636 CompoundAssignStatement::new(
637 CompoundOperator::Plus,
638 FieldExpression::new(ParentheseExpression::new(Expression::identifier("t")), "field"),
639 1
640 )
641 ),
642 ));
643
644 snapshot_node!($mod_name, $generator, expression, write_expression => (
645 false_value => false,
646 true_value => true,
647 nil_value => Expression::nil(),
648 variable_arguments => Expression::variable_arguments(),
649 true_in_parenthese => Expression::from(true).in_parentheses(),
650 ));
651
652 snapshot_node!($mod_name, $generator, assign, write_statement => (
653 variable_with_one_value => AssignStatement::new(
654 vec![Variable::new("var")],
655 vec![Expression::from(false)],
656 ),
657 two_variables_with_one_value => AssignStatement::new(
658 vec![Variable::new("foo"), Variable::new("var")],
659 vec![Expression::from(false)],
660 ),
661 two_variables_with_two_values => AssignStatement::new(
662 vec![Variable::new("foo"), Variable::new("var")],
663 vec![Expression::nil(), Expression::from(false)],
664 ),
665 ));
666
667 snapshot_node!($mod_name, $generator, do_statement, write_statement => (
668 empty => DoStatement::default(),
669 nested_do => DoStatement::new(
670 Block::default().with_statement(DoStatement::default())
671 ),
672 ));
673
674 snapshot_node!($mod_name, $generator, compound_assign_statement, write_statement => (
675 increment_var_by_one => CompoundAssignStatement::new(
676 CompoundOperator::Plus,
677 Variable::new("var"),
678 1_f64,
679 ),
680 ));
681
682 snapshot_node!($mod_name, $generator, function_statement, write_statement => (
683 empty => FunctionStatement::from_name("foo", Block::default()),
684 empty_with_field => FunctionStatement::new(
685 FunctionName::from_name("foo").with_fields(vec!["bar".into()]),
686 Block::default(),
687 Vec::new(),
688 false
689 ),
690 empty_with_name_ending_with_number_with_field => FunctionStatement::new(
691 FunctionName::from_name("fn1").with_fields(vec!["bar".into()]),
692 Block::default(),
693 Vec::new(),
694 false
695 ),
696 empty_with_one_typed_parameter => FunctionStatement::from_name("fn", Block::default())
697 .with_parameter(Identifier::new("a").with_type(TypeName::new("string"))),
698 empty_with_two_typed_parameters => FunctionStatement::from_name("fn", Block::default())
699 .with_parameter(Identifier::new("a").with_type(TypeName::new("string")))
700 .with_parameter(Identifier::new("b").with_type(TypeName::new("bool"))),
701 empty_variadic_with_one_typed_parameter => FunctionStatement::from_name("fn", Block::default())
702 .variadic()
703 .with_parameter(Identifier::new("a").with_type(TypeName::new("string"))),
704 empty_variadic_typed_with_one_typed_parameter => FunctionStatement::from_name("fn", Block::default())
705 .with_variadic_type(TypeName::new("any"))
706 .with_parameter(Identifier::new("a").with_type(TypeName::new("string"))),
707 empty_with_string_return_type => FunctionStatement::from_name("fn", Block::default())
708 .with_return_type(TypeName::new("string")),
709 empty_with_void_return_type => FunctionStatement::from_name("fn", Block::default())
710 .with_return_type(TypePack::default()),
711 empty_with_generic_pack_return_type => FunctionStatement::from_name("fn", Block::default())
712 .with_return_type(GenericTypePack::new("T")),
713 empty_with_variadic_pack_return_type => FunctionStatement::from_name("fn", Block::default())
714 .with_return_type(
715 VariadicTypePack::new(ParentheseType::new(
716 UnionType::new(Type::from(true), Type::nil())
717 ))
718 ),
719 empty_with_method => FunctionStatement::new(
720 FunctionName::from_name("foo").with_method("bar"),
721 Block::default(),
722 Vec::new(),
723 false
724 ),
725 ));
726
727 snapshot_node!($mod_name, $generator, generic_for, write_statement => (
728 empty => GenericForStatement::new(
729 vec!["var".into()],
730 vec![Expression::from(true)],
731 Block::default()
732 ),
733 empty_with_typed_var => GenericForStatement::new(
734 vec![Identifier::new("var").with_type(TypeName::new("string"))],
735 vec![Expression::from(true)],
736 Block::default()
737 ),
738 empty_with_two_typed_vars => GenericForStatement::new(
739 vec![
740 Identifier::new("key").with_type(TypeName::new("string")),
741 Identifier::new("value").with_type(TypeName::new("bool")),
742 ],
743 vec![Expression::from(true)],
744 Block::default()
745 ),
746 ));
747
748 snapshot_node!($mod_name, $generator, type_declaration, write_type_declaration_statement => (
749 string_alias => TypeDeclarationStatement::new("Str", TypeName::new("string")),
750 type_field => TypeDeclarationStatement::new("Object", TypeField::new("module", TypeName::new("Object"))),
751 type_field_with_name_ending_with_number
752 => TypeDeclarationStatement::new("Object", TypeField::new("module0", TypeName::new("Object"))),
753 exported_string_alias => TypeDeclarationStatement::new("Str", TypeName::new("string"))
754 .export(),
755 generic_array => TypeDeclarationStatement::new("Array", ArrayType::new(TypeName::new("T")))
756 .with_generic_parameters(
757 GenericParametersWithDefaults::from_type_variable("T")
758 ),
759 generic_array_with_default
760 => TypeDeclarationStatement::new("Array", ArrayType::new(TypeName::new("T")))
761 .with_generic_parameters(
762 GenericParametersWithDefaults::from_type_variable_with_default(
763 TypeVariableWithDefault::new("T", Type::nil())
764 )
765 ),
766 table_with_one_property => TypeDeclarationStatement::new(
767 "Obj",
768 TableType::default()
769 .with_property(TablePropertyType::new("name", TypeName::new("string")))
770 ),
771 table_with_indexer_type => TypeDeclarationStatement::new(
772 "StringArray",
773 TableType::default()
774 .with_indexer_type(TableIndexerType::new(TypeName::new("number"), TypeName::new("string")))
775 ),
776 table_with_one_property_and_indexer_type => TypeDeclarationStatement::new(
777 "PackedArray",
778 TableType::default()
779 .with_property(TablePropertyType::new("n", TypeName::new("number")))
780 .with_indexer_type(TableIndexerType::new(TypeName::new("number"), TypeName::new("string")))
781 ),
782 callback_with_variadic_type_is_string => TypeDeclarationStatement::new(
783 "Fn",
784 FunctionType::new(TypePack::default())
785 .with_variadic_type(VariadicTypePack::new(TypeName::new("string")))
786 ),
787 callback_with_variadic_type_is_generic_pack => TypeDeclarationStatement::new(
788 "Fn",
789 FunctionType::new(TypePack::default())
790 .with_variadic_type(GenericTypePack::new("T"))
791 ),
792 generic_fn_with_default_generic_pack
793 => TypeDeclarationStatement::new("Fn", FunctionType::new(GenericTypePack::new("R")))
794 .with_generic_parameters(
795 GenericParametersWithDefaults::from_generic_type_pack_with_default(
796 GenericTypePackWithDefault::new(
797 GenericTypePack::new("R"),
798 GenericTypePack::new("T")
799 )
800 )
801 ),
802 generic_fn_with_type_variable_and_default_generic_pack
803 => TypeDeclarationStatement::new(
804 "Fn",
805 FunctionType::new(GenericTypePack::new("R"))
806 .with_argument(TypeName::new("T"))
807 )
808 .with_generic_parameters(
809 GenericParametersWithDefaults::from_type_variable("T")
810 .with_generic_type_pack_with_default(
811 GenericTypePackWithDefault::new(
812 GenericTypePack::new("R"),
813 VariadicTypePack::new(TypeName::new("string"))
814 )
815 )
816 ),
817 generic_fn_with_type_variable_with_default_and_default_generic_pack
818 => TypeDeclarationStatement::new(
819 "Fn",
820 FunctionType::new(GenericTypePack::new("R"))
821 .with_argument(TypeName::new("T"))
822 )
823 .with_generic_parameters(
824 GenericParametersWithDefaults::from_type_variable_with_default(
825 TypeVariableWithDefault::new("T", TypeName::new("boolean"))
826 )
827 .with_generic_type_pack_with_default(
828 GenericTypePackWithDefault::new(
829 GenericTypePack::new("R"),
830 VariadicTypePack::new(TypeName::new("string"))
831 )
832 )
833 ),
834 ));
835
836 snapshot_node!($mod_name, $generator, if_statement, write_statement => (
837 empty => IfStatement::create(false, Block::default()),
838 empty_with_empty_else => IfStatement::create(false, Block::default())
839 .with_else_block(Block::default()),
840 empty_with_empty_multiple_branch => IfStatement::create(false, Block::default())
841 .with_new_branch(Expression::nil(), Block::default())
842 .with_new_branch(false, Block::default()),
843 ));
844
845 snapshot_node!($mod_name, $generator, intersection_type, write_intersection_type => (
846 single_type => IntersectionType::from(vec![Type::from(true)]),
847 two_types => IntersectionType::from(vec![Type::from(true), Type::from(false)]),
848 two_types_with_leading_token => IntersectionType::from(vec![Type::from(true), Type::from(false)])
849 .with_leading_token(),
850 ));
851
852 snapshot_node!($mod_name, $generator, union_type, write_union_type => (
853 single_type => UnionType::from(vec![Type::from(true)]),
854 two_types => UnionType::from(vec![Type::from(true), Type::from(false)]),
855 two_types_with_leading_token => UnionType::from(vec![Type::from(true), Type::from(false)])
856 .with_leading_token(),
857 ));
858
859 snapshot_node!($mod_name, $generator, local_assign, write_statement => (
860 foo_unassigned => LocalAssignStatement::from_variable("foo"),
861 foo_typed_unassigned => LocalAssignStatement::from_variable(
862 Identifier::new("foo").with_type(Type::from(true))
863 ),
864 foo_and_bar_unassigned => LocalAssignStatement::from_variable("foo")
865 .with_variable("bar"),
866 foo_and_bar_typed_unassigned => LocalAssignStatement::from_variable("foo")
867 .with_variable(Identifier::new("bar").with_type(Type::from(false))),
868 var_assign_to_false => LocalAssignStatement::from_variable("var")
869 .with_value(false),
870 typed_generic_var_break_equal_sign => LocalAssignStatement::from_variable(
871 Identifier::new("var").with_type(
872 TypeName::new("List").with_type_parameter(TypeName::new("string"))
873 )
874 ).with_value(false),
875 ));
876
877 snapshot_node!($mod_name, $generator, local_function, write_statement => (
878 empty => LocalFunctionStatement::from_name("foo", Block::default()),
879 empty_variadic => LocalFunctionStatement::from_name("foo", Block::default())
880 .variadic(),
881 empty_with_one_parameter => LocalFunctionStatement::from_name("foo", Block::default())
882 .with_parameter("bar"),
883 empty_with_two_parameters => LocalFunctionStatement::from_name("foo", Block::default())
884 .with_parameter("bar")
885 .with_parameter("baz"),
886 empty_variadic_with_one_parameter => LocalFunctionStatement::from_name("foo", Block::default())
887 .with_parameter("bar")
888 .variadic(),
889 empty_with_generic_pack_return_type => LocalFunctionStatement::from_name("foo", Block::default())
890 .with_return_type(GenericTypePack::new("R")),
891 ));
892
893 snapshot_node!($mod_name, $generator, numeric_for, write_statement => (
894 empty_without_step => NumericForStatement::new(
895 "i",
896 Expression::identifier("start"),
897 Expression::identifier("max"),
898 None,
899 Block::default()
900 ),
901 empty_typed_without_step => NumericForStatement::new(
902 Identifier::new("i").with_type(TypeName::new("number")),
903 Expression::identifier("start"),
904 Expression::identifier("max"),
905 None,
906 Block::default()
907 ),
908 empty_with_step => NumericForStatement::new(
909 "i",
910 Expression::identifier("start"),
911 Expression::identifier("max"),
912 Some(Expression::identifier("step")),
913 Block::default()
914 ),
915 empty_typed_with_step => NumericForStatement::new(
916 Identifier::new("i").with_type(TypeName::new("number")),
917 Expression::identifier("start"),
918 Expression::identifier("max"),
919 Some(Expression::identifier("step")),
920 Block::default()
921 ),
922 ));
923
924 snapshot_node!($mod_name, $generator, repeat, write_statement => (
925 empty => RepeatStatement::new(
926 Block::default(),
927 false
928 ),
929 ));
930
931 snapshot_node!($mod_name, $generator, while_statement, write_statement => (
932 empty => WhileStatement::new(
933 Block::default(),
934 false
935 ),
936 ));
937
938 snapshot_node!($mod_name, $generator, last, write_last_statement => (
939 break_statement => LastStatement::new_break(),
940 continue_statement => LastStatement::new_continue(),
941 return_without_values => ReturnStatement::default(),
942 return_one_expression => ReturnStatement::one(Expression::from(true)),
943 return_two_expressions => ReturnStatement::one(Expression::from(true))
944 .with_expression(Expression::nil()),
945 return_parentheses => ReturnStatement::one(Expression::from(true).in_parentheses()),
946 ));
947
948 snapshot_node!($mod_name, $generator, binary, write_expression => (
949 true_and_false => BinaryExpression::new(
950 BinaryOperator::And,
951 Expression::from(true),
952 Expression::from(false)
953 ),
954 true_equal_false => BinaryExpression::new(
955 BinaryOperator::Equal,
956 Expression::from(true),
957 Expression::from(false)
958 ),
959 type_cast_break_type_parameters => BinaryExpression::new(
960 BinaryOperator::Equal,
961 TypeCastExpression::new(
962 true,
963 TypeName::new("Array").with_type_parameter(TypeName::new("string"))
964 ),
965 Expression::from(false)
966 ),
967 wrap_left_to_break_type_name_parameters => BinaryExpression::new(
968 BinaryOperator::LowerThan,
969 TypeCastExpression::new(true, TypeName::new("Array")),
970 Expression::from(false)
971 ),
972 wrap_left_to_break_type_field_parameters => BinaryExpression::new(
973 BinaryOperator::LowerThan,
974 TypeCastExpression::new(
975 true,
976 TypeField::new("Collections", TypeName::new("Array"))
977 ),
978 Expression::from(false)
979 ),
980 ));
981
982 snapshot_node!($mod_name, $generator, field, write_expression => (
983 identifier_prefix => FieldExpression::new(Prefix::from_name("foo"), "bar"),
984 identifier_ending_with_number_prefix => FieldExpression::new(Prefix::from_name("oof0"), "field"),
985 ));
986
987 snapshot_node!($mod_name, $generator, index, write_expression => (
988 identifier_prefix_with_identifier_value => IndexExpression::new(
989 Prefix::from_name("foo"),
990 Prefix::from_name("bar"),
991 ),
992 ));
993
994 snapshot_node!($mod_name, $generator, function_expr, write_expression => (
995 empty => FunctionExpression::default(),
996 empty_variadic => FunctionExpression::default().variadic(),
997 empty_variadic_with_one_parameter => FunctionExpression::default()
998 .with_parameter("a")
999 .variadic(),
1000 empty_variadic_with_two_parameter => FunctionExpression::default()
1001 .with_parameter("a")
1002 .with_parameter("b")
1003 .variadic(),
1004 empty_with_two_parameter => FunctionExpression::default()
1005 .with_parameter("a")
1006 .with_parameter("b"),
1007 empty_with_generic_pack_return_type => FunctionExpression::default()
1008 .with_return_type(GenericTypePack::new("R")),
1009 ));
1010
1011 snapshot_node!($mod_name, $generator, prefix, write_prefix => (
1012 identifier => Prefix::from_name("foo"),
1013 identifier_in_parenthese => Prefix::Parenthese(ParentheseExpression::new(Expression::identifier("foo"))),
1014 ));
1015
1016 snapshot_node!($mod_name, $generator, string, write_expression => (
1017 only_letters => StringExpression::from_value("hello"),
1018 with_single_quotes => StringExpression::from_value("I'm cool"),
1019 with_double_quotes => StringExpression::from_value(r#"Say: "Hi""#),
1020 with_single_and_double_quotes => StringExpression::from_value(r#"Say: "Don't""#),
1021 ));
1022
1023 snapshot_node!($mod_name, $generator, interpolated_string, write_expression => (
1024 only_letters => InterpolatedStringExpression::empty()
1025 .with_segment("hello"),
1026 with_single_quotes => InterpolatedStringExpression::empty()
1027 .with_segment("I'm cool"),
1028 with_double_quotes => InterpolatedStringExpression::empty()
1029 .with_segment(r#"Say: "Hi""#),
1030 with_backticks => InterpolatedStringExpression::empty()
1031 .with_segment("Say: `Hi`"),
1032 with_single_and_double_quotes => InterpolatedStringExpression::empty()
1033 .with_segment(r#"Say: "Don't""#),
1034 with_true_value => InterpolatedStringExpression::empty()
1035 .with_segment(true),
1036 with_empty_table => InterpolatedStringExpression::empty()
1037 .with_segment(TableExpression::default()),
1038 with_empty_table_in_type_cast => InterpolatedStringExpression::empty()
1039 .with_segment(TypeCastExpression::new(TableExpression::default(), TypeName::new("any"))),
1040 ));
1041
1042 snapshot_node!($mod_name, $generator, number, write_expression => (
1043 number_1 => 1.0,
1044 number_0_5 => 0.5,
1045 number_123 => 123.0,
1046 number_0_005 => 0.005,
1047 number_nan => DecimalNumber::new(f64::NAN),
1048 number_positive_infinity => DecimalNumber::new(f64::INFINITY),
1049 number_negative_infinity => DecimalNumber::new(f64::NEG_INFINITY),
1050 number_1_2345e_minus50 => 1.2345e-50,
1051 number_thousand => 1000.0,
1052 number_1_2345e50 => 1.2345e50,
1053 number_100_25 => 100.25,
1054 number_2000_05 => 2000.05,
1055 binary_0b10101 => BinaryNumber::new(0b10101, false),
1056 ));
1057
1058 snapshot_node!($mod_name, $generator, table, write_expression => (
1059 empty => TableExpression::default(),
1060 list_with_single_value => TableExpression::new(vec![
1061 TableEntry::Value(Expression::from(true)),
1062 ]),
1063 list_with_two_values => TableExpression::new(vec![
1064 TableEntry::Value(Expression::from(true)),
1065 TableEntry::Value(Expression::from(false)),
1066 ]),
1067 with_field_entry => TableExpression::new(vec![
1068 TableFieldEntry::new("field", true).into(),
1069 ]),
1070 with_index_entry => TableExpression::new(vec![
1071 TableIndexEntry::new(false, true).into(),
1072 ]),
1073 mixed_table => TableExpression::new(vec![
1074 TableEntry::Value(Expression::from(true)),
1075 TableFieldEntry::new("field", true).into(),
1076 TableIndexEntry::new(false, true).into(),
1077 ]),
1078 ));
1079
1080 snapshot_node!($mod_name, $generator, unary, write_expression => (
1081 not_true => UnaryExpression::new(
1082 UnaryOperator::Not,
1083 true,
1084 ),
1085 two_unary_minus_breaks_between_them => UnaryExpression::new(
1086 UnaryOperator::Minus,
1087 UnaryExpression::new(
1088 UnaryOperator::Minus,
1089 Expression::identifier("a"),
1090 ),
1091 ),
1092 wraps_in_parens_if_an_inner_binary_has_lower_precedence => UnaryExpression::new(
1093 UnaryOperator::Not,
1094 BinaryExpression::new(
1095 BinaryOperator::Or,
1096 false,
1097 true,
1098 ),
1099 ),
1100 does_not_wrap_in_parens_if_an_inner_binary_has_higher_precedence => UnaryExpression::new(
1101 UnaryOperator::Minus,
1102 BinaryExpression::new(
1103 BinaryOperator::Caret,
1104 DecimalNumber::new(2.0),
1105 DecimalNumber::new(2.0),
1106 ),
1107 ),
1108 ));
1109
1110 snapshot_node!($mod_name, $generator, arguments, write_arguments => (
1111 empty_tuple => TupleArguments::default(),
1112 tuple_with_one_value => TupleArguments::new(vec![true.into()]),
1113 tuple_with_two_values => TupleArguments::new(vec![true.into(), false.into()]),
1114 ));
1115 }
1116}
1117
1118 };
1119 }
1120
1121 snapshot_generator!(dense, DenseLuaGenerator::default());
1122 snapshot_generator!(readable, ReadableLuaGenerator::default());
1123 snapshot_generator!(token_based, TokenBasedLuaGenerator::new(""));
1124}