From f9ce32b4749026d3b6c05b8880f5549967cdb6ad Mon Sep 17 00:00:00 2001 From: Ysopwnable <161784452+N0zoM1z0@users.noreply.github.com> Date: Sat, 10 Oct 2026 17:50:36 +0800 Subject: [PATCH] test(javascript): verify escaped receivers through CLI and MCP --- ...iptSemanticAnalysis.member_mutations.test.ts | 4 +--- .../javascriptReturnedReferences.test.ts | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/domain/javascript/javascriptSemanticAnalysis.member_mutations.test.ts b/src/domain/javascript/javascriptSemanticAnalysis.member_mutations.test.ts index bf7d35c47f..11bf30d0b8 100644 --- a/src/domain/javascript/javascriptSemanticAnalysis.member_mutations.test.ts +++ b/src/domain/javascript/javascriptSemanticAnalysis.member_mutations.test.ts @@ -628,7 +628,7 @@ describe("results of methods on an escaped receiver", () => { }); }); - it("expands a receiver's methods once rather than once per call (#1495)", () => { + it("keeps a shared result uncertain across a wide escaped receiver (#1495)", () => { const count = 2000; const methods = Array.from( { length: count }, @@ -638,11 +638,9 @@ describe("results of methods on an escaped receiver", () => { { length: count }, (_, index) => `box.m${index}().p${index} = ${index};`, ).join(" "); - const start = performance.now(); const value = resultValue( `const shared = { token: "TOKEN" }; const box = { ${methods} }; ${calls} return [shared.token];`, ); - expect(performance.now() - start).toBeLessThan(2000); expect(value).toMatchObject({ status: "array", items: [{ value: { status: "unknown" } }], diff --git a/tests/acceptance/applications/javascriptReturnedReferences.test.ts b/tests/acceptance/applications/javascriptReturnedReferences.test.ts index bd9a05c761..d9f4c324b4 100644 --- a/tests/acceptance/applications/javascriptReturnedReferences.test.ts +++ b/tests/acceptance/applications/javascriptReturnedReferences.test.ts @@ -47,6 +47,10 @@ const writes = { constructor: "function Box() { return shared; } const t = new Box(); t.x = 2;", callback: "const get = () => shared; [0].forEach(() => { get().x = 2; });", + wideMethods: `const box = { ${Array.from( + { length: 64 }, + (_, index) => `m${index}() { return shared; }`, + ).join(", ")} }; box.m0().x = 2; box.m63().other = 3;`, }; const source = [ ...Object.entries(writes).map( @@ -61,6 +65,8 @@ const source = [ "export function unused(){ const shared = {x: 1}; const get = () => shared; get(); return shared.x; }", "export function nestedCallable(){ const shared = {x: 1}; const get = () => { const inner = () => shared; return {x: 0}; }; get().x = 2; return shared.x; }", "export function unrelated(){ const shared = {x: 1}; const other = {x: 9}; const get = () => shared; get().x = 2; return other.x; }", + "export function receiverDistinctScopes(){ const shared = {x: 1}; const box = {outer(){ return shared; }, inner(){ const shared = {x: 9}; return shared; }, noop(){}}; box.noop(); return {outer: shared.x, inner: box.inner().x}; }", + "export function receiverDistinctPaths(){ const parent = {left: {x: 1}, right: {x: 9}, keep: 7}; const box = {left(){ return parent.left; }, right(){ return parent.right; }, noop(){}}; box.noop(); return {left: parent.left.x, right: parent.right.x, keep: parent.keep}; }", ].join("\n"); const assertReturns = (fields: JavaScriptReturnFields): void => { @@ -91,6 +97,17 @@ const assertReturns = (fields: JavaScriptReturnFields): void => { expect(fields("unrelated")).toContainEqual( expect.objectContaining({ path: "", state: "literal", value: 9 }), ); + for (const path of ["/outer", "/inner"]) + expect(fields("receiverDistinctScopes")).toContainEqual( + expect.objectContaining({ path, state: "unknown" }), + ); + for (const path of ["/left", "/right"]) + expect(fields("receiverDistinctPaths")).toContainEqual( + expect.objectContaining({ path, state: "unknown" }), + ); + expect(fields("receiverDistinctPaths")).toContainEqual( + expect.objectContaining({ path: "/keep", state: "literal", value: 7 }), + ); }; cliTest(