修复被调用函数条件赋值状态合并

保留被调用函数内条件赋值前的既有 alias 状态
新增条件副作用同时可达真实与候选接收者的回归测试
This commit is contained in:
2026-08-04 12:48:11 +08:00
parent 141726e0f1
commit 865ff7e7d8
@@ -4591,8 +4591,12 @@ fn javascript_apply_alias_transition(
return;
}
if transition.conditional {
let had_state = state.resolved;
state.indices.extend(transition.indices);
state.resolved = true;
if !had_state {
state.conditional = true;
}
} else {
*state = transition;
}
@@ -9582,6 +9586,19 @@ mod javascript_projection_reachability_tests {
assert!(javascript_position_is_reachable(content, &ranges, decoy));
}
#[test]
fn conditional_assignment_inside_an_invoked_function_preserves_prior_state() {
let content = "const real = { run() { return import('./real.mjs'); } }; const decoy = { run() { return import('./decoy.mjs'); } }; let receiver = real; function maybeSwap() { if (flag) receiver = decoy; } maybeSwap(); function start() { return receiver.run(); } start();";
let ranges = named_javascript_function_ranges(content);
for source in ["./real.mjs", "./decoy.mjs"] {
let position = content.find(source).expect("find conditional callee owner");
assert!(
javascript_position_is_reachable(content, &ranges, position),
"a conditional callee side effect must preserve both states: {source}",
);
}
}
#[test]
fn super_owner_is_fixed_when_the_class_is_defined() {
let content = "let Base = class { run() { return import('./real-base.mjs'); } }; class Game extends Base { start() { return super.run(); } } Base = class { run() { return import('./decoy-base.mjs'); } }; new Game().start();";