#![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 windjammer::analyzer::Analyzer;
use windjammer::codegen::rust::CodeGenerator;
use windjammer::lexer::Lexer;
use windjammer::parser::{Parser, Program};
use windjammer::CompilationTarget;
fn parse_code(code: &str) -> Program<'static> {
let mut lexer = Lexer::new(code);
let tokens = lexer.tokenize_with_locations();
let parser = Box::leak(Box::new(Parser::new(tokens)));
parser.parse().unwrap()
}
#[test]
fn test_string_param_assigned_to_string_field() {
let code = r#"
struct Config {
name: string,
}
impl Config {
pub fn set_name(self, name: string) {
self.name = name
}
}
"#;
let program = parse_code(code);
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);
let generated = generator.generate_program(&program, &analyzed_functions);
assert!(
generated.contains("name: String"),
"Parameter should be String when assigned to String field!\nGenerated:\n{}",
generated
);
assert!(
!generated.contains("set_name(&mut self, name: &str)"),
"Parameter should NOT be &str when assigned to String field!\nGenerated:\n{}",
generated
);
}
#[test]
fn test_string_param_not_assigned_can_be_str() {
let code = r#"
struct Logger {
logs: Vec<string>,
}
impl Logger {
pub fn log(self, message: string) {
// Just prints, doesn't assign to field
println(message)
}
}
"#;
let program = parse_code(code);
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);
let generated = generator.generate_program(&program, &analyzed_functions);
assert!(
generated.contains("message: &String") || generated.contains("message: &str") || generated.contains("message: String"),
"Parameter should be borrowed (&String or &str) or owned (String) when not assigned to field!\nGenerated:\n{}",
generated
);
}
#[test]
fn test_string_param_assigned_to_vec_push() {
let code = r#"
struct Logger {
logs: Vec<string>,
}
impl Logger {
pub fn add_log(self, message: string) {
self.logs.push(message)
}
}
"#;
let program = parse_code(code);
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);
let generated = generator.generate_program(&program, &analyzed_functions);
assert!(
generated.contains("message: String"),
"Parameter should be String when pushed to Vec<String>!\nGenerated:\n{}",
generated
);
}
#[test]
fn test_multiple_string_params() {
let code = r#"
struct User {
name: string,
email: string,
}
impl User {
pub fn update(self, name: string, email: string) {
self.name = name
self.email = email
}
}
"#;
let program = parse_code(code);
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);
let generated = generator.generate_program(&program, &analyzed_functions);
assert!(
generated.contains("name: String"),
"name parameter should be String!\nGenerated:\n{}",
generated
);
assert!(
generated.contains("email: String"),
"email parameter should be String!\nGenerated:\n{}",
generated
);
}
#[test]
fn test_concatenate_string_params_ownership() {
let code = r#"
pub fn concatenate(a: string, b: string, c: string) -> string {
return a + &b + &c
}
"#;
let program = parse_code(code);
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);
let generated = generator.generate_program(&program, &analyzed_functions);
assert!(
generated.contains("a: String") || generated.contains("mut a: String"),
"First param (a) should be String (owned). Generated:\n{}",
generated
);
assert!(
generated.contains("b: &str") && generated.contains("c: &str"),
"Params b and c should be &str (Phase 2 optimization). Generated:\n{}",
generated
);
}