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::VariableAssignment) {
588 self.push_str(assign.get_assignment_kind().as_keyword());
589 self.push_space();
590
591 self.push_can_add_new_line(false);
592
593 let variables_length = assign.variables_len();
594 let last_variable_index = variables_length.saturating_sub(1);
595
596 for (index, variable) in assign.iter_variables().enumerate() {
597 self.write_typed_identifier(variable);
598
599 if index != last_variable_index {
600 self.raw_push_char(',');
601 self.raw_push_char(' ');
602 }
603 }
604
605 for i in 0..assign.required_new_variables() {
608 if i != 0 || variables_length > 0 {
609 self.push_char(',');
610 }
611 utils::THROWAWAY_IDENTIFIER.with(|identifier| {
612 self.write_typed_identifier(identifier);
613 });
614 }
615
616 let required_nil_values = assign.required_nil_values();
619
620 let has_values = assign.has_values();
621
622 if has_values || required_nil_values > 0 {
623 self.raw_push_str(" = ");
624
625 let last_value_index = assign.values_len().saturating_sub(1);
626
627 for (index, value) in assign.iter_values().enumerate() {
628 self.write_expression(value);
629
630 if index != last_value_index {
631 self.raw_push_char(',');
632 self.raw_push_char(' ');
633 }
634 }
635
636 for i in 0..required_nil_values {
637 if i != 0 || has_values {
638 self.push_char(',');
639 }
640 utils::NIL_EXPRESSION.with(|nil| {
641 self.write_expression(nil);
642 })
643 }
644 };
645
646 self.pop_can_add_new_line();
647 }
648
649 fn write_compound_assign(&mut self, assign: &nodes::CompoundAssignStatement) {
650 self.push_can_add_new_line(false);
651
652 self.write_variable(assign.get_variable());
653
654 self.raw_push_char(' ');
655 self.raw_push_str(assign.get_operator().to_str());
656 self.push_space();
657
658 self.write_expression(assign.get_value());
659
660 self.pop_can_add_new_line();
661 }
662
663 fn write_local_function(&mut self, function: &nodes::FunctionAssignment) {
664 self.write_attributes(function.attributes());
665
666 self.push_str(function.get_assignment_kind().as_keyword());
667 self.push_str(" function ");
668 self.raw_push_str(function.get_name());
669
670 if let Some(generics) = function.get_generic_parameters() {
671 self.write_function_generics(generics);
672 }
673
674 self.raw_push_char('(');
675
676 let parameters = function.get_parameters();
677 self.write_function_parameters(
678 parameters,
679 function.is_variadic(),
680 function.get_variadic_type(),
681 );
682 self.raw_push_char(')');
683
684 if let Some(return_type) = function.get_return_type() {
685 self.write_function_return_type_suffix(return_type);
686 }
687
688 let block = function.get_block();
689
690 if block.is_empty() {
691 self.raw_push_str(" end");
692 } else {
693 self.push_new_line();
694 self.indent_and_write_block(block);
695 self.push_str("end");
696 }
697 }
698
699 fn write_generic_for(&mut self, generic_for: &nodes::GenericForStatement) {
700 self.push_str("for ");
701
702 let identifiers = generic_for.get_identifiers();
703 let last_identifier_index = identifiers.len().saturating_sub(1);
704 identifiers
705 .iter()
706 .enumerate()
707 .for_each(|(index, identifier)| {
708 self.write_typed_identifier(identifier);
709
710 if index != last_identifier_index {
711 self.raw_push_char(',');
712 self.raw_push_char(' ');
713 }
714 });
715
716 self.raw_push_str(" in ");
717
718 let expressions = generic_for.get_expressions();
719 let last_expression_index = expressions.len().saturating_sub(1);
720 expressions
721 .iter()
722 .enumerate()
723 .for_each(|(index, expression)| {
724 self.write_expression(expression);
725
726 if index != last_expression_index {
727 self.raw_push_char(',');
728 self.raw_push_char(' ');
729 }
730 });
731
732 let block = generic_for.get_block();
733
734 if block.is_empty() {
735 self.raw_push_str(" do end");
736 } else {
737 self.push_str("do");
738 self.push_new_line();
739 self.indent_and_write_block(block);
740 self.push_str("end");
741 }
742 }
743
744 fn write_numeric_for(&mut self, numeric_for: &nodes::NumericForStatement) {
745 self.push_str("for ");
746
747 self.write_typed_identifier(numeric_for.get_identifier());
748 self.raw_push_char(' ');
749 self.raw_push_char('=');
750 self.raw_push_char(' ');
751 self.write_expression(numeric_for.get_start());
752 self.raw_push_char(',');
753 self.raw_push_char(' ');
754 self.write_expression(numeric_for.get_end());
755
756 if let Some(step) = numeric_for.get_step() {
757 self.raw_push_char(',');
758 self.raw_push_char(' ');
759 self.write_expression(step);
760 }
761
762 let block = numeric_for.get_block();
763
764 if block.is_empty() {
765 self.raw_push_str(" do end");
766 } else {
767 self.push_str("do");
768 self.push_new_line();
769 self.indent_and_write_block(block);
770 self.push_str("end");
771 }
772 }
773
774 fn write_if_statement(&mut self, if_statement: &nodes::IfStatement) {
775 let branches = if_statement.get_branches();
776
777 branches.iter().enumerate().for_each(|(index, branch)| {
778 if index == 0 {
779 self.push_str("if ");
780 } else {
781 self.push_str("elseif ");
782 }
783
784 self.write_expression(branch.get_condition());
785 self.raw_push_str(" then");
786 self.push_new_line();
787 self.indent_and_write_block(branch.get_block());
788 });
789
790 if let Some(else_block) = if_statement.get_else_block() {
791 self.push_str("else");
792 self.push_new_line();
793 self.indent_and_write_block(else_block);
794 }
795
796 self.push_str("end");
797 }
798
799 fn write_function_statement(&mut self, function: &nodes::FunctionStatement) {
800 self.write_attributes(function.attributes());
801 self.push_str("function ");
802 let name = function.get_name();
803
804 self.raw_push_str(name.get_name().get_name());
805 name.get_field_names().iter().for_each(|field| {
806 self.raw_push_char('.');
807 self.raw_push_str(field.get_name());
808 });
809
810 if let Some(method) = name.get_method() {
811 self.raw_push_char(':');
812 self.raw_push_str(method.get_name());
813 }
814
815 if let Some(generics) = function.get_generic_parameters() {
816 self.write_function_generics(generics);
817 }
818
819 self.raw_push_char('(');
820 self.write_function_parameters(
821 function.get_parameters(),
822 function.is_variadic(),
823 function.get_variadic_type(),
824 );
825 self.raw_push_char(')');
826
827 if let Some(return_type) = function.get_return_type() {
828 self.write_function_return_type_suffix(return_type);
829 }
830
831 let block = function.get_block();
832
833 if block.is_empty() {
834 self.raw_push_str(" end");
835 } else {
836 self.push_new_line();
837 self.indent_and_write_block(block);
838 self.push_str("end");
839 }
840 }
841
842 fn write_do_statement(&mut self, do_statement: &nodes::DoStatement) {
843 let block = do_statement.get_block();
844
845 if block.is_empty() {
846 self.push_str("do end");
847 } else {
848 self.push_str("do");
849 self.push_new_line();
850 self.indent_and_write_block(block);
851 self.push_str("end");
852 }
853 }
854
855 fn write_repeat_statement(&mut self, repeat: &nodes::RepeatStatement) {
856 self.push_str("repeat");
857
858 let block = repeat.get_block();
859
860 if block.is_empty() {
861 self.raw_push_str(" until ");
862 } else {
863 self.push_new_line();
864 self.indent_and_write_block(block);
865 self.push_str("until ");
866 }
867
868 self.write_expression(repeat.get_condition());
869 }
870
871 fn write_while_statement(&mut self, while_statement: &nodes::WhileStatement) {
872 self.push_str("while");
873 self.push_can_add_new_line(false);
874 self.write_expression(while_statement.get_condition());
875 self.pop_can_add_new_line();
876
877 let block = while_statement.get_block();
878
879 if block.is_empty() {
880 self.raw_push_str(" do end");
881 } else {
882 self.raw_push_str(" do");
883 self.push_new_line();
884 self.indent_and_write_block(block);
885 self.push_str("end");
886 }
887 }
888
889 fn write_type_declaration_statement(&mut self, statement: &nodes::TypeDeclarationStatement) {
890 if statement.is_exported() {
891 self.push_str("export");
892 }
893 self.push_can_add_new_line(false);
894 self.push_str("type");
895
896 self.write_identifier(statement.get_name());
897
898 if let Some(generic_parameters) = statement
899 .get_generic_parameters()
900 .filter(|generic_parameters| !generic_parameters.is_empty())
901 {
902 self.push_char('<');
903 let last_index = generic_parameters.len().saturating_sub(1);
904 for (i, parameter) in generic_parameters.iter().enumerate() {
905 use nodes::GenericParameterRef;
906
907 match parameter {
908 GenericParameterRef::TypeVariable(identifier) => {
909 self.write_identifier(identifier);
910 }
911 GenericParameterRef::TypeVariableWithDefault(identifier_with_default) => {
912 self.write_identifier(identifier_with_default.get_type_variable());
913 self.push_char('=');
914 self.write_type(identifier_with_default.get_default_type());
915 }
916 GenericParameterRef::GenericTypePack(generic_type_pack) => {
917 self.write_generic_type_pack(generic_type_pack);
918 }
919 GenericParameterRef::GenericTypePackWithDefault(generic_pack_with_default) => {
920 self.write_generic_type_pack(
921 generic_pack_with_default.get_generic_type_pack(),
922 );
923 self.push_char('=');
924 self.write_generic_type_pack_default(
925 generic_pack_with_default.get_default_type(),
926 );
927 }
928 }
929
930 if i != last_index {
931 self.push_char(',');
932 self.push_char(' ');
933 }
934 }
935 self.push_char('>');
936 }
937
938 self.push_char(' ');
939 self.push_char('=');
940 self.push_char(' ');
941
942 self.pop_can_add_new_line();
943
944 self.write_type(statement.get_type());
945 }
946
947 fn write_type_function_statement(&mut self, function: &nodes::TypeFunctionStatement) {
948 self.push_can_add_new_line(false);
949 if function.is_exported() {
950 self.push_str("export");
951 }
952 self.push_str("type function ");
953 self.write_identifier(function.get_identifier());
954
955 if let Some(generics) = function.get_generic_parameters() {
956 self.write_function_generics(generics);
957 }
958
959 self.raw_push_char('(');
960
961 self.pop_can_add_new_line();
962
963 let parameters = function.get_parameters();
964 self.write_function_parameters(
965 parameters,
966 function.is_variadic(),
967 function.get_variadic_type(),
968 );
969 self.raw_push_char(')');
970
971 if let Some(return_type) = function.get_return_type() {
972 self.write_function_return_type_suffix(return_type);
973 }
974
975 let block = function.get_block();
976
977 if block.is_empty() {
978 self.raw_push_str(" end");
979 } else {
980 self.push_new_line();
981 self.indent_and_write_block(block);
982 self.push_str("end");
983 }
984 }
985
986 fn write_false_expression(&mut self, _token: &Option<nodes::Token>) {
987 self.push_str("false");
988 }
989
990 fn write_true_expression(&mut self, _token: &Option<nodes::Token>) {
991 self.push_str("true");
992 }
993
994 fn write_nil_expression(&mut self, _token: &Option<nodes::Token>) {
995 self.push_str("nil");
996 }
997
998 fn write_variable_arguments_expression(&mut self, _token: &Option<nodes::Token>) {
999 self.push_str_and_break_if("...", utils::break_variable_arguments);
1000 }
1001
1002 fn write_binary_expression(&mut self, binary: &nodes::BinaryExpression) {
1003 let operator = binary.operator();
1004 let left = binary.left();
1005 let right = binary.right();
1006
1007 if operator.left_needs_parentheses(left) {
1008 self.write_expression_in_parentheses(left);
1009 } else {
1010 self.write_expression(left);
1011 }
1012
1013 self.push_space();
1014 self.push_str(binary.operator().to_str());
1015 self.push_space();
1016
1017 if operator.right_needs_parentheses(right) {
1018 self.write_expression_in_parentheses(right);
1019 } else {
1020 self.write_expression(right);
1021 }
1022 }
1023
1024 fn write_unary_expression(&mut self, unary: &nodes::UnaryExpression) {
1025 use nodes::{Expression, UnaryOperator::*};
1026
1027 match unary.operator() {
1028 Length => self.push_char('#'),
1029 Minus => self.push_str_and_break_if("-", utils::break_minus),
1030 Not => self.push_str("not "),
1031 }
1032
1033 let expression = unary.get_expression();
1034
1035 match expression {
1036 Expression::Binary(binary) if !binary.operator().precedes_unary_expression() => {
1037 self.write_expression_in_parentheses(expression);
1038 }
1039 _ => self.write_expression(expression),
1040 }
1041 }
1042
1043 fn write_function(&mut self, function: &nodes::FunctionExpression) {
1044 self.push_can_add_new_line(false);
1045 self.write_attributes(function.attributes());
1046 self.pop_can_add_new_line();
1047 self.push_str("function");
1048
1049 if let Some(generics) = function.get_generic_parameters() {
1050 self.write_function_generics(generics);
1051 }
1052
1053 self.push_char('(');
1054
1055 let parameters = function.get_parameters();
1056 self.write_function_parameters(
1057 parameters,
1058 function.is_variadic(),
1059 function.get_variadic_type(),
1060 );
1061 self.raw_push_char(')');
1062
1063 if let Some(return_type) = function.get_return_type() {
1064 self.write_function_return_type_suffix(return_type);
1065 }
1066
1067 let block = function.get_block();
1068
1069 if block.is_empty() {
1070 self.raw_push_str(" end");
1071 } else {
1072 self.push_new_line();
1073 self.indent_and_write_block(block);
1074 self.push_str("end");
1075 }
1076 }
1077
1078 fn write_function_call(&mut self, call: &nodes::FunctionCall) {
1079 self.push_can_add_new_line(false);
1080 self.write_prefix(call.get_prefix());
1081
1082 if let Some(method) = &call.get_method() {
1083 self.push_char(':');
1084 self.push_str(method.get_name());
1085 }
1086
1087 self.write_arguments(call.get_arguments());
1088
1089 self.pop_can_add_new_line();
1090 }
1091
1092 fn write_tuple_arguments(&mut self, arguments: &nodes::TupleArguments) {
1093 self.raw_push_char('(');
1094
1095 let last_index = arguments.len().saturating_sub(1);
1096 arguments
1097 .iter_values()
1098 .enumerate()
1099 .for_each(|(index, expression)| {
1100 self.write_expression(expression);
1101
1102 if index != last_index {
1103 self.raw_push_char(',');
1104 self.raw_push_char(' ');
1105 }
1106 });
1107
1108 self.push_char(')');
1109 }
1110
1111 fn write_field(&mut self, field: &nodes::FieldExpression) {
1112 self.push_can_add_new_line(false);
1113 self.write_prefix(field.get_prefix());
1114 self.pop_can_add_new_line();
1115
1116 self.push_new_line_if_needed(1);
1117 self.raw_push_char('.');
1118 self.raw_push_str(field.get_field().get_name());
1119 }
1120
1121 fn write_index(&mut self, index: &nodes::IndexExpression) {
1122 self.push_can_add_new_line(false);
1123
1124 self.write_prefix(index.get_prefix());
1125
1126 self.push_char('[');
1127 self.write_expression(index.get_index());
1128 self.push_char(']');
1129
1130 self.pop_can_add_new_line();
1131 }
1132
1133 fn write_if_expression(&mut self, if_expression: &nodes::IfExpression) {
1134 self.push_str("if");
1135 self.write_expression(if_expression.get_condition());
1136
1137 if if_expression.has_elseif_branch() {
1138 self.push_indentation();
1139
1140 self.push_new_line();
1141 self.write_indentation();
1142 self.push_str("then");
1143 self.write_expression(if_expression.get_result());
1144
1145 for branch in if_expression.iter_branches() {
1146 self.push_new_line();
1147 self.write_indentation();
1148 self.push_str("elseif");
1149 self.write_expression(branch.get_condition());
1150
1151 self.push_new_line();
1152 self.write_indentation();
1153 self.push_str("then");
1154 self.write_expression(branch.get_result());
1155 }
1156
1157 self.push_new_line();
1158 self.write_indentation();
1159 self.push_str("else");
1160 self.write_expression(if_expression.get_else_result());
1161
1162 self.pop_indentation();
1163 } else {
1164 self.push_str("then");
1165 self.write_expression(if_expression.get_result());
1166 self.push_str("else");
1167 self.write_expression(if_expression.get_else_result());
1168 }
1169 }
1170
1171 fn write_table(&mut self, table: &nodes::TableExpression) {
1172 self.push_char('{');
1173
1174 let entries = table.get_entries();
1175 let table_len = entries.len();
1176
1177 if table_len == 0 {
1178 self.raw_push_char('}');
1179 } else {
1180 let column_space = self.column_span.saturating_sub(self.current_line_length);
1181 if self.table_fits_on_line(entries, column_space) {
1182 let last_index = table_len.saturating_sub(1);
1183
1184 entries.iter().enumerate().for_each(|(index, entry)| {
1185 self.write_table_entry(entry);
1186
1187 if index != last_index {
1188 self.raw_push_char(',');
1189 self.raw_push_char(' ');
1190 }
1191 });
1192 } else {
1193 self.push_indentation();
1194
1195 entries.iter().for_each(|entry| {
1196 self.push_new_line();
1197 self.write_indentation();
1198 self.write_table_entry(entry);
1199
1200 self.raw_push_char(',');
1201 });
1202
1203 self.pop_indentation();
1204 self.push_new_line();
1205 }
1206
1207 self.push_char('}');
1208 }
1209 }
1210
1211 fn write_table_entry(&mut self, entry: &nodes::TableEntry) {
1212 match entry {
1213 nodes::TableEntry::Field(entry) => {
1214 self.raw_push_str(entry.get_field().get_name());
1215 self.raw_push_str(" = ");
1216 self.write_expression(entry.get_value());
1217 }
1218 nodes::TableEntry::Index(entry) => {
1219 self.raw_push_char('[');
1220 self.push_can_add_new_line(false);
1221 self.write_expression(entry.get_key());
1222 self.pop_can_add_new_line();
1223 self.raw_push_str("] = ");
1224 self.write_expression(entry.get_value());
1225 }
1226 nodes::TableEntry::Value(expression) => self.write_expression(expression),
1227 }
1228 }
1229
1230 fn write_number(&mut self, number: &nodes::NumberExpression) {
1231 self.push_str(&utils::write_number(number));
1232 }
1233
1234 fn write_string(&mut self, string: &nodes::StringExpression) {
1235 let result = utils::write_string(string.get_value());
1236 if result.starts_with('[') {
1237 self.push_str_and_break_if(&result, utils::break_long_string);
1238 } else {
1239 self.push_str(&result);
1240 }
1241 }
1242
1243 fn write_interpolated_string(
1244 &mut self,
1245 interpolated_string: &nodes::InterpolatedStringExpression,
1246 ) {
1247 self.push_char('`');
1248
1249 for segment in interpolated_string.iter_segments() {
1250 match segment {
1251 nodes::InterpolationSegment::String(string_segment) => {
1252 self.raw_push_str(&utils::write_interpolated_string_segment(string_segment));
1253 }
1254 nodes::InterpolationSegment::Value(value) => {
1255 self.raw_push_char('{');
1256 let expression = value.get_expression();
1258 if utils::starts_with_table(expression).is_some() {
1259 self.raw_push_char(' ');
1260 }
1261 self.write_expression(expression);
1262 self.push_char('}');
1263 }
1264 }
1265 }
1266
1267 self.raw_push_char('`');
1268 }
1269
1270 fn write_literal_table(&mut self, table: &nodes::LiteralTable) {
1271 self.push_char('{');
1272 let last_index = table.len().saturating_sub(1);
1273 for (index, entry) in table.iter_entries().enumerate() {
1274 self.write_literal_table_entry(entry);
1275 if index != last_index {
1276 self.push_char(',');
1277 }
1278 }
1279 self.push_char('}');
1280 }
1281
1282 fn write_literal_table_entry(&mut self, entry: &nodes::LiteralTableEntry) {
1283 use nodes::LiteralTableEntry::*;
1284
1285 self.push_can_add_new_line(false);
1286
1287 match entry {
1288 Field(field) => {
1289 self.write_identifier(field.get_field());
1290 self.push_char('=');
1291 self.write_literal_expression(field.get_value());
1292 }
1293 Value(value) => {
1294 self.write_literal_expression(value);
1295 }
1296 }
1297
1298 self.pop_can_add_new_line();
1299 }
1300
1301 fn write_attribute_tuple_arguments(&mut self, tuple: &nodes::AttributeTupleArguments) {
1302 self.push_char('(');
1303 self.push_can_add_new_line(false);
1304
1305 let last_index = tuple.len().saturating_sub(1);
1306 for (index, value) in tuple.iter_values().enumerate() {
1307 self.write_literal_expression(value);
1308 if index != last_index {
1309 self.push_char(',');
1310 self.push_char(' ');
1311 }
1312 }
1313
1314 self.pop_can_add_new_line();
1315 self.push_char(')');
1316 }
1317
1318 fn write_identifier(&mut self, identifier: &nodes::Identifier) {
1319 self.push_str(identifier.get_name());
1320 }
1321
1322 fn write_parenthese(&mut self, parenthese: &nodes::ParentheseExpression) {
1323 self.push_char('(');
1324 self.push_can_add_new_line(false);
1325
1326 self.write_expression(parenthese.inner_expression());
1327
1328 self.pop_can_add_new_line();
1329 self.push_char(')');
1330 }
1331
1332 fn write_type_cast(&mut self, type_cast: &nodes::TypeCastExpression) {
1333 let inner_expression = type_cast.get_expression();
1334
1335 if nodes::TypeCastExpression::needs_parentheses(inner_expression) {
1336 self.push_char('(');
1337 self.push_can_add_new_line(false);
1338 self.write_expression(inner_expression);
1339 self.pop_can_add_new_line();
1340 self.push_char(')');
1341 } else {
1342 self.write_expression(inner_expression);
1343 }
1344
1345 self.push_can_add_new_line(false);
1346 self.push_str("::");
1347 self.write_type(type_cast.get_type());
1348 self.pop_can_add_new_line();
1349 }
1350
1351 fn write_type_instantiation(
1352 &mut self,
1353 type_instantiation: &nodes::TypeInstantiationExpression,
1354 ) {
1355 self.write_prefix(type_instantiation.get_prefix());
1356 self.push_can_add_new_line(false);
1357
1358 self.push_str("<<");
1359
1360 let last_index = type_instantiation.types_len().saturating_sub(1);
1361 for (index, r#type) in type_instantiation.iter_types().enumerate() {
1362 self.write_type(r#type);
1363 if index != last_index {
1364 self.push_char(',');
1365 }
1366 }
1367
1368 self.push_str(">>");
1369
1370 self.pop_can_add_new_line();
1371 }
1372
1373 fn write_type_name(&mut self, type_name: &nodes::TypeName) {
1374 self.write_identifier(type_name.get_type_name());
1375 if let Some(parameters) = type_name.get_type_parameters() {
1376 self.push_char('<');
1377 self.push_can_add_new_line(false);
1378 let last_index = parameters.len().saturating_sub(1);
1379 for (index, parameter) in parameters.iter().enumerate() {
1380 self.write_type_parameter(parameter);
1381 if index != last_index {
1382 self.push_char(',');
1383 self.push_char(' ');
1384 }
1385 }
1386
1387 self.pop_can_add_new_line();
1388 self.push_char('>');
1389 }
1390 }
1391
1392 fn write_type_field(&mut self, type_field: &nodes::TypeField) {
1393 self.write_identifier(type_field.get_namespace());
1394 self.push_new_line_if_needed(1);
1395 self.raw_push_char('.');
1396 self.write_type_name(type_field.get_type_name());
1397 }
1398
1399 fn write_true_type(&mut self, _: &Option<nodes::Token>) {
1400 self.push_str("true");
1401 }
1402
1403 fn write_false_type(&mut self, _: &Option<nodes::Token>) {
1404 self.push_str("false");
1405 }
1406
1407 fn write_nil_type(&mut self, _: &Option<nodes::Token>) {
1408 self.push_str("nil");
1409 }
1410
1411 fn write_string_type(&mut self, string_type: &nodes::StringType) {
1412 let result = utils::write_string(string_type.get_value());
1413 if result.starts_with('[') {
1414 self.push_str_and_break_if(&result, utils::break_long_string);
1415 } else {
1416 self.push_str(&result);
1417 }
1418 }
1419
1420 fn write_array_type(&mut self, array: &nodes::ArrayType) {
1421 self.push_char('{');
1422 self.write_type(array.get_element_type());
1423 self.push_char('}');
1424 }
1425
1426 fn write_table_type(&mut self, table_type: &nodes::TableType) {
1427 self.push_char('{');
1428
1429 let last_index = table_type.len().saturating_sub(1);
1430 for (index, property) in table_type.iter_entries().enumerate() {
1431 if let Some(modifier) = property.get_modifier() {
1432 match modifier {
1433 nodes::TablePropertyModifier::Read => self.push_str("read"),
1434 nodes::TablePropertyModifier::Write => self.push_str("write"),
1435 }
1436 self.push_char(' ');
1437 }
1438
1439 match property {
1440 nodes::TableEntryType::Property(property) => {
1441 self.write_identifier(property.get_identifier());
1442 self.push_char(':');
1443 self.push_char(' ');
1444 self.write_type(property.get_type());
1445 }
1446 nodes::TableEntryType::Literal(property) => {
1447 self.push_char('[');
1448 self.write_string_type(property.get_string());
1449 self.push_char(']');
1450 self.push_char(':');
1451 self.push_char(' ');
1452 self.write_type(property.get_type());
1453 }
1454 nodes::TableEntryType::Indexer(indexer) => {
1455 self.push_char('[');
1456
1457 let key_type = indexer.get_key_type();
1458
1459 let need_parentheses = matches!(
1460 key_type,
1461 nodes::Type::Optional(_)
1462 | nodes::Type::Intersection(_)
1463 | nodes::Type::Union(_)
1464 );
1465
1466 if need_parentheses {
1467 self.push_char('(');
1468 self.write_type(key_type);
1469 self.push_char(')');
1470 } else {
1471 self.write_type(key_type);
1472 }
1473
1474 self.push_char(']');
1475 self.push_char(':');
1476 self.push_char(' ');
1477 self.write_type(indexer.get_value_type());
1478 }
1479 }
1480 if index != last_index {
1481 self.push_char(',');
1482 self.push_char(' ');
1483 }
1484 }
1485
1486 self.push_char('}');
1487 }
1488
1489 fn write_expression_type(&mut self, expression_type: &nodes::ExpressionType) {
1490 self.push_str("typeof(");
1491 self.write_expression(expression_type.get_expression());
1492 self.push_char(')');
1493 }
1494
1495 fn write_parenthese_type(&mut self, parenthese_type: &nodes::ParentheseType) {
1496 self.write_type_in_parentheses(parenthese_type.get_inner_type());
1497 }
1498
1499 fn write_function_type(&mut self, function_type: &nodes::FunctionType) {
1500 if let Some(generics) = function_type.get_generic_parameters() {
1501 self.write_function_generics(generics);
1502 }
1503
1504 self.push_char('(');
1505
1506 let last_index = function_type.argument_len().saturating_sub(1);
1507
1508 for (index, argument) in function_type.iter_arguments().enumerate() {
1509 if let Some(name) = argument.get_name() {
1510 self.write_identifier(name);
1511 self.push_char(':');
1512 }
1513 self.write_type(argument.get_type());
1514
1515 if index != last_index {
1516 self.push_char(',');
1517 self.push_space();
1518 }
1519 }
1520
1521 if let Some(variadic_argument_type) = function_type.get_variadic_argument_type() {
1522 if function_type.argument_len() > 0 {
1523 self.push_char(',');
1524 self.push_space();
1525 }
1526 self.write_variadic_argument_type(variadic_argument_type);
1527 }
1528
1529 self.push_str(") -> ");
1530 self.write_function_return_type(function_type.get_return_type());
1531 }
1532
1533 fn write_optional_type(&mut self, optional: &nodes::OptionalType) {
1534 let inner_type = optional.get_inner_type();
1535 if nodes::OptionalType::needs_parentheses(inner_type) {
1536 self.write_type_in_parentheses(inner_type);
1537 } else {
1538 self.write_type(inner_type);
1539 }
1540 self.push_char('?');
1541 }
1542
1543 fn write_intersection_type(&mut self, intersection: &nodes::IntersectionType) {
1544 if intersection.has_leading_token() {
1545 self.push_char('&');
1546 }
1547
1548 let length = intersection.len();
1549 let last_index = length.saturating_sub(1);
1550
1551 for (i, r#type) in intersection.iter_types().enumerate() {
1552 if i != 0 {
1553 self.push_char('&');
1554 }
1555
1556 let need_parentheses = if i == last_index {
1557 nodes::IntersectionType::last_needs_parentheses(r#type)
1558 } else {
1559 nodes::IntersectionType::intermediate_needs_parentheses(r#type)
1560 };
1561
1562 if need_parentheses {
1563 self.write_type_in_parentheses(r#type);
1564 } else {
1565 self.write_type(r#type);
1566 }
1567 }
1568 }
1569
1570 fn write_union_type(&mut self, union: &nodes::UnionType) {
1571 let length = union.len();
1572 let last_index = length.saturating_sub(1);
1573
1574 if union.has_leading_token() {
1575 self.push_char('|');
1576 self.push_space();
1577 }
1578
1579 for (i, r#type) in union.iter_types().enumerate() {
1580 if i != 0 {
1581 self.push_space();
1582 self.push_char('|');
1583 self.push_space();
1584 }
1585
1586 let need_parentheses = if i == last_index {
1587 nodes::UnionType::last_needs_parentheses(r#type)
1588 } else {
1589 nodes::UnionType::intermediate_needs_parentheses(r#type)
1590 };
1591
1592 if need_parentheses {
1593 self.write_type_in_parentheses(r#type);
1594 } else {
1595 self.write_type(r#type);
1596 }
1597 }
1598 }
1599
1600 fn write_type_pack(&mut self, type_pack: &nodes::TypePack) {
1601 self.push_char('(');
1602
1603 let last_index = type_pack.len().saturating_sub(1);
1604
1605 for (index, r#type) in type_pack.into_iter().enumerate() {
1606 self.write_type(r#type);
1607 if index != last_index {
1608 self.push_char(',');
1609 }
1610 }
1611
1612 if let Some(variadic_argument_type) = type_pack.get_variadic_type() {
1613 if !type_pack.is_empty() {
1614 self.push_char(',');
1615 }
1616 self.write_variadic_argument_type(variadic_argument_type);
1617 }
1618
1619 self.push_char(')');
1620 }
1621
1622 fn write_variadic_type_pack(&mut self, variadic_type_pack: &nodes::VariadicTypePack) {
1623 self.push_str("...");
1624 self.write_type(variadic_type_pack.get_type());
1625 }
1626
1627 fn write_generic_type_pack(&mut self, generic_type_pack: &nodes::GenericTypePack) {
1628 self.write_identifier(generic_type_pack.get_name());
1629 self.push_str("...");
1630 }
1631}