1use crate::generator::{utils, LuaGenerator};
2use crate::nodes;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5enum StatementType {
6 Assign,
7 Do,
8 Call,
9 CompoundAssign,
10 Function,
11 GenericFor,
12 If,
13 LocalAssign,
14 LocalFunction,
15 NumericFor,
16 Repeat,
17 While,
18 TypeDeclaration,
19 TypeFunction,
20 Return,
21 Break,
22 Continue,
23}
24
25impl From<&nodes::Statement> for StatementType {
26 fn from(statement: &nodes::Statement) -> Self {
27 use nodes::Statement::*;
28 match statement {
29 Assign(_) => Self::Assign,
30 Do(_) => Self::Do,
31 Call(_) => Self::Call,
32 CompoundAssign(_) => Self::CompoundAssign,
33 Function(_) => Self::Function,
34 GenericFor(_) => Self::GenericFor,
35 If(_) => Self::If,
36 LocalAssign(_) => Self::LocalAssign,
37 LocalFunction(_) => Self::LocalFunction,
38 NumericFor(_) => Self::NumericFor,
39 Repeat(_) => Self::Repeat,
40 While(_) => Self::While,
41 TypeDeclaration(_) => Self::TypeDeclaration,
42 TypeFunction(_) => Self::TypeFunction,
43 }
44 }
45}
46
47impl From<&nodes::LastStatement> for StatementType {
48 fn from(statement: &nodes::LastStatement) -> Self {
49 use nodes::LastStatement::*;
50 match statement {
51 Break(_) => Self::Break,
52 Continue(_) => Self::Continue,
53 Return(_) => Self::Return,
54 }
55 }
56}
57
58#[derive(Debug, Clone)]
61pub struct ReadableLuaGenerator {
62 column_span: usize,
63 indentation: usize,
64 current_line_length: usize,
65 current_indentation: usize,
66 output: String,
67 last_push_length: usize,
68 can_add_new_line_stack: Vec<bool>,
69}
70
71impl ReadableLuaGenerator {
72 pub fn new(column_span: usize) -> Self {
73 Self {
74 column_span,
75 indentation: 4,
76 current_line_length: 0,
77 current_indentation: 0,
78 output: String::new(),
79 last_push_length: 0,
80 can_add_new_line_stack: Vec::new(),
81 }
82 }
83
84 #[inline]
85 fn can_add_new_line(&self) -> bool {
86 self.can_add_new_line_stack.last().copied().unwrap_or(true)
87 }
88
89 #[inline]
90 fn push_can_add_new_line(&mut self, value: bool) {
91 self.can_add_new_line_stack.push(value);
92 }
93
94 #[inline]
95 fn pop_can_add_new_line(&mut self) {
96 self.can_add_new_line_stack.pop();
97 }
98
99 #[inline]
100 fn push_indentation(&mut self) {
101 self.current_indentation += 1;
102 }
103
104 #[inline]
105 fn pop_indentation(&mut self) {
106 self.current_indentation -= 1;
107 }
108
109 #[inline]
110 fn write_indentation(&mut self) {
111 let indentation = " ".repeat(self.indentation * self.current_indentation);
112 self.raw_push_str(&indentation);
113 }
114
115 #[inline]
116 fn push_new_line(&mut self) {
117 self.output.push('\n');
118 self.current_line_length = 0;
119 }
120
121 #[inline]
122 fn fits_on_current_line(&self, length: usize) -> bool {
123 self.current_line_length + length <= self.column_span
124 }
125
126 #[inline]
127 fn push_space(&mut self) {
128 self.output.push(' ');
129 self.current_line_length += 1;
130 }
131
132 fn push_str(&mut self, content: &str) {
135 if let Some(next_char) = content.chars().next() {
136 self.push_space_if_needed(next_char, content.len());
137 self.raw_push_str(content);
138 }
139 }
140
141 fn push_char(&mut self, character: char) {
143 self.push_space_if_needed(character, 1);
144
145 self.output.push(character);
146 self.current_line_length += 1;
147 self.last_push_length = 1;
148 }
149
150 #[inline]
151 fn raw_push_str(&mut self, content: &str) {
152 self.output.push_str(content);
153 self.last_push_length = content.len();
154 self.current_line_length += self.last_push_length;
155 }
156
157 #[inline]
158 fn raw_push_char(&mut self, character: char) {
159 self.output.push(character);
160 self.last_push_length = 1;
161 self.current_line_length += 1;
162 }
163
164 #[inline]
165 fn needs_space(&self, next_character: char) -> bool {
166 if let Some(previous) = self.output.chars().last() {
167 utils::should_break_with_space(previous, next_character)
168 } else {
169 false
170 }
171 }
172
173 #[inline]
174 fn indent_and_write_block(&mut self, block: &nodes::Block) {
175 self.push_indentation();
176 self.write_block(block);
177 self.pop_indentation();
178 }
179
180 fn push_new_line_if_needed(&mut self, pushed_length: usize) {
181 if self.current_line_length == 0 && self.current_indentation != 0 {
182 self.write_indentation();
183 }
184
185 if self.can_add_new_line() {
186 if self.current_line_length >= self.column_span {
187 self.push_new_line();
188 } else {
189 let total_length = self.current_line_length + pushed_length;
190
191 if total_length > self.column_span {
192 self.push_new_line();
193 }
194 }
195 }
196 }
197
198 fn push_space_if_needed(&mut self, next_character: char, pushed_length: usize) {
199 if self.current_line_length == 0 && self.current_indentation != 0 {
200 self.write_indentation();
201 }
202
203 if self.can_add_new_line() {
204 if self.current_line_length >= self.column_span {
205 self.push_new_line();
206 } else {
207 let total_length = self.current_line_length + pushed_length;
208
209 if self.needs_space(next_character) {
210 if total_length + 1 > self.column_span {
211 self.push_new_line();
212 } else {
213 self.push_space();
214 }
215 } else if total_length > self.column_span {
216 self.push_new_line();
217 }
218 }
219 } else if self.needs_space(next_character) {
220 self.push_space();
221 }
222 }
223
224 fn push_str_and_break_if<F>(&mut self, content: &str, predicate: F)
227 where
228 F: Fn(&str) -> bool,
229 {
230 if predicate(self.get_last_push_str()) {
231 if self.fits_on_current_line(1 + content.len()) {
232 self.push_space();
233 } else {
234 self.push_new_line();
235 }
236 } else if !self.fits_on_current_line(content.len()) {
237 self.push_new_line();
238 }
239 self.raw_push_str(content);
240 }
241
242 fn get_last_push_str(&self) -> &str {
243 self.output
244 .get((self.output.len() - self.last_push_length)..)
245 .unwrap_or("")
246 }
247
248 fn table_fits_on_line(&self, entries: &[nodes::TableEntry], _width: usize) -> bool {
249 use nodes::TableEntry;
250
251 entries.len() < 4
253 && entries.iter().all(|entry| match entry {
254 TableEntry::Value(value) => self.is_small_expression(value),
255 _ => false,
256 })
257 || entries.len() == 1
258 && entries.iter().all(|entry| match entry {
259 TableEntry::Field(entry) => self.is_small_expression(entry.get_value()),
260 TableEntry::Index(entry) => {
261 self.is_small_expression(entry.get_key())
262 && self.is_small_expression(entry.get_value())
263 }
264 _ => false,
265 })
266 }
267
268 fn is_small_expression(&self, expression: &nodes::Expression) -> bool {
269 use nodes::Expression::*;
270 match expression {
271 True(_) | False(_) | Nil(_) | Identifier(_) | VariableArguments(_) | Number(_) => true,
272 Table(table) => table.is_empty(),
273 _ => false,
274 }
275 }
276
277 fn write_attributes(&mut self, attributes: &nodes::Attributes) {
278 use nodes::Attribute;
279
280 for attribute in attributes.iter_attributes() {
281 match attribute {
282 Attribute::Name(named) => {
283 let name = named.get_identifier().get_name();
284
285 self.push_space_if_needed('@', 1 + name.len());
286 self.raw_push_char('@');
287 self.raw_push_str(name);
288 self.push_new_line();
289 }
290 Attribute::Group(group) => {
291 if !group.is_empty() {
292 self.push_str("@[");
293
294 let last_index = group.len().saturating_sub(1);
295
296 for (index, attribute) in group.iter_attributes().enumerate() {
297 self.push_str(attribute.name().get_name());
298
299 if let Some(arguments) = attribute.get_arguments() {
300 self.write_attribute_arguments(arguments);
301 }
302
303 if index != last_index {
304 self.push_char(',');
305 self.push_char(' ');
306 }
307 }
308
309 self.push_char(']');
310 self.push_new_line();
311 }
312 }
313 }
314 }
315 }
316
317 fn write_function_parameters(
318 &mut self,
319 parameters: &[nodes::TypedIdentifier],
320 is_variadic: bool,
321 variadic_type: Option<&nodes::FunctionVariadicType>,
322 ) {
323 let mut parameters_length = parameters.iter().fold(0, |acc, parameter| {
324 acc + parameter.get_name().len()
325 + if parameter.has_type() {
326 10
328 } else {
329 0
330 }
331 });
332 parameters_length += parameters.len() * 2;
334
335 if is_variadic {
336 parameters_length += 3;
338 if parameters.len() > 1 {
339 parameters_length += 2;
341 }
342 }
343
344 let last_index = parameters.len().saturating_sub(1);
345
346 if self.fits_on_current_line(parameters_length) {
347 parameters.iter().enumerate().for_each(|(index, variable)| {
348 self.write_typed_identifier(variable);
349
350 if index != last_index {
351 self.raw_push_char(',');
352 self.raw_push_char(' ');
353 }
354 });
355
356 if is_variadic {
357 if !parameters.is_empty() {
358 self.raw_push_char(',');
359 self.raw_push_char(' ');
360 };
361 self.raw_push_str("...");
362
363 if let Some(variadic_type) = variadic_type {
364 self.raw_push_char(':');
365 self.raw_push_char(' ');
366 self.write_function_variadic_type(r#variadic_type);
367 }
368 };
369 } else {
370 self.push_indentation();
371
372 parameters.iter().enumerate().for_each(|(index, variable)| {
373 self.push_new_line();
374 self.write_indentation();
375 self.write_typed_identifier(variable);
376
377 if index != last_index {
378 self.raw_push_char(',');
379 }
380 });
381
382 if is_variadic {
383 if !parameters.is_empty() {
384 self.raw_push_char(',');
385 };
386 self.push_new_line();
387 self.write_indentation();
388 self.raw_push_str("...");
389
390 if let Some(variadic_type) = variadic_type {
391 self.raw_push_char(':');
392 self.raw_push_char(' ');
393 self.write_function_variadic_type(r#variadic_type);
394 }
395 };
396
397 self.pop_indentation();
398 self.push_new_line();
399 self.write_indentation();
400 }
401 }
402
403 fn write_variable(&mut self, variable: &nodes::Variable) {
404 use nodes::Variable::*;
405 match variable {
406 Identifier(identifier) => self.push_str(identifier.get_name()),
407 Field(field) => self.write_field(field),
408 Index(index) => self.write_index(index),
409 }
410 }
411
412 fn write_typed_identifier(&mut self, typed_identifier: &nodes::TypedIdentifier) {
413 self.push_str(typed_identifier.get_name());
414
415 if let Some(r#type) = typed_identifier.get_type() {
416 self.push_char(':');
417 self.push_space();
418 self.write_type(r#type);
419 }
420 }
421
422 fn write_function_return_type(&mut self, return_type: &nodes::FunctionReturnType) {
423 match return_type {
424 nodes::FunctionReturnType::Type(r#type) => self.write_type(r#type),
425 nodes::FunctionReturnType::TypePack(type_pack) => self.write_type_pack(type_pack),
426 nodes::FunctionReturnType::VariadicTypePack(variadic_type_pack) => {
427 self.write_variadic_type_pack(variadic_type_pack);
428 }
429 nodes::FunctionReturnType::GenericTypePack(generic_type_pack) => {
430 self.write_generic_type_pack(generic_type_pack);
431 }
432 }
433 }
434
435 fn write_function_return_type_suffix(&mut self, return_type: &nodes::FunctionReturnType) {
436 self.raw_push_char(':');
437 self.raw_push_char(' ');
438 self.write_function_return_type(return_type);
439 }
440
441 fn write_expression_in_parentheses(&mut self, expression: &nodes::Expression) {
442 self.push_char('(');
443 self.write_expression(expression);
444 self.push_char(')');
445 }
446
447 fn write_type_in_parentheses(&mut self, r#type: &nodes::Type) {
448 self.push_char('(');
449 self.write_type(r#type);
450 self.push_char(')');
451 }
452
453 fn write_function_generics(&mut self, generics: &nodes::GenericParameters) {
454 if generics.is_empty() {
455 return;
456 }
457 self.push_char('<');
458 let mut write_comma = false;
459 for type_variable in generics.iter_type_variable() {
460 if write_comma {
461 self.push_char(',');
462 self.push_char(' ');
463 } else {
464 write_comma = true;
465 }
466 self.write_identifier(type_variable);
467 }
468 for generic_pack in generics.iter_generic_type_pack() {
469 if write_comma {
470 self.push_char(',');
471 self.push_char(' ');
472 } else {
473 write_comma = true;
474 }
475 self.write_generic_type_pack(generic_pack);
476 }
477 self.push_char('>');
478 }
479}
480
481impl Default for ReadableLuaGenerator {
482 fn default() -> Self {
483 Self::new(80)
484 }
485}
486
487impl LuaGenerator for ReadableLuaGenerator {
488 fn into_string(self) -> String {
489 self.output
490 }
491
492 fn write_block(&mut self, block: &nodes::Block) {
493 let mut statements = block.iter_statements().peekable();
494
495 while let Some(statement) = statements.next() {
496 let current_type: StatementType = statement.into();
497
498 self.push_can_add_new_line(false);
499 self.write_statement(statement);
500
501 if let Some(next_statement) = statements.peek() {
502 if utils::starts_with_parenthese(next_statement)
503 && utils::ends_with_prefix(statement)
504 {
505 self.push_char(';');
506 }
507
508 if current_type != (*next_statement).into() {
509 self.push_new_line();
510 }
511 }
512
513 self.pop_can_add_new_line();
514 self.push_new_line();
515 }
516
517 if let Some(last_statement) = block.get_last_statement() {
518 if block.iter_statements().next().is_some() {
519 self.push_new_line();
520 }
521 self.write_last_statement(last_statement);
522 self.push_new_line();
523 }
524 }
525
526 fn write_last_statement(&mut self, statement: &nodes::LastStatement) {
527 use nodes::LastStatement::*;
528
529 match statement {
530 Break(_) => self.push_str("break"),
531 Continue(_) => self.push_str("continue"),
532 Return(expressions) => {
533 self.push_str("return");
534 self.push_can_add_new_line(false);
535 let last_index = expressions.len().saturating_sub(1);
536
537 if !expressions.is_empty() {
538 self.raw_push_char(' ');
539 }
540
541 expressions
542 .iter_expressions()
543 .enumerate()
544 .for_each(|(index, expression)| {
545 self.write_expression(expression);
546
547 if index != last_index {
548 self.raw_push_char(',');
549 self.raw_push_char(' ');
550 }
551 });
552
553 self.pop_can_add_new_line();
554 }
555 }
556 }
557
558 fn write_assign_statement(&mut self, assign: &nodes::AssignStatement) {
559 self.push_can_add_new_line(false);
560
561 let variables = assign.get_variables();
562 let last_variable_index = variables.len() - 1;
563 variables.iter().enumerate().for_each(|(index, variable)| {
564 self.write_variable(variable);
565
566 if index != last_variable_index {
567 self.raw_push_char(',');
568 self.raw_push_char(' ');
569 }
570 });
571
572 self.raw_push_str(" = ");
573
574 let last_value_index = assign.values_len() - 1;
575 assign.iter_values().enumerate().for_each(|(index, value)| {
576 self.write_expression(value);
577
578 if index != last_value_index {
579 self.raw_push_char(',');
580 self.raw_push_char(' ');
581 }
582 });
583
584 self.pop_can_add_new_line();
585 }
586
587 fn write_local_assign(&mut self, assign: &nodes::LocalAssignStatement) {
588 self.push_str("local ");
589
590 self.push_can_add_new_line(false);
591
592 let variables = assign.get_variables();
593 let last_variable_index = variables.len().saturating_sub(1);
594
595 variables.iter().enumerate().for_each(|(index, variable)| {
596 self.write_typed_identifier(variable);
597
598 if index != last_variable_index {
599 self.raw_push_char(',');
600 self.raw_push_char(' ');
601 }
602 });
603
604 if assign.has_values() {
605 self.raw_push_str(" = ");
606
607 let last_value_index = assign.values_len() - 1;
608
609 assign.iter_values().enumerate().for_each(|(index, value)| {
610 self.write_expression(value);
611
612 if index != last_value_index {
613 self.raw_push_char(',');
614 self.raw_push_char(' ');
615 }
616 });
617 };
618
619 self.pop_can_add_new_line();
620 }
621
622 fn write_compound_assign(&mut self, assign: &nodes::CompoundAssignStatement) {
623 self.push_can_add_new_line(false);
624
625 self.write_variable(assign.get_variable());
626
627 self.raw_push_char(' ');
628 self.raw_push_str(assign.get_operator().to_str());
629 self.push_space();
630
631 self.write_expression(assign.get_value());
632
633 self.pop_can_add_new_line();
634 }
635
636 fn write_local_function(&mut self, function: &nodes::LocalFunctionStatement) {
637 self.write_attributes(function.attributes());
638 self.push_str("local function ");
639 self.raw_push_str(function.get_name());
640
641 if let Some(generics) = function.get_generic_parameters() {
642 self.write_function_generics(generics);
643 }
644
645 self.raw_push_char('(');
646
647 let parameters = function.get_parameters();
648 self.write_function_parameters(
649 parameters,
650 function.is_variadic(),
651 function.get_variadic_type(),
652 );
653 self.raw_push_char(')');
654
655 if let Some(return_type) = function.get_return_type() {
656 self.write_function_return_type_suffix(return_type);
657 }
658
659 let block = function.get_block();
660
661 if block.is_empty() {
662 self.raw_push_str(" end");
663 } else {
664 self.push_new_line();
665 self.indent_and_write_block(block);
666 self.push_str("end");
667 }
668 }
669
670 fn write_generic_for(&mut self, generic_for: &nodes::GenericForStatement) {
671 self.push_str("for ");
672
673 let identifiers = generic_for.get_identifiers();
674 let last_identifier_index = identifiers.len().saturating_sub(1);
675 identifiers
676 .iter()
677 .enumerate()
678 .for_each(|(index, identifier)| {
679 self.write_typed_identifier(identifier);
680
681 if index != last_identifier_index {
682 self.raw_push_char(',');
683 self.raw_push_char(' ');
684 }
685 });
686
687 self.raw_push_str(" in ");
688
689 let expressions = generic_for.get_expressions();
690 let last_expression_index = expressions.len().saturating_sub(1);
691 expressions
692 .iter()
693 .enumerate()
694 .for_each(|(index, expression)| {
695 self.write_expression(expression);
696
697 if index != last_expression_index {
698 self.raw_push_char(',');
699 self.raw_push_char(' ');
700 }
701 });
702
703 let block = generic_for.get_block();
704
705 if block.is_empty() {
706 self.raw_push_str(" do end");
707 } else {
708 self.push_str("do");
709 self.push_new_line();
710 self.indent_and_write_block(block);
711 self.push_str("end");
712 }
713 }
714
715 fn write_numeric_for(&mut self, numeric_for: &nodes::NumericForStatement) {
716 self.push_str("for ");
717
718 self.write_typed_identifier(numeric_for.get_identifier());
719 self.raw_push_char(' ');
720 self.raw_push_char('=');
721 self.raw_push_char(' ');
722 self.write_expression(numeric_for.get_start());
723 self.raw_push_char(',');
724 self.raw_push_char(' ');
725 self.write_expression(numeric_for.get_end());
726
727 if let Some(step) = numeric_for.get_step() {
728 self.raw_push_char(',');
729 self.raw_push_char(' ');
730 self.write_expression(step);
731 }
732
733 let block = numeric_for.get_block();
734
735 if block.is_empty() {
736 self.raw_push_str(" do end");
737 } else {
738 self.push_str("do");
739 self.push_new_line();
740 self.indent_and_write_block(block);
741 self.push_str("end");
742 }
743 }
744
745 fn write_if_statement(&mut self, if_statement: &nodes::IfStatement) {
746 let branches = if_statement.get_branches();
747
748 branches.iter().enumerate().for_each(|(index, branch)| {
749 if index == 0 {
750 self.push_str("if ");
751 } else {
752 self.push_str("elseif ");
753 }
754
755 self.write_expression(branch.get_condition());
756 self.raw_push_str(" then");
757 self.push_new_line();
758 self.indent_and_write_block(branch.get_block());
759 });
760
761 if let Some(else_block) = if_statement.get_else_block() {
762 self.push_str("else");
763 self.push_new_line();
764 self.indent_and_write_block(else_block);
765 }
766
767 self.push_str("end");
768 }
769
770 fn write_function_statement(&mut self, function: &nodes::FunctionStatement) {
771 self.write_attributes(function.attributes());
772 self.push_str("function ");
773 let name = function.get_name();
774
775 self.raw_push_str(name.get_name().get_name());
776 name.get_field_names().iter().for_each(|field| {
777 self.raw_push_char('.');
778 self.raw_push_str(field.get_name());
779 });
780
781 if let Some(method) = name.get_method() {
782 self.raw_push_char(':');
783 self.raw_push_str(method.get_name());
784 }
785
786 if let Some(generics) = function.get_generic_parameters() {
787 self.write_function_generics(generics);
788 }
789
790 self.raw_push_char('(');
791 self.write_function_parameters(
792 function.get_parameters(),
793 function.is_variadic(),
794 function.get_variadic_type(),
795 );
796 self.raw_push_char(')');
797
798 if let Some(return_type) = function.get_return_type() {
799 self.write_function_return_type_suffix(return_type);
800 }
801
802 let block = function.get_block();
803
804 if block.is_empty() {
805 self.raw_push_str(" end");
806 } else {
807 self.push_new_line();
808 self.indent_and_write_block(block);
809 self.push_str("end");
810 }
811 }
812
813 fn write_do_statement(&mut self, do_statement: &nodes::DoStatement) {
814 let block = do_statement.get_block();
815
816 if block.is_empty() {
817 self.push_str("do end");
818 } else {
819 self.push_str("do");
820 self.push_new_line();
821 self.indent_and_write_block(block);
822 self.push_str("end");
823 }
824 }
825
826 fn write_repeat_statement(&mut self, repeat: &nodes::RepeatStatement) {
827 self.push_str("repeat");
828
829 let block = repeat.get_block();
830
831 if block.is_empty() {
832 self.raw_push_str(" until ");
833 } else {
834 self.push_new_line();
835 self.indent_and_write_block(block);
836 self.push_str("until ");
837 }
838
839 self.write_expression(repeat.get_condition());
840 }
841
842 fn write_while_statement(&mut self, while_statement: &nodes::WhileStatement) {
843 self.push_str("while");
844 self.push_can_add_new_line(false);
845 self.write_expression(while_statement.get_condition());
846 self.pop_can_add_new_line();
847
848 let block = while_statement.get_block();
849
850 if block.is_empty() {
851 self.raw_push_str(" do end");
852 } else {
853 self.raw_push_str(" do");
854 self.push_new_line();
855 self.indent_and_write_block(block);
856 self.push_str("end");
857 }
858 }
859
860 fn write_type_declaration_statement(&mut self, statement: &nodes::TypeDeclarationStatement) {
861 if statement.is_exported() {
862 self.push_str("export");
863 }
864 self.push_can_add_new_line(false);
865 self.push_str("type");
866
867 self.write_identifier(statement.get_name());
868
869 if let Some(generic_parameters) = statement
870 .get_generic_parameters()
871 .filter(|generic_parameters| !generic_parameters.is_empty())
872 {
873 self.push_char('<');
874 let last_index = generic_parameters.len().saturating_sub(1);
875 for (i, parameter) in generic_parameters.iter().enumerate() {
876 use nodes::GenericParameterRef;
877
878 match parameter {
879 GenericParameterRef::TypeVariable(identifier) => {
880 self.write_identifier(identifier);
881 }
882 GenericParameterRef::TypeVariableWithDefault(identifier_with_default) => {
883 self.write_identifier(identifier_with_default.get_type_variable());
884 self.push_char('=');
885 self.write_type(identifier_with_default.get_default_type());
886 }
887 GenericParameterRef::GenericTypePack(generic_type_pack) => {
888 self.write_generic_type_pack(generic_type_pack);
889 }
890 GenericParameterRef::GenericTypePackWithDefault(generic_pack_with_default) => {
891 self.write_generic_type_pack(
892 generic_pack_with_default.get_generic_type_pack(),
893 );
894 self.push_char('=');
895 self.write_generic_type_pack_default(
896 generic_pack_with_default.get_default_type(),
897 );
898 }
899 }
900
901 if i != last_index {
902 self.push_char(',');
903 self.push_char(' ');
904 }
905 }
906 self.push_char('>');
907 }
908
909 self.push_char(' ');
910 self.push_char('=');
911 self.push_char(' ');
912
913 self.pop_can_add_new_line();
914
915 self.write_type(statement.get_type());
916 }
917
918 fn write_type_function_statement(&mut self, function: &nodes::TypeFunctionStatement) {
919 self.push_can_add_new_line(false);
920 if function.is_exported() {
921 self.push_str("export");
922 }
923 self.push_str("type function ");
924 self.write_identifier(function.get_identifier());
925
926 if let Some(generics) = function.get_generic_parameters() {
927 self.write_function_generics(generics);
928 }
929
930 self.raw_push_char('(');
931
932 self.pop_can_add_new_line();
933
934 let parameters = function.get_parameters();
935 self.write_function_parameters(
936 parameters,
937 function.is_variadic(),
938 function.get_variadic_type(),
939 );
940 self.raw_push_char(')');
941
942 if let Some(return_type) = function.get_return_type() {
943 self.write_function_return_type_suffix(return_type);
944 }
945
946 let block = function.get_block();
947
948 if block.is_empty() {
949 self.raw_push_str(" end");
950 } else {
951 self.push_new_line();
952 self.indent_and_write_block(block);
953 self.push_str("end");
954 }
955 }
956
957 fn write_false_expression(&mut self, _token: &Option<nodes::Token>) {
958 self.push_str("false");
959 }
960
961 fn write_true_expression(&mut self, _token: &Option<nodes::Token>) {
962 self.push_str("true");
963 }
964
965 fn write_nil_expression(&mut self, _token: &Option<nodes::Token>) {
966 self.push_str("nil");
967 }
968
969 fn write_variable_arguments_expression(&mut self, _token: &Option<nodes::Token>) {
970 self.push_str_and_break_if("...", utils::break_variable_arguments);
971 }
972
973 fn write_binary_expression(&mut self, binary: &nodes::BinaryExpression) {
974 let operator = binary.operator();
975 let left = binary.left();
976 let right = binary.right();
977
978 if operator.left_needs_parentheses(left) {
979 self.write_expression_in_parentheses(left);
980 } else {
981 self.write_expression(left);
982 }
983
984 self.push_space();
985 self.push_str(binary.operator().to_str());
986 self.push_space();
987
988 if operator.right_needs_parentheses(right) {
989 self.write_expression_in_parentheses(right);
990 } else {
991 self.write_expression(right);
992 }
993 }
994
995 fn write_unary_expression(&mut self, unary: &nodes::UnaryExpression) {
996 use nodes::{Expression, UnaryOperator::*};
997
998 match unary.operator() {
999 Length => self.push_char('#'),
1000 Minus => self.push_str_and_break_if("-", utils::break_minus),
1001 Not => self.push_str("not "),
1002 }
1003
1004 let expression = unary.get_expression();
1005
1006 match expression {
1007 Expression::Binary(binary) if !binary.operator().precedes_unary_expression() => {
1008 self.write_expression_in_parentheses(expression);
1009 }
1010 _ => self.write_expression(expression),
1011 }
1012 }
1013
1014 fn write_function(&mut self, function: &nodes::FunctionExpression) {
1015 self.push_can_add_new_line(false);
1016 self.write_attributes(function.attributes());
1017 self.pop_can_add_new_line();
1018 self.push_str("function");
1019
1020 if let Some(generics) = function.get_generic_parameters() {
1021 self.write_function_generics(generics);
1022 }
1023
1024 self.push_char('(');
1025
1026 let parameters = function.get_parameters();
1027 self.write_function_parameters(
1028 parameters,
1029 function.is_variadic(),
1030 function.get_variadic_type(),
1031 );
1032 self.raw_push_char(')');
1033
1034 if let Some(return_type) = function.get_return_type() {
1035 self.write_function_return_type_suffix(return_type);
1036 }
1037
1038 let block = function.get_block();
1039
1040 if block.is_empty() {
1041 self.raw_push_str(" end");
1042 } else {
1043 self.push_new_line();
1044 self.indent_and_write_block(block);
1045 self.push_str("end");
1046 }
1047 }
1048
1049 fn write_function_call(&mut self, call: &nodes::FunctionCall) {
1050 self.push_can_add_new_line(false);
1051 self.write_prefix(call.get_prefix());
1052
1053 if let Some(method) = &call.get_method() {
1054 self.push_char(':');
1055 self.push_str(method.get_name());
1056 }
1057
1058 self.write_arguments(call.get_arguments());
1059
1060 self.pop_can_add_new_line();
1061 }
1062
1063 fn write_tuple_arguments(&mut self, arguments: &nodes::TupleArguments) {
1064 self.raw_push_char('(');
1065
1066 let last_index = arguments.len().saturating_sub(1);
1067 arguments
1068 .iter_values()
1069 .enumerate()
1070 .for_each(|(index, expression)| {
1071 self.write_expression(expression);
1072
1073 if index != last_index {
1074 self.raw_push_char(',');
1075 self.raw_push_char(' ');
1076 }
1077 });
1078
1079 self.push_char(')');
1080 }
1081
1082 fn write_field(&mut self, field: &nodes::FieldExpression) {
1083 self.push_can_add_new_line(false);
1084 self.write_prefix(field.get_prefix());
1085 self.pop_can_add_new_line();
1086
1087 self.push_new_line_if_needed(1);
1088 self.raw_push_char('.');
1089 self.raw_push_str(field.get_field().get_name());
1090 }
1091
1092 fn write_index(&mut self, index: &nodes::IndexExpression) {
1093 self.push_can_add_new_line(false);
1094
1095 self.write_prefix(index.get_prefix());
1096
1097 self.push_char('[');
1098 self.write_expression(index.get_index());
1099 self.push_char(']');
1100
1101 self.pop_can_add_new_line();
1102 }
1103
1104 fn write_if_expression(&mut self, if_expression: &nodes::IfExpression) {
1105 self.push_str("if");
1106 self.write_expression(if_expression.get_condition());
1107
1108 if if_expression.has_elseif_branch() {
1109 self.push_indentation();
1110
1111 self.push_new_line();
1112 self.write_indentation();
1113 self.push_str("then");
1114 self.write_expression(if_expression.get_result());
1115
1116 for branch in if_expression.iter_branches() {
1117 self.push_new_line();
1118 self.write_indentation();
1119 self.push_str("elseif");
1120 self.write_expression(branch.get_condition());
1121
1122 self.push_new_line();
1123 self.write_indentation();
1124 self.push_str("then");
1125 self.write_expression(branch.get_result());
1126 }
1127
1128 self.push_new_line();
1129 self.write_indentation();
1130 self.push_str("else");
1131 self.write_expression(if_expression.get_else_result());
1132
1133 self.pop_indentation();
1134 } else {
1135 self.push_str("then");
1136 self.write_expression(if_expression.get_result());
1137 self.push_str("else");
1138 self.write_expression(if_expression.get_else_result());
1139 }
1140 }
1141
1142 fn write_table(&mut self, table: &nodes::TableExpression) {
1143 self.push_char('{');
1144
1145 let entries = table.get_entries();
1146 let table_len = entries.len();
1147
1148 if table_len == 0 {
1149 self.raw_push_char('}');
1150 } else {
1151 let column_space = self.column_span.saturating_sub(self.current_line_length);
1152 if self.table_fits_on_line(entries, column_space) {
1153 let last_index = table_len.saturating_sub(1);
1154
1155 entries.iter().enumerate().for_each(|(index, entry)| {
1156 self.write_table_entry(entry);
1157
1158 if index != last_index {
1159 self.raw_push_char(',');
1160 self.raw_push_char(' ');
1161 }
1162 });
1163 } else {
1164 self.push_indentation();
1165
1166 entries.iter().for_each(|entry| {
1167 self.push_new_line();
1168 self.write_indentation();
1169 self.write_table_entry(entry);
1170
1171 self.raw_push_char(',');
1172 });
1173
1174 self.pop_indentation();
1175 self.push_new_line();
1176 }
1177
1178 self.push_char('}');
1179 }
1180 }
1181
1182 fn write_table_entry(&mut self, entry: &nodes::TableEntry) {
1183 match entry {
1184 nodes::TableEntry::Field(entry) => {
1185 self.raw_push_str(entry.get_field().get_name());
1186 self.raw_push_str(" = ");
1187 self.write_expression(entry.get_value());
1188 }
1189 nodes::TableEntry::Index(entry) => {
1190 self.raw_push_char('[');
1191 self.push_can_add_new_line(false);
1192 self.write_expression(entry.get_key());
1193 self.pop_can_add_new_line();
1194 self.raw_push_str("] = ");
1195 self.write_expression(entry.get_value());
1196 }
1197 nodes::TableEntry::Value(expression) => self.write_expression(expression),
1198 }
1199 }
1200
1201 fn write_number(&mut self, number: &nodes::NumberExpression) {
1202 self.push_str(&utils::write_number(number));
1203 }
1204
1205 fn write_string(&mut self, string: &nodes::StringExpression) {
1206 let result = utils::write_string(string.get_value());
1207 if result.starts_with('[') {
1208 self.push_str_and_break_if(&result, utils::break_long_string);
1209 } else {
1210 self.push_str(&result);
1211 }
1212 }
1213
1214 fn write_interpolated_string(
1215 &mut self,
1216 interpolated_string: &nodes::InterpolatedStringExpression,
1217 ) {
1218 self.push_char('`');
1219
1220 for segment in interpolated_string.iter_segments() {
1221 match segment {
1222 nodes::InterpolationSegment::String(string_segment) => {
1223 self.raw_push_str(&utils::write_interpolated_string_segment(string_segment));
1224 }
1225 nodes::InterpolationSegment::Value(value) => {
1226 self.raw_push_char('{');
1227 let expression = value.get_expression();
1229 if utils::starts_with_table(expression).is_some() {
1230 self.raw_push_char(' ');
1231 }
1232 self.write_expression(expression);
1233 self.push_char('}');
1234 }
1235 }
1236 }
1237
1238 self.raw_push_char('`');
1239 }
1240
1241 fn write_literal_table(&mut self, table: &nodes::LiteralTable) {
1242 self.push_char('{');
1243 let last_index = table.len().saturating_sub(1);
1244 for (index, entry) in table.iter_entries().enumerate() {
1245 self.write_literal_table_entry(entry);
1246 if index != last_index {
1247 self.push_char(',');
1248 }
1249 }
1250 self.push_char('}');
1251 }
1252
1253 fn write_literal_table_entry(&mut self, entry: &nodes::LiteralTableEntry) {
1254 use nodes::LiteralTableEntry::*;
1255
1256 self.push_can_add_new_line(false);
1257
1258 match entry {
1259 Field(field) => {
1260 self.write_identifier(field.get_field());
1261 self.push_char('=');
1262 self.write_literal_expression(field.get_value());
1263 }
1264 Value(value) => {
1265 self.write_literal_expression(value);
1266 }
1267 }
1268
1269 self.pop_can_add_new_line();
1270 }
1271
1272 fn write_attribute_tuple_arguments(&mut self, tuple: &nodes::AttributeTupleArguments) {
1273 self.push_char('(');
1274 self.push_can_add_new_line(false);
1275
1276 let last_index = tuple.len().saturating_sub(1);
1277 for (index, value) in tuple.iter_values().enumerate() {
1278 self.write_literal_expression(value);
1279 if index != last_index {
1280 self.push_char(',');
1281 self.push_char(' ');
1282 }
1283 }
1284
1285 self.pop_can_add_new_line();
1286 self.push_char(')');
1287 }
1288
1289 fn write_identifier(&mut self, identifier: &nodes::Identifier) {
1290 self.push_str(identifier.get_name());
1291 }
1292
1293 fn write_parenthese(&mut self, parenthese: &nodes::ParentheseExpression) {
1294 self.push_char('(');
1295 self.push_can_add_new_line(false);
1296
1297 self.write_expression(parenthese.inner_expression());
1298
1299 self.pop_can_add_new_line();
1300 self.push_char(')');
1301 }
1302
1303 fn write_type_cast(&mut self, type_cast: &nodes::TypeCastExpression) {
1304 let inner_expression = type_cast.get_expression();
1305
1306 if nodes::TypeCastExpression::needs_parentheses(inner_expression) {
1307 self.push_char('(');
1308 self.push_can_add_new_line(false);
1309 self.write_expression(inner_expression);
1310 self.pop_can_add_new_line();
1311 self.push_char(')');
1312 } else {
1313 self.write_expression(inner_expression);
1314 }
1315
1316 self.push_can_add_new_line(false);
1317 self.push_str("::");
1318 self.write_type(type_cast.get_type());
1319 self.pop_can_add_new_line();
1320 }
1321
1322 fn write_type_name(&mut self, type_name: &nodes::TypeName) {
1323 self.write_identifier(type_name.get_type_name());
1324 if let Some(parameters) = type_name.get_type_parameters() {
1325 self.push_char('<');
1326 self.push_can_add_new_line(false);
1327 let last_index = parameters.len().saturating_sub(1);
1328 for (index, parameter) in parameters.iter().enumerate() {
1329 self.write_type_parameter(parameter);
1330 if index != last_index {
1331 self.push_char(',');
1332 self.push_char(' ');
1333 }
1334 }
1335
1336 self.pop_can_add_new_line();
1337 self.push_char('>');
1338 }
1339 }
1340
1341 fn write_type_field(&mut self, type_field: &nodes::TypeField) {
1342 self.write_identifier(type_field.get_namespace());
1343 self.push_new_line_if_needed(1);
1344 self.raw_push_char('.');
1345 self.write_type_name(type_field.get_type_name());
1346 }
1347
1348 fn write_true_type(&mut self, _: &Option<nodes::Token>) {
1349 self.push_str("true");
1350 }
1351
1352 fn write_false_type(&mut self, _: &Option<nodes::Token>) {
1353 self.push_str("false");
1354 }
1355
1356 fn write_nil_type(&mut self, _: &Option<nodes::Token>) {
1357 self.push_str("nil");
1358 }
1359
1360 fn write_string_type(&mut self, string_type: &nodes::StringType) {
1361 let result = utils::write_string(string_type.get_value());
1362 if result.starts_with('[') {
1363 self.push_str_and_break_if(&result, utils::break_long_string);
1364 } else {
1365 self.push_str(&result);
1366 }
1367 }
1368
1369 fn write_array_type(&mut self, array: &nodes::ArrayType) {
1370 self.push_char('{');
1371 self.write_type(array.get_element_type());
1372 self.push_char('}');
1373 }
1374
1375 fn write_table_type(&mut self, table_type: &nodes::TableType) {
1376 self.push_char('{');
1377
1378 let last_index = table_type.len().saturating_sub(1);
1379 for (index, property) in table_type.iter_entries().enumerate() {
1380 if let Some(modifier) = property.get_modifier() {
1381 match modifier {
1382 nodes::TablePropertyModifier::Read => self.push_str("read"),
1383 nodes::TablePropertyModifier::Write => self.push_str("write"),
1384 }
1385 self.push_char(' ');
1386 }
1387
1388 match property {
1389 nodes::TableEntryType::Property(property) => {
1390 self.write_identifier(property.get_identifier());
1391 self.push_char(':');
1392 self.push_char(' ');
1393 self.write_type(property.get_type());
1394 }
1395 nodes::TableEntryType::Literal(property) => {
1396 self.push_char('[');
1397 self.write_string_type(property.get_string());
1398 self.push_char(']');
1399 self.push_char(':');
1400 self.push_char(' ');
1401 self.write_type(property.get_type());
1402 }
1403 nodes::TableEntryType::Indexer(indexer) => {
1404 self.push_char('[');
1405
1406 let key_type = indexer.get_key_type();
1407
1408 let need_parentheses = matches!(
1409 key_type,
1410 nodes::Type::Optional(_)
1411 | nodes::Type::Intersection(_)
1412 | nodes::Type::Union(_)
1413 );
1414
1415 if need_parentheses {
1416 self.push_char('(');
1417 self.write_type(key_type);
1418 self.push_char(')');
1419 } else {
1420 self.write_type(key_type);
1421 }
1422
1423 self.push_char(']');
1424 self.push_char(':');
1425 self.push_char(' ');
1426 self.write_type(indexer.get_value_type());
1427 }
1428 }
1429 if index != last_index {
1430 self.push_char(',');
1431 self.push_char(' ');
1432 }
1433 }
1434
1435 self.push_char('}');
1436 }
1437
1438 fn write_expression_type(&mut self, expression_type: &nodes::ExpressionType) {
1439 self.push_str("typeof(");
1440 self.write_expression(expression_type.get_expression());
1441 self.push_char(')');
1442 }
1443
1444 fn write_parenthese_type(&mut self, parenthese_type: &nodes::ParentheseType) {
1445 self.write_type_in_parentheses(parenthese_type.get_inner_type());
1446 }
1447
1448 fn write_function_type(&mut self, function_type: &nodes::FunctionType) {
1449 if let Some(generics) = function_type.get_generic_parameters() {
1450 self.write_function_generics(generics);
1451 }
1452
1453 self.push_char('(');
1454
1455 let last_index = function_type.argument_len().saturating_sub(1);
1456
1457 for (index, argument) in function_type.iter_arguments().enumerate() {
1458 if let Some(name) = argument.get_name() {
1459 self.write_identifier(name);
1460 self.push_char(':');
1461 }
1462 self.write_type(argument.get_type());
1463
1464 if index != last_index {
1465 self.push_char(',');
1466 self.push_space();
1467 }
1468 }
1469
1470 if let Some(variadic_argument_type) = function_type.get_variadic_argument_type() {
1471 if function_type.argument_len() > 0 {
1472 self.push_char(',');
1473 self.push_space();
1474 }
1475 self.write_variadic_argument_type(variadic_argument_type);
1476 }
1477
1478 self.push_str(") -> ");
1479 self.write_function_return_type(function_type.get_return_type());
1480 }
1481
1482 fn write_optional_type(&mut self, optional: &nodes::OptionalType) {
1483 let inner_type = optional.get_inner_type();
1484 if nodes::OptionalType::needs_parentheses(inner_type) {
1485 self.write_type_in_parentheses(inner_type);
1486 } else {
1487 self.write_type(inner_type);
1488 }
1489 self.push_char('?');
1490 }
1491
1492 fn write_intersection_type(&mut self, intersection: &nodes::IntersectionType) {
1493 if intersection.has_leading_token() {
1494 self.push_char('&');
1495 }
1496
1497 let length = intersection.len();
1498 let last_index = length.saturating_sub(1);
1499
1500 for (i, r#type) in intersection.iter_types().enumerate() {
1501 if i != 0 {
1502 self.push_char('&');
1503 }
1504
1505 let need_parentheses = if i == last_index {
1506 nodes::IntersectionType::last_needs_parentheses(r#type)
1507 } else {
1508 nodes::IntersectionType::intermediate_needs_parentheses(r#type)
1509 };
1510
1511 if need_parentheses {
1512 self.write_type_in_parentheses(r#type);
1513 } else {
1514 self.write_type(r#type);
1515 }
1516 }
1517 }
1518
1519 fn write_union_type(&mut self, union: &nodes::UnionType) {
1520 let length = union.len();
1521 let last_index = length.saturating_sub(1);
1522
1523 if union.has_leading_token() {
1524 self.push_char('|');
1525 self.push_space();
1526 }
1527
1528 for (i, r#type) in union.iter_types().enumerate() {
1529 if i != 0 {
1530 self.push_space();
1531 self.push_char('|');
1532 self.push_space();
1533 }
1534
1535 let need_parentheses = if i == last_index {
1536 nodes::UnionType::last_needs_parentheses(r#type)
1537 } else {
1538 nodes::UnionType::intermediate_needs_parentheses(r#type)
1539 };
1540
1541 if need_parentheses {
1542 self.write_type_in_parentheses(r#type);
1543 } else {
1544 self.write_type(r#type);
1545 }
1546 }
1547 }
1548
1549 fn write_type_pack(&mut self, type_pack: &nodes::TypePack) {
1550 self.push_char('(');
1551
1552 let last_index = type_pack.len().saturating_sub(1);
1553
1554 for (index, r#type) in type_pack.into_iter().enumerate() {
1555 self.write_type(r#type);
1556 if index != last_index {
1557 self.push_char(',');
1558 }
1559 }
1560
1561 if let Some(variadic_argument_type) = type_pack.get_variadic_type() {
1562 if !type_pack.is_empty() {
1563 self.push_char(',');
1564 }
1565 self.write_variadic_argument_type(variadic_argument_type);
1566 }
1567
1568 self.push_char(')');
1569 }
1570
1571 fn write_variadic_type_pack(&mut self, variadic_type_pack: &nodes::VariadicTypePack) {
1572 self.push_str("...");
1573 self.write_type(variadic_type_pack.get_type());
1574 }
1575
1576 fn write_generic_type_pack(&mut self, generic_type_pack: &nodes::GenericTypePack) {
1577 self.write_identifier(generic_type_pack.get_name());
1578 self.push_str("...");
1579 }
1580}