1#![allow(clippy::approx_constant)]
2use crate::frontend::ast::{Expr, ExprKind};
5use crate::quality::formatter_config::FormatterConfig;
6use anyhow::Result;
7
8pub struct Formatter {
9 config: FormatterConfig,
10 source: Option<String>,
11}
12
13impl Formatter {
14 pub fn new() -> Self {
25 Self::with_config(FormatterConfig::default())
26 }
27
28 pub fn with_config(config: FormatterConfig) -> Self {
40 Self {
41 config,
42 source: None,
43 }
44 }
45
46 pub fn set_source(&mut self, source: impl Into<String>) {
57 self.source = Some(source.into());
58 }
59 pub fn format(&self, ast: &Expr) -> Result<String> {
69 if self.should_ignore(ast) {
71 if let Some(original) = self.get_original_text(ast) {
72 return Ok(original);
73 }
74 }
75
76 if let ExprKind::Block(exprs) = &ast.kind {
78 let mut result = String::new();
79 for (i, expr) in exprs.iter().enumerate() {
80 if i > 0 {
81 result.push('\n');
82 }
83 result.push_str(&self.format_expr(expr, 0));
84 }
85 Ok(result)
86 } else {
87 Ok(self.format_expr(ast, 0))
89 }
90 }
91 fn format_type(ty_kind: &crate::frontend::ast::TypeKind) -> String {
92 use crate::frontend::ast::TypeKind;
93
94 match ty_kind {
95 TypeKind::Named(name) => name.clone(),
96 TypeKind::Generic { base, params } => {
97 let params_str = params
98 .iter()
99 .map(|t| Self::format_type(&t.kind))
100 .collect::<Vec<_>>()
101 .join(", ");
102 format!("{base}<{params_str}>")
103 }
104 TypeKind::Function { params, ret } => {
105 let params_str = params
106 .iter()
107 .map(|t| Self::format_type(&t.kind))
108 .collect::<Vec<_>>()
109 .join(", ");
110 format!("({}) -> {}", params_str, Self::format_type(&ret.kind))
111 }
112 TypeKind::Tuple(types) => {
113 format!(
114 "({})",
115 types
116 .iter()
117 .map(|t| Self::format_type(&t.kind))
118 .collect::<Vec<_>>()
119 .join(", ")
120 )
121 }
122 TypeKind::Array { elem_type, size } => {
123 format!("[{}; {}]", Self::format_type(&elem_type.kind), size)
124 }
125 _ => format!("{ty_kind:?}"),
126 }
127 }
128 fn should_ignore(&self, expr: &Expr) -> bool {
130 expr.leading_comments.iter().any(|comment| {
131 use crate::frontend::ast::CommentKind;
132 match &comment.kind {
133 CommentKind::Line(text) => {
134 let trimmed = text.trim();
135 trimmed == "ruchy-fmt-ignore" || trimmed == "ruchy-fmt-ignore-next"
136 }
137 _ => false,
138 }
139 })
140 }
141
142 fn get_original_text(&self, expr: &Expr) -> Option<String> {
144 self.source.as_ref().map(|src| {
145 let start = if expr.leading_comments.is_empty() {
147 expr.span.start
148 } else {
149 expr.leading_comments[0].span.start
150 };
151
152 let mut end = Self::find_rightmost_span_end(expr);
154
155 let bytes = src.as_bytes();
159
160 let mut brace_depth = 0;
162 let mut in_expression = false;
163
164 let mut scan_pos = start;
167 while scan_pos < bytes.len() {
169 while scan_pos < bytes.len()
171 && (bytes[scan_pos] == b' ' || bytes[scan_pos] == b'\t')
172 {
173 scan_pos += 1;
174 }
175 if scan_pos + 1 < bytes.len()
177 && bytes[scan_pos] == b'/'
178 && bytes[scan_pos + 1] == b'/'
179 {
180 while scan_pos < bytes.len() && bytes[scan_pos] != b'\n' {
182 scan_pos += 1;
183 }
184 if scan_pos < bytes.len() {
185 scan_pos += 1; }
187 } else {
188 break;
189 }
190 }
191 while scan_pos < bytes.len()
193 && (bytes[scan_pos] == b' ' || bytes[scan_pos] == b'\t' || bytes[scan_pos] == b'\n')
194 {
195 scan_pos += 1;
196 }
197 if scan_pos < bytes.len() && bytes[scan_pos] == b'{' {
199 brace_depth = 1;
200 in_expression = true;
201 scan_pos += 1;
202 }
203
204 if in_expression {
205 while scan_pos < bytes.len() && brace_depth > 0 {
207 if bytes[scan_pos] == b'{' {
208 brace_depth += 1;
209 } else if bytes[scan_pos] == b'}' {
210 brace_depth -= 1;
211 if brace_depth == 0 {
212 end = scan_pos + 1;
214 break;
215 }
216 }
217 scan_pos += 1;
218 }
219 } else {
220 while end < bytes.len() {
222 if bytes[end] == b'\n' {
223 break;
224 }
225 end += 1;
226 }
227 }
228
229 let start = start.min(src.len());
230 let end = end.min(src.len());
231 src[start..end].to_string()
232 })
233 }
234
235 fn find_rightmost_span_end(expr: &Expr) -> usize {
237 use ExprKind::{Binary, Block, Function, Let};
238 let mut max_end = expr.span.end;
239
240 match &expr.kind {
241 Let { value, body, .. } => {
242 max_end = max_end.max(Self::find_rightmost_span_end(value));
243 max_end = max_end.max(Self::find_rightmost_span_end(body));
244 }
245 Binary { left, right, .. } => {
246 max_end = max_end.max(Self::find_rightmost_span_end(left));
247 max_end = max_end.max(Self::find_rightmost_span_end(right));
248 }
249 Function { body, .. } => {
250 max_end = max_end.max(Self::find_rightmost_span_end(body));
252 }
253 Block(exprs) => {
254 if let Some(last) = exprs.last() {
256 max_end = max_end.max(Self::find_rightmost_span_end(last));
257 }
258 }
259 _ => {
260 }
263 }
264
265 max_end
266 }
267
268 fn format_expr(&self, expr: &Expr, indent: usize) -> String {
269 if self.should_ignore(expr) {
271 if let Some(original) = self.get_original_text(expr) {
273 return original;
274 }
275 }
277
278 let indent_str = if self.config.use_tabs {
279 "\t".repeat(indent)
280 } else {
281 " ".repeat(indent * self.config.indent_width)
282 };
283
284 let mut result = String::new();
286 for comment in &expr.leading_comments {
287 result.push_str(&self.format_comment(comment, indent));
288 result.push('\n');
289 }
290
291 let expr_str = match &expr.kind {
293 ExprKind::Literal(lit) => match lit {
294 crate::frontend::ast::Literal::Integer(n, _) => n.to_string(),
295 crate::frontend::ast::Literal::Float(f) => f.to_string(),
296 crate::frontend::ast::Literal::String(s) => {
297 format!("\"{}\"", s.replace('"', "\\\""))
298 }
299 crate::frontend::ast::Literal::Bool(b) => b.to_string(),
300 crate::frontend::ast::Literal::Char(c) => format!("'{c}'"),
301 crate::frontend::ast::Literal::Byte(b) => format!("b'{}'", *b as char),
302 crate::frontend::ast::Literal::Unit => "()".to_string(),
303 crate::frontend::ast::Literal::Null => "null".to_string(),
304 crate::frontend::ast::Literal::Atom(s) => format!(":{s}"),
305 },
306 ExprKind::Identifier(name) => name.clone(),
307 ExprKind::Let {
308 name, value, body, ..
309 } => {
310 let is_sequential_statement = matches!(
315 body.kind,
316 ExprKind::Literal(crate::frontend::ast::Literal::Unit)
317 | ExprKind::Block(_)
318 | ExprKind::Call { .. }
319 | ExprKind::MethodCall { .. }
320 | ExprKind::Let { .. } );
322
323 if is_sequential_statement {
324 let mut result = format!("let {} = {}", name, self.format_expr(value, indent));
326
327 if let ExprKind::Block(body_exprs) = &body.kind {
330 let indent_str = if self.config.use_tabs {
331 "\t".repeat(indent)
332 } else {
333 " ".repeat(indent * self.config.indent_width)
334 };
335 for expr in body_exprs {
336 result.push('\n');
337 result.push_str(&indent_str);
338 result.push_str(&self.format_expr(expr, indent));
339 }
340 } else if !matches!(
341 body.kind,
342 ExprKind::Literal(crate::frontend::ast::Literal::Unit)
343 ) {
344 let indent_str = if self.config.use_tabs {
348 "\t".repeat(indent)
349 } else {
350 " ".repeat(indent * self.config.indent_width)
351 };
352 result.push('\n');
353 result.push_str(&indent_str);
354 result.push_str(&self.format_expr(body, indent));
355 }
356 result
359 } else {
360 format!(
363 "let {} = {} in {}",
364 name,
365 self.format_expr(value, indent),
366 self.format_expr(body, indent)
367 )
368 }
369 }
370 ExprKind::Binary { left, op, right } => {
371 format!(
373 "{} {} {}",
374 self.format_expr(left, indent),
375 op, self.format_expr(right, indent)
377 )
378 }
379 ExprKind::Block(exprs) => {
380 let mut result = String::from("{\n");
381 let inner_indent_str = if self.config.use_tabs {
382 "\t".repeat(indent + 1)
383 } else {
384 " ".repeat((indent + 1) * self.config.indent_width)
385 };
386 for expr in exprs {
387 result.push_str(&format!(
388 "{}{}\n",
389 inner_indent_str,
390 self.format_expr(expr, indent + 1)
391 ));
392 }
393 result.push_str(&format!("{indent_str}}}"));
394 result
395 }
396 ExprKind::Function {
397 name,
398 params,
399 return_type,
400 body,
401 ..
402 } => {
403 let mut result = format!("fun {name}");
404 result.push('(');
406 for (i, param) in params.iter().enumerate() {
407 if i > 0 {
408 result.push_str(", ");
409 }
410 if let crate::frontend::ast::Pattern::Identifier(param_name) = ¶m.pattern {
411 result.push_str(param_name);
412 if let crate::frontend::ast::TypeKind::Named(type_name) = ¶m.ty.kind {
414 if type_name != "Any" {
415 result.push_str(": ");
416 result.push_str(type_name);
417 }
418 } else {
419 result.push_str(": ");
420 result.push_str(&Self::format_type(¶m.ty.kind));
421 }
422 }
423 }
424 result.push(')');
425 if let Some(ret_ty) = return_type {
427 result.push_str(" -> ");
428 result.push_str(&Self::format_type(&ret_ty.kind));
429 }
430 result.push(' ');
431 result.push_str(&self.format_expr(body.as_ref(), indent));
432 result
433 }
434 ExprKind::If {
435 condition,
436 then_branch,
437 else_branch,
438 } => {
439 let mut result = "if ".to_string();
440 result.push_str(&self.format_expr(condition, indent));
441 result.push(' ');
442 result.push_str(&self.format_expr(then_branch, indent));
443 if let Some(else_expr) = else_branch {
444 result.push_str(" else ");
445 result.push_str(&self.format_expr(else_expr, indent));
446 }
447 result
448 }
449 ExprKind::Call { func, args } => {
450 let mut result = self.format_expr(func, indent);
451 result.push('(');
452 for (i, arg) in args.iter().enumerate() {
453 if i > 0 {
454 result.push_str(", ");
455 }
456 result.push_str(&self.format_expr(arg, indent));
457 }
458 result.push(')');
459 result
460 }
461 ExprKind::MethodCall {
462 receiver,
463 method,
464 args,
465 ..
466 } => {
467 let mut result = self.format_expr(receiver, indent);
468 result.push('.');
469 result.push_str(method);
470 result.push('(');
471 for (i, arg) in args.iter().enumerate() {
472 if i > 0 {
473 result.push_str(", ");
474 }
475 result.push_str(&self.format_expr(arg, indent));
476 }
477 result.push(')');
478 result
479 }
480 ExprKind::For {
481 var,
482 pattern,
483 iter,
484 body,
485 ..
486 } => {
487 let mut result = "for ".to_string();
488 if let Some(pat) = pattern {
489 if let crate::frontend::ast::Pattern::Identifier(name) = pat {
490 result.push_str(name);
491 } else {
492 result.push_str(&format!("{pat:?}"));
493 }
494 } else {
495 result.push_str(var);
496 }
497 result.push_str(" in ");
498 result.push_str(&self.format_expr(iter, indent));
499 result.push(' ');
500 result.push_str(&self.format_expr(body, indent));
501 result
502 }
503 ExprKind::IndexAccess { object, index } => {
505 format!(
506 "{}[{}]",
507 self.format_expr(object, indent),
508 self.format_expr(index, indent)
509 )
510 }
511 ExprKind::Assign { target, value } => {
513 format!(
514 "{} = {}",
515 self.format_expr(target, indent),
516 self.format_expr(value, indent)
517 )
518 }
519 ExprKind::Return { value } => {
521 if let Some(val) = value {
522 format!("return {}", self.format_expr(val, indent))
523 } else {
524 "return".to_string()
525 }
526 }
527 ExprKind::FieldAccess { object, field } => {
529 format!("{}.{}", self.format_expr(object, indent), field)
530 }
531 ExprKind::While {
533 condition, body, ..
534 } => {
535 format!(
536 "while {} {}",
537 self.format_expr(condition, indent),
538 self.format_expr(body, indent)
539 )
540 }
541 ExprKind::Break { value, .. } => {
543 if let Some(val) = value {
544 format!("break {}", self.format_expr(val, indent))
545 } else {
546 "break".to_string()
547 }
548 }
549 ExprKind::Continue { .. } => "continue".to_string(),
551 ExprKind::Range {
553 start,
554 end,
555 inclusive,
556 } => {
557 let op = if *inclusive { "..=" } else { ".." };
558 format!(
559 "{}{}{}",
560 self.format_expr(start, indent),
561 op,
562 self.format_expr(end, indent)
563 )
564 }
565 ExprKind::Unary { op, operand } => {
567 format!("{}{}", op, self.format_expr(operand, indent))
568 }
569 ExprKind::List(items) => {
571 let formatted_items: Vec<String> = items
572 .iter()
573 .map(|item| self.format_expr(item, indent))
574 .collect();
575 format!("[{}]", formatted_items.join(", "))
576 }
577 ExprKind::Tuple(items) => {
579 let formatted_items: Vec<String> = items
580 .iter()
581 .map(|item| self.format_expr(item, indent))
582 .collect();
583 format!("({})", formatted_items.join(", "))
584 }
585 ExprKind::Match { expr, arms } => {
587 let mut result = format!("match {} {{\n", self.format_expr(expr, indent));
588 for arm in arms {
589 let pattern_str = format!("{:?}", arm.pattern); result.push_str(&format!(
591 "{} {} => {},\n",
592 " ".repeat(indent * self.config.indent_width),
593 pattern_str,
594 self.format_expr(&arm.body, indent + 1)
595 ));
596 }
597 result.push_str(&format!(
598 "{}}}",
599 " ".repeat(indent * self.config.indent_width)
600 ));
601 result
602 }
603 ExprKind::CompoundAssign { target, op, value } => {
605 format!(
606 "{} {}= {}",
607 self.format_expr(target, indent),
608 op,
609 self.format_expr(value, indent)
610 )
611 }
612 ExprKind::Lambda { params, body } => {
614 let params_str = params
615 .iter()
616 .map(|p| self.format_pattern(&p.pattern))
617 .collect::<Vec<_>>()
618 .join(", ");
619 format!("|{}| {}", params_str, self.format_expr(body, indent))
620 }
621 ExprKind::ObjectLiteral { fields } => {
622 if fields.is_empty() {
623 "{}".to_string()
624 } else {
625 let fields_str = fields
626 .iter()
627 .map(|f| match f {
628 crate::frontend::ast::ObjectField::KeyValue { key, value } => {
629 format!("{}: {}", key, self.format_expr(value, indent))
630 }
631 crate::frontend::ast::ObjectField::Spread { expr } => {
632 format!("...{}", self.format_expr(expr, indent))
633 }
634 })
635 .collect::<Vec<_>>()
636 .join(", ");
637 format!("{{ {fields_str} }}")
638 }
639 }
640 ExprKind::StructLiteral { name, fields, base } => {
641 let fields_str = fields
642 .iter()
643 .map(|(key, val)| format!("{}: {}", key, self.format_expr(val, indent)))
644 .collect::<Vec<_>>()
645 .join(", ");
646
647 if let Some(base_expr) = base {
648 format!(
649 "{} {{ {}, ..{} }}",
650 name,
651 fields_str,
652 self.format_expr(base_expr, indent)
653 )
654 } else {
655 format!("{name} {{ {fields_str} }}")
656 }
657 }
658 ExprKind::Ternary {
659 condition,
660 true_expr,
661 false_expr,
662 } => {
663 format!(
664 "{} ? {} : {}",
665 self.format_expr(condition, indent),
666 self.format_expr(true_expr, indent),
667 self.format_expr(false_expr, indent)
668 )
669 }
670 ExprKind::Throw { expr } => {
671 format!("throw {}", self.format_expr(expr, indent))
672 }
673 ExprKind::TryCatch {
674 try_block,
675 catch_clauses,
676 finally_block,
677 } => {
678 let mut result = format!("try {}", self.format_expr(try_block, indent));
679
680 for catch_clause in catch_clauses {
681 result.push_str(&format!(
682 " catch ({}) {}",
683 self.format_pattern(&catch_clause.pattern),
684 self.format_expr(&catch_clause.body, indent)
685 ));
686 }
687
688 if let Some(finally) = finally_block {
689 result.push_str(&format!(" finally {}", self.format_expr(finally, indent)));
690 }
691
692 result
693 }
694 ExprKind::Await { expr } => {
695 format!("await {}", self.format_expr(expr, indent))
696 }
697 ExprKind::AsyncBlock { body } => {
698 format!("async {}", self.format_expr(body, indent))
699 }
700 ExprKind::TypeCast { expr, target_type } => {
701 format!("{} as {}", self.format_expr(expr, indent), target_type)
702 }
703
704 ExprKind::ArrayInit { value, size } => {
706 format!(
707 "[{}; {}]",
708 self.format_expr(value, indent),
709 self.format_expr(size, indent)
710 )
711 }
712 ExprKind::Ok { value } => {
713 format!("Ok({})", self.format_expr(value, indent))
714 }
715 ExprKind::Err { error } => {
716 format!("Err({})", self.format_expr(error, indent))
717 }
718 ExprKind::Some { value } => {
719 format!("Some({})", self.format_expr(value, indent))
720 }
721 ExprKind::None => "None".to_string(),
722 ExprKind::Try { expr } => {
723 format!("{}?", self.format_expr(expr, indent))
724 }
725 ExprKind::Spawn { actor } => {
726 format!("spawn {}", self.format_expr(actor, indent))
727 }
728 ExprKind::AsyncLambda { params, body } => {
729 let params_str = params.join(", ");
730 format!("async |{}| {}", params_str, self.format_expr(body, indent))
731 }
732 ExprKind::IfLet {
733 pattern,
734 expr,
735 then_branch,
736 else_branch,
737 } => {
738 let mut result = format!(
739 "if let {} = {} {}",
740 self.format_pattern(pattern),
741 self.format_expr(expr, indent),
742 self.format_expr(then_branch, indent)
743 );
744 if let Some(else_expr) = else_branch {
745 result.push_str(&format!(" else {}", self.format_expr(else_expr, indent)));
746 }
747 result
748 }
749 ExprKind::OptionalFieldAccess { object, field } => {
750 format!("{}?.{}", self.format_expr(object, indent), field)
751 }
752 ExprKind::Slice { object, start, end } => {
753 let start_str = start
754 .as_ref()
755 .map_or(String::new(), |e| self.format_expr(e, indent));
756 let end_str = end
757 .as_ref()
758 .map_or(String::new(), |e| self.format_expr(e, indent));
759 format!(
760 "{}[{}..{}]",
761 self.format_expr(object, indent),
762 start_str,
763 end_str
764 )
765 }
766
767 ExprKind::Struct {
769 name,
770 type_params,
771 fields,
772 is_pub,
773 ..
774 } => {
775 let pub_str = if *is_pub { "pub " } else { "" };
776 let type_params_str = if type_params.is_empty() {
777 String::new()
778 } else {
779 format!("<{}>", type_params.join(", "))
780 };
781 let fields_str = fields
782 .iter()
783 .map(|f| format!("{}: {}", f.name, Self::format_type(&f.ty.kind)))
784 .collect::<Vec<_>>()
785 .join(", ");
786 format!("{pub_str}struct {name}{type_params_str} {{ {fields_str} }}")
787 }
788 ExprKind::TupleStruct {
789 name,
790 type_params,
791 fields,
792 is_pub,
793 ..
794 } => {
795 let pub_str = if *is_pub { "pub " } else { "" };
796 let type_params_str = if type_params.is_empty() {
797 String::new()
798 } else {
799 format!("<{}>", type_params.join(", "))
800 };
801 let fields_str = fields
802 .iter()
803 .map(|ty| Self::format_type(&ty.kind))
804 .collect::<Vec<_>>()
805 .join(", ");
806 format!("{pub_str}struct {name}{type_params_str}({fields_str})")
807 }
808 ExprKind::Enum {
809 name,
810 type_params,
811 variants,
812 is_pub,
813 } => {
814 let pub_str = if *is_pub { "pub " } else { "" };
815 let type_params_str = if type_params.is_empty() {
816 String::new()
817 } else {
818 format!("<{}>", type_params.join(", "))
819 };
820 let variants_str = variants
821 .iter()
822 .map(|v| self.format_enum_variant(v))
823 .collect::<Vec<_>>()
824 .join(", ");
825 format!("{pub_str}enum {name}{type_params_str} {{ {variants_str} }}")
826 }
827 ExprKind::Trait {
828 name,
829 type_params,
830 methods,
831 is_pub,
832 ..
833 } => {
834 let pub_str = if *is_pub { "pub " } else { "" };
835 let type_params_str = if type_params.is_empty() {
836 String::new()
837 } else {
838 format!("<{}>", type_params.join(", "))
839 };
840 let methods_str = methods
841 .iter()
842 .map(|m| self.format_trait_method(m))
843 .collect::<Vec<_>>()
844 .join(" ");
845 format!("{pub_str}trait {name}{type_params_str} {{ {methods_str} }}")
846 }
847 ExprKind::Impl {
848 type_params,
849 trait_name,
850 for_type,
851 methods,
852 ..
853 } => {
854 let type_params_str = if type_params.is_empty() {
855 String::new()
856 } else {
857 format!("<{}>", type_params.join(", "))
858 };
859 let trait_part = trait_name
860 .as_ref()
861 .map_or(String::new(), |t| format!("{t} for "));
862 let methods_str = methods
863 .iter()
864 .map(|m| self.format_impl_method(m))
865 .collect::<Vec<_>>()
866 .join(" ");
867 format!("impl{type_params_str} {trait_part}{for_type} {{ {methods_str} }}")
868 }
869 ExprKind::Class {
870 name,
871 type_params,
872 fields,
873 ..
874 } => {
875 let type_params_str = if type_params.is_empty() {
876 String::new()
877 } else {
878 format!("<{}>", type_params.join(", "))
879 };
880 let fields_str = fields
881 .iter()
882 .map(|f| format!("{}: {}", f.name, Self::format_type(&f.ty.kind)))
883 .collect::<Vec<_>>()
884 .join(", ");
885 format!("class {name}{type_params_str} {{ {fields_str} }}")
886 }
887 ExprKind::Module { name, body } => {
888 format!("mod {} {}", name, self.format_expr(body, indent))
889 }
890 ExprKind::ModuleDeclaration { name } => {
891 format!("mod {name};")
893 }
894 ExprKind::Import { module, items } => {
895 if let Some(item_list) = items {
896 format!("import {}::{{{}}}", module, item_list.join(", "))
897 } else {
898 format!("import {module}")
899 }
900 }
901 ExprKind::Export { expr, is_default } => {
902 if *is_default {
903 format!("export default {}", self.format_expr(expr, indent))
904 } else {
905 format!("export {}", self.format_expr(expr, indent))
906 }
907 }
908 ExprKind::LetPattern {
909 pattern,
910 value,
911 body,
912 ..
913 } => {
914 format!(
915 "let {} = {} in {}",
916 self.format_pattern(pattern),
917 self.format_expr(value, indent),
918 self.format_expr(body, indent)
919 )
920 }
921 ExprKind::WhileLet {
922 pattern,
923 expr,
924 body,
925 ..
926 } => {
927 format!(
928 "while let {} = {} {}",
929 self.format_pattern(pattern),
930 self.format_expr(expr, indent),
931 self.format_expr(body, indent)
932 )
933 }
934 ExprKind::StringInterpolation { parts } => {
935 let parts_str = parts
936 .iter()
937 .map(|part| match part {
938 crate::frontend::ast::StringPart::Text(s) => s.clone(),
939 crate::frontend::ast::StringPart::Expr(e) => {
940 format!("{{{}}}", self.format_expr(e, indent))
941 }
942 crate::frontend::ast::StringPart::ExprWithFormat { expr, format_spec } => {
943 format!("{{{}:{}}}", self.format_expr(expr, indent), format_spec)
944 }
945 })
946 .collect::<String>();
947 format!("f\"{parts_str}\"")
948 }
949 ExprKind::Actor {
950 name,
951 state,
952 handlers,
953 } => {
954 let state_str = state
955 .iter()
956 .map(|f| format!("{}: {}", f.name, Self::format_type(&f.ty.kind)))
957 .collect::<Vec<_>>()
958 .join(", ");
959 let handlers_str = handlers
960 .iter()
961 .map(|h| format!("handle {}", h.message_type))
962 .collect::<Vec<_>>()
963 .join(" ");
964 format!("actor {name} {{ {state_str} {handlers_str} }}")
965 }
966 ExprKind::Effect { name, operations } => {
968 let ops_str = operations
969 .iter()
970 .map(|op| {
971 let params_str = op
972 .params
973 .iter()
974 .map(|p| format!("{:?}: {:?}", p.pattern, p.ty))
975 .collect::<Vec<_>>()
976 .join(", ");
977 let ret_str = op
978 .return_type
979 .as_ref()
980 .map(|t| format!(" -> {:?}", t.kind))
981 .unwrap_or_default();
982 format!("{}({}){}", op.name, params_str, ret_str)
983 })
984 .collect::<Vec<_>>()
985 .join(", ");
986 format!("effect {name} {{ {ops_str} }}")
987 }
988 ExprKind::Handle { expr, handlers } => {
990 let expr_str = self.format_expr(expr, indent);
991 let handlers_str = handlers
992 .iter()
993 .map(|h| {
994 let params_str = if h.params.is_empty() {
995 String::new()
996 } else {
997 format!(
998 "({})",
999 h.params
1000 .iter()
1001 .map(|p| format!("{p:?}"))
1002 .collect::<Vec<_>>()
1003 .join(", ")
1004 )
1005 };
1006 let body_str = self.format_expr(&h.body, indent);
1007 format!("{}{} => {}", h.operation, params_str, body_str)
1008 })
1009 .collect::<Vec<_>>()
1010 .join(", ");
1011 format!("handle {expr_str} with {{ {handlers_str} }}")
1012 }
1013 ExprKind::Send { actor, message } => {
1014 format!(
1015 "send({}, {})",
1016 self.format_expr(actor, indent),
1017 self.format_expr(message, indent)
1018 )
1019 }
1020 ExprKind::Loop { body, .. } => {
1022 format!(
1023 "loop {{\n{}\n{}}}",
1024 self.format_expr(body, indent + 1),
1025 " ".repeat(indent * self.config.indent_width)
1026 )
1027 }
1028 ExprKind::Pipeline { expr, stages } => {
1029 let mut result = self.format_expr(expr, indent);
1031 for stage in stages {
1032 result.push_str(" |> ");
1033 result.push_str(&self.format_expr(&stage.op, indent));
1034 }
1035 result
1036 }
1037 ExprKind::PreIncrement { target } => {
1039 format!("++{}", self.format_expr(target, indent))
1040 }
1041 ExprKind::PostIncrement { target } => {
1042 format!("{}++", self.format_expr(target, indent))
1043 }
1044 ExprKind::PreDecrement { target } => {
1045 format!("--{}", self.format_expr(target, indent))
1046 }
1047 ExprKind::PostDecrement { target } => {
1048 format!("{}--", self.format_expr(target, indent))
1049 }
1050 ExprKind::ActorSend { actor, message } => {
1051 format!(
1052 "{} <- {}",
1053 self.format_expr(actor, indent),
1054 self.format_expr(message, indent)
1055 )
1056 }
1057 ExprKind::ActorQuery { actor, message } => {
1058 format!(
1059 "{} <? {}",
1060 self.format_expr(actor, indent),
1061 self.format_expr(message, indent)
1062 )
1063 }
1064 ExprKind::Ask { actor, message, .. } => {
1065 format!(
1067 "ask {} {}",
1068 self.format_expr(actor, indent),
1069 self.format_expr(message, indent)
1070 )
1071 }
1072 ExprKind::ListComprehension { element, clauses } => {
1073 let clauses_str = clauses
1074 .iter()
1075 .map(|clause| {
1076 let cond = clause
1077 .condition
1078 .as_ref()
1079 .map(|c| format!(" if {}", self.format_expr(c, indent)))
1080 .unwrap_or_default();
1081 format!(
1082 "{} in {}{}",
1083 clause.variable,
1084 self.format_expr(&clause.iterable, indent),
1085 cond
1086 )
1087 })
1088 .collect::<Vec<_>>()
1089 .join(", ");
1090 format!(
1091 "[{} for {}]",
1092 self.format_expr(element, indent),
1093 clauses_str
1094 )
1095 }
1096 ExprKind::DictComprehension {
1097 key,
1098 value,
1099 clauses,
1100 } => {
1101 let clauses_str = clauses
1102 .iter()
1103 .map(|clause| {
1104 let cond = clause
1105 .condition
1106 .as_ref()
1107 .map(|c| format!(" if {}", self.format_expr(c, indent)))
1108 .unwrap_or_default();
1109 format!(
1110 "{} in {}{}",
1111 clause.variable,
1112 self.format_expr(&clause.iterable, indent),
1113 cond
1114 )
1115 })
1116 .collect::<Vec<_>>()
1117 .join(", ");
1118 format!(
1119 "{{{}: {} for {}}}",
1120 self.format_expr(key, indent),
1121 self.format_expr(value, indent),
1122 clauses_str
1123 )
1124 }
1125 ExprKind::SetComprehension { element, clauses } => {
1126 let clauses_str = clauses
1127 .iter()
1128 .map(|clause| {
1129 let cond = clause
1130 .condition
1131 .as_ref()
1132 .map(|c| format!(" if {}", self.format_expr(c, indent)))
1133 .unwrap_or_default();
1134 format!(
1135 "{} in {}{}",
1136 clause.variable,
1137 self.format_expr(&clause.iterable, indent),
1138 cond
1139 )
1140 })
1141 .collect::<Vec<_>>()
1142 .join(", ");
1143 format!(
1144 "{{{} for {}}}",
1145 self.format_expr(element, indent),
1146 clauses_str
1147 )
1148 }
1149 ExprKind::ImportAll { module, .. } => {
1150 format!("import {module}::*")
1151 }
1152 ExprKind::ImportDefault { module, name } => {
1153 format!("import default {name} from {module}")
1154 }
1155 ExprKind::ExportList { names } => {
1156 format!("export {{ {} }}", names.join(", "))
1157 }
1158 ExprKind::ExportDefault { expr } => {
1159 format!("export default {}", self.format_expr(expr, indent))
1160 }
1161 ExprKind::Command { program, args, .. } => {
1162 let full_cmd = if args.is_empty() {
1164 program.clone()
1165 } else {
1166 format!("{} {}", program, args.join(" "))
1167 };
1168 format!("`{full_cmd}`")
1169 }
1170 ExprKind::QualifiedName { module, name } => {
1172 format!("{module}::{name}")
1173 }
1174 ExprKind::TypeAlias { name, target_type } => {
1175 format!("type {} = {}", name, Self::format_type(&target_type.kind))
1176 }
1177 ExprKind::Spread { expr } => {
1178 format!("...{}", self.format_expr(expr, indent))
1179 }
1180 ExprKind::OptionalMethodCall {
1181 receiver,
1182 method,
1183 args,
1184 } => {
1185 let args_str = args
1186 .iter()
1187 .map(|arg| self.format_expr(arg, indent))
1188 .collect::<Vec<_>>()
1189 .join(", ");
1190 format!(
1191 "{}?.{}({})",
1192 self.format_expr(receiver, indent),
1193 method,
1194 args_str
1195 )
1196 }
1197 ExprKind::Extension {
1198 target_type,
1199 methods,
1200 } => {
1201 let indent_str = " ".repeat(indent * self.config.indent_width);
1202 let methods_str = methods
1203 .iter()
1204 .map(|method| {
1205 let params_str = method
1206 .params
1207 .iter()
1208 .map(|p| self.format_pattern(&p.pattern))
1209 .collect::<Vec<_>>()
1210 .join(", ");
1211 format!(
1212 "{} fun {}({}) {{ }}",
1213 indent_str, method.name, params_str
1214 )
1215 })
1216 .collect::<Vec<_>>()
1217 .join("\n");
1218 format!("extension {target_type} {{\n{methods_str}\n{indent_str}}}")
1219 }
1220 ExprKind::ReExport { items, module } => {
1221 format!("export {{ {} }} from {}", items.join(", "), module)
1222 }
1223 ExprKind::Macro { name, args } => {
1224 let args_str = args
1225 .iter()
1226 .map(|arg| self.format_expr(arg, indent))
1227 .collect::<Vec<_>>()
1228 .join(", ");
1229 format!("macro {name}({args_str}) {{ }}")
1230 }
1231 ExprKind::MacroInvocation { name, args } => {
1232 let args_str = args
1233 .iter()
1234 .map(|arg| self.format_expr(arg, indent))
1235 .collect::<Vec<_>>()
1236 .join(", ");
1237 format!("{name}!({args_str})")
1238 }
1239 ExprKind::VecRepeat { value, count } => {
1241 let value_str = self.format_expr(value, indent);
1242 let count_str = self.format_expr(count, indent);
1243 format!("vec![{value_str}; {count_str}]")
1244 }
1245 ExprKind::DataFrame { columns } => {
1246 let columns_str = columns
1247 .iter()
1248 .map(|col| {
1249 let values_str = col
1250 .values
1251 .iter()
1252 .map(|v| self.format_expr(v, indent))
1253 .collect::<Vec<_>>()
1254 .join(", ");
1255 format!("\"{}\" => [{}]", col.name, values_str)
1256 })
1257 .collect::<Vec<_>>()
1258 .join(", ");
1259 format!("df![{columns_str}]")
1260 }
1261 ExprKind::DataFrameOperation { source, operation } => {
1262 format!("{}.{:?}", self.format_expr(source, indent), operation)
1264 }
1265 ExprKind::Lazy { expr } => {
1266 format!("lazy {}", self.format_expr(expr, indent))
1267 }
1268 ExprKind::Set(_) => {
1269 format!("/* UNIMPLEMENTED: {:?} */", expr.kind)
1272 }
1273 };
1274
1275 result.push_str(&expr_str);
1277
1278 if let Some(trailing) = &expr.trailing_comment {
1280 result.push(' ');
1281 result.push_str(&self.format_comment(trailing, 0)); }
1283
1284 result
1285 }
1286
1287 fn format_comment(&self, comment: &crate::frontend::ast::Comment, indent: usize) -> String {
1289 let indent_str = if self.config.use_tabs {
1290 "\t".repeat(indent)
1291 } else {
1292 " ".repeat(indent * self.config.indent_width)
1293 };
1294
1295 match &comment.kind {
1296 crate::frontend::ast::CommentKind::Line(text) => {
1297 format!("{indent_str}//{text}")
1299 }
1300 crate::frontend::ast::CommentKind::Doc(text) => {
1301 format!("{indent_str}///{text}")
1303 }
1304 crate::frontend::ast::CommentKind::Block(text) => {
1305 format!("{indent_str}/*{text}*/")
1307 }
1308 }
1309 }
1310
1311 fn format_pattern(&self, pattern: &crate::frontend::ast::Pattern) -> String {
1313 use crate::frontend::ast::Pattern;
1314
1315 match pattern {
1316 Pattern::Wildcard => "_".to_string(),
1317 Pattern::Literal(lit) => self.format_literal(lit),
1318 Pattern::Identifier(name) => name.clone(),
1319 Pattern::QualifiedName(parts) => parts.join("::"),
1320 Pattern::Tuple(patterns) => {
1321 let inner = patterns
1322 .iter()
1323 .map(|p| self.format_pattern(p))
1324 .collect::<Vec<_>>()
1325 .join(", ");
1326 format!("({inner})")
1327 }
1328 Pattern::List(patterns) => {
1329 let inner = patterns
1330 .iter()
1331 .map(|p| self.format_pattern(p))
1332 .collect::<Vec<_>>()
1333 .join(", ");
1334 format!("[{inner}]")
1335 }
1336 Pattern::Struct {
1337 name,
1338 fields,
1339 has_rest,
1340 } => {
1341 let fields_str = fields
1342 .iter()
1343 .map(|f| self.format_struct_pattern_field(f))
1344 .collect::<Vec<_>>()
1345 .join(", ");
1346 if *has_rest {
1347 format!("{name} {{ {fields_str}, .. }}")
1348 } else {
1349 format!("{name} {{ {fields_str} }}")
1350 }
1351 }
1352 Pattern::TupleVariant { path, patterns } => {
1353 let path_str = path.join("::");
1354 let patterns_str = patterns
1355 .iter()
1356 .map(|p| self.format_pattern(p))
1357 .collect::<Vec<_>>()
1358 .join(", ");
1359 format!("{path_str}({patterns_str})")
1360 }
1361 Pattern::Range {
1362 start,
1363 end,
1364 inclusive,
1365 } => {
1366 let op = if *inclusive { "..=" } else { ".." };
1367 format!(
1368 "{}{}{}",
1369 self.format_pattern(start),
1370 op,
1371 self.format_pattern(end)
1372 )
1373 }
1374 Pattern::Or(patterns) => patterns
1375 .iter()
1376 .map(|p| self.format_pattern(p))
1377 .collect::<Vec<_>>()
1378 .join(" | "),
1379 Pattern::Rest => "..".to_string(),
1380 Pattern::RestNamed(name) => format!("..{name}"),
1381 Pattern::AtBinding { name, pattern } => {
1382 format!("{} @ {}", name, self.format_pattern(pattern))
1383 }
1384 Pattern::WithDefault { pattern, default } => {
1385 format!(
1386 "{} = {}",
1387 self.format_pattern(pattern),
1388 self.format_expr(default, 0)
1389 )
1390 }
1391 Pattern::Mut(pattern) => {
1392 format!("mut {}", self.format_pattern(pattern))
1393 }
1394 Pattern::Ok(pattern) => {
1395 format!("Ok({})", self.format_pattern(pattern))
1396 }
1397 Pattern::Err(pattern) => {
1398 format!("Err({})", self.format_pattern(pattern))
1399 }
1400 Pattern::Some(pattern) => {
1401 format!("Some({})", self.format_pattern(pattern))
1402 }
1403 Pattern::None => "None".to_string(),
1404 }
1405 }
1406
1407 fn format_struct_pattern_field(
1409 &self,
1410 field: &crate::frontend::ast::StructPatternField,
1411 ) -> String {
1412 if let Some(pattern) = &field.pattern {
1413 format!("{}: {}", field.name, self.format_pattern(pattern))
1414 } else {
1415 field.name.clone()
1417 }
1418 }
1419
1420 fn format_literal(&self, literal: &crate::frontend::ast::Literal) -> String {
1422 use crate::frontend::ast::Literal;
1423
1424 match literal {
1425 Literal::Integer(val, suffix) => {
1426 if let Some(suffix) = suffix {
1427 format!("{val}{suffix}")
1428 } else {
1429 val.to_string()
1430 }
1431 }
1432 Literal::Float(val) => val.to_string(),
1433 Literal::String(s) => format!("\"{s}\""),
1434 Literal::Bool(b) => b.to_string(),
1435 Literal::Char(c) => format!("'{c}'"),
1436 Literal::Byte(b) => format!("{b}u8"),
1437 crate::frontend::ast::Literal::Unit => "()".to_string(),
1438 crate::frontend::ast::Literal::Null => "null".to_string(),
1439 crate::frontend::ast::Literal::Atom(s) => format!(":{s}"),
1440 }
1441 }
1442 fn format_enum_variant(&self, variant: &crate::frontend::ast::EnumVariant) -> String {
1444 use crate::frontend::ast::EnumVariantKind;
1445
1446 match &variant.kind {
1447 EnumVariantKind::Unit => variant.name.clone(),
1448 EnumVariantKind::Tuple(types) => {
1449 let types_str = types
1450 .iter()
1451 .map(|t| Self::format_type(&t.kind))
1452 .collect::<Vec<_>>()
1453 .join(", ");
1454 format!("{}({})", variant.name, types_str)
1455 }
1456 EnumVariantKind::Struct(fields) => {
1457 let fields_str = fields
1458 .iter()
1459 .map(|f| format!("{}: {}", f.name, Self::format_type(&f.ty.kind)))
1460 .collect::<Vec<_>>()
1461 .join(", ");
1462 format!("{} {{ {} }}", variant.name, fields_str)
1463 }
1464 }
1465 }
1466
1467 fn format_trait_method(&self, method: &crate::frontend::ast::TraitMethod) -> String {
1469 let params_str = method
1470 .params
1471 .iter()
1472 .map(|p| {
1473 format!(
1474 "{}: {}",
1475 self.format_pattern(&p.pattern),
1476 Self::format_type(&p.ty.kind)
1477 )
1478 })
1479 .collect::<Vec<_>>()
1480 .join(", ");
1481 let return_str = method.return_type.as_ref().map_or(String::new(), |t| {
1482 format!(" -> {}", Self::format_type(&t.kind))
1483 });
1484 format!("fun {}({}){}; ", method.name, params_str, return_str)
1485 }
1486
1487 fn format_impl_method(&self, method: &crate::frontend::ast::ImplMethod) -> String {
1489 let params_str = method
1490 .params
1491 .iter()
1492 .map(|p| {
1493 format!(
1494 "{}: {}",
1495 self.format_pattern(&p.pattern),
1496 Self::format_type(&p.ty.kind)
1497 )
1498 })
1499 .collect::<Vec<_>>()
1500 .join(", ");
1501 let return_str = method.return_type.as_ref().map_or(String::new(), |t| {
1502 format!(" -> {}", Self::format_type(&t.kind))
1503 });
1504 format!(
1505 "fun {}({}){} {}",
1506 method.name,
1507 params_str,
1508 return_str,
1509 self.format_expr(&method.body, 0)
1510 )
1511 }
1512}
1513impl Default for Formatter {
1514 fn default() -> Self {
1515 Self::new()
1516 }
1517}
1518#[cfg(test)]
1519mod tests {
1520 use super::*;
1521 use crate::frontend::ast::*;
1522
1523 fn create_simple_literal(value: i64) -> Expr {
1524 Expr::new(
1525 ExprKind::Literal(Literal::Integer(value, None)),
1526 Default::default(),
1527 )
1528 }
1529
1530 fn create_identifier(name: &str) -> Expr {
1531 Expr::new(ExprKind::Identifier(name.to_string()), Default::default())
1532 }
1533
1534 #[test]
1535 fn test_formatter_new() {
1536 let formatter = Formatter::new();
1537 assert_eq!(formatter.config.indent_width, 4);
1538 assert!(!formatter.config.use_tabs);
1539 }
1540
1541 #[test]
1542 fn test_formatter_default() {
1543 let formatter = Formatter::default();
1544 assert_eq!(formatter.config.indent_width, 4);
1545 assert!(!formatter.config.use_tabs);
1546 }
1547
1548 #[test]
1549 fn test_format_integer_literal() {
1550 let formatter = Formatter::new();
1551 let expr = create_simple_literal(42);
1552 let result = formatter
1553 .format(&expr)
1554 .expect("operation should succeed in test");
1555 assert_eq!(result, "42");
1556 }
1557
1558 #[test]
1559 fn test_format_float_literal() {
1560 let formatter = Formatter::new();
1561 let expr = Expr::new(ExprKind::Literal(Literal::Float(3.15)), Default::default());
1562 let result = formatter
1563 .format(&expr)
1564 .expect("operation should succeed in test");
1565 assert_eq!(result, "3.15");
1566 }
1567
1568 #[test]
1569 fn test_format_string_literal() {
1570 let formatter = Formatter::new();
1571 let expr = Expr::new(
1572 ExprKind::Literal(Literal::String("hello".to_string())),
1573 Default::default(),
1574 );
1575 let result = formatter
1576 .format(&expr)
1577 .expect("operation should succeed in test");
1578 assert_eq!(result, "\"hello\"");
1579 }
1580
1581 #[test]
1582 fn test_format_bool_literal() {
1583 let formatter = Formatter::new();
1584 let expr = Expr::new(ExprKind::Literal(Literal::Bool(true)), Default::default());
1585 let result = formatter
1586 .format(&expr)
1587 .expect("operation should succeed in test");
1588 assert_eq!(result, "true");
1589
1590 let expr = Expr::new(ExprKind::Literal(Literal::Bool(false)), Default::default());
1591 let result = formatter
1592 .format(&expr)
1593 .expect("operation should succeed in test");
1594 assert_eq!(result, "false");
1595 }
1596
1597 #[test]
1598 fn test_format_char_literal() {
1599 let formatter = Formatter::new();
1600 let expr = Expr::new(ExprKind::Literal(Literal::Char('a')), Default::default());
1601 let result = formatter
1602 .format(&expr)
1603 .expect("operation should succeed in test");
1604 assert_eq!(result, "'a'");
1605 }
1606
1607 #[test]
1608 fn test_format_unit_literal() {
1609 let formatter = Formatter::new();
1610 let expr = Expr::new(ExprKind::Literal(Literal::Unit), Default::default());
1611 let result = formatter
1612 .format(&expr)
1613 .expect("operation should succeed in test");
1614 assert_eq!(result, "()");
1615 }
1616
1617 #[test]
1618 fn test_format_identifier() {
1619 let formatter = Formatter::new();
1620 let expr = create_identifier("my_var");
1621 let result = formatter
1622 .format(&expr)
1623 .expect("operation should succeed in test");
1624 assert_eq!(result, "my_var");
1625 }
1626
1627 #[test]
1628 fn test_format_binary_expression() {
1629 let formatter = Formatter::new();
1630 let left = create_simple_literal(1);
1631 let right = create_simple_literal(2);
1632 let expr = Expr::new(
1633 ExprKind::Binary {
1634 left: Box::new(left),
1635 op: BinaryOp::Add,
1636 right: Box::new(right),
1637 },
1638 Default::default(),
1639 );
1640 let result = formatter
1641 .format(&expr)
1642 .expect("operation should succeed in test");
1643 assert_eq!(result, "1 + 2"); }
1645
1646 #[test]
1647 fn test_format_let_expression() {
1648 let formatter = Formatter::new();
1649 let value = create_simple_literal(42);
1650 let body = create_identifier("x");
1651 let expr = Expr::new(
1652 ExprKind::Let {
1653 name: "x".to_string(),
1654 value: Box::new(value),
1655 body: Box::new(body),
1656 type_annotation: Some(Type {
1657 kind: TypeKind::Named("Int".to_string()),
1658 span: Default::default(),
1659 }),
1660 is_mutable: false,
1661 else_block: None,
1662 },
1663 Default::default(),
1664 );
1665 let result = formatter
1666 .format(&expr)
1667 .expect("operation should succeed in test");
1668 assert_eq!(result, "let x = 42 in x");
1669 }
1670
1671 #[test]
1672 fn test_format_block_expression() {
1673 let formatter = Formatter::new();
1674 let exprs = vec![create_simple_literal(1), create_simple_literal(2)];
1675 let expr = Expr::new(ExprKind::Block(exprs), Default::default());
1676 let result = formatter
1677 .format(&expr)
1678 .expect("operation should succeed in test");
1679 assert!(!result.is_empty());
1681 }
1682
1683 #[test]
1684 fn test_format_if_expression() {
1685 let formatter = Formatter::new();
1686 let condition = Expr::new(ExprKind::Literal(Literal::Bool(true)), Default::default());
1687 let then_branch = create_simple_literal(1);
1688 let else_branch = create_simple_literal(2);
1689 let expr = Expr::new(
1690 ExprKind::If {
1691 condition: Box::new(condition),
1692 then_branch: Box::new(then_branch),
1693 else_branch: Some(Box::new(else_branch)),
1694 },
1695 Default::default(),
1696 );
1697 let result = formatter
1698 .format(&expr)
1699 .expect("operation should succeed in test");
1700 assert_eq!(result, "if true 1 else 2");
1701 }
1702
1703 #[test]
1704 fn test_format_if_without_else() {
1705 let formatter = Formatter::new();
1706 let condition = Expr::new(ExprKind::Literal(Literal::Bool(true)), Default::default());
1707 let then_branch = create_simple_literal(1);
1708 let expr = Expr::new(
1709 ExprKind::If {
1710 condition: Box::new(condition),
1711 then_branch: Box::new(then_branch),
1712 else_branch: None,
1713 },
1714 Default::default(),
1715 );
1716 let result = formatter
1717 .format(&expr)
1718 .expect("operation should succeed in test");
1719 assert_eq!(result, "if true 1");
1720 }
1721
1722 #[test]
1723 fn test_format_function_simple() {
1724 let formatter = Formatter::new();
1725 let body = create_simple_literal(42);
1726 let expr = Expr::new(
1727 ExprKind::Function {
1728 name: "test".to_string(),
1729 type_params: vec![],
1730 params: vec![],
1731 return_type: None,
1732 body: Box::new(body),
1733 is_async: false,
1734 is_pub: false,
1735 },
1736 Default::default(),
1737 );
1738 let result = formatter
1739 .format(&expr)
1740 .expect("operation should succeed in test");
1741 assert!(!result.is_empty());
1743 }
1744
1745 #[test]
1746 fn test_format_function_with_params() {
1747 let formatter = Formatter::new();
1748 let body = create_identifier("x");
1749 let param = Param {
1750 pattern: Pattern::Identifier("x".to_string()),
1751 ty: Type {
1752 kind: TypeKind::Named("Int".to_string()),
1753 span: Default::default(),
1754 },
1755 span: Default::default(),
1756 is_mutable: false,
1757 default_value: None,
1758 };
1759 let expr = Expr::new(
1760 ExprKind::Function {
1761 name: "identity".to_string(),
1762 type_params: vec![],
1763 params: vec![param],
1764 return_type: Some(Type {
1765 kind: TypeKind::Named("Int".to_string()),
1766 span: Default::default(),
1767 }),
1768 body: Box::new(body),
1769 is_async: false,
1770 is_pub: false,
1771 },
1772 Default::default(),
1773 );
1774 let result = formatter
1775 .format(&expr)
1776 .expect("operation should succeed in test");
1777 assert!(!result.is_empty());
1779 }
1780
1781 #[test]
1782 fn test_format_type_named() {
1783 let _formatter = Formatter::new();
1784 let type_kind = TypeKind::Named("String".to_string());
1785 let result = Formatter::format_type(&type_kind);
1786 assert_eq!(result, "String");
1787 }
1788
1789 #[test]
1790 fn test_format_type_fallback() {
1791 let _formatter = Formatter::new();
1792 let type_kind = TypeKind::List(Box::new(Type {
1793 kind: TypeKind::Named("Int".to_string()),
1794 span: Default::default(),
1795 }));
1796 let result = Formatter::format_type(&type_kind);
1797 assert!(result.contains("List"));
1798 }
1799
1800 #[test]
1801 fn test_format_with_tabs() {
1802 let mut formatter = Formatter::new();
1803 formatter.config.use_tabs = true;
1804 let exprs = vec![create_simple_literal(1)];
1805 let expr = Expr::new(ExprKind::Block(exprs), Default::default());
1806 let result = formatter
1807 .format(&expr)
1808 .expect("operation should succeed in test");
1809 assert!(!result.is_empty());
1812 }
1813
1814 #[test]
1815 fn test_format_with_spaces() {
1816 let mut formatter = Formatter::new();
1817 formatter.config.use_tabs = false;
1818 formatter.config.indent_width = 2;
1819 let exprs = vec![create_simple_literal(1)];
1820 let expr = Expr::new(ExprKind::Block(exprs), Default::default());
1821 let result = formatter
1822 .format(&expr)
1823 .expect("operation should succeed in test");
1824 assert!(!result.is_empty());
1827 }
1828
1829 #[test]
1830 fn test_format_nested_expressions() {
1831 let formatter = Formatter::new();
1832 let inner = Expr::new(
1833 ExprKind::Binary {
1834 left: Box::new(create_simple_literal(1)),
1835 op: BinaryOp::Add,
1836 right: Box::new(create_simple_literal(2)),
1837 },
1838 Default::default(),
1839 );
1840 let outer = Expr::new(
1841 ExprKind::Binary {
1842 left: Box::new(inner),
1843 op: BinaryOp::Multiply,
1844 right: Box::new(create_simple_literal(3)),
1845 },
1846 Default::default(),
1847 );
1848 let result = formatter
1849 .format(&outer)
1850 .expect("operation should succeed in test");
1851 assert!(result.contains("1 + 2"));
1853 assert!(result.contains("* 3"));
1854 }
1855
1856 #[test]
1857 fn test_format_multiple_params() {
1858 let formatter = Formatter::new();
1859 let body = create_simple_literal(0);
1860 let param1 = Param {
1861 pattern: Pattern::Identifier("x".to_string()),
1862 ty: Type {
1863 kind: TypeKind::Named("Int".to_string()),
1864 span: Default::default(),
1865 },
1866 span: Default::default(),
1867 is_mutable: false,
1868 default_value: None,
1869 };
1870 let param2 = Param {
1871 pattern: Pattern::Identifier("y".to_string()),
1872 ty: Type {
1873 kind: TypeKind::Named("Float".to_string()),
1874 span: Default::default(),
1875 },
1876 span: Default::default(),
1877 is_mutable: false,
1878 default_value: None,
1879 };
1880 let expr = Expr::new(
1881 ExprKind::Function {
1882 name: "test".to_string(),
1883 type_params: vec![],
1884 params: vec![param1, param2],
1885 return_type: None,
1886 body: Box::new(body),
1887 is_async: false,
1888 is_pub: false,
1889 },
1890 Default::default(),
1891 );
1892 let result = formatter
1893 .format(&expr)
1894 .expect("operation should succeed in test");
1895 assert!(result.contains("x: Int, y: Float"));
1896 }
1897
1898 #[test]
1899 fn test_format_empty_block() {
1900 let formatter = Formatter::new();
1901 let expr = Expr::new(ExprKind::Block(vec![]), Default::default());
1902 let result = formatter.format(&expr);
1903 assert!(result.is_ok());
1905 }
1906
1907 #[test]
1908 fn test_format_string_with_quotes() {
1909 let formatter = Formatter::new();
1910 let expr = Expr::new(
1911 ExprKind::Literal(Literal::String("hello \"world\"".to_string())),
1912 Default::default(),
1913 );
1914 let result = formatter
1915 .format(&expr)
1916 .expect("operation should succeed in test");
1917 assert_eq!(result, "\"hello \\\"world\\\"\"");
1918 }
1919
1920 #[test]
1921 fn test_format_special_characters() {
1922 let formatter = Formatter::new();
1923 let expr = Expr::new(ExprKind::Literal(Literal::Char('\n')), Default::default());
1924 let result = formatter
1925 .format(&expr)
1926 .expect("operation should succeed in test");
1927 assert_eq!(result, "'\n'");
1928 }
1929
1930 #[test]
1931 fn test_format_fallback_case() {
1932 let formatter = Formatter::new();
1933 let expr = Expr::new(
1935 ExprKind::StringInterpolation { parts: vec![] },
1936 Default::default(),
1937 );
1938 let result = formatter
1939 .format(&expr)
1940 .expect("operation should succeed in test");
1941 assert!(!result.is_empty());
1943 }
1944
1945 #[test]
1946 fn test_formatter_field_access() {
1947 let formatter = Formatter::new();
1948 assert_eq!(formatter.config.indent_width, 4);
1949 assert!(!formatter.config.use_tabs);
1950 }
1951
1952 #[test]
1953 fn test_format_deeply_nested_block() {
1954 let formatter = Formatter::new();
1955 let inner_block = Expr::new(
1956 ExprKind::Block(vec![create_simple_literal(1)]),
1957 Default::default(),
1958 );
1959 let outer_block = Expr::new(ExprKind::Block(vec![inner_block]), Default::default());
1960 let result = formatter
1961 .format(&outer_block)
1962 .expect("operation should succeed in test");
1963 assert!(!result.is_empty());
1965 }
1966
1967 #[test]
1972 fn test_format_null_literal() {
1973 let formatter = Formatter::new();
1974 let expr = Expr::new(ExprKind::Literal(Literal::Null), Default::default());
1975 let result = formatter.format(&expr).expect("should format");
1976 assert_eq!(result, "null");
1977 }
1978
1979 #[test]
1980 fn test_format_atom_literal() {
1981 let formatter = Formatter::new();
1982 let expr = Expr::new(
1983 ExprKind::Literal(Literal::Atom("foo".to_string())),
1984 Default::default(),
1985 );
1986 let result = formatter.format(&expr).expect("should format");
1987 assert_eq!(result, ":foo");
1988 }
1989
1990 #[test]
1991 fn test_format_byte_literal() {
1992 let formatter = Formatter::new();
1993 let expr = Expr::new(ExprKind::Literal(Literal::Byte(b'x')), Default::default());
1994 let result = formatter.format(&expr).expect("should format");
1995 assert_eq!(result, "b'x'");
1996 }
1997
1998 #[test]
1999 fn test_format_with_tabs_coverage() {
2000 let config = FormatterConfig {
2001 use_tabs: true,
2002 indent_width: 4,
2003 ..Default::default()
2004 };
2005 let formatter = Formatter::with_config(config);
2006 let inner_block = Expr::new(
2008 ExprKind::Block(vec![create_simple_literal(42)]),
2009 Default::default(),
2010 );
2011 let outer_block = Expr::new(ExprKind::Block(vec![inner_block]), Default::default());
2013 let result = formatter.format(&outer_block).expect("should format");
2014 assert!(result.contains('\t'));
2016 }
2017
2018 #[test]
2019 fn test_format_binary_expression_coverage() {
2020 let formatter = Formatter::new();
2021 let left = create_simple_literal(1);
2022 let right = create_simple_literal(2);
2023 let expr = Expr::new(
2024 ExprKind::Binary {
2025 left: Box::new(left),
2026 op: crate::frontend::ast::BinaryOp::Add,
2027 right: Box::new(right),
2028 },
2029 Default::default(),
2030 );
2031 let result = formatter.format(&expr).expect("should format");
2032 assert!(result.contains('+'));
2033 assert!(result.contains('1'));
2034 assert!(result.contains('2'));
2035 }
2036
2037 #[test]
2038 fn test_format_let_statement() {
2039 let formatter = Formatter::new();
2040 let value = create_simple_literal(42);
2041 let body = Expr::new(ExprKind::Literal(Literal::Unit), Default::default());
2042 let expr = Expr::new(
2043 ExprKind::Let {
2044 name: "x".to_string(),
2045 is_mutable: false,
2046 type_annotation: None,
2047 value: Box::new(value),
2048 body: Box::new(body),
2049 else_block: None,
2050 },
2051 Default::default(),
2052 );
2053 let result = formatter.format(&expr).expect("should format");
2054 assert!(result.contains("let"));
2055 assert!(result.contains("x"));
2056 assert!(result.contains("42"));
2057 }
2058
2059 #[test]
2060 fn test_format_let_with_block_body() {
2061 let formatter = Formatter::new();
2062 let value = create_simple_literal(10);
2063 let block_content = create_simple_literal(20);
2064 let body = Expr::new(ExprKind::Block(vec![block_content]), Default::default());
2065 let expr = Expr::new(
2066 ExprKind::Let {
2067 name: "y".to_string(),
2068 is_mutable: false,
2069 type_annotation: None,
2070 value: Box::new(value),
2071 body: Box::new(body),
2072 else_block: None,
2073 },
2074 Default::default(),
2075 );
2076 let result = formatter.format(&expr).expect("should format");
2077 assert!(result.contains("let"));
2078 assert!(result.contains("y"));
2079 }
2080
2081 #[test]
2082 fn test_format_type_named_coverage() {
2083 use crate::frontend::ast::{Type, TypeKind};
2085 let ty = Type {
2086 kind: TypeKind::Named("i32".to_string()),
2087 span: Default::default(),
2088 };
2089 let result = Formatter::format_type(&ty.kind);
2090 assert_eq!(result, "i32");
2091 }
2092
2093 #[test]
2094 fn test_format_type_generic() {
2095 use crate::frontend::ast::{Type, TypeKind};
2096 let inner = Type {
2097 kind: TypeKind::Named("String".to_string()),
2098 span: Default::default(),
2099 };
2100 let ty = Type {
2101 kind: TypeKind::Generic {
2102 base: "Vec".to_string(),
2103 params: vec![inner],
2104 },
2105 span: Default::default(),
2106 };
2107 let result = Formatter::format_type(&ty.kind);
2108 assert_eq!(result, "Vec<String>");
2109 }
2110
2111 #[test]
2112 fn test_format_type_tuple() {
2113 use crate::frontend::ast::{Type, TypeKind};
2114 let int_type = Type {
2115 kind: TypeKind::Named("i32".to_string()),
2116 span: Default::default(),
2117 };
2118 let str_type = Type {
2119 kind: TypeKind::Named("String".to_string()),
2120 span: Default::default(),
2121 };
2122 let ty = Type {
2123 kind: TypeKind::Tuple(vec![int_type, str_type]),
2124 span: Default::default(),
2125 };
2126 let result = Formatter::format_type(&ty.kind);
2127 assert!(result.contains("i32"));
2128 assert!(result.contains("String"));
2129 }
2130
2131 #[test]
2132 fn test_format_type_array() {
2133 use crate::frontend::ast::{Type, TypeKind};
2134 let elem_type = Type {
2135 kind: TypeKind::Named("u8".to_string()),
2136 span: Default::default(),
2137 };
2138 let ty = Type {
2139 kind: TypeKind::Array {
2140 elem_type: Box::new(elem_type),
2141 size: 10,
2142 },
2143 span: Default::default(),
2144 };
2145 let result = Formatter::format_type(&ty.kind);
2146 assert!(result.contains("u8"));
2147 assert!(result.contains("10"));
2148 }
2149
2150 #[test]
2151 fn test_format_type_function() {
2152 use crate::frontend::ast::{Type, TypeKind};
2153 let param_type = Type {
2154 kind: TypeKind::Named("i32".to_string()),
2155 span: Default::default(),
2156 };
2157 let ret_type = Type {
2158 kind: TypeKind::Named("bool".to_string()),
2159 span: Default::default(),
2160 };
2161 let ty = Type {
2162 kind: TypeKind::Function {
2163 params: vec![param_type],
2164 ret: Box::new(ret_type),
2165 },
2166 span: Default::default(),
2167 };
2168 let result = Formatter::format_type(&ty.kind);
2169 assert!(result.contains("i32"));
2170 assert!(result.contains("->"));
2171 assert!(result.contains("bool"));
2172 }
2173
2174 #[test]
2175 fn test_set_source() {
2176 let mut formatter = Formatter::new();
2177 formatter.set_source("let x = 42");
2178 assert!(formatter.source.is_some());
2179 }
2180
2181 #[test]
2182 fn test_format_call_expression() {
2183 let formatter = Formatter::new();
2184 let func = create_identifier("print");
2185 let arg = create_simple_literal(42);
2186 let expr = Expr::new(
2187 ExprKind::Call {
2188 func: Box::new(func),
2189 args: vec![arg],
2190 },
2191 Default::default(),
2192 );
2193 let result = formatter.format(&expr).expect("should format");
2194 assert!(result.contains("print"));
2195 assert!(result.contains("42"));
2196 }
2197
2198 #[test]
2199 fn test_format_array_literal() {
2200 let code = "[1, 2]";
2202 let mut parser = crate::frontend::parser::Parser::new(code);
2203 if let Ok(ast) = parser.parse() {
2204 let formatter = Formatter::new();
2205 let result = formatter.format(&ast).expect("should format");
2206 assert!(result.contains('['));
2207 assert!(result.contains(']'));
2208 }
2209 }
2210
2211 #[test]
2212 fn test_format_tuple_literal() {
2213 let code = "(1, 2)";
2215 let mut parser = crate::frontend::parser::Parser::new(code);
2216 if let Ok(ast) = parser.parse() {
2217 let formatter = Formatter::new();
2218 let result = formatter.format(&ast).expect("should format");
2219 assert!(result.contains('(') || result.contains(')'));
2220 }
2221 }
2222
2223 #[test]
2224 fn test_format_if_expression_coverage() {
2225 let formatter = Formatter::new();
2226 let condition = Expr::new(ExprKind::Literal(Literal::Bool(true)), Default::default());
2227 let then_branch = create_simple_literal(1);
2228 let else_branch = create_simple_literal(2);
2229 let expr = Expr::new(
2230 ExprKind::If {
2231 condition: Box::new(condition),
2232 then_branch: Box::new(then_branch),
2233 else_branch: Some(Box::new(else_branch)),
2234 },
2235 Default::default(),
2236 );
2237 let result = formatter.format(&expr).expect("should format");
2238 assert!(result.contains("if"));
2239 }
2240
2241 #[test]
2242 fn test_format_unary_negation() {
2243 let formatter = Formatter::new();
2244 let operand = create_simple_literal(42);
2245 let expr = Expr::new(
2246 ExprKind::Unary {
2247 op: crate::frontend::ast::UnaryOp::Negate,
2248 operand: Box::new(operand),
2249 },
2250 Default::default(),
2251 );
2252 let result = formatter.format(&expr).expect("should format");
2253 assert!(result.contains('-') || result.contains("42"));
2254 }
2255
2256 #[test]
2257 fn test_format_unary_not() {
2258 let formatter = Formatter::new();
2259 let operand = Expr::new(ExprKind::Literal(Literal::Bool(true)), Default::default());
2260 let expr = Expr::new(
2261 ExprKind::Unary {
2262 op: crate::frontend::ast::UnaryOp::Not,
2263 operand: Box::new(operand),
2264 },
2265 Default::default(),
2266 );
2267 let result = formatter.format(&expr).expect("should format");
2268 assert!(result.contains('!') || result.contains("true"));
2269 }
2270
2271 #[test]
2272 fn test_format_field_access() {
2273 let formatter = Formatter::new();
2274 let obj = create_identifier("point");
2275 let expr = Expr::new(
2276 ExprKind::FieldAccess {
2277 object: Box::new(obj),
2278 field: "x".to_string(),
2279 },
2280 Default::default(),
2281 );
2282 let result = formatter.format(&expr).expect("should format");
2283 assert!(result.contains("point"));
2284 assert!(result.contains('x'));
2285 }
2286
2287 #[test]
2288 fn test_format_index_access() {
2289 let formatter = Formatter::new();
2290 let arr = create_identifier("arr");
2291 let idx = create_simple_literal(0);
2292 let expr = Expr::new(
2293 ExprKind::IndexAccess {
2294 object: Box::new(arr),
2295 index: Box::new(idx),
2296 },
2297 Default::default(),
2298 );
2299 let result = formatter.format(&expr).expect("should format");
2300 assert!(result.contains("arr"));
2301 assert!(result.contains('['));
2302 }
2303
2304 #[test]
2305 fn test_format_return() {
2306 let formatter = Formatter::new();
2307 let value = create_simple_literal(42);
2308 let expr = Expr::new(
2309 ExprKind::Return {
2310 value: Some(Box::new(value)),
2311 },
2312 Default::default(),
2313 );
2314 let result = formatter.format(&expr).expect("should format");
2315 assert!(result.contains("return") || result.contains("42"));
2316 }
2317
2318 #[test]
2319 fn test_format_break() {
2320 let formatter = Formatter::new();
2321 let expr = Expr::new(
2322 ExprKind::Break {
2323 label: None,
2324 value: None,
2325 },
2326 Default::default(),
2327 );
2328 let result = formatter.format(&expr).expect("should format");
2329 assert!(result.contains("break"));
2330 }
2331
2332 #[test]
2333 fn test_format_continue() {
2334 let formatter = Formatter::new();
2335 let expr = Expr::new(ExprKind::Continue { label: None }, Default::default());
2336 let result = formatter.format(&expr).expect("should format");
2337 assert!(result.contains("continue"));
2338 }
2339
2340 #[test]
2341 fn test_format_range() {
2342 let code = "0..10";
2344 let mut parser = crate::frontend::parser::Parser::new(code);
2345 if let Ok(ast) = parser.parse() {
2346 let formatter = Formatter::new();
2347 let result = formatter.format(&ast).expect("should format");
2348 assert!(result.contains("..") || (result.contains('0') && result.contains("10")));
2349 }
2350 }
2351
2352 #[test]
2353 fn test_format_object_literal() {
2354 let code = "{ x: 42 }";
2356 let mut parser = crate::frontend::parser::Parser::new(code);
2357 if let Ok(ast) = parser.parse() {
2358 let formatter = Formatter::new();
2359 let result = formatter.format(&ast).expect("should format");
2360 assert!(result.contains('{') || result.contains('x'));
2361 }
2362 }
2363
2364 #[test]
2365 fn test_formatter_with_different_indent_widths() {
2366 for width in [2, 4, 8] {
2367 let config = FormatterConfig {
2368 indent_width: width,
2369 use_tabs: false,
2370 ..Default::default()
2371 };
2372 let formatter = Formatter::with_config(config);
2373 let block = Expr::new(
2374 ExprKind::Block(vec![create_simple_literal(1)]),
2375 Default::default(),
2376 );
2377 let result = formatter.format(&block).expect("should format");
2378 assert!(!result.is_empty());
2379 }
2380 }
2381}
2382
2383#[cfg(test)]
2384#[allow(clippy::expect_used)]
2385mod property_tests_formatter {
2386 use super::*;
2387 use proptest::prelude::*;
2388
2389 proptest! {
2390 #![proptest_config(ProptestConfig::with_cases(50))]
2391
2392 #[test]
2394 fn prop_formatter_new_never_panics(_dummy: u8) {
2395 let _formatter = Formatter::new();
2396 prop_assert!(true);
2397 }
2398
2399 #[test]
2401 fn prop_set_source_never_panics(source in "[a-zA-Z0-9_ ]{0,100}") {
2402 let mut formatter = Formatter::new();
2403 formatter.set_source(source);
2404 prop_assert!(true);
2405 }
2406
2407 #[test]
2409 fn prop_formatter_config_default_valid(_dummy: u8) {
2410 let config = FormatterConfig::default();
2411 prop_assert!(config.indent_width > 0);
2412 }
2413
2414 #[test]
2416 fn prop_indent_config_valid(indent in 1usize..8) {
2417 let config = FormatterConfig {
2418 indent_width: indent,
2419 ..Default::default()
2420 };
2421 let _formatter = Formatter::with_config(config);
2422 prop_assert!(true);
2423 }
2424
2425 #[test]
2427 fn prop_format_parsed_integer(n in -1000i64..1000) {
2428 let code = format!("{n}");
2429 let mut parser = crate::frontend::parser::Parser::new(&code);
2430 if let Ok(ast) = parser.parse() {
2431 let formatter = Formatter::new();
2432 let result = formatter.format(&ast);
2433 prop_assert!(result.is_ok());
2434 }
2435 }
2436
2437 #[test]
2439 fn prop_format_parsed_bool(b in proptest::bool::ANY) {
2440 let code = if b { "true" } else { "false" };
2441 let mut parser = crate::frontend::parser::Parser::new(code);
2442 if let Ok(ast) = parser.parse() {
2443 let formatter = Formatter::new();
2444 let result = formatter.format(&ast);
2445 prop_assert!(result.is_ok());
2446 }
2447 }
2448
2449 #[test]
2451 fn prop_format_parsed_string(s in "[a-zA-Z0-9]{0,20}") {
2452 let code = format!("\"{s}\"");
2453 let mut parser = crate::frontend::parser::Parser::new(&code);
2454 if let Ok(ast) = parser.parse() {
2455 let formatter = Formatter::new();
2456 let result = formatter.format(&ast);
2457 prop_assert!(result.is_ok());
2458 }
2459 }
2460
2461 #[test]
2463 fn prop_format_parsed_identifier(name in "[a-z][a-z0-9_]{0,10}") {
2464 let mut parser = crate::frontend::parser::Parser::new(&name);
2465 if let Ok(ast) = parser.parse() {
2466 let formatter = Formatter::new();
2467 let result = formatter.format(&ast);
2468 prop_assert!(result.is_ok());
2469 }
2470 }
2471
2472 #[test]
2474 fn prop_format_parsed_let(n in -100i64..100) {
2475 let code = format!("let x = {n}");
2476 let mut parser = crate::frontend::parser::Parser::new(&code);
2477 if let Ok(ast) = parser.parse() {
2478 let formatter = Formatter::new();
2479 let result = formatter.format(&ast);
2480 prop_assert!(result.is_ok());
2481 }
2482 }
2483 }
2484}
2485
2486#[cfg(test)]
2488mod formatter_tests_r164 {
2489 use super::*;
2490 use crate::frontend::ast::*;
2491
2492 fn create_simple_literal(value: i64) -> Expr {
2493 Expr::new(
2494 ExprKind::Literal(Literal::Integer(value, None)),
2495 Default::default(),
2496 )
2497 }
2498
2499 fn create_identifier(name: &str) -> Expr {
2500 Expr::new(ExprKind::Identifier(name.to_string()), Default::default())
2501 }
2502
2503 fn create_bool_literal(b: bool) -> Expr {
2504 Expr::new(ExprKind::Literal(Literal::Bool(b)), Default::default())
2505 }
2506
2507 #[test]
2509 fn test_format_while_loop_r164() {
2510 let formatter = Formatter::new();
2511 let condition = create_bool_literal(true);
2512 let body = Expr::new(
2513 ExprKind::Block(vec![create_simple_literal(1)]),
2514 Default::default(),
2515 );
2516 let expr = Expr::new(
2517 ExprKind::While {
2518 condition: Box::new(condition),
2519 body: Box::new(body),
2520 label: None,
2521 },
2522 Default::default(),
2523 );
2524 let result = formatter.format(&expr).expect("should format");
2525 assert!(result.contains("while"));
2526 }
2527
2528 #[test]
2530 fn test_format_for_loop_r164() {
2531 let formatter = Formatter::new();
2532 let iter = create_identifier("items");
2533 let body = Expr::new(
2534 ExprKind::Block(vec![create_simple_literal(1)]),
2535 Default::default(),
2536 );
2537 let expr = Expr::new(
2538 ExprKind::For {
2539 var: "x".to_string(),
2540 pattern: Some(Pattern::Identifier("x".to_string())),
2541 iter: Box::new(iter),
2542 body: Box::new(body),
2543 label: None,
2544 },
2545 Default::default(),
2546 );
2547 let result = formatter.format(&expr).expect("should format");
2548 assert!(result.contains("for"));
2549 assert!(result.contains("in"));
2550 }
2551
2552 #[test]
2554 fn test_format_method_call_r164() {
2555 let formatter = Formatter::new();
2556 let receiver = create_identifier("obj");
2557 let expr = Expr::new(
2558 ExprKind::MethodCall {
2559 receiver: Box::new(receiver),
2560 method: "get".to_string(),
2561 args: vec![create_simple_literal(0)],
2562 },
2563 Default::default(),
2564 );
2565 let result = formatter.format(&expr).expect("should format");
2566 assert!(result.contains("obj"));
2567 assert!(result.contains("get"));
2568 }
2569
2570 #[test]
2572 fn test_format_lambda_r164() {
2573 let formatter = Formatter::new();
2574 let body = create_simple_literal(42);
2575 let param = Param {
2576 pattern: Pattern::Identifier("x".to_string()),
2577 ty: Type {
2578 kind: TypeKind::Named("Any".to_string()),
2579 span: Default::default(),
2580 },
2581 span: Default::default(),
2582 is_mutable: false,
2583 default_value: None,
2584 };
2585 let expr = Expr::new(
2586 ExprKind::Lambda {
2587 params: vec![param],
2588 body: Box::new(body),
2589 },
2590 Default::default(),
2591 );
2592 let result = formatter.format(&expr).expect("should format");
2593 assert!(result.contains("|"));
2594 assert!(result.contains("42"));
2595 }
2596
2597 #[test]
2599 fn test_format_ternary_r164() {
2600 let formatter = Formatter::new();
2601 let condition = create_bool_literal(true);
2602 let true_expr = create_simple_literal(1);
2603 let false_expr = create_simple_literal(2);
2604 let expr = Expr::new(
2605 ExprKind::Ternary {
2606 condition: Box::new(condition),
2607 true_expr: Box::new(true_expr),
2608 false_expr: Box::new(false_expr),
2609 },
2610 Default::default(),
2611 );
2612 let result = formatter.format(&expr).expect("should format");
2613 assert!(result.contains("?"));
2614 assert!(result.contains(":"));
2615 }
2616
2617 #[test]
2619 fn test_format_assign_r164() {
2620 let formatter = Formatter::new();
2621 let target = create_identifier("x");
2622 let value = create_simple_literal(42);
2623 let expr = Expr::new(
2624 ExprKind::Assign {
2625 target: Box::new(target),
2626 value: Box::new(value),
2627 },
2628 Default::default(),
2629 );
2630 let result = formatter.format(&expr).expect("should format");
2631 assert!(result.contains("x"));
2632 assert!(result.contains("="));
2633 assert!(result.contains("42"));
2634 }
2635
2636 #[test]
2638 fn test_format_compound_assign_r164() {
2639 let formatter = Formatter::new();
2640 let target = create_identifier("x");
2641 let value = create_simple_literal(1);
2642 let expr = Expr::new(
2643 ExprKind::CompoundAssign {
2644 target: Box::new(target),
2645 op: BinaryOp::Add,
2646 value: Box::new(value),
2647 },
2648 Default::default(),
2649 );
2650 let result = formatter.format(&expr).expect("should format");
2651 assert!(result.contains("+=") || (result.contains("x") && result.contains("1")));
2652 }
2653
2654 #[test]
2656 fn test_format_return_no_value_r164() {
2657 let formatter = Formatter::new();
2658 let expr = Expr::new(ExprKind::Return { value: None }, Default::default());
2659 let result = formatter.format(&expr).expect("should format");
2660 assert_eq!(result, "return");
2661 }
2662
2663 #[test]
2665 fn test_format_break_with_value_r164() {
2666 let formatter = Formatter::new();
2667 let value = create_simple_literal(42);
2668 let expr = Expr::new(
2669 ExprKind::Break {
2670 label: None,
2671 value: Some(Box::new(value)),
2672 },
2673 Default::default(),
2674 );
2675 let result = formatter.format(&expr).expect("should format");
2676 assert!(result.contains("break"));
2677 assert!(result.contains("42"));
2678 }
2679
2680 #[test]
2682 fn test_format_list_literal_r164() {
2683 let formatter = Formatter::new();
2684 let items = vec![
2685 create_simple_literal(1),
2686 create_simple_literal(2),
2687 create_simple_literal(3),
2688 ];
2689 let expr = Expr::new(ExprKind::List(items), Default::default());
2690 let result = formatter.format(&expr).expect("should format");
2691 assert!(result.contains("["));
2692 assert!(result.contains("]"));
2693 assert!(result.contains("1"));
2694 assert!(result.contains("2"));
2695 assert!(result.contains("3"));
2696 }
2697
2698 #[test]
2700 fn test_format_tuple_literal_direct_r164() {
2701 let formatter = Formatter::new();
2702 let items = vec![create_simple_literal(1), create_simple_literal(2)];
2703 let expr = Expr::new(ExprKind::Tuple(items), Default::default());
2704 let result = formatter.format(&expr).expect("should format");
2705 assert!(result.contains("("));
2706 assert!(result.contains(")"));
2707 }
2708
2709 #[test]
2711 fn test_format_range_exclusive_r164() {
2712 let formatter = Formatter::new();
2713 let start = create_simple_literal(0);
2714 let end = create_simple_literal(10);
2715 let expr = Expr::new(
2716 ExprKind::Range {
2717 start: Box::new(start),
2718 end: Box::new(end),
2719 inclusive: false,
2720 },
2721 Default::default(),
2722 );
2723 let result = formatter.format(&expr).expect("should format");
2724 assert!(result.contains(".."));
2725 assert!(!result.contains("..="));
2726 }
2727
2728 #[test]
2730 fn test_format_range_inclusive_r164() {
2731 let formatter = Formatter::new();
2732 let start = create_simple_literal(0);
2733 let end = create_simple_literal(10);
2734 let expr = Expr::new(
2735 ExprKind::Range {
2736 start: Box::new(start),
2737 end: Box::new(end),
2738 inclusive: true,
2739 },
2740 Default::default(),
2741 );
2742 let result = formatter.format(&expr).expect("should format");
2743 assert!(result.contains("..="));
2744 }
2745
2746 #[test]
2748 fn test_format_throw_r164() {
2749 let formatter = Formatter::new();
2750 let error = Expr::new(
2751 ExprKind::Literal(Literal::String("error".to_string())),
2752 Default::default(),
2753 );
2754 let expr = Expr::new(
2755 ExprKind::Throw {
2756 expr: Box::new(error),
2757 },
2758 Default::default(),
2759 );
2760 let result = formatter.format(&expr).expect("should format");
2761 assert!(result.contains("throw"));
2762 }
2763
2764 #[test]
2766 fn test_format_await_r164() {
2767 let formatter = Formatter::new();
2768 let inner = create_identifier("future");
2769 let expr = Expr::new(
2770 ExprKind::Await {
2771 expr: Box::new(inner),
2772 },
2773 Default::default(),
2774 );
2775 let result = formatter.format(&expr).expect("should format");
2776 assert!(result.contains("await"));
2777 assert!(result.contains("future"));
2778 }
2779
2780 #[test]
2782 fn test_format_async_block_r164() {
2783 let formatter = Formatter::new();
2784 let body = create_simple_literal(42);
2785 let expr = Expr::new(
2786 ExprKind::AsyncBlock {
2787 body: Box::new(body),
2788 },
2789 Default::default(),
2790 );
2791 let result = formatter.format(&expr).expect("should format");
2792 assert!(result.contains("async"));
2793 }
2794
2795 #[test]
2797 fn test_format_ok_variant_r164() {
2798 let formatter = Formatter::new();
2799 let value = create_simple_literal(42);
2800 let expr = Expr::new(
2801 ExprKind::Ok {
2802 value: Box::new(value),
2803 },
2804 Default::default(),
2805 );
2806 let result = formatter.format(&expr).expect("should format");
2807 assert!(result.contains("Ok"));
2808 assert!(result.contains("42"));
2809 }
2810
2811 #[test]
2813 fn test_format_err_variant_r164() {
2814 let formatter = Formatter::new();
2815 let error = Expr::new(
2816 ExprKind::Literal(Literal::String("error".to_string())),
2817 Default::default(),
2818 );
2819 let expr = Expr::new(
2820 ExprKind::Err {
2821 error: Box::new(error),
2822 },
2823 Default::default(),
2824 );
2825 let result = formatter.format(&expr).expect("should format");
2826 assert!(result.contains("Err"));
2827 }
2828
2829 #[test]
2831 fn test_format_some_variant_r164() {
2832 let formatter = Formatter::new();
2833 let value = create_simple_literal(42);
2834 let expr = Expr::new(
2835 ExprKind::Some {
2836 value: Box::new(value),
2837 },
2838 Default::default(),
2839 );
2840 let result = formatter.format(&expr).expect("should format");
2841 assert!(result.contains("Some"));
2842 }
2843
2844 #[test]
2846 fn test_format_none_variant_r164() {
2847 let formatter = Formatter::new();
2848 let expr = Expr::new(ExprKind::None, Default::default());
2849 let result = formatter.format(&expr).expect("should format");
2850 assert_eq!(result, "None");
2851 }
2852
2853 #[test]
2855 fn test_format_try_expr_r164() {
2856 let formatter = Formatter::new();
2857 let inner = create_identifier("result");
2858 let expr = Expr::new(
2859 ExprKind::Try {
2860 expr: Box::new(inner),
2861 },
2862 Default::default(),
2863 );
2864 let result = formatter.format(&expr).expect("should format");
2865 assert!(result.contains("?"));
2866 }
2867
2868 #[test]
2870 fn test_format_spawn_r164() {
2871 let formatter = Formatter::new();
2872 let actor = create_identifier("my_actor");
2873 let expr = Expr::new(
2874 ExprKind::Spawn {
2875 actor: Box::new(actor),
2876 },
2877 Default::default(),
2878 );
2879 let result = formatter.format(&expr).expect("should format");
2880 assert!(result.contains("spawn"));
2881 }
2882
2883 #[test]
2885 fn test_format_optional_field_access_r164() {
2886 let formatter = Formatter::new();
2887 let obj = create_identifier("maybe_obj");
2888 let expr = Expr::new(
2889 ExprKind::OptionalFieldAccess {
2890 object: Box::new(obj),
2891 field: "value".to_string(),
2892 },
2893 Default::default(),
2894 );
2895 let result = formatter.format(&expr).expect("should format");
2896 assert!(result.contains("?."));
2897 }
2898
2899 #[test]
2901 fn test_format_type_cast_r164() {
2902 let formatter = Formatter::new();
2903 let value = create_simple_literal(42);
2904 let expr = Expr::new(
2905 ExprKind::TypeCast {
2906 expr: Box::new(value),
2907 target_type: "f64".to_string(),
2908 },
2909 Default::default(),
2910 );
2911 let result = formatter.format(&expr).expect("should format");
2912 assert!(result.contains("as"));
2913 assert!(result.contains("f64"));
2914 }
2915
2916 #[test]
2918 fn test_format_array_init_r164() {
2919 let formatter = Formatter::new();
2920 let value = create_simple_literal(0);
2921 let size = create_simple_literal(10);
2922 let expr = Expr::new(
2923 ExprKind::ArrayInit {
2924 value: Box::new(value),
2925 size: Box::new(size),
2926 },
2927 Default::default(),
2928 );
2929 let result = formatter.format(&expr).expect("should format");
2930 assert!(result.contains("["));
2931 assert!(result.contains(";"));
2932 assert!(result.contains("]"));
2933 }
2934
2935 #[test]
2937 fn test_format_qualified_name_r164() {
2938 let formatter = Formatter::new();
2939 let expr = Expr::new(
2940 ExprKind::QualifiedName {
2941 module: "std".to_string(),
2942 name: "println".to_string(),
2943 },
2944 Default::default(),
2945 );
2946 let result = formatter.format(&expr).expect("should format");
2947 assert!(result.contains("std"));
2948 assert!(result.contains("::"));
2949 assert!(result.contains("println"));
2950 }
2951
2952 #[test]
2954 fn test_format_spread_r164() {
2955 let formatter = Formatter::new();
2956 let inner = create_identifier("arr");
2957 let expr = Expr::new(
2958 ExprKind::Spread {
2959 expr: Box::new(inner),
2960 },
2961 Default::default(),
2962 );
2963 let result = formatter.format(&expr).expect("should format");
2964 assert!(result.contains("..."));
2965 }
2966
2967 #[test]
2969 fn test_format_pre_increment_r164() {
2970 let formatter = Formatter::new();
2971 let target = create_identifier("x");
2972 let expr = Expr::new(
2973 ExprKind::PreIncrement {
2974 target: Box::new(target),
2975 },
2976 Default::default(),
2977 );
2978 let result = formatter.format(&expr).expect("should format");
2979 assert!(result.contains("++"));
2980 }
2981
2982 #[test]
2984 fn test_format_post_increment_r164() {
2985 let formatter = Formatter::new();
2986 let target = create_identifier("x");
2987 let expr = Expr::new(
2988 ExprKind::PostIncrement {
2989 target: Box::new(target),
2990 },
2991 Default::default(),
2992 );
2993 let result = formatter.format(&expr).expect("should format");
2994 assert!(result.contains("++"));
2995 }
2996
2997 #[test]
2999 fn test_format_pre_decrement_r164() {
3000 let formatter = Formatter::new();
3001 let target = create_identifier("x");
3002 let expr = Expr::new(
3003 ExprKind::PreDecrement {
3004 target: Box::new(target),
3005 },
3006 Default::default(),
3007 );
3008 let result = formatter.format(&expr).expect("should format");
3009 assert!(result.contains("--"));
3010 }
3011
3012 #[test]
3014 fn test_format_post_decrement_r164() {
3015 let formatter = Formatter::new();
3016 let target = create_identifier("x");
3017 let expr = Expr::new(
3018 ExprKind::PostDecrement {
3019 target: Box::new(target),
3020 },
3021 Default::default(),
3022 );
3023 let result = formatter.format(&expr).expect("should format");
3024 assert!(result.contains("--"));
3025 }
3026
3027 #[test]
3029 fn test_format_import_r164() {
3030 let formatter = Formatter::new();
3031 let expr = Expr::new(
3032 ExprKind::Import {
3033 module: "std::io".to_string(),
3034 items: Some(vec!["read".to_string(), "write".to_string()]),
3035 },
3036 Default::default(),
3037 );
3038 let result = formatter.format(&expr).expect("should format");
3039 assert!(result.contains("import"));
3040 }
3041
3042 #[test]
3044 fn test_format_module_declaration_r164() {
3045 let formatter = Formatter::new();
3046 let expr = Expr::new(
3047 ExprKind::ModuleDeclaration {
3048 name: "utils".to_string(),
3049 },
3050 Default::default(),
3051 );
3052 let result = formatter.format(&expr).expect("should format");
3053 assert!(result.contains("mod"));
3054 assert!(result.contains("utils"));
3055 }
3056
3057 #[test]
3059 fn test_format_export_r164() {
3060 let formatter = Formatter::new();
3061 let inner = create_identifier("my_fn");
3062 let expr = Expr::new(
3063 ExprKind::Export {
3064 expr: Box::new(inner),
3065 is_default: false,
3066 },
3067 Default::default(),
3068 );
3069 let result = formatter.format(&expr).expect("should format");
3070 assert!(result.contains("export"));
3071 }
3072
3073 #[test]
3075 fn test_format_export_default_r164() {
3076 let formatter = Formatter::new();
3077 let inner = create_identifier("main");
3078 let expr = Expr::new(
3079 ExprKind::Export {
3080 expr: Box::new(inner),
3081 is_default: true,
3082 },
3083 Default::default(),
3084 );
3085 let result = formatter.format(&expr).expect("should format");
3086 assert!(result.contains("export"));
3087 assert!(result.contains("default"));
3088 }
3089
3090 #[test]
3092 fn test_format_loop_r164() {
3093 let formatter = Formatter::new();
3094 let body = create_simple_literal(1);
3095 let expr = Expr::new(
3096 ExprKind::Loop {
3097 body: Box::new(body),
3098 label: None,
3099 },
3100 Default::default(),
3101 );
3102 let result = formatter.format(&expr).expect("should format");
3103 assert!(result.contains("loop"));
3104 }
3105
3106 #[test]
3108 fn test_format_binary_sub_r164() {
3109 let formatter = Formatter::new();
3110 let left = create_simple_literal(10);
3111 let right = create_simple_literal(5);
3112 let expr = Expr::new(
3113 ExprKind::Binary {
3114 left: Box::new(left),
3115 op: BinaryOp::Subtract,
3116 right: Box::new(right),
3117 },
3118 Default::default(),
3119 );
3120 let result = formatter.format(&expr).expect("should format");
3121 assert!(result.contains("-"));
3122 }
3123
3124 #[test]
3126 fn test_format_binary_mul_r164() {
3127 let formatter = Formatter::new();
3128 let left = create_simple_literal(3);
3129 let right = create_simple_literal(4);
3130 let expr = Expr::new(
3131 ExprKind::Binary {
3132 left: Box::new(left),
3133 op: BinaryOp::Multiply,
3134 right: Box::new(right),
3135 },
3136 Default::default(),
3137 );
3138 let result = formatter.format(&expr).expect("should format");
3139 assert!(result.contains("*"));
3140 }
3141
3142 #[test]
3144 fn test_format_binary_div_r164() {
3145 let formatter = Formatter::new();
3146 let left = create_simple_literal(10);
3147 let right = create_simple_literal(2);
3148 let expr = Expr::new(
3149 ExprKind::Binary {
3150 left: Box::new(left),
3151 op: BinaryOp::Divide,
3152 right: Box::new(right),
3153 },
3154 Default::default(),
3155 );
3156 let result = formatter.format(&expr).expect("should format");
3157 assert!(result.contains("/"));
3158 }
3159
3160 #[test]
3162 fn test_format_binary_mod_r164() {
3163 let formatter = Formatter::new();
3164 let left = create_simple_literal(10);
3165 let right = create_simple_literal(3);
3166 let expr = Expr::new(
3167 ExprKind::Binary {
3168 left: Box::new(left),
3169 op: BinaryOp::Modulo,
3170 right: Box::new(right),
3171 },
3172 Default::default(),
3173 );
3174 let result = formatter.format(&expr).expect("should format");
3175 assert!(result.contains("%"));
3176 }
3177
3178 #[test]
3180 fn test_format_binary_eq_r164() {
3181 let formatter = Formatter::new();
3182 let left = create_simple_literal(1);
3183 let right = create_simple_literal(1);
3184 let expr = Expr::new(
3185 ExprKind::Binary {
3186 left: Box::new(left),
3187 op: BinaryOp::Equal,
3188 right: Box::new(right),
3189 },
3190 Default::default(),
3191 );
3192 let result = formatter.format(&expr).expect("should format");
3193 assert!(result.contains("=="));
3194 }
3195
3196 #[test]
3198 fn test_format_binary_ne_r164() {
3199 let formatter = Formatter::new();
3200 let left = create_simple_literal(1);
3201 let right = create_simple_literal(2);
3202 let expr = Expr::new(
3203 ExprKind::Binary {
3204 left: Box::new(left),
3205 op: BinaryOp::NotEqual,
3206 right: Box::new(right),
3207 },
3208 Default::default(),
3209 );
3210 let result = formatter.format(&expr).expect("should format");
3211 assert!(result.contains("!="));
3212 }
3213
3214 #[test]
3216 fn test_format_binary_lt_r164() {
3217 let formatter = Formatter::new();
3218 let left = create_simple_literal(1);
3219 let right = create_simple_literal(2);
3220 let expr = Expr::new(
3221 ExprKind::Binary {
3222 left: Box::new(left),
3223 op: BinaryOp::Less,
3224 right: Box::new(right),
3225 },
3226 Default::default(),
3227 );
3228 let result = formatter.format(&expr).expect("should format");
3229 assert!(result.contains("<"));
3230 }
3231
3232 #[test]
3234 fn test_format_binary_gt_r164() {
3235 let formatter = Formatter::new();
3236 let left = create_simple_literal(2);
3237 let right = create_simple_literal(1);
3238 let expr = Expr::new(
3239 ExprKind::Binary {
3240 left: Box::new(left),
3241 op: BinaryOp::Greater,
3242 right: Box::new(right),
3243 },
3244 Default::default(),
3245 );
3246 let result = formatter.format(&expr).expect("should format");
3247 assert!(result.contains(">"));
3248 }
3249
3250 #[test]
3252 fn test_format_binary_and_r164() {
3253 let formatter = Formatter::new();
3254 let left = create_bool_literal(true);
3255 let right = create_bool_literal(false);
3256 let expr = Expr::new(
3257 ExprKind::Binary {
3258 left: Box::new(left),
3259 op: BinaryOp::And,
3260 right: Box::new(right),
3261 },
3262 Default::default(),
3263 );
3264 let result = formatter.format(&expr).expect("should format");
3265 assert!(result.contains("&&"));
3266 }
3267
3268 #[test]
3270 fn test_format_binary_or_r164() {
3271 let formatter = Formatter::new();
3272 let left = create_bool_literal(true);
3273 let right = create_bool_literal(false);
3274 let expr = Expr::new(
3275 ExprKind::Binary {
3276 left: Box::new(left),
3277 op: BinaryOp::Or,
3278 right: Box::new(right),
3279 },
3280 Default::default(),
3281 );
3282 let result = formatter.format(&expr).expect("should format");
3283 assert!(result.contains("||"));
3284 }
3285}