Skip to content

fix: extract INHERITS edges for Go, Kotlin, Swift, Dart, Objective-C - #22

Merged
murari316 merged 5 commits into
intuit:mainfrom
pradeepmouli:fix/go-kotlin-swift-dart-objc-inherits
Jul 24, 2026
Merged

fix: extract INHERITS edges for Go, Kotlin, Swift, Dart, Objective-C#22
murari316 merged 5 commits into
intuit:mainfrom
pradeepmouli:fix/go-kotlin-swift-dart-objc-inherits

Conversation

@pradeepmouli

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #21 (TypeScript/Rust INHERITS extraction). Same class of
gap in five more mainstream languages -- none captured any
inheritance-like relationship at all:

  • go: struct embedding (Go's closest analog to inheritance -- an
    anonymous field with no name, just a type). Interface satisfaction is
    implicit/structural in Go and can't be determined from syntax alone, so
    it's intentionally not covered.
  • kotlin: class inheritance and interface implementation via
    delegation_specifiers (class X : Y() / class X : Y).
  • swift: class/struct/enum inheritance and protocol conformance
    (class X: Y, protocol X: Y).
  • dart: extends and implements.
  • objc: class inheritance (@interface X : Y). Also fixes a separate,
    deeper bug in objc/entities.scm: class_interface,
    class_implementation, and protocol_declaration all used a name:
    field that doesn't exist on those grammar nodes (confirmed against
    tree-sitter-objc's node-types.json -- the class name is an unlabeled
    positional child, not a field), so every Objective-C class/protocol
    produced zero symbols at all, not just zero inheritance edges.
    Without fixing that too, the new relations.scm pattern would have
    nothing to bind to.

Fix

Verified every grammar's exact node structure against the vendored
tree-sitter-* node-types.json (and, for Objective-C, the compiled
grammar.json for positional/unlabeled child structure) rather than
guessing.

Test plan

  • Compiles clean, no language-pack load warnings for any of the five
  • Full infigraph-core (268) and infigraph-languages (16) test
    suites pass
  • Five new regression tests in
    infigraph-languages/tests/registry_integration.rs, one per
    language (the Objective-C test also asserts symbols are extracted,
    covering the entities.scm fix)
  • End-to-end against synthetic files covering each pattern -- all
    five produce correct INHERITS edges (Objective-C additionally
    confirmed to now produce symbols where it previously produced zero)

🤖 Generated with Claude Code

https://claude.ai/code/session_01TAXDJyFdnA4BV1U2fxufdC

Same class of gap as the earlier TypeScript/Rust fix -- none of these five
languages captured any inheritance-like relationship at all:

- go: struct embedding (Go's closest analog to inheritance -- an anonymous
  field with no name, just a type). Interface satisfaction is implicit/
  structural in Go and can't be determined from syntax alone, so it's
  intentionally not covered.
- kotlin: class inheritance and interface implementation via
  delegation_specifiers (class X : Y() / class X : Y).
- swift: class/struct/enum inheritance and protocol conformance
  (class X: Y, protocol X: Y).
- dart: class extends and implements.
- objc: class inheritance (@interface X : Y). Also fixes a separate,
  deeper bug in objc/entities.scm: class_interface, class_implementation,
  and protocol_declaration all used a `name:` field that doesn't exist on
  those grammar nodes (confirmed against tree-sitter-objc's
  node-types.json -- the class name is an unlabeled positional child, not
  a field), so every Objective-C class/protocol produced zero symbols at
  all, not just zero inheritance edges. Without this, the new relations.scm
  pattern would have nothing to bind to.

All five verified against vendored tree-sitter grammar node-types.json
rather than guessed. Tested end-to-end against synthetic files covering
each pattern -- all five produce correct INHERITS edges (and, for objc,
correct symbols too), with no language-pack load warnings.

