fix: unwrap computed string-literal keys in typeMap/prototype extraction sites#2022
Conversation
…type extraction sites extractObjectLiteralFunctions' pair branch was fixed for this gap in #1764, but several adjacent extraction sites in both engines still fell back to raw bracket/quote text for computed_property_name keys instead of unwrapping resolvable string literals, producing garbled typeMap/prototype entries like obj.['foo'] and under-extracting object-rest-param bindings for computed keys. Introduces a shared resolvePairKeyName (TS) / reuses the existing resolve_pair_key_name (Rust, added in #1764) helper and routes these sites through it: - handleObjectLiteralTypeMap's pair and method_definition branches - handleDefinePropertyTypeMap's defineProperties pair-iteration branch - seedProtoProperties's pair branch (Object.create prototype literal) - collectObjectRestParams's pair branch (now unwraps resolvable computed keys instead of blanket-skipping all computed keys) - extractPrototypeObjectLiteral's method_definition and pair branches Mirrors: seed_object_create_entries, seed_descriptor_object, seed_objlit_type_map_entries, extract_js_prototype_object_literal, and collect_object_rest_params in the Rust extractor. Impact: 6 functions changed, 15 affected
Greptile SummaryThis PR extends the computed string-literal key fix from #1764 to the remaining extraction sites in both the TypeScript and Rust engines. Previously only
Confidence Score: 5/5Safe to merge — all changed sites are narrowly scoped to key-resolution logic with direct test coverage, and both engines produce identical outputs for the fixed patterns. The fix is a clean mechanical substitution: ad-hoc inline key-stripping in seven pair/method_definition branches is replaced by a well-tested shared helper that already existed for the No files require special attention. All three changed files are well-structured and consistently handled. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[pair node key field] --> B{keyNode.type?}
B -->|string| C[Strip outer quotes]
B -->|computed_property_name| D[resolveComputedKeyName]
B -->|identifier or other| E[Return keyNode.text as-is]
D --> F{inner child type?}
F -->|string or string_fragment| G[Return stripped string content]
F -->|other e.g. Symbol.x| H[Return empty string]
C --> I{keyName empty?}
G --> I
E --> I
H --> I
I -->|yes| J[skip - no entry emitted]
I -->|no| K[Emit qualified typeMap or definition entry]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[pair node key field] --> B{keyNode.type?}
B -->|string| C[Strip outer quotes]
B -->|computed_property_name| D[resolveComputedKeyName]
B -->|identifier or other| E[Return keyNode.text as-is]
D --> F{inner child type?}
F -->|string or string_fragment| G[Return stripped string content]
F -->|other e.g. Symbol.x| H[Return empty string]
C --> I{keyName empty?}
G --> I
E --> I
H --> I
I -->|yes| J[skip - no entry emitted]
I -->|no| K[Emit qualified typeMap or definition entry]
Reviews (1): Last reviewed commit: "fix(extractors): unwrap computed string-..." | Re-trigger Greptile |
Codegraph Impact Analysis6 functions changed → 15 callers affected across 1 files
|
Summary
#1764 fixed
extractObjectLiteralFunctions'spairbranch (and its Rust mirror) so a computed string-literal key like{ ['foo']: () => {} }resolves to the plain qualifiedDefinition.name(obj.foo) instead of the raw bracket/quote text (obj.['foo']). This issue covers the remaining sites found during that fix — same "only unwrap plainstring-typed keys, fall back to raw text forcomputed_property_name" gap, but in functions that feedtypeMapseeding and other adjacent extraction paths rather thanDefinition.namedirectly. Left uncorrected, they produce dangling/garbled typeMap keys and under-extracted bindings for the affected call patterns (correctness bug, not just cosmetic).TypeScript (
src/extractors/javascript.ts)handleObjectLiteralTypeMap'spairbranch — same string-only gap for typeMap seeding.handleObjectLiteralTypeMap'smethod_definitionbranch — used rawnameNode.textunconditionally (would even mishandle[Symbol.iterator]-style keys).handleDefinePropertyTypeMap'sdefinePropertiespair-iteration branch.seedProtoProperties'spairbranch (Object.create({ ['foo']: fn })).collectObjectRestParams'spairbranch — previously blanket-skipped all computed keys (including resolvable string literals); now unwraps resolvable ones instead of under-extracting.extractPrototypeObjectLiteral'smethod_definitionbranch — didn't callresolveMethodDefinitionName(cross-engine divergence: Rust's mirror already did).extractPrototypeObjectLiteral'spairbranch.Extracted a shared
resolvePairKeyName(keyNode)helper (mirrors the Rustresolve_pair_key_nameadded in #1764) and routed all of the above through it.Rust (
crates/codegraph-core/src/extractors/javascript.rs)seed_object_create_entries,seed_descriptor_object,seed_objlit_type_map_entries,extract_js_prototype_object_literal— same string-only gap in theirpairarms; now route through the existingresolve_pair_key_namehelper.collect_object_rest_params'spairarm had the identical blanket-skip-all-computed-keys bug as its TS counterpart (not explicitly listed in the issue body, but the same root cause in the mirrored function) — fixed the same way for engine parity.Both engines verified to produce identical results on a manual repro exercising every fixed site (
codegraph query <fn> -Tshows identical caller edges under--engine wasmand--engine native).Closes #1884
Test plan
npx vitest run tests/parsers/javascript.test.ts— 230 passed, including 13 new tests covering every fixed site (both the resolvable-computed-key and non-string-computed-key-skip cases)cargo test --manifest-path crates/codegraph-core/Cargo.toml --lib— 577 passed (8 new), including mirrors of the same 13 TS casesnpm test— full suite: 3912 passed, 1 pre-existing unrelated flake (checkNoNewCyclescycle-node ordering, filed separately as Flaky cycle-node ordering in checkNoNewCycles full-suite run (tests/integration/check.test.ts) #1990, reproduces identically with this fix's files reverted)npm run lint/npm run build— cleannode_modules/@optave/codegraph-darwin-arm64for a real end-to-end check (not npm-registry prebuilt) —--engine wasmand--engine nativeproduce identical node/edge counts and caller sets for the repro