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_attributes(&mut self, attributes: &nodes::Attributes) {
220 use nodes::Attribute;
221
222 for attribute in attributes.iter_attributes() {
223 match attribute {
224 Attribute::Name(named) => {
225 let name = named.get_identifier().get_name();
226
227 self.push_space_if_needed('@', 1 + name.len());
228 self.raw_push_char('@');
229 self.raw_push_str(name);
230 }
231 Attribute::Group(group) => {
232 if !group.is_empty() {
233 self.push_str("@[");
234
235 let last_index = group.len().saturating_sub(1);
236
237 for (index, attribute) in group.iter_attributes().enumerate() {
238 self.push_str(attribute.name().get_name());
239
240 if let Some(arguments) = attribute.get_arguments() {
241 self.write_attribute_arguments(arguments);
242 }
243
244 if index != last_index {
245 self.push_char(',');
246 }
247 }
248
249 self.push_char(']');
250 }
251 }
252 }
253 }
254 }
255
256 fn write_typed_identifier(&mut self, typed_identifier: &nodes::TypedIdentifier) {
257 self.push_str(typed_identifier.get_name());
258
259 if let Some(r#type) = typed_identifier.get_type() {
260 self.push_char(':');
261 self.write_type(r#type);
262 }
263 }
264
265 fn write_function_return_type(&mut self, return_type: &nodes::FunctionReturnType) {
266 match return_type {
267 nodes::FunctionReturnType::Type(r#type) => self.write_type(r#type),
268 nodes::FunctionReturnType::TypePack(type_pack) => self.write_type_pack(type_pack),
269 nodes::FunctionReturnType::VariadicTypePack(variadic_type_pack) => {
270 self.write_variadic_type_pack(variadic_type_pack);
271 }
272 nodes::FunctionReturnType::GenericTypePack(generic_type_pack) => {
273 self.write_generic_type_pack(generic_type_pack);
274 }
275 }
276 }
277
278 fn write_expression_in_parentheses(&mut self, expression: &nodes::Expression) {
279 self.push_char('(');
280 self.write_expression(expression);
281 self.push_char(')');
282 }
283
284 fn write_type_in_parentheses(&mut self, r#type: &nodes::Type) {
285 self.push_char('(');
286 self.write_type(r#type);
287 self.push_char(')');
288 }
289
290 fn write_function_generics(&mut self, generics: &nodes::GenericParameters) {
291 if generics.is_empty() {
292 return;
293 }
294 self.push_char('<');
295 let mut write_comma = false;
296 for type_variable in generics.iter_type_variable() {
297 if write_comma {
298 self.push_char(',');
299 } else {
300 write_comma = true;
301 }
302 self.write_identifier(type_variable);
303 }
304 for generic_pack in generics.iter_generic_type_pack() {
305 if write_comma {
306 self.push_char(',');
307 } else {
308 write_comma = true;
309 }
310 self.write_generic_type_pack(generic_pack);
311 }
312 self.push_char('>');
313 }
314}
315
316impl Default for DenseLuaGenerator {
317 fn default() -> Self {
318 Self::new(80)
319 }
320}
321
322impl LuaGenerator for DenseLuaGenerator {
323 fn into_string(self) -> String {
325 self.output
326 }
327
328 fn write_block(&mut self, block: &nodes::Block) {
329 let mut statements = block.iter_statements().peekable();
330
331 while let Some(statement) = statements.next() {
332 self.write_statement(statement);
333
334 if let Some(next_statement) = statements.peek() {
335 if utils::starts_with_parenthese(next_statement)
336 && utils::ends_with_prefix(statement)
337 {
338 self.push_char(';');
339 }
340 }
341 }
342
343 if let Some(last_statement) = block.get_last_statement() {
344 self.write_last_statement(last_statement);
345 }
346 }
347
348 fn write_assign_statement(&mut self, assign: &nodes::AssignStatement) {
349 let variables = assign.get_variables();
350 let last_variable_index = variables.len().saturating_sub(1);
351
352 variables.iter().enumerate().for_each(|(index, variable)| {
353 self.write_variable(variable);
354
355 if index != last_variable_index {
356 self.push_char(',');
357 }
358 });
359
360 self.push_char_and_break_if('=', utils::break_equal);
361
362 let last_value_index = assign.values_len().saturating_sub(1);
363
364 assign.iter_values().enumerate().for_each(|(index, value)| {
365 self.write_expression(value);
366
367 if index != last_value_index {
368 self.push_char(',');
369 }
370 });
371 }
372
373 fn write_do_statement(&mut self, do_statement: &nodes::DoStatement) {
374 self.push_str("do");
375 self.write_block(do_statement.get_block());
376 self.push_str("end");
377 }
378
379 fn write_generic_for(&mut self, generic_for: &nodes::GenericForStatement) {
380 self.push_str("for");
381
382 let identifiers = generic_for.get_identifiers();
383 let last_identifier_index = identifiers.len().saturating_sub(1);
384 identifiers
385 .iter()
386 .enumerate()
387 .for_each(|(index, identifier)| {
388 self.write_typed_identifier(identifier);
389
390 if index != last_identifier_index {
391 self.push_char(',');
392 }
393 });
394 self.push_str("in");
395
396 let expressions = generic_for.get_expressions();
397 let last_expression_index = expressions.len().saturating_sub(1);
398 expressions
399 .iter()
400 .enumerate()
401 .for_each(|(index, expression)| {
402 self.write_expression(expression);
403
404 if index != last_expression_index {
405 self.push_char(',');
406 }
407 });
408
409 self.push_str("do");
410 self.write_block(generic_for.get_block());
411 self.push_str("end");
412 }
413
414 fn write_if_statement(&mut self, if_statement: &nodes::IfStatement) {
415 let branches = if_statement.get_branches();
416
417 branches.iter().enumerate().for_each(|(index, branch)| {
418 if index == 0 {
419 self.push_str("if");
420 } else {
421 self.push_str("elseif");
422 }
423
424 self.write_expression(branch.get_condition());
425 self.push_str("then");
426 self.write_block(branch.get_block());
427 });
428
429 if let Some(else_block) = if_statement.get_else_block() {
430 self.push_str("else");
431 self.write_block(else_block)
432 }
433
434 self.push_str("end");
435 }
436
437 fn write_function_statement(&mut self, function: &nodes::FunctionStatement) {
438 self.write_attributes(function.attributes());
439 self.push_str("function");
440 let name = function.get_name();
441
442 self.push_str(name.get_name().get_name());
443 name.get_field_names().iter().for_each(|field| {
444 self.push_new_line_if_needed(1);
445 self.raw_push_char('.');
446 self.push_str(field.get_name());
447 });
448
449 if let Some(method) = name.get_method() {
450 self.push_char(':');
451 self.push_str(method.get_name());
452 }
453
454 if let Some(generics) = function.get_generic_parameters() {
455 self.write_function_generics(generics);
456 }
457
458 self.push_char('(');
459 self.write_function_parameters(
460 function.get_parameters(),
461 function.is_variadic(),
462 function.get_variadic_type(),
463 );
464 self.push_char(')');
465
466 if let Some(return_type) = function.get_return_type() {
467 self.push_char(':');
468 self.write_function_return_type(return_type);
469 }
470
471 let block = function.get_block();
472
473 if !block.is_empty() {
474 self.write_block(block);
475 }
476 self.push_str("end");
477 }
478
479 fn write_last_statement(&mut self, statement: &nodes::LastStatement) {
480 use nodes::LastStatement::*;
481
482 match statement {
483 Break(_) => self.push_str("break"),
484 Continue(_) => self.push_str("continue"),
485 Return(expressions) => {
486 self.push_str("return");
487 let last_index = expressions.len().saturating_sub(1);
488
489 expressions
490 .iter_expressions()
491 .enumerate()
492 .for_each(|(index, expression)| {
493 self.write_expression(expression);
494
495 if index != last_index {
496 self.push_char(',');
497 }
498 });
499 }
500 }
501 }
502
503 fn write_local_assign(&mut self, assign: &nodes::VariableAssignment) {
504 self.push_str(assign.get_assignment_kind().as_keyword());
505
506 let variables_length = assign.variables_len();
507 let last_variable_index = variables_length.saturating_sub(1);
508
509 for (index, variable) in assign.iter_variables().enumerate() {
510 self.write_typed_identifier(variable);
511
512 if index != last_variable_index {
513 self.push_char(',');
514 }
515 }
516
517 for i in 0..assign.required_new_variables() {
520 if i != 0 || variables_length > 0 {
521 self.push_char(',');
522 }
523 utils::THROWAWAY_IDENTIFIER.with(|identifier| {
524 self.write_typed_identifier(identifier);
525 });
526 }
527
528 let required_nil_values = assign.required_nil_values();
531
532 let has_values = assign.has_values();
533
534 if has_values || required_nil_values > 0 {
535 self.push_char_and_break_if('=', utils::break_equal);
536
537 let last_value_index = assign.values_len().saturating_sub(1);
538
539 for (index, value) in assign.iter_values().enumerate() {
540 self.write_expression(value);
541
542 if index != last_value_index {
543 self.push_char(',');
544 }
545 }
546
547 for i in 0..required_nil_values {
548 if i != 0 || has_values {
549 self.push_char(',');
550 }
551 utils::NIL_EXPRESSION.with(|nil| {
552 self.write_expression(nil);
553 })
554 }
555 };
556 }
557
558 fn write_compound_assign(&mut self, assign: &nodes::CompoundAssignStatement) {
559 self.write_variable(assign.get_variable());
560
561 self.push_str(assign.get_operator().to_str());
562
563 self.write_expression(assign.get_value());
564 }
565
566 fn write_local_function(&mut self, function: &nodes::FunctionAssignment) {
567 self.write_attributes(function.attributes());
568 self.push_str(function.get_assignment_kind().as_keyword());
569 self.push_space();
570 self.push_str("function");
571 self.push_space();
572 self.push_str(function.get_name());
573
574 if let Some(generics) = function.get_generic_parameters() {
575 self.write_function_generics(generics);
576 }
577
578 self.push_char('(');
579
580 let parameters = function.get_parameters();
581 self.write_function_parameters(
582 parameters,
583 function.is_variadic(),
584 function.get_variadic_type(),
585 );
586 self.push_char(')');
587
588 if let Some(return_type) = function.get_return_type() {
589 self.push_char(':');
590 self.write_function_return_type(return_type);
591 }
592
593 let block = function.get_block();
594
595 if !block.is_empty() {
596 self.write_block(block);
597 }
598 self.push_str("end");
599 }
600
601 fn write_numeric_for(&mut self, numeric_for: &nodes::NumericForStatement) {
602 self.push_str("for");
603
604 self.write_typed_identifier(numeric_for.get_identifier());
605
606 self.push_char_and_break_if('=', utils::break_equal);
607
608 self.write_expression(numeric_for.get_start());
609 self.push_char(',');
610 self.write_expression(numeric_for.get_end());
611
612 if let Some(step) = numeric_for.get_step() {
613 self.push_char(',');
614 self.write_expression(step);
615 }
616
617 let block = numeric_for.get_block();
618
619 if block.is_empty() {
620 self.push_str("do end");
621 } else {
622 self.push_str("do");
623 self.write_block(block);
624 self.push_str("end");
625 }
626 }
627
628 fn write_repeat_statement(&mut self, repeat: &nodes::RepeatStatement) {
629 self.push_str("repeat");
630
631 let block = repeat.get_block();
632
633 if !block.is_empty() {
634 self.write_block(block);
635 }
636
637 self.push_str("until");
638 self.write_expression(repeat.get_condition());
639 }
640
641 fn write_while_statement(&mut self, while_statement: &nodes::WhileStatement) {
642 self.push_str("while");
643 self.write_expression(while_statement.get_condition());
644
645 let block = while_statement.get_block();
646
647 if block.is_empty() {
648 self.push_str("do end");
649 } else {
650 self.push_str("do");
651 self.write_block(block);
652 self.push_str("end");
653 }
654 }
655
656 fn write_type_declaration_statement(&mut self, statement: &nodes::TypeDeclarationStatement) {
657 if statement.is_exported() {
658 self.push_str("export");
659 }
660 self.push_str("type");
661
662 self.write_identifier(statement.get_name());
663
664 if let Some(generic_parameters) = statement
665 .get_generic_parameters()
666 .filter(|generic_parameters| !generic_parameters.is_empty())
667 {
668 self.push_char('<');
669 let last_index = generic_parameters.len().saturating_sub(1);
670 for (i, parameter) in generic_parameters.iter().enumerate() {
671 use nodes::GenericParameterRef;
672
673 match parameter {
674 GenericParameterRef::TypeVariable(identifier) => {
675 self.write_identifier(identifier);
676 }
677 GenericParameterRef::TypeVariableWithDefault(identifier_with_default) => {
678 self.write_identifier(identifier_with_default.get_type_variable());
679 self.push_char('=');
680 self.write_type(identifier_with_default.get_default_type());
681 }
682 GenericParameterRef::GenericTypePack(generic_type_pack) => {
683 self.write_generic_type_pack(generic_type_pack);
684 }
685 GenericParameterRef::GenericTypePackWithDefault(generic_pack_with_default) => {
686 self.write_generic_type_pack(
687 generic_pack_with_default.get_generic_type_pack(),
688 );
689 self.push_char('=');
690 self.write_generic_type_pack_default(
691 generic_pack_with_default.get_default_type(),
692 );
693 }
694 }
695
696 if i != last_index {
697 self.push_char(',');
698 }
699 }
700
701 self.push_char('>');
702 }
703
704 self.push_char_and_break_if('=', utils::break_equal);
705 self.write_type(statement.get_type());
706 }
707
708 fn write_type_function_statement(&mut self, function: &nodes::TypeFunctionStatement) {
709 if function.is_exported() {
710 self.push_str("export");
711 }
712 self.push_str("type");
713 self.push_str("function");
714
715 self.write_identifier(function.get_identifier());
716
717 if let Some(generics) = function.get_generic_parameters() {
718 self.write_function_generics(generics);
719 }
720
721 self.push_char('(');
722
723 let parameters = function.get_parameters();
724 self.write_function_parameters(
725 parameters,
726 function.is_variadic(),
727 function.get_variadic_type(),
728 );
729 self.push_char(')');
730
731 if let Some(return_type) = function.get_return_type() {
732 self.push_char(':');
733 self.write_function_return_type(return_type);
734 }
735
736 let block = function.get_block();
737
738 if !block.is_empty() {
739 self.write_block(block);
740 }
741 self.push_str("end");
742 }
743
744 fn write_false_expression(&mut self, _token: &Option<nodes::Token>) {
745 self.push_str("false");
746 }
747
748 fn write_true_expression(&mut self, _token: &Option<nodes::Token>) {
749 self.push_str("true");
750 }
751
752 fn write_nil_expression(&mut self, _token: &Option<nodes::Token>) {
753 self.push_str("nil");
754 }
755
756 fn write_variable_arguments_expression(&mut self, _token: &Option<nodes::Token>) {
757 self.push_str_and_break_if("...", utils::break_variable_arguments);
758 }
759
760 fn write_binary_expression(&mut self, binary: &nodes::BinaryExpression) {
761 use nodes::BinaryOperator;
762
763 let operator = binary.operator();
764 let left = binary.left();
765 let right = binary.right();
766
767 if operator.left_needs_parentheses(left) {
768 self.write_expression_in_parentheses(left);
769 } else {
770 self.write_expression(left);
771 }
772
773 match operator {
774 BinaryOperator::Concat => self.push_str_and_break_if("..", utils::break_concat),
775 _ => self.push_str(operator.to_str()),
776 }
777
778 if operator.right_needs_parentheses(right) {
779 self.write_expression_in_parentheses(right);
780 } else {
781 self.write_expression(right);
782 }
783 }
784
785 fn write_unary_expression(&mut self, unary: &nodes::UnaryExpression) {
786 use nodes::{Expression, UnaryOperator::*};
787
788 match unary.operator() {
789 Length => self.push_char('#'),
790 Minus => self.push_char_and_break_if('-', utils::break_minus),
791 Not => self.push_str("not"),
792 }
793
794 let expression = unary.get_expression();
795
796 match expression {
797 Expression::Binary(binary) if !binary.operator().precedes_unary_expression() => {
798 self.write_expression_in_parentheses(expression);
799 }
800 _ => self.write_expression(expression),
801 }
802 }
803
804 fn write_function(&mut self, function: &nodes::FunctionExpression) {
805 self.write_attributes(function.attributes());
806 self.push_str("function");
807
808 if let Some(generics) = function.get_generic_parameters() {
809 self.write_function_generics(generics);
810 }
811
812 self.push_char('(');
813
814 let parameters = function.get_parameters();
815 self.write_function_parameters(
816 parameters,
817 function.is_variadic(),
818 function.get_variadic_type(),
819 );
820 self.push_char(')');
821
822 if let Some(return_type) = function.get_return_type() {
823 self.push_char(':');
824 self.write_function_return_type(return_type);
825 }
826
827 let block = function.get_block();
828
829 if !block.is_empty() {
830 self.write_block(block);
831 }
832 self.push_str("end");
833 }
834
835 fn write_function_call(&mut self, call: &nodes::FunctionCall) {
836 self.write_prefix(call.get_prefix());
837
838 if let Some(method) = &call.get_method() {
839 self.push_char(':');
840 self.push_str(method.get_name());
841 }
842
843 self.write_arguments(call.get_arguments());
844 }
845
846 fn write_field(&mut self, field: &nodes::FieldExpression) {
847 self.write_prefix(field.get_prefix());
848
849 self.push_new_line_if_needed(1);
850 self.raw_push_char('.');
851
852 self.push_str(field.get_field().get_name());
853 }
854
855 fn write_index(&mut self, index: &nodes::IndexExpression) {
856 self.write_prefix(index.get_prefix());
857
858 self.push_char('[');
859 self.write_expression(index.get_index());
860 self.push_char(']');
861 }
862
863 fn write_if_expression(&mut self, if_expression: &nodes::IfExpression) {
864 self.push_str("if");
865 self.write_expression(if_expression.get_condition());
866 self.push_str("then");
867 self.write_expression(if_expression.get_result());
868
869 for branch in if_expression.iter_branches() {
870 self.push_str("elseif");
871 self.write_expression(branch.get_condition());
872 self.push_str("then");
873 self.write_expression(branch.get_result());
874 }
875
876 self.push_str("else");
877 self.write_expression(if_expression.get_else_result());
878 }
879
880 fn write_table(&mut self, table: &nodes::TableExpression) {
881 self.push_char('{');
882
883 let entries = table.get_entries();
884 let last_index = entries.len().saturating_sub(1);
885
886 entries.iter().enumerate().for_each(|(index, entry)| {
887 self.write_table_entry(entry);
888
889 if index != last_index {
890 self.push_char(',');
891 }
892 });
893
894 self.push_char('}');
895 }
896
897 fn write_table_entry(&mut self, entry: &nodes::TableEntry) {
898 match entry {
899 nodes::TableEntry::Field(entry) => {
900 self.push_str(entry.get_field().get_name());
901 self.push_char('=');
902 self.write_expression(entry.get_value());
903 }
904 nodes::TableEntry::Index(entry) => {
905 self.push_char('[');
906 self.write_expression(entry.get_key());
907 self.push_char(']');
908 self.push_char('=');
909 self.write_expression(entry.get_value());
910 }
911 nodes::TableEntry::Value(expression) => self.write_expression(expression),
912 }
913 }
914
915 fn write_number(&mut self, number: &nodes::NumberExpression) {
916 use nodes::NumberExpression::*;
917
918 match number {
919 Decimal(decimal) => {
920 let float = decimal.get_raw_float();
921 if float.is_nan() {
922 self.push_char('(');
923 self.push_char('0');
924 self.push_char('/');
925 self.push_char('0');
926 self.push_char(')');
927 } else if float.is_infinite() {
928 self.push_char('(');
929 if float.is_sign_negative() {
930 self.push_char('-');
931 }
932 self.push_char('1');
933 self.push_char('/');
934 self.push_char('0');
935 self.push_char(')');
936 } else {
937 let result = utils::write_number(number);
938
939 self.push_str(&result);
940 }
941 }
942 Hex(number) => {
943 let mut result = format!(
944 "0{}{:x}",
945 if number.is_x_uppercase() { 'X' } else { 'x' },
946 number.get_raw_integer()
947 );
948
949 if let Some(exponent) = number.get_exponent() {
950 let exponent_char = number
951 .is_exponent_uppercase()
952 .map(|is_uppercase| if is_uppercase { 'P' } else { 'p' })
953 .unwrap_or('p');
954
955 result.push(exponent_char);
956 result.push_str(&format!("{}", exponent));
957 };
958
959 self.push_str(&result);
960 }
961 Binary(number) => {
962 self.push_str(&format!(
963 "0{}{:b}",
964 if number.is_b_uppercase() { 'B' } else { 'b' },
965 number.get_raw_value()
966 ));
967 }
968 }
969 }
970
971 fn write_tuple_arguments(&mut self, arguments: &nodes::TupleArguments) {
972 self.merge_char('(');
973
974 let last_index = arguments.len().saturating_sub(1);
975 arguments
976 .iter_values()
977 .enumerate()
978 .for_each(|(index, expression)| {
979 self.write_expression(expression);
980
981 if index != last_index {
982 self.push_char(',');
983 }
984 });
985
986 self.push_char(')');
987 }
988
989 fn write_string(&mut self, string: &nodes::StringExpression) {
990 let result = utils::write_string(string.get_value());
991 if result.starts_with('[') {
992 self.push_str_and_break_if(&result, utils::break_long_string);
993 } else {
994 self.push_str(&result);
995 }
996 }
997
998 fn write_interpolated_string(
999 &mut self,
1000 interpolated_string: &nodes::InterpolatedStringExpression,
1001 ) {
1002 self.push_char('`');
1003
1004 for segment in interpolated_string.iter_segments() {
1005 match segment {
1006 nodes::InterpolationSegment::String(string_segment) => {
1007 self.raw_push_str(&utils::write_interpolated_string_segment(string_segment));
1008 }
1009 nodes::InterpolationSegment::Value(value) => {
1010 self.raw_push_char('{');
1011 let expression = value.get_expression();
1013 if utils::starts_with_table(expression).is_some() {
1014 self.raw_push_char(' ');
1015 }
1016 self.write_expression(expression);
1017 self.push_char('}');
1018 }
1019 }
1020 }
1021
1022 self.raw_push_char('`');
1023 }
1024
1025 fn write_attribute_tuple_arguments(&mut self, tuple: &nodes::AttributeTupleArguments) {
1026 self.push_char('(');
1027
1028 let last_index = tuple.len().saturating_sub(1);
1029 for (index, value) in tuple.iter_values().enumerate() {
1030 self.write_literal_expression(value);
1031 if index != last_index {
1032 self.push_char(',');
1033 }
1034 }
1035
1036 self.push_char(')');
1037 }
1038
1039 fn write_literal_table(&mut self, table: &nodes::LiteralTable) {
1040 self.push_char('{');
1041 let last_index = table.len().saturating_sub(1);
1042 for (index, entry) in table.iter_entries().enumerate() {
1043 self.write_literal_table_entry(entry);
1044 if index != last_index {
1045 self.push_char(',');
1046 }
1047 }
1048 self.push_char('}');
1049 }
1050
1051 fn write_literal_table_entry(&mut self, entry: &nodes::LiteralTableEntry) {
1052 use nodes::LiteralTableEntry::*;
1053 match entry {
1054 Field(field) => {
1055 self.write_identifier(field.get_field());
1056 self.push_char('=');
1057 self.write_literal_expression(field.get_value());
1058 }
1059 Value(value) => {
1060 self.write_literal_expression(value);
1061 }
1062 }
1063 }
1064
1065 fn write_identifier(&mut self, identifier: &nodes::Identifier) {
1066 self.push_str(identifier.get_name());
1067 }
1068
1069 fn write_parenthese(&mut self, parenthese: &nodes::ParentheseExpression) {
1070 self.write_expression_in_parentheses(parenthese.inner_expression());
1071 }
1072
1073 fn write_type_cast(&mut self, type_cast: &nodes::TypeCastExpression) {
1074 let inner_expression = type_cast.get_expression();
1075
1076 if nodes::TypeCastExpression::needs_parentheses(inner_expression) {
1077 self.write_expression_in_parentheses(inner_expression);
1078 } else {
1079 self.write_expression(inner_expression);
1080 }
1081
1082 self.push_str("::");
1083 self.write_type(type_cast.get_type());
1084 }
1085
1086 fn write_type_instantiation(
1087 &mut self,
1088 type_instantiation: &nodes::TypeInstantiationExpression,
1089 ) {
1090 self.write_prefix(type_instantiation.get_prefix());
1091
1092 self.push_new_line_if_needed(2);
1093 self.raw_push_char('<');
1094 self.raw_push_char('<');
1095
1096 let last_index = type_instantiation.types_len().saturating_sub(1);
1097 for (index, r#type) in type_instantiation.iter_types().enumerate() {
1098 self.write_type(r#type);
1099 if index != last_index {
1100 self.push_char(',');
1101 }
1102 }
1103
1104 self.push_new_line_if_needed(2);
1105 self.raw_push_char('>');
1106 self.raw_push_char('>');
1107 }
1108
1109 fn write_type_name(&mut self, type_name: &nodes::TypeName) {
1110 self.write_identifier(type_name.get_type_name());
1111 if let Some(parameters) = type_name.get_type_parameters() {
1112 self.push_char('<');
1113 let last_index = parameters.len().saturating_sub(1);
1114 for (index, parameter) in parameters.iter().enumerate() {
1115 self.write_type_parameter(parameter);
1116 if index != last_index {
1117 self.push_char(',');
1118 }
1119 }
1120
1121 self.push_char('>');
1122 }
1123 }
1124
1125 fn write_type_field(&mut self, type_field: &nodes::TypeField) {
1126 self.write_identifier(type_field.get_namespace());
1127 self.push_new_line_if_needed(1);
1128 self.raw_push_char('.');
1129 self.write_type_name(type_field.get_type_name());
1130 }
1131
1132 fn write_true_type(&mut self, _: &Option<nodes::Token>) {
1133 self.push_str("true");
1134 }
1135
1136 fn write_false_type(&mut self, _: &Option<nodes::Token>) {
1137 self.push_str("false");
1138 }
1139
1140 fn write_nil_type(&mut self, _: &Option<nodes::Token>) {
1141 self.push_str("nil");
1142 }
1143
1144 fn write_string_type(&mut self, string_type: &nodes::StringType) {
1145 let result = utils::write_string(string_type.get_value());
1146 if result.starts_with('[') {
1147 self.push_str_and_break_if(&result, utils::break_long_string);
1148 } else {
1149 self.push_str(&result);
1150 }
1151 }
1152
1153 fn write_array_type(&mut self, array: &nodes::ArrayType) {
1154 self.push_char('{');
1155 self.write_type(array.get_element_type());
1156 self.push_char('}');
1157 }
1158
1159 fn write_table_type(&mut self, table_type: &nodes::TableType) {
1160 self.push_char('{');
1161
1162 let last_index = table_type.len().saturating_sub(1);
1163 for (index, property) in table_type.iter_entries().enumerate() {
1164 if let Some(modifier) = property.get_modifier() {
1165 match modifier {
1166 nodes::TablePropertyModifier::Read => self.push_str("read"),
1167 nodes::TablePropertyModifier::Write => self.push_str("write"),
1168 }
1169 }
1170
1171 match property {
1172 nodes::TableEntryType::Property(property) => {
1173 self.write_identifier(property.get_identifier());
1174 self.push_char(':');
1175 self.write_type(property.get_type());
1176 }
1177 nodes::TableEntryType::Literal(property) => {
1178 self.push_char('[');
1179 self.write_string_type(property.get_string());
1180 self.push_char(']');
1181 self.push_char(':');
1182 self.write_type(property.get_type());
1183 }
1184 nodes::TableEntryType::Indexer(indexer) => {
1185 self.push_char('[');
1186
1187 let key_type = indexer.get_key_type();
1188
1189 let need_parentheses = matches!(
1190 key_type,
1191 nodes::Type::Optional(_)
1192 | nodes::Type::Intersection(_)
1193 | nodes::Type::Union(_)
1194 );
1195
1196 if need_parentheses {
1197 self.push_char('(');
1198 self.write_type(key_type);
1199 self.push_char(')');
1200 } else {
1201 self.write_type(key_type);
1202 }
1203
1204 self.push_char(']');
1205 self.push_char(':');
1206 self.write_type(indexer.get_value_type());
1207 }
1208 }
1209 if index != last_index {
1210 self.push_char(',');
1211 }
1212 }
1213
1214 self.push_char('}');
1215 }
1216
1217 fn write_expression_type(&mut self, expression_type: &nodes::ExpressionType) {
1218 self.push_str("typeof(");
1219 self.write_expression(expression_type.get_expression());
1220 self.push_char(')');
1221 }
1222
1223 fn write_parenthese_type(&mut self, parenthese_type: &nodes::ParentheseType) {
1224 self.write_type_in_parentheses(parenthese_type.get_inner_type());
1225 }
1226
1227 fn write_function_type(&mut self, function_type: &nodes::FunctionType) {
1228 if let Some(generics) = function_type.get_generic_parameters() {
1229 self.write_function_generics(generics);
1230 }
1231
1232 self.push_char('(');
1233
1234 let last_index = function_type.argument_len().saturating_sub(1);
1235
1236 for (index, argument) in function_type.iter_arguments().enumerate() {
1237 if let Some(name) = argument.get_name() {
1238 self.write_identifier(name);
1239 self.push_char(':');
1240 }
1241 self.write_type(argument.get_type());
1242
1243 if index != last_index {
1244 self.push_char(',');
1245 }
1246 }
1247
1248 if let Some(variadic_argument_type) = function_type.get_variadic_argument_type() {
1249 if function_type.argument_len() > 0 {
1250 self.push_char(',');
1251 }
1252 self.write_variadic_argument_type(variadic_argument_type);
1253 }
1254
1255 self.push_str(")->");
1256 self.write_function_return_type(function_type.get_return_type());
1257 }
1258
1259 fn write_optional_type(&mut self, optional: &nodes::OptionalType) {
1260 let inner_type = optional.get_inner_type();
1261 if nodes::OptionalType::needs_parentheses(inner_type) {
1262 self.write_type_in_parentheses(inner_type);
1263 } else {
1264 self.write_type(inner_type);
1265 }
1266 self.push_char('?');
1267 }
1268
1269 fn write_intersection_type(&mut self, intersection: &nodes::IntersectionType) {
1270 let length = intersection.len();
1271 let last_index = length.saturating_sub(1);
1272 for (i, r#type) in intersection.iter_types().enumerate() {
1273 if i != 0 || intersection.has_leading_token() {
1274 self.push_char('&');
1275 }
1276
1277 let need_parentheses = if i == last_index {
1278 nodes::IntersectionType::last_needs_parentheses(r#type)
1279 } else {
1280 nodes::IntersectionType::intermediate_needs_parentheses(r#type)
1281 };
1282
1283 if need_parentheses {
1284 self.write_type_in_parentheses(r#type);
1285 } else {
1286 self.write_type(r#type);
1287 }
1288 }
1289 }
1290
1291 fn write_union_type(&mut self, union: &nodes::UnionType) {
1292 let length = union.len();
1293 let last_index = length.saturating_sub(1);
1294 for (i, r#type) in union.iter_types().enumerate() {
1295 if i != 0 || union.has_leading_token() {
1296 self.push_char('|');
1297 }
1298
1299 let need_parentheses = if i == last_index {
1300 nodes::UnionType::last_needs_parentheses(r#type)
1301 } else {
1302 nodes::UnionType::intermediate_needs_parentheses(r#type)
1303 };
1304
1305 if need_parentheses {
1306 self.write_type_in_parentheses(r#type);
1307 } else {
1308 self.write_type(r#type);
1309 }
1310 }
1311 }
1312
1313 fn write_type_pack(&mut self, type_pack: &nodes::TypePack) {
1314 self.push_char('(');
1315
1316 let last_index = type_pack.len().saturating_sub(1);
1317
1318 for (index, r#type) in type_pack.into_iter().enumerate() {
1319 self.write_type(r#type);
1320 if index != last_index {
1321 self.push_char(',');
1322 }
1323 }
1324
1325 if let Some(variadic_argument_type) = type_pack.get_variadic_type() {
1326 if !type_pack.is_empty() {
1327 self.push_char(',');
1328 }
1329 self.write_variadic_argument_type(variadic_argument_type);
1330 }
1331
1332 self.push_char(')');
1333 }
1334
1335 fn write_variadic_type_pack(&mut self, variadic_type_pack: &nodes::VariadicTypePack) {
1336 self.push_str("...");
1337 self.write_type(variadic_type_pack.get_type());
1338 }
1339
1340 fn write_generic_type_pack(&mut self, generic_type_pack: &nodes::GenericTypePack) {
1341 self.write_identifier(generic_type_pack.get_name());
1342 self.push_str("...");
1343 }
1344}