Regression tests added to infigraph-languages/tests/registry_integration.rs
for all five languages.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TAXDJyFdnA4BV1U2fxufdC
Unrelated to this PR's INHERITS-extraction change, but the pre-commit
hook's fmt/clippy checks block all commits until fixed.
- registry_integration.rs: cargo fmt drift
- lsp-to-scip/main.rs, vuln/mod.rs: allow question_mark /
  useless_borrows_in_formatting lints that newly apply because the
  'stable' toolchain drifted since this code was written in May, not
  because the code changed (CI's dtolnay/rust-toolchain@stable also
  resolves to rustc 1.97.x).
Rewrites the two spots suppressed in the prior commit instead of
disabling the lints:
- lsp-to-scip/main.rs: replace if-let/else-if-let/else with ? operator
- vuln/mod.rs: remove redundant & in format! arg
; Interface satisfaction is implicit/structural in Go and can't be
; determined from syntax alone, so it isn't captured here.
(type_spec
name: (type_identifier) @inherit.child

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same issue like PR#21 - Kindly check here also @pradeepmouli

crates/infigraph-languages/languages/go/relations.scm, embedded-field query (type: (type_identifier)):
🔴 bug: field_declaration.type field allows qualified_type (cross-package embed) and generic_type too, per grammar. type Dog struct { pkg.Animal } — very common Go pattern — parses as qualified_type, not type_identifier. Edge silently dropped. Fix: type: (_) @inherit.parent. Add test for package-qualified embedding.

crates/infigraph-languages/languages/dart/relations.scm, L28 and L35 ((type_identifier) inside superclass/interfaces):
🔴 bug: Dart's _type_not_void grammar rule (used by both extends/implements) wraps the type name plus optional type_arguments, and the type name itself can be library-prefixed (pkg.Animal). class Dog extends Animal<T> or extends pkg.Animal won't match a bare type_identifier child. Fix: (type_identifier)(_) @inherit.parent, or match on the type node directly without descending into a specific child type. Add tests for generic and prefixed base classes.

pradeepmouli and others added 2 commits July 23, 2026 14:54
…Swift/Dart

Same shared resolver architecture as the TS/Rust/Python/Java fix (PR #21):
extract/relations.rs::resolve_inherit_text recursively decomposes a captured
@inherit.parent/@inherit.child node via a per-language decomposition query,
threaded through LanguagePack via with_inherit_decompose() on
ParserBackend::TreeSitter (boxed from the outset this time to avoid the
clippy::large_enum_variant round-trip hit on the first branch).

Go: wildcards field_declaration's embedded-field type position (previously
narrow type_identifier-only, silently dropping edges for generic/qualified
embedded fields e.g. `Base[T]`, `pkg.Animal`); the !name embedded-field-
detection guard is untouched. Kotlin/Swift: wildcard the delegation_specifier/
inheritance_specifier capture positions; decomposed via kind+anchor-based
queries rather than field-based ones, since both grammars declare no fields
at all on their compound user_type node (confirmed empirically, same finding
as Java on the other branch). Dart: needs no separate decomposition file at
all -- a single fully-anchored pattern (leading anchor picks the first
type-field child, skipping the sibling type-arguments blob Dart's grammar
produces; trailing anchor requires the identifier to be that node's only
child) correctly handles generic, qualified, and plain bases in one shot,
verified against all three plus the multi-interface `implements A, B<T>`
case. ObjC: confirmed unchanged -- its class_interface.superclass field is
grammar-constrained to plain identifier only, no compound shape possible.

New regression tests cover the actual compound cases (generic/qualified
embedded fields for Go, generic superclasses for Kotlin/Swift, generic
extends plus multi-interface implements for Dart).

Every pattern verified against the real vendored tree-sitter grammars via a
scratch harness before being written here, not assumed from documentation.
# Conflicts:
#	crates/infigraph-languages/tests/registry_integration.rs
@murari316
murari316 merged commit fe410eb into intuit:main Jul 24, 2026
1 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants