#![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",
))]
use tempfile::TempDir;
use windjammer::{build_project_ext, CompilationTarget};
#[test]
fn test_cross_file_function_arg_inference() {
let temp = TempDir::new().unwrap();
let src = temp.path().join("src");
let build = temp.path().join("build");
std::fs::create_dir_all(src.join("combat")).unwrap();
std::fs::write(
src.join("combat/combat_system.wj"),
r#"
pub struct CombatStats {
pub health: f32,
pub max_health: f32,
pub damage: f32
}
impl CombatStats {
pub fn new(max_health: f32, max_damage: f32, armor: f32) -> CombatStats {
CombatStats {
health: max_health,
max_health: max_health,
damage: max_damage
}
}
}
"#,
)
.unwrap();
std::fs::write(
src.join("combat/enemy.wj"),
r#"
use crate::combat_system::CombatStats
pub struct Enemy {
pub stats: CombatStats,
pub x: f32,
pub y: f32
}
pub fn create_grunt(x: f32, y: f32) -> Enemy {
// These should infer f32 from CombatStats::new signature
Enemy {
stats: CombatStats::new(100.0, 50.0, 10.0),
x: x,
y: y
}
}
"#,
)
.unwrap();
std::fs::write(
src.join("combat/mod.wj"),
r#"
pub mod combat_system
pub mod enemy
"#,
)
.unwrap();
std::fs::write(
src.join("mod.wj"),
r#"
pub mod combat
"#,
)
.unwrap();
build_project_ext(
&src.join("mod.wj"),
&build,
CompilationTarget::Rust,
false,
true, &[],
)
.expect("Build should succeed");
let enemy_code = std::fs::read_to_string(build.join("combat/enemy.rs")).unwrap();
println!(
"Generated enemy.rs:\n{}",
enemy_code
.lines()
.filter(|l| l.contains("CombatStats::new") || l.contains("100.0") || l.contains("50.0"))
.collect::<Vec<_>>()
.join("\n")
);
assert!(
!enemy_code.contains("100.0_f64"),
"Should infer f32 from CombatStats::new params (cross-file). Found:\n{}",
enemy_code
.lines()
.find(|l| l.contains("100.0"))
.unwrap_or("NOT FOUND")
);
assert!(
!enemy_code.contains("50.0_f64"),
"Should infer f32 from function signature (cross-file)"
);
assert!(
!enemy_code.contains("10.0_f64"),
"Should infer f32 from function signature (cross-file)"
);
}
#[test]
fn test_cross_file_struct_field_inference() {
let temp = TempDir::new().unwrap();
let src = temp.path().join("src");
let build = temp.path().join("build");
std::fs::create_dir_all(&src).unwrap();
std::fs::write(
src.join("types.wj"),
r#"
pub struct Position {
pub x: f32,
pub y: f32,
pub z: f32
}
"#,
)
.unwrap();
std::fs::write(
src.join("spawner.wj"),
r#"
use crate::types::Position
pub fn spawn_at(x_pos: f32, y_pos: f32) -> Position {
Position {
x: x_pos,
y: y_pos,
z: 0.0
}
}
"#,
)
.unwrap();
std::fs::write(
src.join("mod.wj"),
r#"
pub mod types
pub mod spawner
"#,
)
.unwrap();
build_project_ext(
&src.join("mod.wj"),
&build,
CompilationTarget::Rust,
false,
true,
&[],
)
.expect("Build should succeed");
let spawner_code = std::fs::read_to_string(build.join("spawner.rs")).unwrap();
eprintln!("=== Generated spawner.rs ===");
eprintln!("{}", spawner_code);
eprintln!("=========================");
assert!(
!spawner_code.contains("0.0_f64"),
"Struct field literal should infer f32 from field type (cross-file)"
);
}