Skip to content

fix(parity): align WASM/native extraction for swift and jelly-micro fixtures#1594

Merged
carlos-alm merged 3 commits into
mainfrom
fix/titan-parity-swift-jelly-micro
Jun 18, 2026
Merged

fix(parity): align WASM/native extraction for swift and jelly-micro fixtures#1594
carlos-alm merged 3 commits into
mainfrom
fix/titan-parity-swift-jelly-micro

Conversation

@carlos-alm

Copy link
Copy Markdown
Contributor

Summary

Fixes 2 engine parity divergences discovered during the Titan parity audit (35/36 fixtures clean after this fix):

  • Swift (3 edges): WASM extractor missed class.method call edges for chained method calls — swift.ts updated to handle chained dispatch
  • jelly-micro (12 nodes): Native extractor missed object-spread property extraction — javascript.rs updated to handle { ...obj } spread patterns; javascript.ts updated to match

Titan Audit Context

Changes

  • src/extractors/swift.ts — chained method call edge extraction
  • crates/codegraph-core/src/extractors/swift.rs — mirror fix
  • src/extractors/javascript.ts — object-spread property extraction
  • tests/parsers/javascript.test.ts — regression test for spread patterns
  • tests/parsers/swift.test.ts — regression test for chained method calls

Metrics Impact

  • Swift fixture: 0/3 edges → 3/3 edges (100% recall)
  • jelly-micro fixture: 12 missing nodes restored

Test plan

  • CI passes (lint + build + tests)
  • tests/parsers/swift.test.ts passes
  • tests/parsers/javascript.test.ts passes
  • Parity benchmark: swift and jelly-micro fixtures both clean

…ixtures

swift:
- WASM extractors/swift.ts: navigation_expression calls used navigation_suffix
  child text (".save") rather than descending into the simple_identifier. Adds
  seedSwiftPropertyTypeMap() to also set typeMap from class-body property
  type annotations so receiver edges resolve correctly (repo -> UserRepository).
- Rust extractors/swift.rs: mirrors the navigation_suffix fix — descends into
  find_child(&n, "simple_identifier") to extract the bare method name.
- Both engines now produce identical calls (name="save", receiver="repo") and
  the 3 missing receiver + calls edges in the swift fixture.

jelly-micro:
- WASM extractors/javascript.ts: extractObjectLiteralFunctions was only called
  for const declarations. Adds extractLetVarObjLiteralDeclarators() to emit
  qualified method definitions (var.method) for let/var object literals,
  called from extractConstantsWalk (which provides the function-scope guard).
  Also adds the equivalent in handleVariableDecl for the walk path.
- 12 missing nodes (x.a, q1.m1, k1.a1, x12.f13, etc.) now produced by WASM.
  Note: no Rust change needed — match_js_objlit_qualified_method_defs already
  handles let/var correctly.

erlang divergence pre-dates this run — no WASM grammar available (issue #1582
filed). All other 35/36 fixtures are now wasm == native.

