Skip to content

fix(kotlin): link a typed-receiver call to an extension declared in a package - #481

Merged
bompus merged 1 commit into
fork/consolidatedfrom
fix/kotlin-extension-call-in-package
Oct 12, 2026
Merged

bompus merged 1 commit into
fork/consolidatedfrom
fix/kotlin-extension-call-in-package

Conversation

@bompus

@bompus bompus commented Oct 12, 2026 •

Copy link
Copy Markdown
Owner

In Kotlin, a call on a typed receiver now links to an extension function declared in a package, such as value.shout() or the infix a join b.

On JetBrains Exposed (2155404) this adds 1,020 call links and removes none; node sets are identical. A sample of 16 of the new links, and the ones whose owner is a standard type (Sequence, Set, Triple, Iterable, String), were checked against the source and all point at the right extension.

Cause

An extension function is stored as Foo::shout (receiver as written, no package) while the class it extends is pkg::Foo. The typed-receiver lookup found members by {class qualified name}::{name}, so an extension in a packaged file was never found. The same extension did link when the file had no package line, or through an implicit receiver.

Change

  • kotlin_receiver.rs: the existing candidate scan for extensions is now kotlin_extension_member, called at the end of kotlin_receiver_member as before.
  • method_call.rs: when the inferable-receiver path finds no member on the receiver's class and the language is Kotlin, it falls back to kotlin_extension_member. A real member still wins.
  • New __tests__/kotlin-extension-call-typed-receiver.test.ts: constructor-typed and parameter-typed receivers, an infix call, member-wins, a different receiver type, and an unrelated extension.
  • __tests__/kotlin-infix-calls.test.ts: the "project numeric extension" case pinned the gap ([]); it now expects Int::and, the extension on a project class declared in a package.

Checks

  • Kernel golden dumps: unchanged.
  • Full vitest run before the pinned-test update: 8,913 passed, the one pinned case failed; it passes after the expectation change.
  • README rows checked: added a bullet to the "About this fork" Kotlin list; the upstream merge point and the benchmark tables are unaffected (no timing change). CHANGELOG entry added under Unreleased Fixes.

Summary by cubic

Links Kotlin calls on typed receivers to extension functions declared in a package, such as value.shout() or the infix a join b where shout/join extend a class under package demo. Previously such calls linked only when the extension's file had no package line, so typical Kotlin projects got no edge.

  • When the receiver's class has no member of that name, the resolver now falls back to the one visible extension whose receiver accepts the type; a real member still wins.
  • On JetBrains Exposed this adds 1,020 call links and removes none.
  • Adds a test covering constructor- and parameter-typed receivers, an infix call, member-wins precedence, a different receiver type, and an unrelated extension, and updates the "project numeric extension" infix case to expect Int::and.

Written for commit da70ad6. Summary will update on new commits.

View guided diff Turn on auto-fix

Summary by CodeRabbit

  • New Features
    • Kotlin calls on typed receivers now link to matching package-declared extension functions, including infix extensions and extensions declared in another file of the same package.
    • Class members take precedence when they share a name with an extension. Ambiguous extension matches are not linked.
    • JetBrains Exposed analysis now reports 1,020 additional call links, with none removed.

…n declared in a package

An extension function is stored as `Foo::shout` whatever its package, while
the class it extends is `pkg::Foo`. The typed-receiver lookup found a method
by the class's qualified name, so the extension linked only in files with no
`package` line (the common project has one, so it got no edge). When the
receiver's class has no such member, a Kotlin call now falls back to the one
visible extension of that name whose receiver accepts the type, as an
implicit receiver already does.

On JetBrains Exposed (2155404) 1,020 call links are gained and none is lost;
a sample of 16 and the ones whose owner is a standard type
(Sequence, Set, Triple, Iterable, String) all check out against the source.
The golden dumps do not move. kotlin-infix-calls pinned the gap ('an
extension on a project class is not linked through a typed receiver'); it now
expects `Int::and`.
@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository YAML (base), Organization UI (inherited)
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 266e3fd8-073a-4b62-9e01-0c8c690691c1

📥 Commits

Reviewing files that changed from the base of the PR and between 66c7e71 and da70ad6.


📒 Files selected for processing (6)
  • CHANGELOG.md
  • README.md
  • __tests__/kotlin-extension-call-typed-receiver.test.ts
  • __tests__/kotlin-infix-calls.test.ts
  • codegraph-kernel/src/resolve/kotlin_receiver.rs
  • codegraph-kernel/src/resolve/method_call.rs

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.



📝 Walkthrough

Walkthrough

Kotlin call resolution now checks package-declared extension functions when typed-receiver member lookup finds no matching class member. Tests cover typed and constructed receivers, infix calls, member precedence, and unmatched receiver types. The README and changelog describe the change.

Changes

Kotlin Extension Resolution

Layer / File(s) Summary
Resolve Kotlin extensions
codegraph-kernel/src/resolve/method_call.rs, codegraph-kernel/src/resolve/kotlin_receiver.rs
When Kotlin receiver-type member lookup finds no match, resolution checks compatible extension methods. It returns a candidate only when matching extensions share a qualified name and file path.
Validate and document extension calls
__tests__/kotlin-extension-call-typed-receiver.test.ts, __tests__/kotlin-infix-calls.test.ts, CHANGELOG.md, README.md
Tests cover typed-receiver and infix extension calls, member precedence, and unmatched receiver types. Documentation describes the resolution behavior and reports 1,020 additional JetBrains Exposed call links with none removed.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to da70a

No confirmed issue remains that should block merging after normal checks.

Pre-merge checks | Passed 6
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: Kotlin typed-receiver calls now link to package-declared extension functions.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Suppressions Explained Passed The pull request adds no lint, type-check, compiler-diagnostic, or ignore directive. The changed Rust, TypeScript, and documentation lines contain no suppression such as #[allow(...)], `eslint-disab…
User-Visible Changes Documented Passed The diff changes Kotlin call-resolution behavior and tests only. It does not add, remove, or rename a CLI command or flag, MCP tool or argument, supported language/framework, agent target, or config k…

✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR

🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@bompus
bompus merged commit fbe1c6f into fork/consolidated Oct 12, 2026
5 checks passed
@bompus
bompus deleted the fix/kotlin-extension-call-in-package branch October 12, 2026 13:44
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.

1 participant