diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt index 69dfb982391..c6241de9f4d 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt @@ -149,46 +149,40 @@ class FakeOverrideGenerator( val origin = IrDeclarationOrigin.FAKE_OVERRIDE val baseSymbol = originalSymbol.unwrapSubstitutionAndIntersectionOverrides() as S - - if (originalSymbol.fir.origin.fromSupertypes && originalSymbol.dispatchReceiverClassOrNull() == classLookupTag) { - // Substitution case - // NB: see comment above about substituted function' parent - val irDeclaration = cachedIrDeclaration(originalDeclaration) { - // Sometimes we can have clashing here when FIR substitution/intersection override - // have the same signature. - // Now we avoid this problem by signature caching, - // so both FIR overrides correspond to one IR fake override - signatureComposer.composeSignature(originalDeclaration) - }?.takeIf { it.parent == irClass } - ?: createIrDeclaration( - originalDeclaration, irClass, - declarationStorage.findIrParent(baseSymbol.fir) as? IrClass, - origin, - isLocal - ) - irDeclaration.parent = irClass - baseSymbols[irDeclaration] = computeBaseSymbols(originalSymbol, baseSymbol, computeDirectOverridden, scope, classLookupTag) - result += irDeclaration - } else if (originalDeclaration.allowsToHaveFakeOverrideIn(klass)) { - // Trivial fake override case - val fakeOverrideSymbol = createFakeOverrideSymbol( - originalDeclaration, baseSymbol - ) - - classifierStorage.preCacheTypeParameters(originalDeclaration) - val irDeclaration = createIrDeclaration( - fakeOverrideSymbol.fir, irClass, - declarationStorage.findIrParent(baseSymbol.fir) as? IrClass, + val baseDeclaration = when { + originalSymbol.fir.origin.fromSupertypes && originalSymbol.dispatchReceiverClassOrNull() == classLookupTag -> { + // Substitution case + originalDeclaration + } + originalDeclaration.allowsToHaveFakeOverrideIn(klass) -> { + // Trivial fake override case + val fakeOverrideSymbol = createFakeOverrideSymbol(originalDeclaration, baseSymbol) + classifierStorage.preCacheTypeParameters(originalDeclaration) + fakeOverrideSymbol.fir + } + else -> { + return + } + } + val irDeclaration = cachedIrDeclaration(baseDeclaration) { + // Sometimes we can have clashing here when FIR substitution/intersection override + // have the same signature. + // Now we avoid this problem by signature caching, + // so both FIR overrides correspond to one IR fake override + signatureComposer.composeSignature(baseDeclaration) + }?.takeIf { it.parent == irClass } + ?: createIrDeclaration( + baseDeclaration, + irClass, + /* thisReceiverOwner = */ declarationStorage.findIrParent(baseSymbol.fir) as? IrClass, origin, isLocal ) - if (containsErrorTypes(irDeclaration)) { - return - } - irDeclaration.parent = irClass - baseSymbols[irDeclaration] = computeBaseSymbols(originalSymbol, baseSymbol, computeDirectOverridden, scope, classLookupTag) - result += irDeclaration + if (containsErrorTypes(irDeclaration)) { + return } + baseSymbols[irDeclaration] = computeBaseSymbols(originalSymbol, baseSymbol, computeDirectOverridden, scope, classLookupTag) + result += irDeclaration } private inline fun > computeBaseSymbols( @@ -208,13 +202,16 @@ class FakeOverrideGenerator( } } + internal fun getOverriddenSymbols(function: IrSimpleFunction): List? { + return baseFunctionSymbols[function]?.map { declarationStorage.getIrFunctionSymbol(it) as IrSimpleFunctionSymbol } + } + fun bindOverriddenSymbols(declarations: List) { for (declaration in declarations) { if (declaration.origin != IrDeclarationOrigin.FAKE_OVERRIDE) continue when (declaration) { is IrSimpleFunction -> { - val baseSymbols = - baseFunctionSymbols[declaration]!!.map { declarationStorage.getIrFunctionSymbol(it) as IrSimpleFunctionSymbol } + val baseSymbols = getOverriddenSymbols(declaration)!! declaration.withFunction { overriddenSymbols = baseSymbols } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt index 1da2d995609..3a02aad285e 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/lazy/Fir2IrLazySimpleFunction.kt @@ -67,6 +67,11 @@ class Fir2IrLazySimpleFunction( } override var overriddenSymbols: List by lazyVar { + val parent = parent + if (isFakeOverride && parent is Fir2IrLazyClass) { + parent.declarations + fakeOverrideGenerator.getOverriddenSymbols(this)?.let { return@lazyVar it } + } fir.generateOverriddenFunctionSymbols(firParent, session, scopeSession, declarationStorage) } diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/FirCompileKotlinAgainstKotlinTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/FirCompileKotlinAgainstKotlinTestGenerated.java index 19dc082737c..9eabc99689d 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/FirCompileKotlinAgainstKotlinTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/codegen/FirCompileKotlinAgainstKotlinTestGenerated.java @@ -435,6 +435,11 @@ public class FirCompileKotlinAgainstKotlinTestGenerated extends AbstractFirCompi runTest("compiler/testData/compileKotlinAgainstKotlin/fir/ExistingSymbolInFakeOverride.kt"); } + @TestMetadata("IrConstAcceptMultiModule.kt") + public void testIrConstAcceptMultiModule() throws Exception { + runTest("compiler/testData/compileKotlinAgainstKotlin/fir/IrConstAcceptMultiModule.kt"); + } + @TestMetadata("LibraryProperty.kt") public void testLibraryProperty() throws Exception { runTest("compiler/testData/compileKotlinAgainstKotlin/fir/LibraryProperty.kt"); diff --git a/compiler/testData/compileKotlinAgainstKotlin/fir/IrConstAcceptMultiModule.kt b/compiler/testData/compileKotlinAgainstKotlin/fir/IrConstAcceptMultiModule.kt new file mode 100644 index 00000000000..e0c04b520e6 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstKotlin/fir/IrConstAcceptMultiModule.kt @@ -0,0 +1,97 @@ +// TARGET_BACKEND: JVM +// FILE: A.kt +// WITH_RUNTIME + +abstract class IrConst : IrExpression(), IrExpressionWithCopy { + abstract val kind: IrConstKind + abstract val value: T + + abstract override fun copy(): IrConst + abstract fun copyWithOffsets(startOffset: Int, endOffset: Int): IrConst +} + +sealed class IrConstKind(val asString: kotlin.String) { + @Suppress("UNCHECKED_CAST") + fun valueOf(aConst: IrConst<*>) = + (aConst as IrConst).value + + object Null : IrConstKind("Null") + object Boolean : IrConstKind("Boolean") + object Char : IrConstKind("Char") + object Byte : IrConstKind("Byte") + object Short : IrConstKind("Short") + object Int : IrConstKind("Int") + object Long : IrConstKind("Long") + object String : IrConstKind("String") + object Float : IrConstKind("Float") + object Double : IrConstKind("Double") + + override fun toString() = asString +} + +interface IrType + +abstract class IrExpression : IrElementBase(), IrStatement, IrVarargElement, IrAttributeContainer { + @Suppress("LeakingThis") + override var attributeOwnerId: IrAttributeContainer = this + + abstract var type: IrType + + override fun transform(transformer: IrElementTransformer, data: D): IrExpression = + accept(transformer, data) as IrExpression + + override fun acceptChildren(visitor: IrElementVisitor, data: D) { + // No children by default + } + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + // No children by default + } +} + +interface IrExpressionWithCopy { + fun copy(): IrExpression +} + +interface IrAttributeContainer : IrElement { + var attributeOwnerId: IrAttributeContainer +} + +abstract class IrElementBase : IrElement + +interface IrStatement : IrElement + +interface IrVarargElement : IrElement + +interface IrElement { + val startOffset: Int + val endOffset: Int + + fun accept(visitor: IrElementVisitor, data: D): R + + fun acceptChildren(visitor: IrElementVisitor, data: D): Unit + + fun transform(transformer: IrElementTransformer, data: D): IrElement = + accept(transformer, data) + + fun transformChildren(transformer: IrElementTransformer, data: D): Unit +} + +interface IrElementVisitor + +interface IrElementTransformer : IrElementVisitor + +// FILE: B.kt + +fun foo(cases: Collection>, exprTransformer: IrElementTransformer, context: Any) { + cases.map { + it.accept(exprTransformer, context) + } +} + +fun box(): String { + return "OK" +} + + + diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java index 7d17c880e71..47dc0148f5e 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/CompileKotlinAgainstKotlinTestGenerated.java @@ -440,6 +440,11 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl runTest("compiler/testData/compileKotlinAgainstKotlin/fir/ExistingSymbolInFakeOverride.kt"); } + @TestMetadata("IrConstAcceptMultiModule.kt") + public void testIrConstAcceptMultiModule() throws Exception { + runTest("compiler/testData/compileKotlinAgainstKotlin/fir/IrConstAcceptMultiModule.kt"); + } + @TestMetadata("LibraryProperty.kt") public void testLibraryProperty() throws Exception { runTest("compiler/testData/compileKotlinAgainstKotlin/fir/LibraryProperty.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstKotlinTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstKotlinTestGenerated.java index 17e2689dd24..c80d0bae244 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstKotlinTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstKotlinTestGenerated.java @@ -435,6 +435,11 @@ public class IrCompileKotlinAgainstKotlinTestGenerated extends AbstractIrCompile runTest("compiler/testData/compileKotlinAgainstKotlin/fir/ExistingSymbolInFakeOverride.kt"); } + @TestMetadata("IrConstAcceptMultiModule.kt") + public void testIrConstAcceptMultiModule() throws Exception { + runTest("compiler/testData/compileKotlinAgainstKotlin/fir/IrConstAcceptMultiModule.kt"); + } + @TestMetadata("LibraryProperty.kt") public void testLibraryProperty() throws Exception { runTest("compiler/testData/compileKotlinAgainstKotlin/fir/LibraryProperty.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/JvmIrAgainstOldBoxTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/JvmIrAgainstOldBoxTestGenerated.java index 216c3c86fab..ec454d9f138 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/JvmIrAgainstOldBoxTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/JvmIrAgainstOldBoxTestGenerated.java @@ -435,6 +435,11 @@ public class JvmIrAgainstOldBoxTestGenerated extends AbstractJvmIrAgainstOldBoxT runTest("compiler/testData/compileKotlinAgainstKotlin/fir/ExistingSymbolInFakeOverride.kt"); } + @TestMetadata("IrConstAcceptMultiModule.kt") + public void testIrConstAcceptMultiModule() throws Exception { + runTest("compiler/testData/compileKotlinAgainstKotlin/fir/IrConstAcceptMultiModule.kt"); + } + @TestMetadata("LibraryProperty.kt") public void testLibraryProperty() throws Exception { runTest("compiler/testData/compileKotlinAgainstKotlin/fir/LibraryProperty.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/JvmOldAgainstIrBoxTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/JvmOldAgainstIrBoxTestGenerated.java index 29e0050ee99..032b2129eca 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/JvmOldAgainstIrBoxTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/JvmOldAgainstIrBoxTestGenerated.java @@ -435,6 +435,11 @@ public class JvmOldAgainstIrBoxTestGenerated extends AbstractJvmOldAgainstIrBoxT runTest("compiler/testData/compileKotlinAgainstKotlin/fir/ExistingSymbolInFakeOverride.kt"); } + @TestMetadata("IrConstAcceptMultiModule.kt") + public void testIrConstAcceptMultiModule() throws Exception { + runTest("compiler/testData/compileKotlinAgainstKotlin/fir/IrConstAcceptMultiModule.kt"); + } + @TestMetadata("LibraryProperty.kt") public void testLibraryProperty() throws Exception { runTest("compiler/testData/compileKotlinAgainstKotlin/fir/LibraryProperty.kt");