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::LocalAssignStatement) {
504 self.push_str("local");
505
506 let variables = assign.get_variables();
507 let last_variable_index = variables.len().saturating_sub(1);
508
509 variables.iter().enumerate().for_each(|(index, variable)| {
510 self.write_typed_identifier(variable);
511
512 if index != last_variable_index {
513 self.push_char(',');
514 }
515 });
516
517 if assign.has_values() {
518 self.push_char_and_break_if('=', utils::break_equal);
519
520 let last_value_index = assign.values_len() - 1;
521
522 assign.iter_values().enumerate().for_each(|(index, value)| {
523 self.write_expression(value);
524
525 if index != last_value_index {
526 self.push_char(',');
527 }
528 });
529 };
530 }
531
532 fn write_compound_assign(&mut self, assign: &nodes::CompoundAssignStatement) {
533 self.write_variable(assign.get_variable());
534
535 self.push_str(assign.get_operator().to_str());
536
537 self.write_expression(assign.get_value());
538 }
539
540 fn write_local_function(&mut self, function: &nodes::LocalFunctionStatement) {
541 self.write_attributes(function.attributes());
542 self.push_str("local function");
543 self.push_str(function.get_name());
544
545 if let Some(generics) = function.get_generic_parameters() {
546 self.write_function_generics(generics);
547 }
548
549 self.push_char('(');
550
551 let parameters = function.get_parameters();
552 self.write_function_parameters(
553 parameters,
554 function.is_variadic(),
555 function.get_variadic_type(),
556 );
557 self.push_char(')');
558
559 if let Some(return_type) = function.get_return_type() {
560 self.push_char(':');
561 self.write_function_return_type(return_type);
562 }
563
564 let block = function.get_block();
565
566 if !block.is_empty() {
567 self.write_block(block);
568 }
569 self.push_str("end");
570 }
571
572 fn write_numeric_for(&mut self, numeric_for: &nodes::NumericForStatement) {
573 self.push_str("for");
574
575 self.write_typed_identifier(numeric_for.get_identifier());
576
577 self.push_char_and_break_if('=', utils::break_equal);
578
579 self.write_expression(numeric_for.get_start());
580 self.push_char(',');
581 self.write_expression(numeric_for.get_end());
582
583 if let Some(step) = numeric_for.get_step() {
584 self.push_char(',');
585 self.write_expression(step);
586 }
587
588 let block = numeric_for.get_block();
589
590 if block.is_empty() {
591 self.push_str("do end");
592 } else {
593 self.push_str("do");
594 self.write_block(block);
595 self.push_str("end");
596 }
597 }
598
599 fn write_repeat_statement(&mut self, repeat: &nodes::RepeatStatement) {
600 self.push_str("repeat");
601
602 let block = repeat.get_block();
603
604 if !block.is_empty() {
605 self.write_block(block);
606 }
607
608 self.push_str("until");
609 self.write_expression(repeat.get_condition());
610 }
611
612 fn write_while_statement(&mut self, while_statement: &nodes::WhileStatement) {
613 self.push_str("while");
614 self.write_expression(while_statement.get_condition());
615
616 let block = while_statement.get_block();
617
618 if block.is_empty() {
619 self.push_str("do end");
620 } else {
621 self.push_str("do");
622 self.write_block(block);
623 self.push_str("end");
624 }
625 }
626
627 fn write_type_declaration_statement(&mut self, statement: &nodes::TypeDeclarationStatement) {
628 if statement.is_exported() {
629 self.push_str("export");
630 }
631 self.push_str("type");
632
633 self.write_identifier(statement.get_name());
634
635 if let Some(generic_parameters) = statement
636 .get_generic_parameters()
637 .filter(|generic_parameters| !generic_parameters.is_empty())
638 {
639 self.push_char('<');
640 let last_index = generic_parameters.len().saturating_sub(1);
641 for (i, parameter) in generic_parameters.iter().enumerate() {
642 use nodes::GenericParameterRef;
643
644 match parameter {
645 GenericParameterRef::TypeVariable(identifier) => {
646 self.write_identifier(identifier);
647 }
648 GenericParameterRef::TypeVariableWithDefault(identifier_with_default) => {
649 self.write_identifier(identifier_with_default.get_type_variable());
650 self.push_char('=');
651 self.write_type(identifier_with_default.get_default_type());
652 }
653 GenericParameterRef::GenericTypePack(generic_type_pack) => {
654 self.write_generic_type_pack(generic_type_pack);
655 }
656 GenericParameterRef::GenericTypePackWithDefault(generic_pack_with_default) => {
657 self.write_generic_type_pack(
658 generic_pack_with_default.get_generic_type_pack(),
659 );
660 self.push_char('=');
661 self.write_generic_type_pack_default(
662 generic_pack_with_default.get_default_type(),
663 );
664 }
665 }
666
667 if i != last_index {
668 self.push_char(',');
669 }
670 }
671
672 self.push_char('>');
673 }
674
675 self.push_char_and_break_if('=', utils::break_equal);
676 self.write_type(statement.get_type());
677 }
678
679 fn write_type_function_statement(&mut self, function: &nodes::TypeFunctionStatement) {
680 if function.is_exported() {
681 self.push_str("export");
682 }
683 self.push_str("type");
684 self.push_str("function");
685
686 self.write_identifier(function.get_identifier());
687
688 if let Some(generics) = function.get_generic_parameters() {
689 self.write_function_generics(generics);
690 }
691
692 self.push_char('(');
693
694 let parameters = function.get_parameters();
695 self.write_function_parameters(
696 parameters,
697 function.is_variadic(),
698 function.get_variadic_type(),
699 );
700 self.push_char(')');
701
702 if let Some(return_type) = function.get_return_type() {
703 self.push_char(':');
704 self.write_function_return_type(return_type);
705 }
706
707 let block = function.get_block();
708
709 if !block.is_empty() {
710 self.write_block(block);
711 }
712 self.push_str("end");
713 }
714
715 fn write_false_expression(&mut self, _token: &Option<nodes::Token>) {
716 self.push_str("false");
717 }
718
719 fn write_true_expression(&mut self, _token: &Option<nodes::Token>) {
720 self.push_str("true");
721 }
722
723 fn write_nil_expression(&mut self, _token: &Option<nodes::Token>) {
724 self.push_str("nil");
725 }
726
727 fn write_variable_arguments_expression(&mut self, _token: &Option<nodes::Token>) {
728 self.push_str_and_break_if("...", utils::break_variable_arguments);
729 }
730
731 fn write_binary_expression(&mut self, binary: &nodes::BinaryExpression) {
732 use nodes::BinaryOperator;
733
734 let operator = binary.operator();
735 let left = binary.left();
736 let right = binary.right();
737
738 if operator.left_needs_parentheses(left) {
739 self.write_expression_in_parentheses(left);
740 } else {
741 self.write_expression(left);
742 }
743
744 match operator {
745 BinaryOperator::Concat => self.push_str_and_break_if("..", utils::break_concat),
746 _ => self.push_str(operator.to_str()),
747 }
748
749 if operator.right_needs_parentheses(right) {
750 self.write_expression_in_parentheses(right);
751 } else {
752 self.write_expression(right);
753 }
754 }
755
756 fn write_unary_expression(&mut self, unary: &nodes::UnaryExpression) {
757 use nodes::{Expression, UnaryOperator::*};
758
759 match unary.operator() {
760 Length => self.push_char('#'),
761 Minus => self.push_char_and_break_if('-', utils::break_minus),
762 Not => self.push_str("not"),
763 }
764
765 let expression = unary.get_expression();
766
767 match expression {
768 Expression::Binary(binary) if !binary.operator().precedes_unary_expression() => {
769 self.write_expression_in_parentheses(expression);
770 }
771 _ => self.write_expression(expression),
772 }
773 }
774
775 fn write_function(&mut self, function: &nodes::FunctionExpression) {
776 self.write_attributes(function.attributes());
777 self.push_str("function");
778
779 if let Some(generics) = function.get_generic_parameters() {
780 self.write_function_generics(generics);
781 }
782
783 self.push_char('(');
784
785 let parameters = function.get_parameters();
786 self.write_function_parameters(
787 parameters,
788 function.is_variadic(),
789 function.get_variadic_type(),
790 );
791 self.push_char(')');
792
793 if let Some(return_type) = function.get_return_type() {
794 self.push_char(':');
795 self.write_function_return_type(return_type);
796 }
797
798 let block = function.get_block();
799
800 if !block.is_empty() {
801 self.write_block(block);
802 }
803 self.push_str("end");
804 }
805
806 fn write_function_call(&mut self, call: &nodes::FunctionCall) {
807 self.write_prefix(call.get_prefix());
808
809 if let Some(method) = &call.get_method() {
810 self.push_char(':');
811 self.push_str(method.get_name());
812 }
813
814 self.write_arguments(call.get_arguments());
815 }
816
817 fn write_field(&mut self, field: &nodes::FieldExpression) {
818 self.write_prefix(field.get_prefix());
819
820 self.push_new_line_if_needed(1);
821 self.raw_push_char('.');
822
823 self.push_str(field.get_field().get_name());
824 }
825
826 fn write_index(&mut self, index: &nodes::IndexExpression) {
827 self.write_prefix(index.get_prefix());
828
829 self.push_char('[');
830 self.write_expression(index.get_index());
831 self.push_char(']');
832 }
833
834 fn write_if_expression(&mut self, if_expression: &nodes::IfExpression) {
835 self.push_str("if");
836 self.write_expression(if_expression.get_condition());
837 self.push_str("then");
838 self.write_expression(if_expression.get_result());
839
840 for branch in if_expression.iter_branches() {
841 self.push_str("elseif");
842 self.write_expression(branch.get_condition());
843 self.push_str("then");
844 self.write_expression(branch.get_result());
845 }
846
847 self.push_str("else");
848 self.write_expression(if_expression.get_else_result());
849 }
850
851 fn write_table(&mut self, table: &nodes::TableExpression) {
852 self.push_char('{');
853
854 let entries = table.get_entries();
855 let last_index = entries.len().saturating_sub(1);
856
857 entries.iter().enumerate().for_each(|(index, entry)| {
858 self.write_table_entry(entry);
859
860 if index != last_index {
861 self.push_char(',');
862 }
863 });
864
865 self.push_char('}');
866 }
867
868 fn write_table_entry(&mut self, entry: &nodes::TableEntry) {
869 match entry {
870 nodes::TableEntry::Field(entry) => {
871 self.push_str(entry.get_field().get_name());
872 self.push_char('=');
873 self.write_expression(entry.get_value());
874 }
875 nodes::TableEntry::Index(entry) => {
876 self.push_char('[');
877 self.write_expression(entry.get_key());
878 self.push_char(']');
879 self.push_char('=');
880 self.write_expression(entry.get_value());
881 }
882 nodes::TableEntry::Value(expression) => self.write_expression(expression),
883 }
884 }
885
886 fn write_number(&mut self, number: &nodes::NumberExpression) {
887 use nodes::NumberExpression::*;
888
889 match number {
890 Decimal(decimal) => {
891 let float = decimal.get_raw_float();
892 if float.is_nan() {
893 self.push_char('(');
894 self.push_char('0');
895 self.push_char('/');
896 self.push_char('0');
897 self.push_char(')');
898 } else if float.is_infinite() {
899 self.push_char('(');
900 if float.is_sign_negative() {
901 self.push_char('-');
902 }
903 self.push_char('1');
904 self.push_char('/');
905 self.push_char('0');
906 self.push_char(')');
907 } else {
908 let result = utils::write_number(number);
909
910 self.push_str(&result);
911 }
912 }
913 Hex(number) => {
914 let mut result = format!(
915 "0{}{:x}",
916 if number.is_x_uppercase() { 'X' } else { 'x' },
917 number.get_raw_integer()
918 );
919
920 if let Some(exponent) = number.get_exponent() {
921 let exponent_char = number
922 .is_exponent_uppercase()
923 .map(|is_uppercase| if is_uppercase { 'P' } else { 'p' })
924 .unwrap_or('p');
925
926 result.push(exponent_char);
927 result.push_str(&format!("{}", exponent));
928 };
929
930 self.push_str(&result);
931 }
932 Binary(number) => {
933 self.push_str(&format!(
934 "0{}{:b}",
935 if number.is_b_uppercase() { 'B' } else { 'b' },
936 number.get_raw_value()
937 ));
938 }
939 }
940 }
941
942 fn write_tuple_arguments(&mut self, arguments: &nodes::TupleArguments) {
943 self.merge_char('(');
944
945 let last_index = arguments.len().saturating_sub(1);
946 arguments
947 .iter_values()
948 .enumerate()
949 .for_each(|(index, expression)| {
950 self.write_expression(expression);
951
952 if index != last_index {
953 self.push_char(',');
954 }
955 });
956
957 self.push_char(')');
958 }
959
960 fn write_string(&mut self, string: &nodes::StringExpression) {
961 let result = utils::write_string(string.get_value());
962 if result.starts_with('[') {
963 self.push_str_and_break_if(&result, utils::break_long_string);
964 } else {
965 self.push_str(&result);
966 }
967 }
968
969 fn write_interpolated_string(
970 &mut self,
971 interpolated_string: &nodes::InterpolatedStringExpression,
972 ) {
973 self.push_char('`');
974
975 for segment in interpolated_string.iter_segments() {
976 match segment {
977 nodes::InterpolationSegment::String(string_segment) => {
978 self.raw_push_str(&utils::write_interpolated_string_segment(string_segment));
979 }
980 nodes::InterpolationSegment::Value(value) => {
981 self.raw_push_char('{');
982 let expression = value.get_expression();
984 if utils::starts_with_table(expression).is_some() {
985 self.raw_push_char(' ');
986 }
987 self.write_expression(expression);
988 self.push_char('}');
989 }
990 }
991 }
992
993 self.raw_push_char('`');
994 }
995
996 fn write_attribute_tuple_arguments(&mut self, tuple: &nodes::AttributeTupleArguments) {
997 self.push_char('(');
998
999 let last_index = tuple.len().saturating_sub(1);
1000 for (index, value) in tuple.iter_values().enumerate() {
1001 self.write_literal_expression(value);
1002 if index != last_index {
1003 self.push_char(',');
1004 }
1005 }
1006
1007 self.push_char(')');
1008 }
1009
1010 fn write_literal_table(&mut self, table: &nodes::LiteralTable) {
1011 self.push_char('{');
1012 let last_index = table.len().saturating_sub(1);
1013 for (index, entry) in table.iter_entries().enumerate() {
1014 self.write_literal_table_entry(entry);
1015 if index != last_index {
1016 self.push_char(',');
1017 }
1018 }
1019 self.push_char('}');
1020 }
1021
1022 fn write_literal_table_entry(&mut self, entry: &nodes::LiteralTableEntry) {
1023 use nodes::LiteralTableEntry::*;
1024 match entry {
1025 Field(field) => {
1026 self.write_identifier(field.get_field());
1027 self.push_char('=');
1028 self.write_literal_expression(field.get_value());
1029 }
1030 Value(value) => {
1031 self.write_literal_expression(value);
1032 }
1033 }
1034 }
1035
1036 fn write_identifier(&mut self, identifier: &nodes::Identifier) {
1037 self.push_str(identifier.get_name());
1038 }
1039
1040 fn write_parenthese(&mut self, parenthese: &nodes::ParentheseExpression) {
1041 self.write_expression_in_parentheses(parenthese.inner_expression());
1042 }
1043
1044 fn write_type_cast(&mut self, type_cast: &nodes::TypeCastExpression) {
1045 let inner_expression = type_cast.get_expression();
1046
1047 if nodes::TypeCastExpression::needs_parentheses(inner_expression) {
1048 self.write_expression_in_parentheses(inner_expression);
1049 } else {
1050 self.write_expression(inner_expression);
1051 }
1052
1053 self.push_str("::");
1054 self.write_type(type_cast.get_type());
1055 }
1056
1057 fn write_type_name(&mut self, type_name: &nodes::TypeName) {
1058 self.write_identifier(type_name.get_type_name());
1059 if let Some(parameters) = type_name.get_type_parameters() {
1060 self.push_char('<');
1061 let last_index = parameters.len().saturating_sub(1);
1062 for (index, parameter) in parameters.iter().enumerate() {
1063 self.write_type_parameter(parameter);
1064 if index != last_index {
1065 self.push_char(',');
1066 }
1067 }
1068
1069 self.push_char('>');
1070 }
1071 }
1072
1073 fn write_type_field(&mut self, type_field: &nodes::TypeField) {
1074 self.write_identifier(type_field.get_namespace());
1075 self.push_new_line_if_needed(1);
1076 self.raw_push_char('.');
1077 self.write_type_name(type_field.get_type_name());
1078 }
1079
1080 fn write_true_type(&mut self, _: &Option<nodes::Token>) {
1081 self.push_str("true");
1082 }
1083
1084 fn write_false_type(&mut self, _: &Option<nodes::Token>) {
1085 self.push_str("false");
1086 }
1087
1088 fn write_nil_type(&mut self, _: &Option<nodes::Token>) {
1089 self.push_str("nil");
1090 }
1091
1092 fn write_string_type(&mut self, string_type: &nodes::StringType) {
1093 let result = utils::write_string(string_type.get_value());
1094 if result.starts_with('[') {
1095 self.push_str_and_break_if(&result, utils::break_long_string);
1096 } else {
1097 self.push_str(&result);
1098 }
1099 }
1100
1101 fn write_array_type(&mut self, array: &nodes::ArrayType) {
1102 self.push_char('{');
1103 self.write_type(array.get_element_type());
1104 self.push_char('}');
1105 }
1106
1107 fn write_table_type(&mut self, table_type: &nodes::TableType) {
1108 self.push_char('{');
1109
1110 let last_index = table_type.len().saturating_sub(1);
1111 for (index, property) in table_type.iter_entries().enumerate() {
1112 if let Some(modifier) = property.get_modifier() {
1113 match modifier {
1114 nodes::TablePropertyModifier::Read => self.push_str("read"),
1115 nodes::TablePropertyModifier::Write => self.push_str("write"),
1116 }
1117 }
1118
1119 match property {
1120 nodes::TableEntryType::Property(property) => {
1121 self.write_identifier(property.get_identifier());
1122 self.push_char(':');
1123 self.write_type(property.get_type());
1124 }
1125 nodes::TableEntryType::Literal(property) => {
1126 self.push_char('[');
1127 self.write_string_type(property.get_string());
1128 self.push_char(']');
1129 self.push_char(':');
1130 self.write_type(property.get_type());
1131 }
1132 nodes::TableEntryType::Indexer(indexer) => {
1133 self.push_char('[');
1134
1135 let key_type = indexer.get_key_type();
1136
1137 let need_parentheses = matches!(
1138 key_type,
1139 nodes::Type::Optional(_)
1140 | nodes::Type::Intersection(_)
1141 | nodes::Type::Union(_)
1142 );
1143
1144 if need_parentheses {
1145 self.push_char('(');
1146 self.write_type(key_type);
1147 self.push_char(')');
1148 } else {
1149 self.write_type(key_type);
1150 }
1151
1152 self.push_char(']');
1153 self.push_char(':');
1154 self.write_type(indexer.get_value_type());
1155 }
1156 }
1157 if index != last_index {
1158 self.push_char(',');
1159 }
1160 }
1161
1162 self.push_char('}');
1163 }
1164
1165 fn write_expression_type(&mut self, expression_type: &nodes::ExpressionType) {
1166 self.push_str("typeof(");
1167 self.write_expression(expression_type.get_expression());
1168 self.push_char(')');
1169 }
1170
1171 fn write_parenthese_type(&mut self, parenthese_type: &nodes::ParentheseType) {
1172 self.write_type_in_parentheses(parenthese_type.get_inner_type());
1173 }
1174
1175 fn write_function_type(&mut self, function_type: &nodes::FunctionType) {
1176 if let Some(generics) = function_type.get_generic_parameters() {
1177 self.write_function_generics(generics);
1178 }
1179
1180 self.push_char('(');
1181
1182 let last_index = function_type.argument_len().saturating_sub(1);
1183
1184 for (index, argument) in function_type.iter_arguments().enumerate() {
1185 if let Some(name) = argument.get_name() {
1186 self.write_identifier(name);
1187 self.push_char(':');
1188 }
1189 self.write_type(argument.get_type());
1190
1191 if index != last_index {
1192 self.push_char(',');
1193 }
1194 }
1195
1196 if let Some(variadic_argument_type) = function_type.get_variadic_argument_type() {
1197 if function_type.argument_len() > 0 {
1198 self.push_char(',');
1199 }
1200 self.write_variadic_argument_type(variadic_argument_type);
1201 }
1202
1203 self.push_str(")->");
1204 self.write_function_return_type(function_type.get_return_type());
1205 }
1206
1207 fn write_optional_type(&mut self, optional: &nodes::OptionalType) {
1208 let inner_type = optional.get_inner_type();
1209 if nodes::OptionalType::needs_parentheses(inner_type) {
1210 self.write_type_in_parentheses(inner_type);
1211 } else {
1212 self.write_type(inner_type);
1213 }
1214 self.push_char('?');
1215 }
1216
1217 fn write_intersection_type(&mut self, intersection: &nodes::IntersectionType) {
1218 let length = intersection.len();
1219 let last_index = length.saturating_sub(1);
1220 for (i, r#type) in intersection.iter_types().enumerate() {
1221 if i != 0 || intersection.has_leading_token() {
1222 self.push_char('&');
1223 }
1224
1225 let need_parentheses = if i == last_index {
1226 nodes::IntersectionType::last_needs_parentheses(r#type)
1227 } else {
1228 nodes::IntersectionType::intermediate_needs_parentheses(r#type)
1229 };
1230
1231 if need_parentheses {
1232 self.write_type_in_parentheses(r#type);
1233 } else {
1234 self.write_type(r#type);
1235 }
1236 }
1237 }
1238
1239 fn write_union_type(&mut self, union: &nodes::UnionType) {
1240 let length = union.len();
1241 let last_index = length.saturating_sub(1);
1242 for (i, r#type) in union.iter_types().enumerate() {
1243 if i != 0 || union.has_leading_token() {
1244 self.push_char('|');
1245 }
1246
1247 let need_parentheses = if i == last_index {
1248 nodes::UnionType::last_needs_parentheses(r#type)
1249 } else {
1250 nodes::UnionType::intermediate_needs_parentheses(r#type)
1251 };
1252
1253 if need_parentheses {
1254 self.write_type_in_parentheses(r#type);
1255 } else {
1256 self.write_type(r#type);
1257 }
1258 }
1259 }
1260
1261 fn write_type_pack(&mut self, type_pack: &nodes::TypePack) {
1262 self.push_char('(');
1263
1264 let last_index = type_pack.len().saturating_sub(1);
1265
1266 for (index, r#type) in type_pack.into_iter().enumerate() {
1267 self.write_type(r#type);
1268 if index != last_index {
1269 self.push_char(',');
1270 }
1271 }
1272
1273 if let Some(variadic_argument_type) = type_pack.get_variadic_type() {
1274 if !type_pack.is_empty() {
1275 self.push_char(',');
1276 }
1277 self.write_variadic_argument_type(variadic_argument_type);
1278 }
1279
1280 self.push_char(')');
1281 }
1282
1283 fn write_variadic_type_pack(&mut self, variadic_type_pack: &nodes::VariadicTypePack) {
1284 self.push_str("...");
1285 self.write_type(variadic_type_pack.get_type());
1286 }
1287
1288 fn write_generic_type_pack(&mut self, generic_type_pack: &nodes::GenericTypePack) {
1289 self.write_identifier(generic_type_pack.get_name());
1290 self.push_str("...");
1291 }
1292}