[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
This commit is contained in:
Dmitriy Novozhilov
2023-04-24 18:28:50 +03:00
committed by Space Team
parent 7b46c59d57
commit 15dfe6c750
7 changed files with 73 additions and 5 deletions
@@ -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<FirProperty, IrProperty> = ConcurrentHashMap()
val fakeOverridesInClass: MutableMap<IrClass, MutableMap<FirCallableDeclaration, FirCallableDeclaration>> = mutableMapOf()
}
val fakeOverridesInClass: MutableMap<IrClass, MutableMap<Fir2IrDeclarationStorage.FakeOverrideKey, FirCallableDeclaration>> = mutableMapOf()
}
@@ -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<IrClass, MutableMap<FirCallableDeclaration, FirCallableDeclaration>> =
private val fakeOverridesInClass: MutableMap<IrClass, MutableMap<FakeOverrideKey, FirCallableDeclaration>> =
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<Pair<FirField, IrDeclarationParent>, 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]
@@ -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 {
@@ -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 {
@@ -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"
@@ -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 {
@@ -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 {