Repository navigation
Conversation
|
Checked 9a41129 against Build and tests: Edge diff,
One regression. In a private Kotlin project, five test methods call a field typed as the concrete class: private lateinit var probe: HttpProbeImpl // implements the Probe interface
fun testA() { probe.probe("relay", "drone", "secret") }
fun testB() { … probe.probe(…) … }
fun tearDown() { probe.close() }
fun otherTest() {
val fake = object : Probe { override fun probe(…) = …; override fun close() = Unit }
…
}
Suggested guard: treat members of an anonymous class that sits inside a function the way Everything else matches the numbers in the description. Nice split of #1872. |
|
Thanks for the detailed edge comparison and the concrete Kotlin example. I reproduced the name-only fallback in a focused regression test: before the fix, I pushed
I cannot access the private Kotlin corpus. Could you recheck the five |
|
Verified 4fedc76 on the same private Kotlin app, plus two others.
LGTM from my side. |
|
I repeated the post- The private Kotlin repro is fixed per the recheck above. I found one separate, source-confirmed false edge in this public corpus: Focused |
|
Reproduced with the three real files at
My guess is that your corpus doesn't include #1933 already covers this: once the receiver's declared type is known and isn't a project type, it emits no edge. With both PRs applied, the result is the same as A narrower guard could also go in #1927, independent of #1933: don't let an |
|
Follow-up to the
These are independent of #1927 and #1933, so this PR's existing commits remain unchanged. Each new PR has a focused regression test, a passing build, and a passing standalone full suite. |
|
The three-file AOSP reproduction still shows a false edge on this PR alone when |
4fedc76 to
58c04ea
Compare
|
Rebased this PR onto #1933 ( |
Integrate Java/Kotlin anonymous inheritance follow-up from upstream colbymchenry#1927
12aec01 to
fb7ff1d
Compare
fb7ff1d to
1ea3c1c
Compare
ca3bb2e to
3bfb25c
Compare
7afee83 to
e817803
Compare
e817803 to
0e8a08d
Compare
…ct expression is an anonymous class (#3051) A supertype written through its enclosing type was lost in three ways. Java and C# kept the dotted path (class Named extends Outer.Inner, class N : Outer.IListener), but the qualified-name match compared it verbatim with p::Outer::Inner, so it stayed unresolved; a Java anonymous class (new Api.Listener() {...}) kept only the last segment, which no nested type is found by; and Kotlin (both engines) took the FIRST segment, so class K : Outer.Inner() extended Outer. A Kotlin object expression, object : Listener {...}, made no class at all: its overrides became local functions of the code around it, which a call through the interface never reached, and bare calls elsewhere could be guessed onto them. A dotted Java, Kotlin or C# supertype now resolves to the type whose qualified name ends with the path, when the file can name the path's first type (its own file, package or namespace, an import; C#'s usings); of several, the one closest in the tree, or none on a tie. The Java anonymous class keeps the written path in its extends reference, and Kotlin joins every segment of a supertype (type arguments left out), in the wasm extractor and the kernel alike. A Kotlin object expression is indexed as Java's anonymous class is: a class <Listener$anon@line> that extends each supertype as written, which the code around it instantiates (the class it builds, else its first supertype, also as written and only ever a type that can be a supertype), with its body's declarations as members; its header (constructor arguments, a by-delegate) stays the enclosing code's. An anonymous class's members, Java's and Kotlin's, are named only inside the declaration holding the class: a bare block() elsewhere is never an object's override val block. The walk up a Java or Kotlin class's supertypes for an inherited method asks each supertype by the chain of types that names it (AssistantMessage::Builder) before its simple name, so a builder's build() is its own AbstractBuilder's and not an MCP annotation's; the name still answers when an extends edge reached a namesake (Minestom's Player extends LivingEntity). The code in an object expression still sees the scope it is written in, as when its overrides were local functions: a property of the class around the object types a receiver there (okhttp's server.url() in an object : Callback is MockWebServer's), an override is not what a call of its own name in it means (original!!.contentLength(), this@Outer.onScroll(), an extension receiver's onDataChanged()), and an object's members out of reach leave a by-name guess as it was (okhttp's it.isReady() is still the SerialTask interface's). Validation: - jvm-dotted-supertypes.test.ts: 13 tests, 11 fail on main 60b0d7a (the other two guard a dotted supertype the file cannot name and the calls inside an anonymous class), all pass here. - Kernel parity, 0 files with diffs: torture.kt 1/1, Torture.java 1/1, okhttp 588/619 Kotlin and 71/71 Java, mihon 891/940, nowinandroid 340/350, SystemUI 188/198 Kotlin and 1141/1141 Java, jextract 218/218, Minestom 1859/1894 (deferrals are main's). - A/B against main 60b0d7a, sites added/removed/retargeted: okhttp +640/-53/149, SystemUI +435/-53/116, Minestom +165/-3/6, kestra +108/-0/6, spring-ai +46/-0/38, playframework +27/-3/13, mihon +22/-5/6, jextract +22/-0/1, spring-modulith +9/-0/10, nowinandroid 0/0/0; serilog, click, gin identical. - Cost (median of 3 interleaved): okhttp CPU 27.8 -> 29.0 s, wall 8.6 -> 8.8 s (its 360 object classes and 1,491 more edges); mihon 23.6 -> 23.8 s, wall 7.8 -> 7.7 s. Reimplements #1927 by @mixxer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks @mixxer! We landed this in #3051, reimplemented independently on main's current resolver, with you credited in the changelog. A supertype written through its outer type ( |
Summary
Preserve Java anonymous classes and Kotlin object-literal members, resolve nested supertypes in source context, and resolve Kotlin property and chained receivers by declared type. Missing external types and ambiguous owners remain unresolved. The original Kotlin receiver commits and authorship from #1933 are retained.
Validation
8a5ba3d02c833f205b5453305b47fffee0008a6b; validated head3bfb25c07ef5d41df097e861786042b920c71927.eda54a121cbc06b13a5f97d215f239e639a22b87: its receiver helpers match the implementation retained here; original authorship and receiver regressions remain preserved.