use cure_engine::Config;
pub fn optimize(text: &str) -> Option<String> {
if std::env::var_os("JSCD_NO_OPT").is_some() {
return None;
}
if text.trim().is_empty() {
return None;
}
let mut parsed = cure_ts_parser::parse_js(text);
if !parsed.errors.is_empty() {
return None;
}
let cfg = Config::default();
let _ = cure_ts_simplify::simplify_unit(&mut parsed.ast, &mut parsed.unit, &cfg);
let printed = cure_ts_print::print_module(&parsed.ast, &parsed.unit);
if printed.trim().is_empty() {
None
} else {
Some(printed)
}
}
#[cfg(test)]
mod tests {
use super::optimize;
#[test]
fn keeps_unreferenced_top_level_declarations() {
let src = "someCall();\nfunction target(a0) { return a0; }\nvar Counter;\nCounter = target;\n";
let out = optimize(src).expect("parse+optimize");
assert!(out.contains("function target"), "顶层函数声明不许丢:{out}");
assert!(out.contains("Counter = target"), "顶层赋值不许丢:{out}");
assert!(out.contains("someCall()"), "{out}");
}
#[test]
fn keeps_registers_with_multiple_uses() {
let src = "let r0 = greet;\nuse(r0);\nuse(r0);\nfunction greet(a0) { return a0; }\n";
let out = optimize(src).expect("parse+optimize");
assert!(out.contains("r0"), "多次读的寄存器不许折叠掉:{out}");
}
#[test]
fn returns_none_on_unparseable_input() {
assert!(optimize("let r0 = ;;;").is_none());
}
#[test]
fn returns_none_on_empty_input() {
assert!(optimize("").is_none());
}
#[test]
fn does_not_rename() {
let src = "let r0 = 1;\nlet r1 = r0 + 1;\nexports.x = r1;\n";
let out = optimize(src).expect("parse+optimize");
assert!(out.contains("exports.x"), "全局引用不许改名:{out}");
}
}