Skip to content

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

Open
danusha2345 wants to merge 1 commit into
colbymchenry:mainfrom
danusha2345:fix/kotlin-project-extension-on-imported-type
Open

danusha2345 wants to merge 1 commit into
colbymchenry:mainfrom
danusha2345:fix/kotlin-project-extension-on-imported-type

Conversation

@danusha2345

Copy link
Copy Markdown
Contributor

Summary

#2196 made a Kotlin import from outside the project own its name: after import androidx.compose.ui.Modifier, Modifier.fillMaxSize() no longer lands on a same-named project method. That rule returns before every other strategy, so a project extension declared on the imported type can't be reached either:

// ui/Ext.kt                              // ui/Screen.kt
package app.ui                            package app.ui
import androidx.compose.ui.Modifier       import androidx.compose.ui.Modifier
fun Modifier.pad(): Modifier = this       fun screen() { Modifier.pad() }   // no edge

(Before #2196 this call was already dropped by the "receiver names a type the project doesn't declare" guard in matchMethodCall; #2196 adds a second block in front of every strategy, so it can no longer be fixed there.)

Change

Inside the outside-import rule, a Kotlin Type.member call now resolves to a project extension indexed as Type::member when

  • the call site can see it — same file or package, or imported by name or .* (the existing isKotlinTopLevelVisible / kotlinFileScope), and
  • the extension's own file imports the same outside type (so an extension on javax.lang.model.element.Modifier is not Compose's).

If several qualify, only one in the calling file is taken; otherwise no edge. Everything else stays unlinked as before — Modifier.fillMaxSize() included. Color.fromHex() on a fun Color.Companion.fromHex() is covered the same way. Chains through an outside call (Modifier.fillMaxSize().pad()) are untouched: the outside call's return type is unknown, and they did not resolve before #2196 either. An instance receiver (val m: Modifier; m.pad()) already resolved on main and is unaffected.

Tests

__tests__/kotlin-extension-on-imported-type.test.ts (fails on main, passes here, kernel and wasm extraction): same-package call, imported-by-name and .* calls, an unimported extension (no edge), an extension on a different Modifier type (no edge), and Compose's own member (no edge). Dropping either check yields a wrong edge in the test. Full suite on Linux passes; the Kotlin suites and #2196's java-outside-imports.test.ts pass with CODEGRAPH_KERNEL_EXPECT=1.

Measurements

Three Android apps (132–793 JVM files): edges identical before and after (0 added / 0 removed) — they call their own extensions through instances only, which #2196 never blocked. So this is a precision-safe fix for the Type.extension() shape rather than a measured win on these repos.

The visibility check follows the kotlinExtensionInScope idea from @mixxer's #1948 discussion; thanks!

🤖 Generated with Claude Code

danusha2345 pushed a commit to danusha2345/codegraph that referenced this pull request Oct 1, 2026
…bymchenry#2259, colbymchenry#2260) into fork main

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@danusha2345
danusha2345 force-pushed the fix/kotlin-project-extension-on-imported-type branch 3 times, most recently from d0236ea to 35d410d Compare October 7, 2026 11:51
…n on it

colbymchenry#2196 made a Kotlin import from outside the project own its name, so
`Modifier.fillMaxSize()` after `import androidx.compose.ui.Modifier` no
longer lands on a same-named project method. The rule returns before any
other strategy, so a project extension on that 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 call site can see (same file or
package, or imported by name or `.*`, as for other top-level Kotlin
declarations) and whose own file imports the same type. Anything else
stays unlinked, as before. The visibility check follows the idea of
`kotlinExtensionInScope` from the discussion in colbymchenry#1948.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@danusha2345
danusha2345 force-pushed the fix/kotlin-project-extension-on-imported-type branch from 35d410d to 48d1d19 Compare October 7, 2026 16:08

This branch has not been deployed

No deployments
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