From f4cabe535fa52672c021a0e0722d52379b6ce5cf Mon Sep 17 00:00:00 2001 From: jayinvers <100169062+jayinvers@users.noreply.github.com> Date: Thu, 22 Oct 2026 09:08:00 +1300 Subject: [PATCH] fix(wasm): pass glue filenames to the JavaScript parser (#4485) associateWasmGlue selected the unnamed-source parser mode even though the selected glue filename was already an adapter argument, so valid JavaScript such as `n===0?H=>({start:H.startY}):H=>({start:H.startX})` was read with the TypeScript grammar (conditional arrows as a return type) and the whole glue file failed parsing, losing every .wasm literal reference after it. Pass the filename so .js glue parses with the JavaScript grammar, matching the general filename-aware parser boundary from #3782. The unnamed-source fallback policy itself is unchanged. Adds a regression test asserting the conditional-arrow fixture parses completely and retains the ./module.wasm reference (line 2, column 6, local-path-candidate, static-literal) while the plain fetch control stays working; reverting the fix fails the new test. Fixes #4474 Co-authored-by: maxazure --- src/wasm/WabtOutput.test.ts | 34 ++++++++++++++++++++++++++++++++++ src/wasm/WasmGlueAdapter.ts | 3 +++ 2 files changed, 37 insertions(+) diff --git a/src/wasm/WabtOutput.test.ts b/src/wasm/WabtOutput.test.ts index d69cafa73f..f1aabe95a9 100644 --- a/src/wasm/WabtOutput.test.ts +++ b/src/wasm/WabtOutput.test.ts @@ -284,6 +284,40 @@ it("keeps exact local, ambiguous URL, computed and unparseable glue distinct", ( }); }); +it("retains .wasm references in glue whose conditional arrows only parse as JavaScript", () => { + const candidates = ["/app/module.wasm"]; + // TypeScript grammar reads `n===0?H=>(x):H=>(y)` as a return type, so the + // unnamed-source fallback fails the file; the .js filename selects JavaScript. + const conditional = associateWasmGlue( + 'const pick=n===0?H=>({start:H.startY}):H=>({start:H.startX});\nfetch("./module.wasm");\n', + "/app/glue.js", + candidates, + ); + expect(conditional.parse_status).toBe("complete"); + expect(conditional.references).toMatchObject([ + { + value: "./module.wasm", + line: 2, + column: 6, + candidate_paths: candidates, + association: "local-path-candidate", + evidence_kind: "static-literal", + }, + ]); + + expect( + associateWasmGlue('fetch("./module.wasm");\n', "/app/glue.js", candidates) + .references, + ).toMatchObject([ + { + value: "./module.wasm", + line: 1, + column: 6, + association: "local-path-candidate", + }, + ]); +}); + it("retains directive literals and matches their cooked escaped path", () => { const candidates = ["/app/module.wasm"]; const directive = associateWasmGlue( diff --git a/src/wasm/WasmGlueAdapter.ts b/src/wasm/WasmGlueAdapter.ts index f249c232cb..4a130508ed 100644 --- a/src/wasm/WasmGlueAdapter.ts +++ b/src/wasm/WasmGlueAdapter.ts @@ -11,8 +11,11 @@ export const associateWasmGlue = ( ) => { // Babel requires a hashbang at offset zero. Removing only its preceding BOM // leaves reference coordinates intact: all code starts on a later line. + // The selected filename selects the JavaScript grammar for .js glue; the + // unnamed-source fallback would misread valid JavaScript conditionals. const file = parseJavaScriptSource( source.startsWith("\uFEFF#!") ? source.slice(1) : source, + path, ); const references: { value: string;