fix(javascript): keep exact empty env keys and method names

`process.env['']` now projects an exact empty environment key with
complete resolution instead of the same null/partial result as a dynamic
`process.env[key]`. `{ ['']() {} }` keeps its exact empty method name in
the IR instead of a generated `[computed@N]` name.

Semantic graph labels stay nonempty: a shared `semanticNameLabel` helper
displays the empty key as `""` for property slots, config sources, and
function nodes, while `properties.key` keeps the exact value.

Refs #783

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Iwakurakaoru0822
2026-10-06 20:35:02 -07:00
parent ef535b81fe
commit f7954a8fd6
8 changed files with 83 additions and 7 deletions
@@ -349,6 +349,38 @@ it.each([
);
},
);
it("keeps exact empty environment keys distinct from dynamic keys", () => {
const graph = graphFor(`
const empty = process.env[''];
const named = process.env.HOME;
const dynamic = process.env[name];
`);
const sources = graph.nodes
.filter(({ kind }) => kind === "config-source")
.map(({ label, properties }) => ({ label, key: properties.key }));
expect(sources).toEqual(
expect.arrayContaining([
{ label: '""', key: "" },
{ label: "HOME", key: "HOME" },
{ label: "environment", key: null },
]),
);
expect(sources).toHaveLength(3);
});
it("labels exact empty method names without inventing computed names", () => {
const graph = graphFor(`
const target = { ['']() { return 42; }, [key]() { return 1; } };
`);
const labels = graph.nodes
.filter(({ kind }) => kind === "function")
.map(({ label }) => label);
expect(labels).toContain('""');
expect(
labels.filter((label) => label?.startsWith("[computed@")),
).toHaveLength(1);
});
it.each([
"Promise.resolve(1)",
"(Promise.resolve(1) as Promise<number>)",