[PR #836] [MERGED] fix(javascript): keep exact empty env keys and method names #2274

Closed
opened 2026-10-16 21:16:35 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/836
Author: @kaoru0822-kitauji
Created: 10/7/2026
Status: ✅ Merged
Merged: 10/7/2026
Merged by: @kaoru0822-kitauji

Base: main ← Head: fix/empty-static-key-consumers


📝 Commits (2)

  • f7954a8 fix(javascript): keep exact empty env keys and method names
  • ad1f6b5 fix(javascript): keep exact empty require paths and request fields

📊 Changes

8 files changed (+138 additions, -17 deletions)

View changed files

📝 src/application/JavaScriptSemanticGraphBuilder.test.ts (+32 -0)
📝 src/application/JavaScriptSemanticGraphBuilder.ts (+3 -1)
📝 src/application/JavaScriptSemanticGraphConstruction.ts (+8 -0)
📝 src/application/JavaScriptSemanticGraphDataProjection.ts (+5 -1)
📝 src/application/JavaScriptSemanticGraphValueProjection.ts (+2 -1)
📝 src/domain/javascriptSemanticAnalysis.empty_keys.test.ts (+72 -0)
📝 src/domain/javascriptSemanticDataEffects.ts (+8 -4)
📝 src/domain/javascriptSemanticProjection.ts (+8 -10)

📄 Description

Summary

Completes the empty-key audit in #783 (follow-up to #764). Every remaining consumer that used "" as both "the exact empty key" and "unknown computed key" now uses the nullable semanticStaticPropertyKey:

Site Before After
processConfigurationMember — process.env[''] key: null, partial (same as dynamic process.env[key]) key: "", complete
callableName — { ['']() { return 42; } } [computed@N] exact "" (Node: o[''].name === "")
semanticModuleOrigin — require("m")[''] origin dropped, no require link require link with importedName: ""
requirePatternBindings — const {'': a} = require("m") binding skipped require link with importedName: ""
requestFields — fetch(url, { '': v }) field skipped field ""

Each has a dynamic-key negative control (process.env[key], [key](), require("m")[key], {[key]: c} = require(...), {[key]: 1}), which still produce null/partial, [computed@N], or no link/field.

API selectors in data-effect, timer, resource, Promise, and Electron helpers compare against their supported names and are intentionally unchanged — recognizing an empty key does not broaden any API whitelist.

Display labels

Graph node labels must be nonempty (label: z.string().min(1).nullable()). A shared semanticNameLabel helper in JavaScriptSemanticGraphConstruction.ts displays the empty key as "" — the convention #764 introduced for property slots — and is now used for property-slot, config-source, and function nodes. Config sources keep the exact key in properties.key; module links and request fields carry the exact value in imported_name/imported_path/field properties.

Contract / behavior changes

No schema changes. Output changes only for sources containing exact empty keys, per the table above.

Verification

  • New regressions in JavaScriptSemanticGraphBuilder.test.ts and javascriptSemanticAnalysis.empty_keys.test.ts fail without the source changes (5 failures across both commits) and pass with them.
  • npm run check:changed — 28 files / 404 tests passed.
  • npm run check:fast — passed.
  • Built CLI rea analyze-javascript-application <dir> --artifact-format directory --format json on fixtures (with a sibling table.js exporting {'': 'HOME'}; Node confirms both forms read HOME) emits config-source "" with key "", function "", imported_name: "" / imported_path: [""], and request field "".

No Hopper/Ghidra/IDA verification needed (static JavaScript analysis only).

While verifying, I found that other empty string literals (fetch(''), bus.on('', f), ipcMain.handle(''), require(''), import '' ) make the whole analysis fail with a generic unreadable_output because they become empty node labels. That is a separate crash, which I'll address in a follow-up PR.

🤖 Generated with Claude Code


🔄 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/836 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/7/2026 **Status:** ✅ Merged **Merged:** 10/7/2026 **Merged by:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Base:** `main` ← **Head:** `fix/empty-static-key-consumers` --- ### 📝 Commits (2) - [`f7954a8`](https://github.com/morluto/rea/commit/f7954a8fd692f262ef3ce1507b957681150ce9c4) fix(javascript): keep exact empty env keys and method names - [`ad1f6b5`](https://github.com/morluto/rea/commit/ad1f6b508fbdd44d8bf1884ed96ae69082808e7d) fix(javascript): keep exact empty require paths and request fields ### 📊 Changes **8 files changed** (+138 additions, -17 deletions) <details> <summary>View changed files</summary> 📝 `src/application/JavaScriptSemanticGraphBuilder.test.ts` (+32 -0) 📝 `src/application/JavaScriptSemanticGraphBuilder.ts` (+3 -1) 📝 `src/application/JavaScriptSemanticGraphConstruction.ts` (+8 -0) 📝 `src/application/JavaScriptSemanticGraphDataProjection.ts` (+5 -1) 📝 `src/application/JavaScriptSemanticGraphValueProjection.ts` (+2 -1) 📝 `src/domain/javascriptSemanticAnalysis.empty_keys.test.ts` (+72 -0) 📝 `src/domain/javascriptSemanticDataEffects.ts` (+8 -4) 📝 `src/domain/javascriptSemanticProjection.ts` (+8 -10) </details> ### 📄 Description ## Summary Completes the empty-key audit in #783 (follow-up to #764). Every remaining consumer that used `""` as both "the exact empty key" and "unknown computed key" now uses the nullable `semanticStaticPropertyKey`: | Site | Before | After | |---|---|---| | `processConfigurationMember` — `process.env['']` | `key: null`, `partial` (same as dynamic `process.env[key]`) | `key: ""`, `complete` | | `callableName` — `{ ['']() { return 42; } }` | `[computed@N]` | exact `""` (Node: `o[''].name === ""`) | | `semanticModuleOrigin` — `require("m")['']` | origin dropped, no require link | require link with `importedName: ""` | | `requirePatternBindings` — `const {'': a} = require("m")` | binding skipped | require link with `importedName: ""` | | `requestFields` — `fetch(url, { '': v })` | field skipped | field `""` | Each has a dynamic-key negative control (`process.env[key]`, `[key]()`, `require("m")[key]`, `{[key]: c} = require(...)`, `{[key]: 1}`), which still produce `null`/`partial`, `[computed@N]`, or no link/field. API selectors in data-effect, timer, resource, Promise, and Electron helpers compare against their supported names and are intentionally unchanged — recognizing an empty key does not broaden any API whitelist. ### Display labels Graph node labels must be nonempty (`label: z.string().min(1).nullable()`). A shared `semanticNameLabel` helper in `JavaScriptSemanticGraphConstruction.ts` displays the empty key as `""` — the convention #764 introduced for property slots — and is now used for property-slot, config-source, and function nodes. Config sources keep the exact key in `properties.key`; module links and request fields carry the exact value in `imported_name`/`imported_path`/`field` properties. ## Contract / behavior changes No schema changes. Output changes only for sources containing exact empty keys, per the table above. ## Verification - New regressions in `JavaScriptSemanticGraphBuilder.test.ts` and `javascriptSemanticAnalysis.empty_keys.test.ts` fail without the source changes (5 failures across both commits) and pass with them. - `npm run check:changed` — 28 files / 404 tests passed. - `npm run check:fast` — passed. - Built CLI `rea analyze-javascript-application <dir> --artifact-format directory --format json` on fixtures (with a sibling `table.js` exporting `{'': 'HOME'}`; Node confirms both forms read `HOME`) emits config-source `""` with key `""`, function `""`, `imported_name: ""` / `imported_path: [""]`, and request field `""`. No Hopper/Ghidra/IDA verification needed (static JavaScript analysis only). ## Related, not in this PR While verifying, I found that other empty **string literals** (`fetch('')`, `bus.on('', f)`, `ipcMain.handle('')`, `require('')`, `import '' `) make the whole analysis fail with a generic `unreadable_output` because they become empty node labels. That is a separate crash, which I'll address in a follow-up PR. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-16 21:16:35 +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#2274
No description provided.