From 434470a4f50c0fefe314ad397a95f4526daf8ba4 Mon Sep 17 00:00:00 2001 From: "Anastasia.Nekrasova" Date: Wed, 31 Jan 2024 20:43:29 +0200 Subject: [PATCH] [K/N][K2]: K2 behavioral difference with inconsistent inheritance of ObjCName The problem arises when retrieveDirectOverriddenOf returns a substitution override member. For such members, it is impossible to get the first base member. For a correct result, it is required to find originalForSubstitutionOverride for all substitutionOverrides. #KT-64276 Fixed --- .../based/LLFirNativeTestGenerated.java | 24 ++++++++++++++ .../LLFirReversedNativeTestGenerated.java | 24 ++++++++++++++ .../checkers/FirNativeObjCNameUtilities.kt | 8 ++--- .../diagnostics/nativeTests/objCName2.kt | 27 ++++++++++++++++ .../diagnostics/nativeTests/objCName3.kt | 23 ++++++++++++++ .../diagnostics/nativeTests/objCName4.kt | 31 +++++++++++++++++++ .../diagnostics/nativeTests/objCName5.kt | 31 +++++++++++++++++++ .../DiagnosticsNativeTestGenerated.java | 24 ++++++++++++++ ...rontendNativeDiagnosticsTestGenerated.java | 24 ++++++++++++++ ...rontendNativeDiagnosticsTestGenerated.java | 24 ++++++++++++++ 10 files changed, 235 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/diagnostics/nativeTests/objCName2.kt create mode 100644 compiler/testData/diagnostics/nativeTests/objCName3.kt create mode 100644 compiler/testData/diagnostics/nativeTests/objCName4.kt create mode 100644 compiler/testData/diagnostics/nativeTests/objCName5.kt diff --git a/analysis/low-level-api-fir/low-level-api-fir-native/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/konan/compiler/based/LLFirNativeTestGenerated.java b/analysis/low-level-api-fir/low-level-api-fir-native/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/konan/compiler/based/LLFirNativeTestGenerated.java index dbf132931de..f114770a8be 100644 --- a/analysis/low-level-api-fir/low-level-api-fir-native/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/konan/compiler/based/LLFirNativeTestGenerated.java +++ b/analysis/low-level-api-fir/low-level-api-fir-native/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/konan/compiler/based/LLFirNativeTestGenerated.java @@ -74,6 +74,30 @@ public class LLFirNativeTestGenerated extends AbstractLLFirNativeTest { runTest("compiler/testData/diagnostics/nativeTests/objCName.kt"); } + @Test + @TestMetadata("objCName2.kt") + public void testObjCName2() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName2.kt"); + } + + @Test + @TestMetadata("objCName3.kt") + public void testObjCName3() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName3.kt"); + } + + @Test + @TestMetadata("objCName4.kt") + public void testObjCName4() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName4.kt"); + } + + @Test + @TestMetadata("objCName5.kt") + public void testObjCName5() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName5.kt"); + } + @Test @TestMetadata("objCRefinement.kt") public void testObjCRefinement() throws Exception { diff --git a/analysis/low-level-api-fir/low-level-api-fir-native/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/konan/compiler/based/LLFirReversedNativeTestGenerated.java b/analysis/low-level-api-fir/low-level-api-fir-native/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/konan/compiler/based/LLFirReversedNativeTestGenerated.java index c0b95a9382d..e0bed3dc3dd 100644 --- a/analysis/low-level-api-fir/low-level-api-fir-native/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/konan/compiler/based/LLFirReversedNativeTestGenerated.java +++ b/analysis/low-level-api-fir/low-level-api-fir-native/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/konan/compiler/based/LLFirReversedNativeTestGenerated.java @@ -74,6 +74,30 @@ public class LLFirReversedNativeTestGenerated extends AbstractLLFirReversedNativ runTest("compiler/testData/diagnostics/nativeTests/objCName.kt"); } + @Test + @TestMetadata("objCName2.kt") + public void testObjCName2() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName2.kt"); + } + + @Test + @TestMetadata("objCName3.kt") + public void testObjCName3() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName3.kt"); + } + + @Test + @TestMetadata("objCName4.kt") + public void testObjCName4() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName4.kt"); + } + + @Test + @TestMetadata("objCName5.kt") + public void testObjCName5() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName5.kt"); + } + @Test @TestMetadata("objCRefinement.kt") public void testObjCRefinement() throws Exception { diff --git a/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeObjCNameUtilities.kt b/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeObjCNameUtilities.kt index c179f1f368c..83b18d2baeb 100644 --- a/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeObjCNameUtilities.kt +++ b/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeObjCNameUtilities.kt @@ -8,12 +8,10 @@ package org.jetbrains.kotlin.fir.analysis.native.checkers import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.diagnostics.reportOn -import org.jetbrains.kotlin.fir.FirAnnotationContainer -import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope import org.jetbrains.kotlin.fir.analysis.diagnostics.native.FirNativeErrors -import org.jetbrains.kotlin.fir.containingClassLookupTag import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol @@ -74,7 +72,7 @@ object FirNativeObjCNameUtilities { context: CheckerContext, reporter: DiagnosticReporter ) { - val overriddenSymbols = firTypeScope.retrieveDirectOverriddenOf(memberSymbol) + val overriddenSymbols = firTypeScope.retrieveDirectOverriddenOf(memberSymbol).map { it.originalForSubstitutionOverride ?: it } if (overriddenSymbols.isEmpty()) return val objCNames = overriddenSymbols.map { it.getFirstBaseSymbol(context).getObjCNames(context.session) } if (!objCNames.allNamesEquals()) { @@ -95,7 +93,7 @@ object FirNativeObjCNameUtilities { val session = context.session val ownScope = containingClassLookupTag()?.toSymbol(session)?.fullyExpandedClass(session)?.unsubstitutedScope(context) ?: return this - val overriddenMemberSymbols = ownScope.retrieveDirectOverriddenOf(this) + val overriddenMemberSymbols = ownScope.retrieveDirectOverriddenOf(this).map { it.originalForSubstitutionOverride ?: it } return if (overriddenMemberSymbols.isEmpty()) this else overriddenMemberSymbols.first().getFirstBaseSymbol(context) } diff --git a/compiler/testData/diagnostics/nativeTests/objCName2.kt b/compiler/testData/diagnostics/nativeTests/objCName2.kt new file mode 100644 index 00000000000..ef7dff9502d --- /dev/null +++ b/compiler/testData/diagnostics/nativeTests/objCName2.kt @@ -0,0 +1,27 @@ +// FIR_IDENTICAL +// FILE: kotlin.kt +@file:OptIn(ExperimentalObjCName::class) + +package kotlin.native +import kotlin.experimental.ExperimentalObjCName + +fun interface BaseInterface { + @ObjCName("close") + fun close() +} + +interface MiddleInterface : BaseInterface { + override fun close() +} + +interface DerivedInterface : MiddleInterface { + override fun close() +} + +open class BaseClass { + @ObjCName("close") + fun close() { + } +} + +class DerivedClass : BaseClass(), DerivedInterface {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/nativeTests/objCName3.kt b/compiler/testData/diagnostics/nativeTests/objCName3.kt new file mode 100644 index 00000000000..04b1cd64a3f --- /dev/null +++ b/compiler/testData/diagnostics/nativeTests/objCName3.kt @@ -0,0 +1,23 @@ +// FIR_IDENTICAL +// FILE: kotlin.kt +@file:OptIn(ExperimentalObjCName::class) + +package kotlin.native +import kotlin.experimental.ExperimentalObjCName + +fun interface BaseInterface { + @ObjCName("close") + fun close() +} + +interface DerivedInterface : BaseInterface { + override fun close() +} + +open class BaseClass { + @ObjCName("close") + fun close(){ + } +} + +class DerivedClass : BaseClass(), DerivedInterface {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/nativeTests/objCName4.kt b/compiler/testData/diagnostics/nativeTests/objCName4.kt new file mode 100644 index 00000000000..8ec90bfa49b --- /dev/null +++ b/compiler/testData/diagnostics/nativeTests/objCName4.kt @@ -0,0 +1,31 @@ +// FIR_IDENTICAL +// FILE: kotlin.kt +@file:OptIn(ExperimentalObjCName::class) + +package kotlin.native + +import kotlin.experimental.ExperimentalObjCName + +fun interface BaseInterface { + @ObjCName("close") + fun close() +} + +interface DerivedInterface : BaseInterface { + override fun close() +} + +fun interface IntersectionInterface { + @ObjCName("close") + fun close() +} + +open class IntersectionAbstract { + @ObjCName("close") + fun close() { + } +} + +open class IntersectionBaseClass : IntersectionAbstract(), IntersectionInterface + +class DerivedClass : IntersectionBaseClass(), DerivedInterface {} \ No newline at end of file diff --git a/compiler/testData/diagnostics/nativeTests/objCName5.kt b/compiler/testData/diagnostics/nativeTests/objCName5.kt new file mode 100644 index 00000000000..54e1bcc7a41 --- /dev/null +++ b/compiler/testData/diagnostics/nativeTests/objCName5.kt @@ -0,0 +1,31 @@ +// FIR_IDENTICAL +// FILE: kotlin.kt +@file:OptIn(ExperimentalObjCName::class) + +package kotlin.native + +import kotlin.experimental.ExperimentalObjCName + +fun interface BaseInterface { + @ObjCName("close") + fun close() +} + +interface DerivedInterface : BaseInterface { + override fun close() +} + +fun interface IntersectionInterface { + @ObjCName("close") + fun close() +} + +open class IntersectionAbstract { + @ObjCName("close") + fun close() { + } +} + +open class IntersectionBaseClass : IntersectionAbstract(), IntersectionInterface + +class DerivedClass : IntersectionBaseClass(), DerivedInterface {} \ No newline at end of file diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/diagnostics/DiagnosticsNativeTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/diagnostics/DiagnosticsNativeTestGenerated.java index 90191e45766..773be1533c4 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/diagnostics/DiagnosticsNativeTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/diagnostics/DiagnosticsNativeTestGenerated.java @@ -72,6 +72,30 @@ public class DiagnosticsNativeTestGenerated extends AbstractDiagnosticsNativeTes runTest("compiler/testData/diagnostics/nativeTests/objCName.kt"); } + @Test + @TestMetadata("objCName2.kt") + public void testObjCName2() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName2.kt"); + } + + @Test + @TestMetadata("objCName3.kt") + public void testObjCName3() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName3.kt"); + } + + @Test + @TestMetadata("objCName4.kt") + public void testObjCName4() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName4.kt"); + } + + @Test + @TestMetadata("objCName5.kt") + public void testObjCName5() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName5.kt"); + } + @Test @TestMetadata("objCRefinement.kt") public void testObjCRefinement() throws Exception { diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/diagnostics/FirLightTreeOldFrontendNativeDiagnosticsTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/diagnostics/FirLightTreeOldFrontendNativeDiagnosticsTestGenerated.java index bd242767b25..b401a5a771c 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/diagnostics/FirLightTreeOldFrontendNativeDiagnosticsTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/diagnostics/FirLightTreeOldFrontendNativeDiagnosticsTestGenerated.java @@ -76,6 +76,30 @@ public class FirLightTreeOldFrontendNativeDiagnosticsTestGenerated extends Abstr runTest("compiler/testData/diagnostics/nativeTests/objCName.kt"); } + @Test + @TestMetadata("objCName2.kt") + public void testObjCName2() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName2.kt"); + } + + @Test + @TestMetadata("objCName3.kt") + public void testObjCName3() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName3.kt"); + } + + @Test + @TestMetadata("objCName4.kt") + public void testObjCName4() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName4.kt"); + } + + @Test + @TestMetadata("objCName5.kt") + public void testObjCName5() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName5.kt"); + } + @Test @TestMetadata("objCRefinement.kt") public void testObjCRefinement() throws Exception { diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/diagnostics/FirPsiOldFrontendNativeDiagnosticsTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/diagnostics/FirPsiOldFrontendNativeDiagnosticsTestGenerated.java index efc2137e0e5..58565265b3e 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/diagnostics/FirPsiOldFrontendNativeDiagnosticsTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/diagnostics/FirPsiOldFrontendNativeDiagnosticsTestGenerated.java @@ -76,6 +76,30 @@ public class FirPsiOldFrontendNativeDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/nativeTests/objCName.kt"); } + @Test + @TestMetadata("objCName2.kt") + public void testObjCName2() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName2.kt"); + } + + @Test + @TestMetadata("objCName3.kt") + public void testObjCName3() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName3.kt"); + } + + @Test + @TestMetadata("objCName4.kt") + public void testObjCName4() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName4.kt"); + } + + @Test + @TestMetadata("objCName5.kt") + public void testObjCName5() throws Exception { + runTest("compiler/testData/diagnostics/nativeTests/objCName5.kt"); + } + @Test @TestMetadata("objCRefinement.kt") public void testObjCRefinement() throws Exception {