#![cfg(any(
not(any(
feature = "parser_tests",
feature = "analyzer_tests",
feature = "codegen_tests",
feature = "interpreter_tests",
feature = "conformance_tests",
feature = "integration_tests",
)),
feature = "integration_tests",
))]
use windjammer::analyzer::Analyzer;
use windjammer::codegen::rust::CodeGenerator;
use windjammer::lexer::Lexer;
use windjammer::parser::Parser;
use windjammer::CompilationTarget;
fn parse_and_generate(code: &str) -> String {
let mut lexer = Lexer::new(code);
let tokens = lexer.tokenize_with_locations();
let mut parser = Parser::new(tokens);
let program = parser.parse().unwrap();
let mut analyzer = Analyzer::new();
let (analyzed_functions, analyzed_structs, _analyzed_trait_methods) =
analyzer.analyze_program(&program).unwrap();
let mut generator = CodeGenerator::new_for_module(analyzed_structs, CompilationTarget::Rust);
generator.generate_program(&program, &analyzed_functions)
}
#[test]
fn test_ffi_mut_local_passed_to_raw_pointer_param() {
let source = r#"
extern fn get_value(out: *mut f32)
fn use_it() -> f32 {
let mut x: f32 = 0.0
get_value(x)
x
}
"#;
let output = parse_and_generate(source);
assert!(
output.contains("&mut x") || output.contains("&mut x as *mut"),
"Should auto-convert mut local to &mut for *mut FFI param. Got:\n{}",
output
);
assert!(
!source.contains("&mut"),
"Source should NOT have explicit &mut (that's Rust leakage)"
);
}
#[test]
fn test_ffi_multiple_mut_out_params() {
let source = r#"
extern fn get_position(x: *mut f32, y: *mut f32, z: *mut f32)
fn use_it() {
let mut x: f32 = 0.0
let mut y: f32 = 0.0
let mut z: f32 = 0.0
get_position(x, y, z)
}
"#;
let output = parse_and_generate(source);
assert!(
output.contains("&mut x") && output.contains("&mut y") && output.contains("&mut z"),
"Should auto-convert all mut locals to &mut for *mut FFI params. Got:\n{}",
output
);
}
#[test]
fn test_ffi_non_mut_param_not_converted() {
let source = r#"
extern fn set_value(val: f32)
fn use_it() {
let x: f32 = 5.0
set_value(x)
}
"#;
let output = parse_and_generate(source);
assert!(
!output.contains("&mut x"),
"Non-pointer params should NOT be converted to &mut. Got:\n{}",
output
);
}
#[test]
fn test_ffi_mixed_params() {
let source = r#"
extern fn ffi_call(handle: u64, out_x: *mut f32, name_len: i32)
fn use_it() {
let h: u64 = 42
let mut x: f32 = 0.0
let n: i32 = 5
ffi_call(h, x, n)
}
"#;
let output = parse_and_generate(source);
assert!(
output.contains("&mut x"),
"Only *mut param should get &mut. Got:\n{}",
output
);
assert!(
!output.contains("&mut h"),
"Non-pointer u64 should NOT get &mut. Got:\n{}",
output
);
}