diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt index 595b0b97c23..01b954c575b 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt @@ -27,14 +27,15 @@ import org.jetbrains.kotlin.fir.resolve.calls.varargElementType import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType import org.jetbrains.kotlin.fir.resolve.inference.suspendFunctionTypeToFunctionTypeWithContinuation import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator +import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData import org.jetbrains.kotlin.fir.scopes.processAllFunctions import org.jetbrains.kotlin.fir.scopes.processAllProperties import org.jetbrains.kotlin.fir.serialization.constant.EnumValue import org.jetbrains.kotlin.fir.serialization.constant.IntValue import org.jetbrains.kotlin.fir.serialization.constant.StringValue import org.jetbrains.kotlin.fir.serialization.constant.toConstantValue -import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirIntersectionCallableSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.impl.FirImplicitNullableAnyTypeRef @@ -48,6 +49,7 @@ import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTabl import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.resolve.RequireKotlinConstants import org.jetbrains.kotlin.serialization.deserialization.ProtoEnumFlags import org.jetbrains.kotlin.types.AbstractTypeApproximator @@ -221,7 +223,29 @@ class FirElementSerializer private constructor( fun addDeclarationIfNeeded(symbol: FirCallableSymbol<*>) { val declaration = symbol.fir as? FirCallableMemberDeclaration<*> ?: return - if (declaration.isSubstitutionOrIntersectionOverride) return + if (declaration.isIntersectionOverride) { + // This part is a kind of hack for case like + // + // interface A { + // fun foo(): String? + // } + // + // interface B : A { + // override fun foo(): String? + // } + // + // abstract class C(a: A) : B, A by a + // We should serialize C::foo as it works almost like real declarations, but currently it's hidden behind intersection scope + // UseSiteScope(C) = DeclaredScope(C) + FirIntersectionScope(UseSiteScope(B), DelegatedScope(a)) + // + // That should be fixed by putting delegated members closer to declared scope + // See KT-47413 + (declaration.symbol as? FirIntersectionCallableSymbol)?.intersections?.firstOrNull { + it.fir.delegatedWrapperData != null + }?.let(::addDeclarationIfNeeded) + return + } + if (declaration.isSubstitutionOverride) return // non-intersection or substitution fake override if (!declaration.isStatic && declaration.dispatchReceiverClassOrNull() != this@declarations.symbol.toLookupTag()) return diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 06b77dd27f0..1ba8387c2d7 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -13778,6 +13778,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/delegation/diamond2.kt"); } + @Test + @TestMetadata("differentModules.kt") + public void testDifferentModules() throws Exception { + runTest("compiler/testData/codegen/box/delegation/differentModules.kt"); + } + @Test @TestMetadata("genericProperty.kt") public void testGenericProperty() throws Exception { diff --git a/compiler/testData/codegen/box/delegation/differentModules.kt b/compiler/testData/codegen/box/delegation/differentModules.kt new file mode 100644 index 00000000000..b39575c0b1d --- /dev/null +++ b/compiler/testData/codegen/box/delegation/differentModules.kt @@ -0,0 +1,28 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME + +// MODULE: base +// FILE: base.kt + +interface PsiClass { + fun foo(): String? +} + +interface UClass : PsiClass { + override fun foo(): String? +} + +abstract class BaseKotlinUClass( + psi: PsiClass, +) : UClass, PsiClass by psi + +// MODULE: main(base) +// FILE: main.kt + +class A(psi: PsiClass) : BaseKotlinUClass(psi) + +fun bar(uClass: UClass): String = uClass.foo()!! + +fun box(): String = bar(A(object : PsiClass { + override fun foo(): String? = "OK" +})) diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index ab5d59ba4a4..a835ae4bb13 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -13778,6 +13778,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/delegation/diamond2.kt"); } + @Test + @TestMetadata("differentModules.kt") + public void testDifferentModules() throws Exception { + runTest("compiler/testData/codegen/box/delegation/differentModules.kt"); + } + @Test @TestMetadata("genericProperty.kt") public void testGenericProperty() throws Exception { 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 0a9c0ff6dee..94455b9d2e7 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 @@ -13778,6 +13778,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/delegation/diamond2.kt"); } + @Test + @TestMetadata("differentModules.kt") + public void testDifferentModules() throws Exception { + runTest("compiler/testData/codegen/box/delegation/differentModules.kt"); + } + @Test @TestMetadata("genericProperty.kt") public void testGenericProperty() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index b4b356a6713..1711a6378eb 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -11219,6 +11219,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/delegation/diamond2.kt"); } + @TestMetadata("differentModules.kt") + public void testDifferentModules() throws Exception { + runTest("compiler/testData/codegen/box/delegation/differentModules.kt"); + } + @TestMetadata("genericProperty.kt") public void testGenericProperty() throws Exception { runTest("compiler/testData/codegen/box/delegation/genericProperty.kt");