Skip to content

fix(kotlin): a call on an outside type reaches the project's extension on it - #3011

Merged
colbymchenry merged 1 commit into
mainfrom
claude/pr-2258-kotlin-extension-outside-type
Oct 29, 2026
Merged

colbymchenry merged 1 commit into
mainfrom
claude/pr-2258-kotlin-extension-outside-type

Conversation

@colbymchenry

Copy link
Copy Markdown
Owner

Summary

In Kotlin, a call on a type imported from outside the project, like Jetpack Compose's Modifier.secondaryItemAlpha(), now links to the extension the project declares on that type (fun Modifier.secondaryItemAlpha()), when the calling file can see it. The library type's own members, like Modifier.fillMaxSize(), still link to nothing.

Root cause

A Kotlin import from outside the project owns its name (#2196), so Modifier.fillMaxSize() after import androidx.compose.ui.Modifier never lands on a same-named project method. That rule returns before any other strategy, so it also cut off the project's own extensions on the imported type: fun Modifier.pad() is indexed as Modifier::pad, and Modifier.pad() could not reach it.

From the contributor, and what we changed

From @danusha2345 (#2258), unchanged: inside the outside-import rule, a Kotlin Type.member call resolves to a project extension Type::member that the calling file can see (its own file or package, or imported by name or with .*) and whose own file imports the same type; anything else stays unlinked. The test file kotlin-extension-on-imported-type.test.ts.

Our changes: the CHANGELOG bullet moved next to the other Kotlin call bullets, with a re-index note and credit. Rebased onto main 13f983db, which has #1933's Kotlin receiver typing (#2972) and #1761's private rule (#3010); the patch applies unchanged. #1933 also leaves a call on a library-typed receiver unlinked unless the project extends that type with the method; this PR covers the other form, a call written on the imported type itself (Modifier.pad()), which #1933 does not reach.

Validation

Tests. kotlin-extension-on-imported-type.test.ts: 2 cases, both red on main, green here.

A/B against main 13f983db, fresh indexes with main's kernel, edges compared by site and target identity:

repo edge sites added removed retargeted
mihonapp/mihon d001e6f 26 0 0
android/nowinandroid 2982e63 2 0 0
square/okhttp c317930, LineageOS SystemUI (Kotlin + Java) identical
openjdk/jextract (Java), pallets/click, gin-gonic/gin (controls) identical

These are the same sites, one for one, as in an earlier run against main 4eb8c2a5, before #1933 and #1761.

All 28 additions are calls on Jetpack Compose's Modifier (or DeviceConfigurationOverride) reaching an extension the project declares on it, each in a file that can see the extension, all right: mihon's Modifier.secondaryItemAlpha() (15), clickableNoIndication() (5), selectedBackground() (2), highlightBackground(), drawVerticalScrollbar(), drawHorizontalScrollbar(), keepInSection(); nowinandroid's Modifier.notificationDot() and DeviceConfigurationOverride.WindowInsets(…).

Cost (mihon, median of 3 interleaved fresh indexes, on main 4eb8c2a5): process CPU 25.7 s on main vs 25.6 s, wall 8.2 s vs 8.4 s.

Suite: CODEGRAPH_KERNEL_EXPECT=1 npx vitest run --maxWorkers=4 --minWorkers=1 on 1d4505e5 (Windows 11, kernel built): 775 files passed, 6 skipped; 9,247 tests passed, 85 skipped, 0 failed.

Lands #2258 by @danusha2345.

🤖 Generated with Claude Code

…n on it

A Kotlin import from outside the project owns its name (#2196), so
Modifier.fillMaxSize() after import androidx.compose.ui.Modifier never
lands on a same-named project method. That rule returns before any other
strategy, so a project extension on the imported type, Compose's
fun Modifier.pad() (indexed as Modifier::pad), could not be reached by
Modifier.pad() either, nor Color.fromHex() on a
fun Color.Companion.fromHex().

Inside the rule, a Kotlin Type.member call now resolves to a project
extension Type::member that the calling file can see (same file or
package, or imported by name or with .*, as for other top-level Kotlin
declarations) and whose own file imports the same type. Anything else
stays unlinked, as before.

Validation:
- kotlin-extension-on-imported-type.test.ts: 2 cases, red on main,
  green here.
- A/B against main 13f983d (with the Kotlin receiver typing of #1933
  and #1761's private rule): mihon +26, all Compose Modifier
  extensions the project declares (secondaryItemAlpha 15,
  clickableNoIndication 5, selectedBackground 2, two scrollbars,
  keepInSection), nowinandroid +2 (Modifier.notificationDot,
  DeviceConfigurationOverride.WindowInsets), all right; okhttp,
  SystemUI, jextract, click and gin identical. The same sites as
  against main 4eb8c2a, before #1933.
- Cost (mihon, median of 3 interleaved indexes, on main 4eb8c2a): CPU
  25.7 s on main vs 25.6 s, wall 8.2 s vs 8.4 s.

Original PR #2258 by @danusha2345.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@colbymchenry
colbymchenry merged commit 40f5851 into main Oct 29, 2026
@colbymchenry
colbymchenry deleted the claude/pr-2258-kotlin-extension-outside-type branch October 29, 2026 16:42
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