From a189509353455afe8b7db7441f187359f63a449d Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 8 Feb 2024 14:11:18 +0100 Subject: [PATCH] K2: build override structure for Java renamed builtins more precisely #KT-65410 Fixed --- .../scopes/JavaClassUseSiteMemberScope.kt | 31 ++++++++++++----- .../codegen/box/collections/removeAtInJava.kt | 1 - .../box/specialBuiltins/weirdCharBuffers.kt | 2 +- .../weirdCharBuffers.overrides.txt | 8 ----- .../j+k/primitiveOverrides/removeAt.fir.kt | 34 ------------------- .../tests/j+k/primitiveOverrides/removeAt.kt | 4 +++ ...r.overrides.txt => removeAt.overrides.txt} | 2 -- 7 files changed, 28 insertions(+), 54 deletions(-) delete mode 100644 compiler/testData/diagnostics/tests/j+k/primitiveOverrides/removeAt.fir.kt rename compiler/testData/diagnostics/tests/j+k/primitiveOverrides/{removeAt.fir.overrides.txt => removeAt.overrides.txt} (83%) diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt index 473593e0bd0..03b01b42714 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt @@ -714,20 +714,35 @@ class JavaClassUseSiteMemberScope( if (explicitlyDeclaredFunctionWithNaturalName != null || overriddenByNaturalName.isNotEmpty()) { // The CharBuffer situation as example: both `get(Int):Char` and `charAt(Int):Char` are declared or inherited. - // CharBuffer.charAt is renamed to get, becomes hidden and overrides kotlin.CharSequence.charAt. - val hiddenRenamedFunction = createCopyWithNaturalName(explicitlyDeclaredOrInheritedFunctionWithBuiltinJvmName, isHidden = true) - destination += hiddenRenamedFunction - setOverrides(hiddenRenamedFunction, resultsOfIntersectionOfRenamed) + // In case `charAt` is declared, or inherited from base function with the same name, we need to create hidden renamed `get` + // Otherwise we don't need it and just use `get` from Java without conflicts + val hiddenRenamedFunctionNeeded = explicitlyDeclaredFunctionWithBuiltinJvmName != null || + explicitlyDeclaredOrInheritedFunctionWithBuiltinJvmName.name == jvmName + if (hiddenRenamedFunctionNeeded) { + // CharBuffer.charAt is renamed to get, becomes hidden and overrides kotlin.CharSequence.charAt. + val hiddenRenamedFunction = + createCopyWithNaturalName(explicitlyDeclaredOrInheritedFunctionWithBuiltinJvmName, isHidden = true) + destination += hiddenRenamedFunction + setOverrides(hiddenRenamedFunction, resultsOfIntersectionOfRenamed) + } val resultOfIntersectionOfNaturalName = supertypeScopeContext.convertGroupedCallablesToIntersectionResults( overriddenByNaturalName.map { it.baseScope to listOf(it.member) } ) if (explicitlyDeclaredFunctionWithNaturalName != null) { - // CharBuffer.get is already in destination, but we need to update its overridden declarations. - // It mustn't override kotlin.CharSequence.charAt, but it can override different declarations with the same signature. - // See compiler/testData/diagnostics/tests/j+k/collectionOverrides/charBuffer.kt - setOverrides(explicitlyDeclaredFunctionWithNaturalName, resultOfIntersectionOfNaturalName) + // `CharBuffer`.get is already in destination, but we need to update its overridden declarations. + setOverrides( + explicitlyDeclaredFunctionWithNaturalName, + when { + // It mustn't override `kotlin.CharSequence.get`, but it can override different declarations with the same signature. + // See compiler/testData/diagnostics/tests/j+k/collectionOverrides/charBuffer.kt + hiddenRenamedFunctionNeeded -> resultOfIntersectionOfNaturalName + // But in case there is no function named `charAt` in hierarchy, + // we can override `kotlin.CharSequence.get` safely + else -> resultsOfIntersectionOfRenamed + } + ) } else { // CharBuffer.get is inherited (possibly a real intersection). // Add it to destination and set overridden declarations. diff --git a/compiler/testData/codegen/box/collections/removeAtInJava.kt b/compiler/testData/codegen/box/collections/removeAtInJava.kt index b2b0a3dc132..d3bb999dabd 100644 --- a/compiler/testData/codegen/box/collections/removeAtInJava.kt +++ b/compiler/testData/codegen/box/collections/removeAtInJava.kt @@ -1,5 +1,4 @@ // TARGET_BACKEND: JVM_IR -// IGNORE_BACKEND_K2: JVM_IR // WITH_STDLIB // ISSUE: KT-65410 diff --git a/compiler/testData/codegen/box/specialBuiltins/weirdCharBuffers.kt b/compiler/testData/codegen/box/specialBuiltins/weirdCharBuffers.kt index 819c8c60781..2e52f9dbda4 100644 --- a/compiler/testData/codegen/box/specialBuiltins/weirdCharBuffers.kt +++ b/compiler/testData/codegen/box/specialBuiltins/weirdCharBuffers.kt @@ -120,7 +120,7 @@ fun box(): String { if (NonCharSequenceBuffer.create().get(0) != 'g') return "FAIL 7" if ((NonCharSequenceBuffer.create() as X).get(0) != 'g') return "FAIL 8" - if (CharBufferCharAtInherited.create().get(0) != 'g') return "FAIL 9" + if (CharBufferCharAtInherited.create().get(0) != 'c') return "FAIL 9" if ((CharBufferCharAtInherited.create() as CharSequence).get(0) != 'c') return "FAIL 10" if (CharBufferXAllInherited.create().get(0) != 'g') return "FAIL 11" diff --git a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/weirdCharBuffers.overrides.txt b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/weirdCharBuffers.overrides.txt index 446384bd5d0..83cf937b7c9 100644 --- a/compiler/testData/diagnostics/tests/j+k/collectionOverrides/weirdCharBuffers.overrides.txt +++ b/compiler/testData/diagnostics/tests/j+k/collectionOverrides/weirdCharBuffers.overrides.txt @@ -16,25 +16,17 @@ NonCharSequenceBuffer: NonCharBuffer: [Enhancement]: public abstract operator fun get(index: R|kotlin/Int|): R|kotlin/Char| from Java enhancement scope for /NonCharBuffer [id: 0] - [Library]: /* hidden due to clash */ public abstract operator fun get(index: R|kotlin/Int|): R|kotlin/Char| from Java enhancement scope for /NonCharBuffer [id: 0] [Library]: public abstract operator fun get(index: R|kotlin/Int|): R|kotlin/Char| from Use site scope of kotlin/CharSequence [id: 1] CharBufferXAllInherited: - [Library]: /* hidden due to clash */ public abstract operator fun get(index: R|kotlin/Int|): R|kotlin/Char| from Java enhancement scope for /CharBufferXAllInherited [id: 0] - [Library]: public abstract operator fun get(index: R|kotlin/Int|): R|kotlin/Char| from Use site scope of kotlin/CharSequence [id: 1] [Enhancement]: public abstract operator fun get(index: R|kotlin/Int|): R|kotlin/Char| from Java enhancement scope for /CharBufferXAllInherited [id: 0] CharBufferXYAllInherited: - [Library]: /* hidden due to clash */ public abstract operator fun get(index: R|kotlin/Int|): R|kotlin/Char| from Java enhancement scope for /CharBufferXYAllInherited [id: 0] - [Library]: public abstract operator fun get(index: R|kotlin/Int|): R|kotlin/Char| from Use site scope of kotlin/CharSequence [id: 1] [IntersectionOverride]: public abstract operator fun get(index: R|kotlin/Int|): R|kotlin/Char| from Java enhancement scope for /CharBufferXYAllInherited [id: 0] [Enhancement]: public abstract operator fun get(index: R|kotlin/Int|): R|kotlin/Char| from Java enhancement scope for /X [id: 1] [Enhancement]: protected/*protected and package*/ abstract operator fun get(index: R|kotlin/Int|): R|kotlin/Char| from Java enhancement scope for /Y [id: 2] CharBufferXYCharAt: - [Library]: /* hidden due to clash */ public abstract operator fun get(index: R|kotlin/Int|): R|kotlin/Char| from Java enhancement scope for /CharBufferXYCharAt [id: 0] - [Library]: public abstract operator fun get(index: R|kotlin/Int|): R|kotlin/Char| from Use site scope of kotlin/CharSequence [id: 1] - [RenamedForOverride]: public abstract fun get(index: R|kotlin/Int|): R|kotlin/Char| from Java enhancement scope for /CharAt [id: 2] [IntersectionOverride]: public abstract operator fun get(index: R|kotlin/Int|): R|kotlin/Char| from Java enhancement scope for /CharBufferXYCharAt [id: 0] [Enhancement]: public abstract operator fun get(index: R|kotlin/Int|): R|kotlin/Char| from Java enhancement scope for /X [id: 1] [Enhancement]: protected/*protected and package*/ abstract operator fun get(index: R|kotlin/Int|): R|kotlin/Char| from Java enhancement scope for /Y [id: 2] diff --git a/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/removeAt.fir.kt b/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/removeAt.fir.kt deleted file mode 100644 index ee942f975ab..00000000000 --- a/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/removeAt.fir.kt +++ /dev/null @@ -1,34 +0,0 @@ -// WITH_STDLIB -// SCOPE_DUMP: A:removeAt -// ISSUE: KT-65410 - -// FILE: Java1.java -import kotlin.collections.AbstractMutableList; - -public class Java1 extends AbstractMutableList { - @Override - public int getSize() { - return 0; - } - - @Override - public void add(int i, Integer integer) {} - - @Override - public Integer removeAt(int i) { - return null; - } - - @Override - public Integer get(int index) { - return null; - } - - @Override - public Integer set(int i, Integer integer) { - return null; - } -} - -// FILE: 1.kt -class A : Java1() diff --git a/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/removeAt.kt b/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/removeAt.kt index 52c18be84a8..32d060d996b 100644 --- a/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/removeAt.kt +++ b/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/removeAt.kt @@ -1,6 +1,10 @@ +// FIR_IDENTICAL // WITH_STDLIB // SCOPE_DUMP: A:removeAt // ISSUE: KT-65410 +// IGNORE_DIAGNOSTIC_API +// IGNORE_REVERSED_RESOLVE +// Reason: SCOPE_DUMP uses different parameter names in AA modes // FILE: Java1.java import kotlin.collections.AbstractMutableList; diff --git a/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/removeAt.fir.overrides.txt b/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/removeAt.overrides.txt similarity index 83% rename from compiler/testData/diagnostics/tests/j+k/primitiveOverrides/removeAt.fir.overrides.txt rename to compiler/testData/diagnostics/tests/j+k/primitiveOverrides/removeAt.overrides.txt index cafb51bfa0e..3a26d40ad30 100644 --- a/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/removeAt.fir.overrides.txt +++ b/compiler/testData/diagnostics/tests/j+k/primitiveOverrides/removeAt.overrides.txt @@ -1,8 +1,6 @@ A: [Enhancement]: public open fun removeAt(i: R|kotlin/Int|): R|kotlin/Int!| from Use site scope of /A [id: 0] [Enhancement]: public open fun removeAt(i: R|kotlin/Int|): R|kotlin/Int!| from Java enhancement scope for /Java1 [id: 0] - [SubstitutionOverride(DeclarationSite)]: /* hidden due to clash */ public abstract fun removeAt(index: R|kotlin/Int|): R|kotlin/Int!| from Use site scope of /A [id: 0] - [SubstitutionOverride(DeclarationSite)]: /* hidden due to clash */ public abstract fun removeAt(index: R|kotlin/Int|): R|kotlin/Int!| from Java enhancement scope for /Java1 [id: 0] [SubstitutionOverride(DeclarationSite)]: public abstract fun removeAt(index: R|kotlin/Int|): R|kotlin/Int!| from Substitution scope for [Use site scope of kotlin/collections/AbstractMutableList] for type Java1 [id: 1] [Library]: public abstract fun removeAt(index: R|kotlin/Int|): R|E| from Use site scope of kotlin/collections/AbstractMutableList [id: 2] [SubstitutionOverride(DeclarationSite)]: public abstract fun removeAt(index: R|kotlin/Int|): R|E| from Substitution scope for [Use site scope of kotlin/collections/MutableList] for type kotlin/collections/AbstractMutableList [id: 3]