[PR #1437] [MERGED] fix(javascript): preserve effects through yielded array references #2886

Closed
opened 2026-10-17 21:11:25 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1437
Author: @N0zoM1z0
Created: 10/10/2026
Status: ✅ Merged
Merged: 10/10/2026
Merged by: @N0zoM1z0

Base: main ← Head: fix/javascript-array-iteration-aliases


📝 Commits (1)

  • 62bffde fix(javascript): preserve effects through yielded array references

📊 Changes

4 files changed (+188 additions, -4 deletions)

View changed files

📝 src/domain/javascript/javascriptSemanticAnalysis.ts (+18 -2)
📝 src/domain/javascript/javascriptSemanticIterationSources.ts (+11 -1)
📝 src/domain/javascript/javascriptSemanticMemberMutations.ts (+14 -1)
➕ tests/acceptance/applications/javascriptIterationAliases.test.ts (+145 -0)

📄 Description

for...of lost the reference from its loop binding to a yielded array element, so a later member write left exported return shapes reporting a stale literal. Preserve yielded references through existing destructuring/copy handling and the iterable fallback boundary. Resolve var and existing assignment targets in their actual lexical scope; treat yielded values stored in member-expression heads as escaped references.

For example:

const shared = { x: 1, keep: 7 };
for (const item of [shared]) item.x = 2;
return { x: shared.x, keep: shared.keep };

Before: x was reported as literal 1. After: x is unknown and keep remains literal 7. Actual source-owned Node 22/24 execution returns x: 2. The static analyzer does not pretend to execute the loop.

Validation:

  • A compiled public CLI regression failed against unmodified main, then passed through both CLI and actual SDK-connected stdio MCP. Covers 24 source variants: inline/named/spread arrays, var and existing/destructured/member targets, copies/defaults/rest, update/delete/escape, for await...of, indexed loops, and unaffected sibling/read-only/empty/for-in/shadow controls. MCP text and structured results preserve the same Evidence; the session remains usable.
  • All 343 adjacent semantic tests pass across six suites.
  • npm run check:fast and npm run verify:test-discovery pass.
  • Real Node 22.22.2 and 24.18.0 stdio MCP probes preserve the corrected values and controls.

No tool inventory or public schema change. No native provider changed; real Hopper/Ghidra verification was not performed. No private application or Node 26 coverage is claimed.

Closes #1428.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/1437 **Author:** [@N0zoM1z0](https://github.com/N0zoM1z0) **Created:** 10/10/2026 **Status:** ✅ Merged **Merged:** 10/10/2026 **Merged by:** [@N0zoM1z0](https://github.com/N0zoM1z0) **Base:** `main` ← **Head:** `fix/javascript-array-iteration-aliases` --- ### 📝 Commits (1) - [`62bffde`](https://github.com/morluto/rea/commit/62bffde3a8727b7947e24c6651da7620e1b291b8) fix(javascript): preserve effects through yielded array references ### 📊 Changes **4 files changed** (+188 additions, -4 deletions) <details> <summary>View changed files</summary> 📝 `src/domain/javascript/javascriptSemanticAnalysis.ts` (+18 -2) 📝 `src/domain/javascript/javascriptSemanticIterationSources.ts` (+11 -1) 📝 `src/domain/javascript/javascriptSemanticMemberMutations.ts` (+14 -1) ➕ `tests/acceptance/applications/javascriptIterationAliases.test.ts` (+145 -0) </details> ### 📄 Description `for...of` lost the reference from its loop binding to a yielded array element, so a later member write left exported return shapes reporting a stale literal. Preserve yielded references through existing destructuring/copy handling and the iterable fallback boundary. Resolve `var` and existing assignment targets in their actual lexical scope; treat yielded values stored in member-expression heads as escaped references. For example: ```js const shared = { x: 1, keep: 7 }; for (const item of [shared]) item.x = 2; return { x: shared.x, keep: shared.keep }; ``` Before: `x` was reported as literal `1`. After: `x` is unknown and `keep` remains literal `7`. Actual source-owned Node 22/24 execution returns `x: 2`. The static analyzer does not pretend to execute the loop. Validation: - A compiled public CLI regression failed against unmodified main, then passed through both CLI and actual SDK-connected stdio MCP. Covers 24 source variants: inline/named/spread arrays, `var` and existing/destructured/member targets, copies/defaults/rest, update/delete/escape, `for await...of`, indexed loops, and unaffected sibling/read-only/empty/for-in/shadow controls. MCP text and structured results preserve the same Evidence; the session remains usable. - All 343 adjacent semantic tests pass across six suites. - `npm run check:fast` and `npm run verify:test-discovery` pass. - Real Node 22.22.2 and 24.18.0 stdio MCP probes preserve the corrected values and controls. No tool inventory or public schema change. No native provider changed; real Hopper/Ghidra verification was not performed. No private application or Node 26 coverage is claimed. Closes #1428. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:11:25 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#2886
No description provided.