Repository navigation
fix(kotlin): a call on an outside type reaches the project's extension on it - #2258
Closed
danusha2345 wants to merge 1 commit into
Closed
danusha2345 wants to merge 1 commit into
danusha2345 wants to merge 1 commit into
Conversation
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
force-pushed
the
fix/kotlin-project-extension-on-imported-type
branch
4 times, most recently
from
October 7, 2026 16:08
35d410d to
48d1d19
Compare
danusha2345
force-pushed
the
fix/kotlin-project-extension-on-imported-type
branch
2 times, most recently
from
October 15, 2026 17:39
f259946 to
e1e08de
Compare
danusha2345
force-pushed
the
fix/kotlin-project-extension-on-imported-type
branch
4 times, most recently
from
October 21, 2026 17:53
e656706 to
df52d43
Compare
…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
force-pushed
the
fix/kotlin-project-extension-on-imported-type
branch
from
October 22, 2026 10:44
df52d43 to
77814af
Compare
danusha2345
pushed a commit
to danusha2345/codegraph
that referenced
this pull request
Oct 24, 2026
…mchenry#2876; 11 landed PRs yield to main; EXTRACTION_VERSION 55) Main landed eleven of our PRs as our own commits with the maintainer's additions (colbymchenry#2847, colbymchenry#2848, colbymchenry#2850, colbymchenry#2851, colbymchenry#2853, colbymchenry#2854, colbymchenry#2855, colbymchenry#2856, colbymchenry#2868, colbymchenry#2874, colbymchenry#2875), the traversal half of colbymchenry#2839 (colbymchenry#2860) and the trail hardening of colbymchenry#1667 (colbymchenry#2869). Where the integration carried our original version, main's wins: play.ts, routes.ts, the tsjs kernel extractor, import-resolver's PHP alias lookup, isDecisiveSameFileMatch, matchNewReceiverCall and the tests of those PRs. Kept beside main: colbymchenry#1952's enclosing-scope member pick, colbymchenry#1936's closest-copy confidence, colbymchenry#2258's Kotlin imported-type block, colbymchenry#1875's commitHdlProfile on indexFiles and hdlAccess, colbymchenry#1583's impact budget (the type-hierarchy walk itself is main's), colbymchenry#1736's C #if tests. 22 changelog bullets of closed PRs removed where main has its own wording. EXTRACTION_VERSION 55: Rust receiver chains (colbymchenry#2846), `new C().m` shapes (colbymchenry#2854), Java records (colbymchenry#2868), Go method exportedness (colbymchenry#2857), generic supertypes (colbymchenry#2856). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
danusha2345
pushed a commit
to danusha2345/codegraph
that referenced
this pull request
Oct 28, 2026
…mchenry#2972; 10 landed PRs yield to main; EXTRACTION_VERSION 56) Main landed ten more of our PRs as our own commits with the maintainer's additions (colbymchenry#2923 ← colbymchenry#1936, colbymchenry#2924 ← colbymchenry#1951, colbymchenry#2925 ← colbymchenry#1939, colbymchenry#2930 ← colbymchenry#2921, colbymchenry#2940 ← colbymchenry#1736, colbymchenry#2942 ← colbymchenry#1947, colbymchenry#2950 ← colbymchenry#1952, colbymchenry#2961 ← colbymchenry#1954, colbymchenry#2965 ← colbymchenry#1942, colbymchenry#2972 ← colbymchenry#1933) and the module-path half of colbymchenry#2308 (colbymchenry#2955). Where the integration carried our version, main's wins: the enclosing-scope member pick and its tests, the Go and Java receiver typers, the delegating-call self-loop rule, the duplicated-module copy confidence, the C #if collapse, the module-path resolution of Rust paths, the trail/path hardening in utils.ts. Kept beside main: colbymchenry#1875's Verilog hooks and status fields, colbymchenry#2839's implementations command, colbymchenry#1923, colbymchenry#2922, colbymchenry#2258, colbymchenry#1761, colbymchenry#1583, the bare-call half of colbymchenry#2308 (rust-use-bindings.ts). CHANGELOG is main's plus the open PRs' bullets. EXTRACTION_VERSION 56: the C #if group handling (colbymchenry#2940) and the kernel change. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
colbymchenry
pushed a commit
that referenced
this pull request
Oct 29, 2026
…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>
Owner
|
Thanks @danusha2345! This landed in #3011, with you as the commit author. Calls like |
colbymchenry
pushed a commit
that referenced
this pull request
Oct 29, 2026
…when two share a name When several classes share a name, resolveMethodOnType picks the one the call file imports by matching the import's path against the candidate's file path (com/example/b/FooConverter.kt). That holds for Java, where a public class names its file, but a Kotlin class often lives in a file named otherwise (FooConverter in Converters.kt), so no candidate matched and the call went to whichever class came first. The imported name is now matched against each candidate's qualified name first: import com.example.b.FooConverter expects the method com.example.b::FooConverter::convert, which the package directive gives every JVM declaration whatever its file is called. The file-path match stays as the fallback. The Java calls this once fixed, a Java file calling a Kotlin class it imports (okhttp's Java tests and mockwebserver3.MockWebServer, SystemUI's BlurUtils), are now resolved on main by the receiver's declared type (#1942), so on today's main the change shows in Kotlin. From #539 we take only this change and its test. Its other two parts, indexing Kotlin class properties and reading Kotlin imports without a trailing semicolon, have since landed on main another way. Validation: - resolution.test.ts: the Kotlin same-name case (#314's shape in Converters.kt files) is red on main, green here. - A/B against main 40f5851 (with the Java receiver typing of #1942 and the Kotlin changes of #1933, #1761 and #2258): no edge changes on okhttp, SystemUI, nowinandroid, mihon, jextract, spring-modulith, Minestom, spring-ai, kestra-java, playframework, click or gin; none of them has the test's shape on a resolved call. Against main 4eb8c2a, before #1942, it moved the 8 Java calls above onto the Kotlin class their file imports; main now reaches them at 0.9. - Cost (mihon, median of 3 interleaved indexes, on main 4eb8c2a): CPU 25.7 s on main vs 25.2 s, wall 8.2 s vs 8.3 s. Original PR #539 by @arttttt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:(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.membercall now resolves to a project extension indexed asType::memberwhen.*(the existingisKotlinTopLevelVisible/kotlinFileScope), andjavax.lang.model.element.Modifieris 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 afun 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 differentModifiertype (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'sjava-outside-imports.test.tspass withCODEGRAPH_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
kotlinExtensionInScopeidea from @mixxer's #1948 discussion; thanks!🤖 Generated with Claude Code