fix(javascript): preserve CommonJS assignment result and receiver uncertainty

Resolve values returned by simple assignment chains at the export boundary. Suppress property links proven to target a detached receiver; retain unresolved links when reassignment may preserve receiver identity. Identify root assignments from their AST target rather than the displayed export name.

Validation: 25 semantic tests, seven targeted compiled CLI/MCP scenarios with Node runtime controls, build, and check:fast passed. Existing full acceptance suite passed before receiver refinements; the final changes were checked with targeted scenarios rather than repeating its 130-second run.
This commit is contained in:
morluto committed 2026-10-11 09:47:41 +08:00
1 parent 7956934965
commit 1e51c732bb
3 files changed
+294 -11

No files matched your search

@@ -342,6 +342,38 @@ describe("JavaScript semantic analysis: structure 2", () => {
);
});
it("resolves the value of a simple assignment expression exported through CommonJS", () => {
const ir = analyzeJavaScriptSemantics(`
function parse() { return { kind: "result" }; }
const holder = {};
module.exports = holder.value = parse;
`);
expect(ir.moduleLinks).toEqual(
expect.arrayContaining([
expect.objectContaining({
kind: "commonjs-export",
localName: "parse",
exportedName: "default",
}),
]),
);
});
it.each(["parse", "default"])(
"does not export a %s property write to a replaced module.exports receiver",
(name) => {
const ir = analyzeJavaScriptSemantics(`
module.exports.${name} = (module.exports = () => ({ kind: "result" }));
`);
expect(ir.moduleLinks).toEqual([
expect.objectContaining({
kind: "commonjs-export",
exportedName: "default",
}),
]);
},
);
it("classifies destructuring and loop targets as writes, not reads", () => {
const ir = analyzeJavaScriptSemantics(`
let a, b, c;