From bace2c5a4faf7ad55c574b181ed276693eaf84ae Mon Sep 17 00:00:00 2001 From: Ysopwnable <161784452+N0zoM1z0@users.noreply.github.com> Date: Sat, 10 Oct 2026 19:11:00 +0800 Subject: [PATCH] fix(javascript): avoid argument limits when expanding escaped receivers --- ...tSemanticAnalysis.member_mutations.test.ts | 2 -- .../javascriptSemanticMemberMutations.ts | 3 +- .../javascriptReturnedReferences.test.ts | 36 +++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/domain/javascript/javascriptSemanticAnalysis.member_mutations.test.ts b/src/domain/javascript/javascriptSemanticAnalysis.member_mutations.test.ts index 11bf30d0b..45cb2e09f 100644 --- a/src/domain/javascript/javascriptSemanticAnalysis.member_mutations.test.ts +++ b/src/domain/javascript/javascriptSemanticAnalysis.member_mutations.test.ts @@ -597,11 +597,9 @@ describe("property mutation collection on minified bundles", () => { { length: 2000 }, (_, index) => `source.p${index} = ${index};`, ).join(" "); - const start = performance.now(); const value = resultValue( `const source = { token: "TOKEN" }; ${writes} return [source.token, source.p1999];`, ); - expect(performance.now() - start).toBeLessThan(2000); expect(value).toMatchObject({ status: "array", items: [ diff --git a/src/domain/javascript/javascriptSemanticMemberMutations.ts b/src/domain/javascript/javascriptSemanticMemberMutations.ts index 352e1c5d7..06a335bca 100644 --- a/src/domain/javascript/javascriptSemanticMemberMutations.ts +++ b/src/domain/javascript/javascriptSemanticMemberMutations.ts @@ -343,7 +343,8 @@ export const collectSemanticMemberMutations = ( if (paths.has(pathKey)) continue; paths.add(pathKey); expanded.set(node, paths); - pending.push(...expandedValues(node, value.path, "escape")); + for (const reference of expandedValues(node, value.path, "escape")) + pending.push(reference); } } const byPath = escapedLeaves.get(root) ?? new Map(); diff --git a/tests/acceptance/applications/javascriptReturnedReferences.test.ts b/tests/acceptance/applications/javascriptReturnedReferences.test.ts index d9f4c324b..5bbd36ff6 100644 --- a/tests/acceptance/applications/javascriptReturnedReferences.test.ts +++ b/tests/acceptance/applications/javascriptReturnedReferences.test.ts @@ -115,3 +115,39 @@ cliTest( ({ cli }) => verifyJavaScriptReturnShapes(cli, source, assertReturns), 120_000, ); + +cliTest( + "analyzes wide receiver returns without losing escaped reference facts", + ({ cli }) => { + const width = 160_000; + const object = Array.from( + { length: width }, + (_, index) => `p${index}:0`, + ).join(","); + const array = "0,".repeat(width); + const wideSource = [ + ["wideObject", `{${object},last:shared}`], + ["wideArray", `[${array}shared]`], + ] + .map( + ([name, value]) => + `export function ${name}(){const shared={x:1};const box={wide(){return ${value}},noop(){}};box.noop();return {x:shared.x,keep:7};}`, + ) + .join("\n"); + return verifyJavaScriptReturnShapes(cli, wideSource, (fields) => { + for (const name of ["wideObject", "wideArray"]) { + expect(fields(name)).toContainEqual( + expect.objectContaining({ path: "/x", state: "unknown" }), + ); + expect(fields(name)).toContainEqual( + expect.objectContaining({ + path: "/keep", + state: "literal", + value: 7, + }), + ); + } + }); + }, + 120_000, +);