## Coverage Report

#### Created: 2025-09-08 21:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /home/noah/src/ruchy/src/quality/formatter.rs

    Line
    Count
    Source
    1
    // Code formatter for Ruchy
    2
    // Toyota Way: Consistent code style prevents defects
    3
    4
    use anyhow::Result;
    5
    use crate::frontend::ast::{Expr, ExprKind};
    6
    7
    pub struct Formatter {
    8
        indent_width: usize,
    9
        use_tabs: bool,
    10
        _line_width: usize,
    11
    }
    12
    13
    impl Formatter {
    14
    0
        pub fn new() -> Self {
    15
    0
            Self {
    16
    0
                indent_width: 4,
    17
    0
                use_tabs: false,
    18
    0
                _line_width: 100,
    19
    0
            }
    20
    0
        }
    21
    22
    0
        pub fn format(&self, ast: &Expr) -> Result<String> {
    23
            // Simple formatter that converts AST back to source
    24
    0
            Ok(self.format_expr(ast, 0))
    25
    0
        }
    26
    27
    0
        fn format_type(&self, ty_kind: &crate::frontend::ast::TypeKind) -> String {
    28
    0
            match ty_kind {
    29
    0
                crate::frontend::ast::TypeKind::Named(name) => name.clone(),
    30
    0
                _ => format!("{ty_kind:?}"),
    31
            }
    32
    0
        }
    33
    34
    0
        fn format_expr(&self, expr: &Expr, indent: usize) -> String {
    35
    0
            let indent_str = if self.use_tabs {
    36
    0
                "\t".repeat(indent)
    37
            } else {
    38
    0
                " ".repeat(indent * self.indent_width)
    39
            };
    40
    41
    0
            match &expr.kind {
    42
    0
                ExprKind::Literal(lit) => match lit {
    43
    0
                    crate::frontend::ast::Literal::Integer(n) => n.to_string(),
    44
    0
                    crate::frontend::ast::Literal::Float(f) => f.to_string(),
    45
    0
                    crate::frontend::ast::Literal::String(s) => format!("\"{s}\""),
    46
    0
                    crate::frontend::ast::Literal::Bool(b) => b.to_string(),
    47
    0
                    crate::frontend::ast::Literal::Char(c) => format!("'{c}'"),
    48
    0
                    crate::frontend::ast::Literal::Unit => "()".to_string(),
    49
                },
    50
    0
                ExprKind::Identifier(name) => name.clone(),
    51
    0
                ExprKind::Let { name, value, body, .. } => {
    52
    0
                    format!(
    53
    0
                        "let {} = {} in {}",
    54
                        name,
    55
    0
                        self.format_expr(value, indent),
    56
    0
                        self.format_expr(body, indent)
    57
                    )
    58
                }
    59
    0
                ExprKind::Binary { left, op, right } => {
    60
    0
                    format!(
    61
    0
                        "{} {} {}",
    62
    0
                        self.format_expr(left, indent),
    63
                        op,
    64
    0
                        self.format_expr(right, indent)
    65
                    )
    66
                }
    67
    0
                ExprKind::Block(exprs) => {
    68
    0
                    let mut result = String::from("{\n");
    69
    0
                    for expr in exprs {
    70
    0
                        result.push_str(&format!(
    71
    0
                            "{}{}\n",
    72
    0
                            indent_str,
    73
    0
                            self.format_expr(expr, indent + 1)
    74
    0
                        ));
    75
    0
                    }
    76
    0
                    result.push_str(&format!("{indent_str}}}"));
    77
    0
                    result
    78
                }
    79
    0
                ExprKind::Function { name, params, return_type, body, .. } => {
    80
    0
                    let mut result = format!("fun {name}");
    81
    82
                    // Parameters
    83
    0
                    result.push('(');
    84
    0
                    for (i, param) in params.iter().enumerate() {
    85
    0
                        if i > 0 { result.push_str(", "); }
    86
    0
                        if let crate::frontend::ast::Pattern::Identifier(param_name) = &param.pattern {
    87
    0
                            result.push_str(param_name);
    88
    0
                            result.push_str(": ");
    89
    0
                            result.push_str(&self.format_type(&param.ty.kind));
    90
    0
                        }
    91
                    }
    92
    0
                    result.push(')');
    93
    94
                    // Return type
    95
    0
                    if let Some(ret_ty) = return_type {
    96
    0
                        result.push_str(" -> ");
    97
    0
                        result.push_str(&self.format_type(&ret_ty.kind));
    98
    0
                    }
    99
    100
    0
                    result.push(' ');
    101
    0
                    result.push_str(&self.format_expr(body.as_ref(), indent));
    102
    0
                    result
    103
                }
    104
    0
                ExprKind::If { condition, then_branch, else_branch } => {
    105
    0
                    let mut result = "if ".to_string();
    106
    0
                    result.push_str(&self.format_expr(condition, indent));
    107
    0
                    result.push(' ');
    108
    0
                    result.push_str(&self.format_expr(then_branch, indent));
    109
    0
                    if let Some(else_expr) = else_branch {
    110
    0
                        result.push_str(" else ");
    111
    0
                        result.push_str(&self.format_expr(else_expr, indent));
    112
    0
                    }
    113
    0
                    result
    114
                }
    115
                _ => {
    116
    0
                    format!("{:?}", expr.kind) // Fallback for unimplemented cases
    117
                }
    118
            }
    119
    0
        }
    120
    }
    121
    122
    impl Default for Formatter {
    123
    0
        fn default() -> Self {
    124
    0
            Self::new()
    125
    0
        }
    126
    }