Verification: cargo test (419 pass), vitest (3125 pass), resolution benchmark
(176 pass), parity audit (35/36 clean, erlang excluded per #1582).
@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Codegraph Impact Analysis

9 functions changed7 callers affected across 2 files

  • match_swift_node in crates/codegraph-core/src/extractors/swift.rs:192 (0 transitive callers)
  • extracts_navigation_call_bare_name in crates/codegraph-core/src/extractors/swift.rs:396 (0 transitive callers)
  • class_property_type_annotation_seeds_type_map in crates/codegraph-core/src/extractors/swift.rs:406 (0 transitive callers)
  • extractConstantsWalk in src/extractors/javascript.ts:468 (2 transitive callers)
  • extractLetVarObjLiteralDeclarators in src/extractors/javascript.ts:599 (3 transitive callers)
  • handleVariableDecl in src/extractors/javascript.ts:1029 (3 transitive callers)
  • walkSwiftNode in src/extractors/swift.ts:27 (1 transitive callers)
  • handleSwiftCallExpression in src/extractors/swift.ts:249 (2 transitive callers)
  • seedSwiftPropertyTypeMap in src/extractors/swift.ts:290 (2 transitive callers)

@greptile-apps

greptile-apps Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes two WASM/native parity divergences found during the Titan audit: Swift's navigation_expression method name was extracted as .save instead of save (leading dot), and JS let/var object-literal method definitions were not extracted at all.

  • swift.ts / swift.rs: Both extractors now descend into navigation_suffix to get the bare simple_identifier, with a trim_start_matches('.') fallback. A new seedSwiftPropertyTypeMap function is added to the TS path to match the pre-existing Rust match_swift_type_map behaviour.
  • javascript.ts: Two complementary sites are updated — extractLetVarObjLiteralDeclarators feeds the query path, and a new else if (!isConst …) branch in handleVariableDecl feeds the walk fallback path — ensuring let q = { m() {} } emits q.m on both code paths. Scope guards mirror the pre-existing const path.

Confidence Score: 5/5

Safe to merge — both fixes are well-scoped, have regression tests, and the two JS extraction paths are mutually exclusive so there is no risk of duplicate definitions.

The Swift changes correctly descend into navigation_suffix in both Rust and TS extractors and are symmetric. The JS changes add let/var object-literal method extraction at exactly two independent code paths (query and walk fallback) with matching scope guards; the paths cannot both fire for the same input. All new behaviour is covered by targeted regression tests.

No files require special attention.

Important Files Changed

Filename Overview
src/extractors/swift.ts Adds navigation_suffix descent for method-name extraction and a new seedSwiftPropertyTypeMap helper; logic is correct and symmetric with the Rust fix.
crates/codegraph-core/src/extractors/swift.rs Rust mirror of the TS navigation_suffix fix; pre-existing match_swift_type_map already seeds type_map, so the new Rust test validates existing behaviour rather than new code.
src/extractors/javascript.ts Adds let/var object-literal qualified method extraction to both the query path (extractLetVarObjLiteralDeclarators) and the walk fallback path (handleVariableDecl else-if branch); paths are mutually exclusive and scope guards are correctly applied.
tests/parsers/javascript.test.ts Three new regression tests covering var/let object-literal method extraction and the function-scope guard; good coverage of the added code paths.
tests/parsers/swift.test.ts Two new tests verify the bare method-name fix and typeMap seeding from class property annotations; well-targeted to the changes.

Reviews (3): Last reviewed commit: "docs: clarify object-literal method extr..." | Re-trigger Greptile

Comment thread src/extractors/swift.ts Outdated
Comment on lines +254 to +258
// obj.method(...) — Swift's tree-sitter grammar wraps the suffix in a
// `navigation_suffix` node: navigation_expression > [simple_identifier, navigation_suffix].
// We must descend into navigation_suffix to get the bare method name.
// Mirrors Rust match_swift_node which reads node_text of the last child directly
// (which equals ".method") and the receiver from child(0).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Stale/inaccurate comment about Rust reference behavior

The comment says the TypeScript "Mirrors Rust match_swift_node which reads node_text of the last child directly (which equals .method)." That describes the old broken Rust behavior — but match_swift_node in swift.rs is also updated in this same PR to descend into navigation_suffix via find_child. The Rust no longer reads the last child's text directly, so framing the TypeScript fix as "mirroring" an already-fixed Rust behavior is misleading and will confuse future readers of this comment.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — the comment now says both TS and Rust descend into navigation_suffix via find_child to extract the inner simple_identifier, with a dot-strip fallback. Commit: b0f5fd0.

Comment on lines +582 to +589
/**
* Extract qualified method definitions from `let`/`var` object-literal declarations.
* Mirrors Rust match_js_objlit_qualified_method_defs which emits qualified definitions
* for method_definition (all declaration kinds) and pair+arrow/function (let/var only,
* since const is already handled by extractConstDeclarators → extractObjectLiteralFunctions).
*
* Called from extractConstantsWalk which already provides the function-scope guard.
* `var q1 = { m1() {} }` → emits Definition { name: 'q1.m1', kind: 'function' }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 PR description vs. actual change mismatch — clarification needed

The PR summary says "Native extractor missed object-spread property extraction — javascript.rs updated to handle { ...obj } spread patterns." However, this diff contains no changes to crates/codegraph-core/src/extractors/javascript.rs, and the actual code here handles method definitions inside let/var object literals ({ m() {} }, { k: () => {} }), not { ...obj } spread patterns. If javascript.rs already had match_js_objlit_qualified_method_defs before this PR, it would be helpful to confirm that explicitly; if it still needs to be added, that fix appears to be missing. Did crates/codegraph-core/src/extractors/javascript.rs already have match_js_objlit_qualified_method_defs for let/var object literals before this PR? The description implies javascript.rs was changed here, but no diff for that file is present. If Rust was already correct, the description is just wrong; if Rust still needs the fix, it's missing from this PR.

Fix in Claude Code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Investigated — match_js_objlit_qualified_method_defs already exists in javascript.rs (no change needed there). The PR description's mention of spread patterns and javascript.rs changes was inaccurate. The TS function extractLetVarObjLiteralDeclarators mirrors the existing Rust equivalent. Updated the JSDoc to say exactly that: it mirrors match_js_objlit_qualified_method_defs in javascript.rs. Commit: 0301a61.

@carlos-alm

Copy link
Copy Markdown
Contributor Author

@greptileai

@carlos-alm carlos-alm merged commit e2b309f into main Jun 18, 2026
37 checks passed
@carlos-alm carlos-alm deleted the fix/titan-parity-swift-jelly-micro branch June 18, 2026 01:27
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 18, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant