windjammer 0.48.0

A simple language inspired by Go, Ruby, and Elixir that transpiles to Rust - 80% of Rust's power with 20% of the complexity
Documentation
#![cfg(any(
    not(any(
        feature = "parser_tests",
        feature = "analyzer_tests",
        feature = "codegen_tests",
        feature = "interpreter_tests",
        feature = "conformance_tests",
        feature = "integration_tests",
    )),
    feature = "analyzer_tests",
))]

/// TDD Test: if-let codegen optimization
///
/// Bug: The parser converts `if let` to a `Statement::Match` with 2 arms:
///   - Arm 0: the destructuring pattern (e.g., `Some(x)`) with body
///   - Arm 1: `Pattern::Wildcard` with an empty block body
///
///     The codegen then emits a full `match` statement with `_ => {}`, triggering
///     clippy's "you seem to be trying to use `match` for destructuring a single
///     pattern" warning (84 instances in windjammer-game).
///
/// Fix: Detect this pattern in Statement::Match codegen and emit `if let`
/// instead of `match`. When the wildcard arm has a non-empty body, emit
/// `if let ... { } else { }`.
#[path = "common/test_utils.rs"]
mod test_utils;

#[test]
fn test_if_let_some_generates_if_let() {
    // `if let Some(x) = expr { ... }` should generate `if let Some(x) = expr { ... }`
    // NOT `match expr { Some(x) => { ... }, _ => {} }`
    let source = r#"
pub struct Container {
    pub value: Option<i32>,
}

impl Container {
    pub fn process(self) {
        if let Some(v) = self.value {
            println("{}", v)
        }
    }
}
"#;

    let generated = test_utils::compile_single(source);
    println!("Generated:\n{}", generated);

    assert!(
        generated.contains("if let Some(v)"),
        "if let Some(v) should generate `if let`, not `match`.\nGenerated:\n{}",
        generated
    );
    assert!(
        !generated.contains("match self.value"),
        "Should NOT generate a match statement for if-let pattern.\nGenerated:\n{}",
        generated
    );
}

#[test]
fn test_if_let_with_else_generates_if_let_else() {
    // `if let Some(x) = expr { ... } else { ... }` should generate `if let ... else`
    let source = r#"
pub struct Container {
    pub value: Option<i32>,
}

impl Container {
    pub fn get_or_default(self) -> i32 {
        if let Some(v) = self.value {
            v
        } else {
            0
        }
    }
}
"#;

    let generated = test_utils::compile_single(source);
    println!("Generated:\n{}", generated);

    assert!(
        generated.contains("if let Some(v)"),
        "if let with else should generate `if let`, not `match`.\nGenerated:\n{}",
        generated
    );
    assert!(
        generated.contains("} else {"),
        "if let with else should have an else block.\nGenerated:\n{}",
        generated
    );
}

#[test]
fn test_if_let_with_mutable_ref() {
    // `if let Some(x) = map.get_mut(&key) { ... }` should also produce if let
    let source = r#"
use std::collections::HashMap

pub struct Registry {
    pub items: HashMap<string, i32>,
}

impl Registry {
    pub fn increment(self, key: string) {
        if let Some(val) = self.items.get_mut(key) {
            *val = *val + 1
        }
    }
}
"#;

    let generated = test_utils::compile_single(source);
    println!("Generated:\n{}", generated);

    assert!(
        generated.contains("if let Some(val)"),
        "if let on get_mut should generate `if let`.\nGenerated:\n{}",
        generated
    );
}

#[test]
fn test_real_match_not_converted() {
    // A real match with multiple meaningful arms should NOT be converted to if-let
    let source = r#"
pub fn describe(opt: Option<i32>) -> string {
    match opt {
        Some(v) => format!("Value: {}", v),
        None => "Nothing".to_string(),
    }
}
"#;

    let generated = test_utils::compile_single(source);
    println!("Generated:\n{}", generated);

    assert!(
        generated.contains("match opt"),
        "Real match with meaningful arms should stay as match.\nGenerated:\n{}",
        generated
    );
}