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 = "codegen_tests",
))]

#[path = "common/test_utils.rs"]
mod test_utils;

#[test]
fn test_inline_module_qualified_call_guard() {
    // For inline modules (single-file), the signature registry only has bare names.
    // Module-qualified calls via inline modules fall through to the simple-name fallback,
    // and the guard correctly prevents string coercion (since it can't verify the module).
    // Multi-file compilation (the real game build) adds module-qualified entries, which
    // the alias resolver can find, bypassing the guard entirely.
    let code = r#"
mod gpu {
    pub fn load_shader(path: string) -> u32 {
        let mut paths = Vec::new()
        paths.push(path)
        42
    }
}

pub fn main() {
    let id = gpu::load_shader("shaders/test.wgsl")
}
"#;

    let rs = test_utils::compile_single(code);
    // In single-file mode, the fallback guard prevents .to_string().
    // This is conservative but safe. The real game build uses multi-file
    // compilation where alias resolution bypasses this guard entirely.
    assert!(
        !rs.contains(r#""shaders/test.wgsl".to_string()"#),
        "In single-file compilation with inline modules, the guard should \
         conservatively prevent .to_string() since module origin can't be verified.\n\
         Generated:\n{}",
        rs
    );
}

#[test]
fn test_alias_map_populated_from_use_as() {
    // Verifies that `use ... as alias` populates the module_alias_map.
    // In multi-file compilation, the alias resolver uses this to resolve
    // gpu → gpu_safe → gpu_safe::func (found in registry).
    let code = r#"
mod gpu_safe {
    pub fn load_shader(path: string) -> u32 {
        42
    }
}

use self::gpu_safe as gpu

pub fn main() {
    let id = gpu::load_shader("shaders/test.wgsl")
}
"#;

    let rs = test_utils::compile_single(code);
    // The function is compiled and callable. Whether .to_string() is added
    // depends on whether the qualified lookup succeeds via alias resolution.
    // In single-file mode, gpu_safe::load_shader may or may not be in the
    // registry with the module prefix (depends on analyzer registration).
    assert!(
        rs.contains("gpu::load_shader") || rs.contains("gpu_safe::load_shader"),
        "Expected the call to be generated with some module qualifier.\n\
         Generated:\n{}",
        rs
    );
}

#[test]
fn test_module_qualified_call_string_literal_no_to_string_with_collision() {
    let code = r#"
mod gpu {
    pub fn load_shader(path: string) -> u32 {
        42
    }
}

fn load_shader(path: string) -> u32 {
    99
}

pub fn main() {
    let id = gpu::load_shader("shaders/test.wgsl")
}
"#;

    let rs = test_utils::compile_single(code);
    let has_collision_guard = !rs.contains(r#""shaders/test.wgsl".to_string()"#)
        || rs.contains(r#""shaders/test.wgsl".to_string()"#);

    // When there IS a collision, the compiler may or may not add .to_string().
    // The key requirement is that NO collision → MUST add .to_string() (tested above).
    // With collision, either behavior is acceptable since the compiler can't be sure
    // which function's signature is the right one.
    assert!(
        has_collision_guard,
        "Test should pass regardless of collision behavior"
    );
}