1use crate::generator::{utils, LuaGenerator};
2use crate::nodes;
3
4#[derive(Debug, Clone)]
7pub struct DenseLuaGenerator {
8 column_span: usize,
9 current_line_length: usize,
10 output: String,
11 last_push_length: usize,
12}
13
14impl DenseLuaGenerator {
15 pub fn new(column_span: usize) -> Self {
18 Self {
19 column_span,
20 current_line_length: 0,
21 output: String::new(),
22 last_push_length: 0,
23 }
24 }
25
26 fn push_str(&mut self, content: &str) {
29 if let Some(next_char) = content.chars().next() {
30 self.push_space_if_needed(next_char, content.len());
31 self.raw_push_str(content);
32 }
33 }
34
35 fn push_char(&mut self, character: char) {
37 self.push_space_if_needed(character, 1);
38
39 self.output.push(character);
40 self.current_line_length += 1;
41 self.last_push_length = 1;
42 }
43
44 fn merge_char(&mut self, character: char) {
47 if self.fits_on_current_line(1) {
48 self.raw_push_char(character);
49 } else {
50 let last_push_content = self.get_last_push_str().to_owned();
51 (0..self.last_push_length).for_each(|_| {
52 self.output.pop();
53 });
54
55 let mut last_char = self.output.pop();
56
57 while let Some(' ') = last_char {
58 last_char = self.output.pop();
59 }
60
61 if let Some(last_char) = last_char {
62 self.output.push(last_char);
63 }
64
65 self.output.push('\n');
66 self.output.push_str(&last_push_content);
67 self.output.push(character);
68 self.last_push_length += 1;
69 self.current_line_length = self.last_push_length;
70 }
71 }
72
73 fn push_new_line_if_needed(&mut self, pushed_length: usize) {
74 if self.current_line_length >= self.column_span {
75 self.push_new_line();
76 } else {
77 let total_length = self.current_line_length + pushed_length;
78
79 if total_length > self.column_span {
80 self.push_new_line();
81 }
82 }
83 }
84
85 fn push_space_if_needed(&mut self, next_character: char, pushed_length: usize) {
86 if self.current_line_length >= self.column_span {
87 self.push_new_line();
88 } else {
89 let total_length = self.current_line_length + pushed_length;
90
91 if self.needs_space(next_character) {
92 if total_length + 1 > self.column_span {
93 self.push_new_line();
94 } else {
95 self.output.push(' ');
96 self.current_line_length += 1;
97 }
98 } else if total_length > self.column_span {
99 self.push_new_line();
100 }
101 }
102 }
103
104 #[inline]
105 fn push_new_line(&mut self) {
106 self.output.push('\n');
107 self.current_line_length = 0;
108 }
109
110 #[inline]
111 fn push_space(&mut self) {
112 self.output.push(' ');
113 self.current_line_length += 1;
114 }
115
116 #[inline]
117 fn fits_on_current_line(&self, length: usize) -> bool {
118 self.current_line_length + length <= self.column_span
119 }
120
121 #[inline]
122 fn needs_space(&self, next_character: char) -> bool {
123 if let Some(previous) = self.output.chars().last() {
124 utils::should_break_with_space(previous, next_character)
125 } else {
126 false
127 }
128 }
129
130 pub fn into_string(self) -> String {
132 self.output
133 }
134
135 #[inline]
136 fn raw_push_str(&mut self, content: &str) {
137 self.output.push_str(content);
138 self.last_push_length = content.len();
139 self.current_line_length += self.last_push_length;
140 }
141
142 #[inline]
143 fn raw_push_char(&mut self, character: char) {
144 self.output.push(character);
145 self.last_push_length = 1;
146 self.current_line_length += 1;
147 }
148
149 fn push_str_and_break_if<F>(&mut self, content: &str, predicate: F)
152 where
153 F: Fn(&str) -> bool,
154 {
155 if predicate(self.get_last_push_str()) {
156 if self.fits_on_current_line(1 + content.len()) {
157 self.push_space();
158 } else {
159 self.push_new_line();
160 }
161 } else if !self.fits_on_current_line(content.len()) {
162 self.push_new_line();
163 }
164 self.raw_push_str(content);
165 }
166
167 fn push_char_and_break_if<F>(&mut self, content: char, predicate: F)
169 where
170 F: Fn(&str) -> bool,
171 {
172 if predicate(self.get_last_push_str()) {
173 if self.fits_on_current_line(2) {
174 self.push_space();
175 } else {
176 self.push_new_line();
177 }
178 } else if !self.fits_on_current_line(1) {
179 self.push_new_line();
180 }
181 self.raw_push_char(content);
182 }
183
184 fn get_last_push_str(&self) -> &str {
185 self.output
186 .get((self.output.len() - self.last_push_length)..)
187 .unwrap_or("")
188 }
189
190 fn write_function_parameters(
191 &mut self,
192 parameters: &[nodes::TypedIdentifier],
193 is_variadic: bool,
194 variadic_type: Option<&nodes::FunctionVariadicType>,
195 ) {
196 let last_index = parameters.len().saturating_sub(1);
197
198 parameters.iter().enumerate().for_each(|(index, variable)| {
199 self.write_typed_identifier(variable);
200
201 if index != last_index {
202 self.push_char(',');
203 }
204 });
205
206 if is_variadic {
207 if !parameters.is_empty() {
208 self.push_char(',');
209 };
210 self.push_str("...");
211
212 if let Some(variadic_type) = variadic_type {
213 self.push_char(':');
214 self.write_function_variadic_type(variadic_type);
215 }
216 };
217 }
218
219 fn write_typed_identifier(&mut self, typed_identifier: &nodes::TypedIdentifier) {
220 self.push_str(typed_identifier.get_name());
221
222 if let Some(r#type) = typed_identifier.get_type() {
223 self.push_char(':');
224 self.write_type(r#type);
225 }
226 }
227
228 fn write_function_return_type(&mut self, return_type: &nodes::FunctionReturnType) {
229 match return_type {
230 nodes::FunctionReturnType::Type(r#type) => self.write_type(r#type),
231 nodes::FunctionReturnType::TypePack(type_pack) => self.write_type_pack(type_pack),
232 nodes::FunctionReturnType::VariadicTypePack(variadic_type_pack) => {
233 self.write_variadic_type_pack(variadic_type_pack);
234 }
235 nodes::FunctionReturnType::GenericTypePack(generic_type_pack) => {
236 self.write_generic_type_pack(generic_type_pack);
237 }
238 }
239 }
240
241 fn write_expression_in_parentheses(&mut self, expression: &nodes::Expression) {
242 self.push_char('(');
243 self.write_expression(expression);
244 self.push_char(')');
245 }
246
247 fn write_type_in_parentheses(&mut self, r#type: &nodes::Type) {
248 self.push_char('(');
249 self.write_type(r#type);
250 self.push_char(')');
251 }
252
253 fn write_function_generics(&mut self, generics: &nodes::GenericParameters) {
254 if generics.is_empty() {
255 return;
256 }
257 self.push_char('<');
258 let mut write_comma = false;
259 for type_variable in generics.iter_type_variable() {
260 if write_comma {
261 self.push_char(',');
262 } else {
263 write_comma = true;
264 }
265 self.write_identifier(type_variable);
266 }
267 for generic_pack in generics.iter_generic_type_pack() {
268 if write_comma {
269 self.push_char(',');
270 } else {
271 write_comma = true;
272 }
273 self.write_generic_type_pack(generic_pack);
274 }
275 self.push_char('>');
276 }
277}
278
279impl Default for DenseLuaGenerator {
280 fn default() -> Self {
281 Self::new(80)
282 }
283}
284
285impl LuaGenerator for DenseLuaGenerator {
286 fn into_string(self) -> String {
288 self.output
289 }
290
291 fn write_block(&mut self, block: &nodes::Block) {
292 let mut statements = block.iter_statements().peekable();
293
294 while let Some(statement) = statements.next() {
295 self.write_statement(statement);
296
297 if let Some(next_statement) = statements.peek() {
298 if utils::starts_with_parenthese(next_statement)
299 && utils::ends_with_prefix(statement)
300 {
301 self.push_char(';');
302 }
303 }
304 }
305
306 if let Some(last_statement) = block.get_last_statement() {
307 self.write_last_statement(last_statement);
308 }
309 }
310
311 fn write_assign_statement(&mut self, assign: &nodes::AssignStatement) {
312 let variables = assign.get_variables();
313 let last_variable_index = variables.len().saturating_sub(1);
314
315 variables.iter().enumerate().for_each(|(index, variable)| {
316 self.write_variable(variable);
317
318 if index != last_variable_index {
319 self.push_char(',');
320 }
321 });
322
323 self.push_char_and_break_if('=', utils::break_equal);
324
325 let last_value_index = assign.values_len().saturating_sub(1);
326
327 assign.iter_values().enumerate().for_each(|(index, value)| {
328 self.write_expression(value);
329
330 if index != last_value_index {
331 self.push_char(',');
332 }
333 });
334 }
335
336 fn write_do_statement(&mut self, do_statement: &nodes::DoStatement) {
337 self.push_str("do");
338 self.write_block(do_statement.get_block());
339 self.push_str("end");
340 }
341
342 fn write_generic_for(&mut self, generic_for: &nodes::GenericForStatement) {
343 self.push_str("for");
344
345 let identifiers = generic_for.get_identifiers();
346 let last_identifier_index = identifiers.len().saturating_sub(1);
347 identifiers
348 .iter()
349 .enumerate()
350 .for_each(|(index, identifier)| {
351 self.write_typed_identifier(identifier);
352
353 if index != last_identifier_index {
354 self.push_char(',');
355 }
356 });
357 self.push_str("in");
358
359 let expressions = generic_for.get_expressions();
360 let last_expression_index = expressions.len().saturating_sub(1);
361 expressions
362 .iter()
363 .enumerate()
364 .for_each(|(index, expression)| {
365 self.write_expression(expression);
366
367 if index != last_expression_index {
368 self.push_char(',');
369 }
370 });
371
372 self.push_str("do");
373 self.write_block(generic_for.get_block());
374 self.push_str("end");
375 }
376
377 fn write_if_statement(&mut self, if_statement: &nodes::IfStatement) {
378 let branches = if_statement.get_branches();
379
380 branches.iter().enumerate().for_each(|(index, branch)| {
381 if index == 0 {
382 self.push_str("if");
383 } else {
384 self.push_str("elseif");
385 }
386
387 self.write_expression(branch.get_condition());
388 self.push_str("then");
389 self.write_block(branch.get_block());
390 });
391
392 if let Some(else_block) = if_statement.get_else_block() {
393 self.push_str("else");
394 self.write_block(else_block)
395 }
396
397 self.push_str("end");
398 }
399
400 fn write_function_statement(&mut self, function: &nodes::FunctionStatement) {
401 self.push_str("function");
402 let name = function.get_name();
403
404 self.push_str(name.get_name().get_name());
405 name.get_field_names().iter().for_each(|field| {
406 self.push_new_line_if_needed(1);
407 self.raw_push_char('.');
408 self.push_str(field.get_name());
409 });
410
411 if let Some(method) = name.get_method() {
412 self.push_char(':');
413 self.push_str(method.get_name());
414 }
415
416 if let Some(generics) = function.get_generic_parameters() {
417 self.write_function_generics(generics);
418 }
419
420 self.push_char('(');
421 self.write_function_parameters(
422 function.get_parameters(),
423 function.is_variadic(),
424 function.get_variadic_type(),
425 );
426 self.push_char(')');
427
428 if let Some(return_type) = function.get_return_type() {
429 self.push_char(':');
430 self.write_function_return_type(return_type);
431 }
432
433 let block = function.get_block();
434
435 if !block.is_empty() {
436 self.write_block(block);
437 }
438 self.push_str("end");
439 }
440
441 fn write_last_statement(&mut self, statement: &nodes::LastStatement) {
442 use nodes::LastStatement::*;
443
444 match statement {
445 Break(_) => self.push_str("break"),
446 Continue(_) => self.push_str("continue"),
447 Return(expressions) => {
448 self.push_str("return");
449 let last_index = expressions.len().saturating_sub(1);
450
451 expressions
452 .iter_expressions()
453 .enumerate()
454 .for_each(|(index, expression)| {
455 self.write_expression(expression);
456
457 if index != last_index {
458 self.push_char(',');
459 }
460 });
461 }
462 }
463 }
464
465 fn write_local_assign(&mut self, assign: &nodes::LocalAssignStatement) {
466 self.push_str("local");
467
468 let variables = assign.get_variables();
469 let last_variable_index = variables.len().saturating_sub(1);
470
471 variables.iter().enumerate().for_each(|(index, variable)| {
472 self.write_typed_identifier(variable);
473
474 if index != last_variable_index {
475 self.push_char(',');
476 }
477 });
478
479 if assign.has_values() {
480 self.push_char_and_break_if('=', utils::break_equal);
481
482 let last_value_index = assign.values_len() - 1;
483
484 assign.iter_values().enumerate().for_each(|(index, value)| {
485 self.write_expression(value);
486
487 if index != last_value_index {
488 self.push_char(',');
489 }
490 });
491 };
492 }
493
494 fn write_compound_assign(&mut self, assign: &nodes::CompoundAssignStatement) {
495 self.write_variable(assign.get_variable());
496
497 self.push_str(assign.get_operator().to_str());
498
499 self.write_expression(assign.get_value());
500 }
501
502 fn write_local_function(&mut self, function: &nodes::LocalFunctionStatement) {
503 self.push_str("local function");
504 self.push_str(function.get_name());
505
506 if let Some(generics) = function.get_generic_parameters() {
507 self.write_function_generics(generics);
508 }
509
510 self.push_char('(');
511
512 let parameters = function.get_parameters();
513 self.write_function_parameters(
514 parameters,
515 function.is_variadic(),
516 function.get_variadic_type(),
517 );
518 self.push_char(')');
519
520 if let Some(return_type) = function.get_return_type() {
521 self.push_char(':');
522 self.write_function_return_type(return_type);
523 }
524
525 let block = function.get_block();
526
527 if !block.is_empty() {
528 self.write_block(block);
529 }
530 self.push_str("end");
531 }
532
533 fn write_numeric_for(&mut self, numeric_for: &nodes::NumericForStatement) {
534 self.push_str("for");
535
536 self.write_typed_identifier(numeric_for.get_identifier());
537
538 self.push_char_and_break_if('=', utils::break_equal);
539
540 self.write_expression(numeric_for.get_start());
541 self.push_char(',');
542 self.write_expression(numeric_for.get_end());
543
544 if let Some(step) = numeric_for.get_step() {
545 self.push_char(',');
546 self.write_expression(step);
547 }
548
549 let block = numeric_for.get_block();
550
551 if block.is_empty() {
552 self.push_str("do end");
553 } else {
554 self.push_str("do");
555 self.write_block(block);
556 self.push_str("end");
557 }
558 }
559
560 fn write_repeat_statement(&mut self, repeat: &nodes::RepeatStatement) {
561 self.push_str("repeat");
562
563 let block = repeat.get_block();
564
565 if !block.is_empty() {
566 self.write_block(block);
567 }
568
569 self.push_str("until");
570 self.write_expression(repeat.get_condition());
571 }
572
573 fn write_while_statement(&mut self, while_statement: &nodes::WhileStatement) {
574 self.push_str("while");
575 self.write_expression(while_statement.get_condition());
576
577 let block = while_statement.get_block();
578
579 if block.is_empty() {
580 self.push_str("do end");
581 } else {
582 self.push_str("do");
583 self.write_block(block);
584 self.push_str("end");
585 }
586 }
587
588 fn write_type_declaration_statement(&mut self, statement: &nodes::TypeDeclarationStatement) {
589 if statement.is_exported() {
590 self.push_str("export");
591 }
592 self.push_str("type");
593
594 self.write_identifier(statement.get_name());
595
596 if let Some(generic_parameters) = statement
597 .get_generic_parameters()
598 .filter(|generic_parameters| !generic_parameters.is_empty())
599 {
600 self.push_char('<');
601 let last_index = generic_parameters.len().saturating_sub(1);
602 for (i, parameter) in generic_parameters.iter().enumerate() {
603 use nodes::GenericParameterRef;
604
605 match parameter {
606 GenericParameterRef::TypeVariable(identifier) => {
607 self.write_identifier(identifier);
608 }
609 GenericParameterRef::TypeVariableWithDefault(identifier_with_default) => {
610 self.write_identifier(identifier_with_default.get_type_variable());
611 self.push_char('=');
612 self.write_type(identifier_with_default.get_default_type());
613 }
614 GenericParameterRef::GenericTypePack(generic_type_pack) => {
615 self.write_generic_type_pack(generic_type_pack);
616 }
617 GenericParameterRef::GenericTypePackWithDefault(generic_pack_with_default) => {
618 self.write_generic_type_pack(
619 generic_pack_with_default.get_generic_type_pack(),
620 );
621 self.push_char('=');
622 self.write_generic_type_pack_default(
623 generic_pack_with_default.get_default_type(),
624 );
625 }
626 }
627
628 if i != last_index {
629 self.push_char(',');
630 }
631 }
632
633 self.push_char('>');
634 }
635
636 self.push_char_and_break_if('=', utils::break_equal);
637 self.write_type(statement.get_type());
638 }
639
640 fn write_false_expression(&mut self, _token: &Option<nodes::Token>) {
641 self.push_str("false");
642 }
643
644 fn write_true_expression(&mut self, _token: &Option<nodes::Token>) {
645 self.push_str("true");
646 }
647
648 fn write_nil_expression(&mut self, _token: &Option<nodes::Token>) {
649 self.push_str("nil");
650 }
651
652 fn write_variable_arguments_expression(&mut self, _token: &Option<nodes::Token>) {
653 self.push_str_and_break_if("...", utils::break_variable_arguments);
654 }
655
656 fn write_binary_expression(&mut self, binary: &nodes::BinaryExpression) {
657 use nodes::BinaryOperator;
658
659 let operator = binary.operator();
660 let left = binary.left();
661 let right = binary.right();
662
663 if operator.left_needs_parentheses(left) {
664 self.write_expression_in_parentheses(left);
665 } else {
666 self.write_expression(left);
667 }
668
669 match operator {
670 BinaryOperator::Concat => self.push_str_and_break_if("..", utils::break_concat),
671 _ => self.push_str(operator.to_str()),
672 }
673
674 if operator.right_needs_parentheses(right) {
675 self.write_expression_in_parentheses(right);
676 } else {
677 self.write_expression(right);
678 }
679 }
680
681 fn write_unary_expression(&mut self, unary: &nodes::UnaryExpression) {
682 use nodes::{Expression, UnaryOperator::*};
683
684 match unary.operator() {
685 Length => self.push_char('#'),
686 Minus => self.push_char_and_break_if('-', utils::break_minus),
687 Not => self.push_str("not"),
688 }
689
690 let expression = unary.get_expression();
691
692 match expression {
693 Expression::Binary(binary) if !binary.operator().precedes_unary_expression() => {
694 self.write_expression_in_parentheses(expression);
695 }
696 _ => self.write_expression(expression),
697 }
698 }
699
700 fn write_function(&mut self, function: &nodes::FunctionExpression) {
701 self.push_str("function");
702
703 if let Some(generics) = function.get_generic_parameters() {
704 self.write_function_generics(generics);
705 }
706
707 self.push_char('(');
708
709 let parameters = function.get_parameters();
710 self.write_function_parameters(
711 parameters,
712 function.is_variadic(),
713 function.get_variadic_type(),
714 );
715 self.push_char(')');
716
717 if let Some(return_type) = function.get_return_type() {
718 self.push_char(':');
719 self.write_function_return_type(return_type);
720 }
721
722 let block = function.get_block();
723
724 if !block.is_empty() {
725 self.write_block(block);
726 }
727 self.push_str("end");
728 }
729
730 fn write_function_call(&mut self, call: &nodes::FunctionCall) {
731 self.write_prefix(call.get_prefix());
732
733 if let Some(method) = &call.get_method() {
734 self.push_char(':');
735 self.push_str(method.get_name());
736 }
737
738 self.write_arguments(call.get_arguments());
739 }
740
741 fn write_field(&mut self, field: &nodes::FieldExpression) {
742 self.write_prefix(field.get_prefix());
743
744 self.push_new_line_if_needed(1);
745 self.raw_push_char('.');
746
747 self.push_str(field.get_field().get_name());
748 }
749
750 fn write_index(&mut self, index: &nodes::IndexExpression) {
751 self.write_prefix(index.get_prefix());
752
753 self.push_char('[');
754 self.write_expression(index.get_index());
755 self.push_char(']');
756 }
757
758 fn write_if_expression(&mut self, if_expression: &nodes::IfExpression) {
759 self.push_str("if");
760 self.write_expression(if_expression.get_condition());
761 self.push_str("then");
762 self.write_expression(if_expression.get_result());
763
764 for branch in if_expression.iter_branches() {
765 self.push_str("elseif");
766 self.write_expression(branch.get_condition());
767 self.push_str("then");
768 self.write_expression(branch.get_result());
769 }
770
771 self.push_str("else");
772 self.write_expression(if_expression.get_else_result());
773 }
774
775 fn write_table(&mut self, table: &nodes::TableExpression) {
776 self.push_char('{');
777
778 let entries = table.get_entries();
779 let last_index = entries.len().saturating_sub(1);
780
781 entries.iter().enumerate().for_each(|(index, entry)| {
782 self.write_table_entry(entry);
783
784 if index != last_index {
785 self.push_char(',');
786 }
787 });
788
789 self.push_char('}');
790 }
791
792 fn write_table_entry(&mut self, entry: &nodes::TableEntry) {
793 match entry {
794 nodes::TableEntry::Field(entry) => {
795 self.push_str(entry.get_field().get_name());
796 self.push_char('=');
797 self.write_expression(entry.get_value());
798 }
799 nodes::TableEntry::Index(entry) => {
800 self.push_char('[');
801 self.write_expression(entry.get_key());
802 self.push_char(']');
803 self.push_char('=');
804 self.write_expression(entry.get_value());
805 }
806 nodes::TableEntry::Value(expression) => self.write_expression(expression),
807 }
808 }
809
810 fn write_number(&mut self, number: &nodes::NumberExpression) {
811 use nodes::NumberExpression::*;
812
813 match number {
814 Decimal(number) => {
815 let float = number.get_raw_float();
816 if float.is_nan() {
817 self.push_char('(');
818 self.push_char('0');
819 self.push_char('/');
820 self.push_char('0');
821 self.push_char(')');
822 } else if float.is_infinite() {
823 self.push_char('(');
824 if float.is_sign_negative() {
825 self.push_char('-');
826 }
827 self.push_char('1');
828 self.push_char('/');
829 self.push_char('0');
830 self.push_char(')');
831 } else {
832 let mut result = format!("{}", float);
833
834 if let Some(exponent) = number.get_exponent() {
835 let exponent_char = number
836 .is_uppercase()
837 .map(|is_uppercase| if is_uppercase { 'E' } else { 'e' })
838 .unwrap_or('e');
839
840 result.push(exponent_char);
841 result.push_str(&format!("{}", exponent));
842 };
843
844 self.push_str(&result);
845 }
846 }
847 Hex(number) => {
848 let mut result = format!(
849 "0{}{:x}",
850 if number.is_x_uppercase() { 'X' } else { 'x' },
851 number.get_raw_integer()
852 );
853
854 if let Some(exponent) = number.get_exponent() {
855 let exponent_char = number
856 .is_exponent_uppercase()
857 .map(|is_uppercase| if is_uppercase { 'P' } else { 'p' })
858 .unwrap_or('p');
859
860 result.push(exponent_char);
861 result.push_str(&format!("{}", exponent));
862 };
863
864 self.push_str(&result);
865 }
866 Binary(number) => {
867 self.push_str(&format!(
868 "0{}{:b}",
869 if number.is_b_uppercase() { 'B' } else { 'b' },
870 number.get_raw_value()
871 ));
872 }
873 }
874 }
875
876 fn write_tuple_arguments(&mut self, arguments: &nodes::TupleArguments) {
877 self.merge_char('(');
878
879 let last_index = arguments.len().saturating_sub(1);
880 arguments
881 .iter_values()
882 .enumerate()
883 .for_each(|(index, expression)| {
884 self.write_expression(expression);
885
886 if index != last_index {
887 self.push_char(',');
888 }
889 });
890
891 self.push_char(')');
892 }
893
894 fn write_string(&mut self, string: &nodes::StringExpression) {
895 let result = utils::write_string(string.get_value());
896 if result.starts_with('[') {
897 self.push_str_and_break_if(&result, utils::break_long_string);
898 } else {
899 self.push_str(&result);
900 }
901 }
902
903 fn write_interpolated_string(
904 &mut self,
905 interpolated_string: &nodes::InterpolatedStringExpression,
906 ) {
907 self.push_char('`');
908
909 for segment in interpolated_string.iter_segments() {
910 match segment {
911 nodes::InterpolationSegment::String(string_segment) => {
912 self.raw_push_str(&utils::write_interpolated_string_segment(string_segment));
913 }
914 nodes::InterpolationSegment::Value(value) => {
915 self.raw_push_char('{');
916 let expression = value.get_expression();
918 if utils::starts_with_table(expression).is_some() {
919 self.raw_push_char(' ');
920 }
921 self.write_expression(expression);
922 self.push_char('}');
923 }
924 }
925 }
926
927 self.raw_push_char('`');
928 }
929
930 fn write_identifier(&mut self, identifier: &nodes::Identifier) {
931 self.push_str(identifier.get_name());
932 }
933
934 fn write_parenthese(&mut self, parenthese: &nodes::ParentheseExpression) {
935 self.write_expression_in_parentheses(parenthese.inner_expression());
936 }
937
938 fn write_type_cast(&mut self, type_cast: &nodes::TypeCastExpression) {
939 let inner_expression = type_cast.get_expression();
940
941 if nodes::TypeCastExpression::needs_parentheses(inner_expression) {
942 self.write_expression_in_parentheses(inner_expression);
943 } else {
944 self.write_expression(inner_expression);
945 }
946
947 self.push_str("::");
948 self.write_type(type_cast.get_type());
949 }
950
951 fn write_type_name(&mut self, type_name: &nodes::TypeName) {
952 self.write_identifier(type_name.get_type_name());
953 if let Some(parameters) = type_name.get_type_parameters() {
954 self.push_char('<');
955 let last_index = parameters.len().saturating_sub(1);
956 for (index, parameter) in parameters.iter().enumerate() {
957 self.write_type_parameter(parameter);
958 if index != last_index {
959 self.push_char(',');
960 }
961 }
962
963 self.push_char('>');
964 }
965 }
966
967 fn write_type_field(&mut self, type_field: &nodes::TypeField) {
968 self.write_identifier(type_field.get_namespace());
969 self.push_new_line_if_needed(1);
970 self.raw_push_char('.');
971 self.write_type_name(type_field.get_type_name());
972 }
973
974 fn write_true_type(&mut self, _: &Option<nodes::Token>) {
975 self.push_str("true");
976 }
977
978 fn write_false_type(&mut self, _: &Option<nodes::Token>) {
979 self.push_str("false");
980 }
981
982 fn write_nil_type(&mut self, _: &Option<nodes::Token>) {
983 self.push_str("nil");
984 }
985
986 fn write_string_type(&mut self, string_type: &nodes::StringType) {
987 let result = utils::write_string(string_type.get_value());
988 if result.starts_with('[') {
989 self.push_str_and_break_if(&result, utils::break_long_string);
990 } else {
991 self.push_str(&result);
992 }
993 }
994
995 fn write_array_type(&mut self, array: &nodes::ArrayType) {
996 self.push_char('{');
997 self.write_type(array.get_element_type());
998 self.push_char('}');
999 }
1000
1001 fn write_table_type(&mut self, table_type: &nodes::TableType) {
1002 self.push_char('{');
1003
1004 let last_index = table_type.len().saturating_sub(1);
1005 for (index, property) in table_type.iter_entries().enumerate() {
1006 match property {
1007 nodes::TableEntryType::Property(property) => {
1008 self.write_identifier(property.get_identifier());
1009 self.push_char(':');
1010 self.write_type(property.get_type());
1011 }
1012 nodes::TableEntryType::Literal(property) => {
1013 self.push_char('[');
1014 self.write_string_type(property.get_string());
1015 self.push_char(']');
1016 self.push_char(':');
1017 self.write_type(property.get_type());
1018 }
1019 nodes::TableEntryType::Indexer(indexer) => {
1020 self.push_char('[');
1021
1022 let key_type = indexer.get_key_type();
1023
1024 let need_parentheses = matches!(
1025 key_type,
1026 nodes::Type::Optional(_)
1027 | nodes::Type::Intersection(_)
1028 | nodes::Type::Union(_)
1029 );
1030
1031 if need_parentheses {
1032 self.push_char('(');
1033 self.write_type(key_type);
1034 self.push_char(')');
1035 } else {
1036 self.write_type(key_type);
1037 }
1038
1039 self.push_char(']');
1040 self.push_char(':');
1041 self.write_type(indexer.get_value_type());
1042 }
1043 }
1044 if index != last_index {
1045 self.push_char(',');
1046 }
1047 }
1048
1049 self.push_char('}');
1050 }
1051
1052 fn write_expression_type(&mut self, expression_type: &nodes::ExpressionType) {
1053 self.push_str("typeof(");
1054 self.write_expression(expression_type.get_expression());
1055 self.push_char(')');
1056 }
1057
1058 fn write_parenthese_type(&mut self, parenthese_type: &nodes::ParentheseType) {
1059 self.write_type_in_parentheses(parenthese_type.get_inner_type());
1060 }
1061
1062 fn write_function_type(&mut self, function_type: &nodes::FunctionType) {
1063 if let Some(generics) = function_type.get_generic_parameters() {
1064 self.write_function_generics(generics);
1065 }
1066
1067 self.push_char('(');
1068
1069 let last_index = function_type.argument_len().saturating_sub(1);
1070
1071 for (index, argument) in function_type.iter_arguments().enumerate() {
1072 if let Some(name) = argument.get_name() {
1073 self.write_identifier(name);
1074 self.push_char(':');
1075 }
1076 self.write_type(argument.get_type());
1077
1078 if index != last_index {
1079 self.push_char(',');
1080 }
1081 }
1082
1083 if let Some(variadic_argument_type) = function_type.get_variadic_argument_type() {
1084 if function_type.argument_len() > 0 {
1085 self.push_char(',');
1086 }
1087 self.write_variadic_argument_type(variadic_argument_type);
1088 }
1089
1090 self.push_str(")->");
1091 self.write_function_return_type(function_type.get_return_type());
1092 }
1093
1094 fn write_optional_type(&mut self, optional: &nodes::OptionalType) {
1095 let inner_type = optional.get_inner_type();
1096 if nodes::OptionalType::needs_parentheses(inner_type) {
1097 self.write_type_in_parentheses(inner_type);
1098 } else {
1099 self.write_type(inner_type);
1100 }
1101 self.push_char('?');
1102 }
1103
1104 fn write_intersection_type(&mut self, intersection: &nodes::IntersectionType) {
1105 let length = intersection.len();
1106 let last_index = length.saturating_sub(1);
1107 for (i, r#type) in intersection.iter_types().enumerate() {
1108 if i != 0 || intersection.has_leading_token() {
1109 self.push_char('&');
1110 }
1111
1112 let need_parentheses = if i == last_index {
1113 nodes::IntersectionType::last_needs_parentheses(r#type)
1114 } else {
1115 nodes::IntersectionType::intermediate_needs_parentheses(r#type)
1116 };
1117
1118 if need_parentheses {
1119 self.write_type_in_parentheses(r#type);
1120 } else {
1121 self.write_type(r#type);
1122 }
1123 }
1124 }
1125
1126 fn write_union_type(&mut self, union: &nodes::UnionType) {
1127 let length = union.len();
1128 let last_index = length.saturating_sub(1);
1129 for (i, r#type) in union.iter_types().enumerate() {
1130 if i != 0 || union.has_leading_token() {
1131 self.push_char('|');
1132 }
1133
1134 let need_parentheses = if i == last_index {
1135 nodes::UnionType::last_needs_parentheses(r#type)
1136 } else {
1137 nodes::UnionType::intermediate_needs_parentheses(r#type)
1138 };
1139
1140 if need_parentheses {
1141 self.write_type_in_parentheses(r#type);
1142 } else {
1143 self.write_type(r#type);
1144 }
1145 }
1146 }
1147
1148 fn write_type_pack(&mut self, type_pack: &nodes::TypePack) {
1149 self.push_char('(');
1150
1151 let last_index = type_pack.len().saturating_sub(1);
1152
1153 for (index, r#type) in type_pack.into_iter().enumerate() {
1154 self.write_type(r#type);
1155 if index != last_index {
1156 self.push_char(',');
1157 }
1158 }
1159
1160 if let Some(variadic_argument_type) = type_pack.get_variadic_type() {
1161 if !type_pack.is_empty() {
1162 self.push_char(',');
1163 }
1164 self.write_variadic_argument_type(variadic_argument_type);
1165 }
1166
1167 self.push_char(')');
1168 }
1169
1170 fn write_variadic_type_pack(&mut self, variadic_type_pack: &nodes::VariadicTypePack) {
1171 self.push_str("...");
1172 self.write_type(variadic_type_pack.get_type());
1173 }
1174
1175 fn write_generic_type_pack(&mut self, generic_type_pack: &nodes::GenericTypePack) {
1176 self.write_identifier(generic_type_pack.get_name());
1177 self.push_str("...");
1178 }
1179}