From 15dfe6c7502c82b207f3a805fff421656cf82963 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Mon, 24 Apr 2023 18:28:50 +0300 Subject: [PATCH] [FIR2IR] Use signature instead of FIR as a key for fake-override storage This is needed to correctly handle the case, when we have the same java class in common and platform module. In this scenario we have two different classes on frontend (because symbol providers are not shared) and completely different enhanced function in scopes of those classes, but exactly one IrClass for those classes, which is cached during conversion of common module together with cache of its fake overrides. So using FirDeclaration as a key to FO cache leads to the problem, when we can not find cached value for platform module, because it has different fir declarations for the same real decalration ^KT-58030 Fixed --- .../fir/backend/Fir2IrCommonMemberStorage.kt | 5 ++-- .../fir/backend/Fir2IrDeclarationStorage.kt | 23 +++++++++++++--- ...LightTreeBlackBoxCodegenTestGenerated.java | 6 +++++ .../FirPsiBlackBoxCodegenTestGenerated.java | 6 +++++ .../box/multiplatform/callToJavaSuper.kt | 26 +++++++++++++++++++ .../IrBlackBoxCodegenTestGenerated.java | 6 +++++ ...kBoxCodegenWithIrInlinerTestGenerated.java | 6 +++++ 7 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/codegen/box/multiplatform/callToJavaSuper.kt diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrCommonMemberStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrCommonMemberStorage.kt index def4ffbcb0b..d68c13680f8 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrCommonMemberStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrCommonMemberStorage.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.signaturer.FirBasedSignatureComposer import org.jetbrains.kotlin.fir.signaturer.FirMangler import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl +import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.IdSignatureComposer import org.jetbrains.kotlin.ir.util.SymbolTable import java.util.concurrent.ConcurrentHashMap @@ -49,5 +50,5 @@ class Fir2IrCommonMemberStorage( val propertyCache: ConcurrentHashMap = ConcurrentHashMap() - val fakeOverridesInClass: MutableMap> = mutableMapOf() -} \ No newline at end of file + val fakeOverridesInClass: MutableMap> = mutableMapOf() +} diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index d27bbe23188..ba0859adfd4 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -110,9 +110,25 @@ class Fir2IrDeclarationStorage( // // Note: reusing is necessary here, because sometimes (see testFakeOverridesInPlatformModule) // we have to match fake override in platform class with overridden fake overrides in common class - private val fakeOverridesInClass: MutableMap> = + private val fakeOverridesInClass: MutableMap> = commonMemberStorage.fakeOverridesInClass + sealed class FakeOverrideKey { + data class Signature(val signature: IdSignature) : FakeOverrideKey() + + /* + * Used for declarations which don't have id signature (e.g. members of local classes) + */ + data class Declaration(val declaration: FirCallableDeclaration) : FakeOverrideKey() + } + + private fun FirCallableDeclaration.asFakeOverrideKey(): FakeOverrideKey { + return when (val signature = signatureComposer.composeSignature(this)) { + null -> FakeOverrideKey.Declaration(this) + else -> FakeOverrideKey.Signature(signature) + } + } + // For pure fields (from Java) only private val fieldToPropertyCache: ConcurrentHashMap, IrProperty> = ConcurrentHashMap() @@ -1028,7 +1044,7 @@ class Fir2IrDeclarationStorage( originalDeclaration: FirCallableDeclaration, fakeOverride: FirCallableDeclaration ) { - fakeOverridesInClass.getOrPut(irClass, ::mutableMapOf)[originalDeclaration] = fakeOverride + fakeOverridesInClass.getOrPut(irClass, ::mutableMapOf)[originalDeclaration.asFakeOverrideKey()] = fakeOverride } fun getFakeOverrideInClass( @@ -1038,7 +1054,8 @@ class Fir2IrDeclarationStorage( if (irClass is Fir2IrLazyClass) { irClass.getFakeOverridesByName(callableDeclaration.symbol.callableId.callableName) } - return fakeOverridesInClass[irClass]?.get(callableDeclaration) + val map = fakeOverridesInClass[irClass] + return map?.get(callableDeclaration.asFakeOverrideKey()) } fun getCachedIrDelegateOrBackingField(field: FirField): IrField? = fieldCache[field] diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java index 031d9ca1149..1edc24a32da 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java @@ -32897,6 +32897,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr runTest("compiler/testData/codegen/box/multiplatform/annotationsViaActualTypeAliasFromBinary2.kt"); } + @Test + @TestMetadata("callToJavaSuper.kt") + public void testCallToJavaSuper() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/callToJavaSuper.kt"); + } + @Test @TestMetadata("commonInternal.kt") public void testCommonInternal() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java index ad59a10e1c4..76a52e2ca84 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java @@ -32897,6 +32897,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo runTest("compiler/testData/codegen/box/multiplatform/annotationsViaActualTypeAliasFromBinary2.kt"); } + @Test + @TestMetadata("callToJavaSuper.kt") + public void testCallToJavaSuper() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/callToJavaSuper.kt"); + } + @Test @TestMetadata("commonInternal.kt") public void testCommonInternal() throws Exception { diff --git a/compiler/testData/codegen/box/multiplatform/callToJavaSuper.kt b/compiler/testData/codegen/box/multiplatform/callToJavaSuper.kt new file mode 100644 index 00000000000..4be5acd5a08 --- /dev/null +++ b/compiler/testData/codegen/box/multiplatform/callToJavaSuper.kt @@ -0,0 +1,26 @@ +// LANGUAGE: +MultiPlatformProjects +// WITH_STDLIB +// TARGET_BACKEND: JVM_IR +// IGNORE_BACKEND_K1: JVM_IR +// Ignore reason: expect/actual are not supported in K1 box tests +// ISSUE: KT-58030 + +// MODULE: common +// FILE: common.kt + +expect open class CancellationException: Exception + +expect class JobCancellationException: CancellationException + +// MODULE: jvm()()(common) +// FILE: jvm.kt + +actual open class CancellationException: Exception() + +actual class JobCancellationException: CancellationException() { + init { + super.fillInStackTrace() + } +} + +fun box() = "OK" diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 602152bdfbc..1be48c9794e 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -32897,6 +32897,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/multiplatform/annotationsViaActualTypeAliasFromBinary2.kt"); } + @Test + @TestMetadata("callToJavaSuper.kt") + public void testCallToJavaSuper() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/callToJavaSuper.kt"); + } + @Test @TestMetadata("commonInternal.kt") public void testCommonInternal() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java index 22c0e785450..6b1f1d8abda 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java @@ -32897,6 +32897,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack runTest("compiler/testData/codegen/box/multiplatform/annotationsViaActualTypeAliasFromBinary2.kt"); } + @Test + @TestMetadata("callToJavaSuper.kt") + public void testCallToJavaSuper() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/callToJavaSuper.kt"); + } + @Test @TestMetadata("commonInternal.kt") public void testCommonInternal() throws Exception {