From 4d3825a8246d639e72fe1548248dd60eb9cf7e74 Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Tue, 30 Mar 2021 11:02:09 +0300 Subject: [PATCH] FIR: Serialize members originated from delegation --- .../fir/serialization/FirElementSerializer.kt | 55 +++++++++++++++---- .../backend/jvm/FirJvmSerializerExtension.kt | 4 +- .../fir/backend/jvm/FirMetadataSerializer.kt | 15 ++++- .../FirBlackBoxCodegenTestGenerated.java | 6 ++ .../delegation/delegationDifferentModule.kt | 16 ++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++ .../IrBlackBoxCodegenTestGenerated.java | 6 ++ .../LightAnalysisModeTestGenerated.java | 5 ++ .../IrJsCodegenBoxES6TestGenerated.java | 5 ++ .../IrJsCodegenBoxTestGenerated.java | 5 ++ .../semantics/JsCodegenBoxTestGenerated.java | 5 ++ .../IrCodegenBoxWasmTestGenerated.java | 5 ++ 12 files changed, 117 insertions(+), 16 deletions(-) create mode 100644 compiler/testData/codegen/box/delegation/delegationDifferentModule.kt 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 7dda86719c8..347724bee6e 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 @@ -11,8 +11,7 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget -import org.jetbrains.kotlin.fir.FirAnnotationContainer -import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor import org.jetbrains.kotlin.fir.deserialization.CONTINUATION_INTERFACE_CLASS_ID @@ -23,18 +22,19 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationCall import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations -import org.jetbrains.kotlin.fir.render +import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.calls.varargElementType -import org.jetbrains.kotlin.fir.resolve.symbolProvider -import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType import org.jetbrains.kotlin.fir.resolve.inference.suspendFunctionTypeToFunctionTypeWithContinuation -import org.jetbrains.kotlin.fir.resolve.toSymbol +import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator +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.fir.symbols.StandardClassIds +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.impl.FirImplicitNullableAnyTypeRef @@ -55,6 +55,7 @@ import org.jetbrains.kotlin.types.TypeApproximatorConfiguration class FirElementSerializer private constructor( private val session: FirSession, + private val scopeSession: ScopeSession, private val containingDeclaration: FirDeclaration?, private val typeParameters: Interner, private val extension: FirSerializerExtension, @@ -139,7 +140,7 @@ class FirElementSerializer private constructor( val callableMembers = extension.customClassMembersProducer?.getCallableMembers(klass) - ?: klass.declarations.filterIsInstance>() + ?: klass.declarations() .sortedWith(FirCallableMemberDeclarationComparator) for (declaration in callableMembers) { @@ -197,6 +198,32 @@ class FirElementSerializer private constructor( return builder } + @OptIn(ExperimentalStdlibApi::class) + private fun FirClass<*>.declarations(): List> = buildList { + val memberScope = + defaultType().scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing) + ?: error("Null scope for $this") + + fun addDeclarationIfNeeded(symbol: FirCallableSymbol<*>) { + val declaration = symbol.fir as? FirCallableMemberDeclaration<*> ?: return + if (declaration.isSubstitutionOrIntersectionOverride) return + + // non-intersection or substitution fake override + if (!declaration.isStatic && declaration.dispatchReceiverClassOrNull() != this@declarations.symbol.toLookupTag()) return + + add(declaration) + } + + memberScope.processAllFunctions(::addDeclarationIfNeeded) + memberScope.processAllProperties(::addDeclarationIfNeeded) + + for (declaration in declarations) { + if (declaration is FirCallableMemberDeclaration<*> && declaration.isStatic) { + add(declaration) + } + } + } + private fun FirPropertyAccessor.nonSourceAnnotations(session: FirSession, property: FirProperty): List = (this as FirAnnotationContainer).nonSourceAnnotations(session) + property.nonSourceAnnotations(session).filter { val useSiteTarget = it.useSiteTarget @@ -747,7 +774,7 @@ class FirElementSerializer private constructor( private fun createChildSerializer(declaration: FirDeclaration): FirElementSerializer = FirElementSerializer( - session, declaration, Interner(typeParameters), extension, + session, scopeSession, declaration, Interner(typeParameters), extension, typeTable, versionRequirementTable, serializeTypeTableToFunction = false, typeApproximator ) @@ -876,11 +903,12 @@ class FirElementSerializer private constructor( @JvmStatic fun createTopLevel( session: FirSession, + scopeSession: ScopeSession, extension: FirSerializerExtension, typeApproximator: AbstractTypeApproximator, ): FirElementSerializer = FirElementSerializer( - session, null, + session, scopeSession, null, Interner(), extension, MutableTypeTable(), MutableVersionRequirementTable(), serializeTypeTableToFunction = false, typeApproximator @@ -889,11 +917,12 @@ class FirElementSerializer private constructor( @JvmStatic fun createForLambda( session: FirSession, + scopeSession: ScopeSession, extension: FirSerializerExtension, typeApproximator: AbstractTypeApproximator, ): FirElementSerializer = FirElementSerializer( - session, null, + session, scopeSession, null, Interner(), extension, MutableTypeTable(), versionRequirementTable = null, serializeTypeTableToFunction = true, typeApproximator @@ -901,6 +930,7 @@ class FirElementSerializer private constructor( @JvmStatic fun create( + scopeSession: ScopeSession, klass: FirClass<*>, extension: FirSerializerExtension, parentSerializer: FirElementSerializer?, @@ -909,9 +939,9 @@ class FirElementSerializer private constructor( val parentClassId = klass.symbol.classId.outerClassId val parent = if (parentClassId != null && !parentClassId.isLocal) { val parentClass = klass.session.symbolProvider.getClassLikeSymbolByFqName(parentClassId)!!.fir as FirRegularClass - parentSerializer ?: create(parentClass, extension, null, typeApproximator) + parentSerializer ?: create(scopeSession, parentClass, extension, null, typeApproximator) } else { - createTopLevel(klass.session, extension, typeApproximator) + createTopLevel(klass.session, scopeSession, extension, typeApproximator) } // Calculate type parameter ids for the outer class beforehand, as it would've had happened if we were always @@ -919,6 +949,7 @@ class FirElementSerializer private constructor( // Otherwise our interner can get wrong ids because we may serialize classes in any order. val serializer = FirElementSerializer( klass.session, + scopeSession, klass, Interner(parent.typeParameters), extension, diff --git a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt index 4e6c16008ab..c755b2bc7f2 100644 --- a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt +++ b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt @@ -45,7 +45,7 @@ class FirJvmSerializerExtension( private val localDelegatedProperties: List, private val approximator: AbstractTypeApproximator, typeMapper: IrTypeMapper, - components: Fir2IrComponents + private val components: Fir2IrComponents ) : FirSerializerExtension() { private val globalBindings = state.globalSerializationBindings override val stringTable = FirJvmElementAwareStringTable(typeMapper, components) @@ -137,7 +137,7 @@ class FirJvmSerializerExtension( extension: GeneratedMessageLite.GeneratedExtension> ) { for (localVariable in localDelegatedProperties) { - val serializer = FirElementSerializer.createForLambda(session, this, approximator) + val serializer = FirElementSerializer.createForLambda(session, components.scopeSession,this, approximator) proto.addExtension(extension, serializer.propertyProto(localVariable)?.build() ?: continue) } } diff --git a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirMetadataSerializer.kt b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirMetadataSerializer.kt index d56749f511a..121b775ad57 100644 --- a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirMetadataSerializer.kt +++ b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirMetadataSerializer.kt @@ -154,10 +154,21 @@ class FirMetadataSerializer( private val serializer: FirElementSerializer? = when (val metadata = irClass.metadata) { is FirMetadataSource.Class -> FirElementSerializer.create( + components.scopeSession, metadata.fir, serializerExtension, (parent as? FirMetadataSerializer)?.serializer, approximator ) - is FirMetadataSource.File -> FirElementSerializer.createTopLevel(metadata.session, serializerExtension, approximator) - is FirMetadataSource.Function -> FirElementSerializer.createForLambda(metadata.session, serializerExtension, approximator) + is FirMetadataSource.File -> FirElementSerializer.createTopLevel( + metadata.session, + components.scopeSession, + serializerExtension, + approximator + ) + is FirMetadataSource.Function -> FirElementSerializer.createForLambda( + metadata.session, + components.scopeSession, + serializerExtension, + approximator + ) else -> null } 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 c2da673ff7c..7ce28a37504 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 @@ -13320,6 +13320,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/delegation/delegationAndInheritanceFromJava.kt"); } + @Test + @TestMetadata("delegationDifferentModule.kt") + public void testDelegationDifferentModule() throws Exception { + runTest("compiler/testData/codegen/box/delegation/delegationDifferentModule.kt"); + } + @Test @TestMetadata("delegationToMap.kt") public void testDelegationToMap() throws Exception { diff --git a/compiler/testData/codegen/box/delegation/delegationDifferentModule.kt b/compiler/testData/codegen/box/delegation/delegationDifferentModule.kt new file mode 100644 index 00000000000..8a791198c2e --- /dev/null +++ b/compiler/testData/codegen/box/delegation/delegationDifferentModule.kt @@ -0,0 +1,16 @@ +// MODULE: lib +// FILE: lib.kt +interface A { + fun foo(): String +} + +abstract class B(a: A) : A by a + +// MODULE: main(lib) +// FILE: main.kt +class AImpl : A { + override fun foo(): String = "OK" +} +class C : B(AImpl()) + +fun box(): String = C().foo() 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 800df5cf850..f68761a77d9 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 @@ -13320,6 +13320,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/delegation/delegationAndInheritanceFromJava.kt"); } + @Test + @TestMetadata("delegationDifferentModule.kt") + public void testDelegationDifferentModule() throws Exception { + runTest("compiler/testData/codegen/box/delegation/delegationDifferentModule.kt"); + } + @Test @TestMetadata("delegationToMap.kt") public void testDelegationToMap() 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 96ac9cb16c8..f9e05624b32 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 @@ -13320,6 +13320,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/delegation/delegationAndInheritanceFromJava.kt"); } + @Test + @TestMetadata("delegationDifferentModule.kt") + public void testDelegationDifferentModule() throws Exception { + runTest("compiler/testData/codegen/box/delegation/delegationDifferentModule.kt"); + } + @Test @TestMetadata("delegationToMap.kt") public void testDelegationToMap() 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 cf30c8dcfc8..c7f425bf923 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -10848,6 +10848,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/delegation/delegationAndInheritanceFromJava.kt"); } + @TestMetadata("delegationDifferentModule.kt") + public void testDelegationDifferentModule() throws Exception { + runTest("compiler/testData/codegen/box/delegation/delegationDifferentModule.kt"); + } + @TestMetadata("delegationToMap.kt") public void testDelegationToMap() throws Exception { runTest("compiler/testData/codegen/box/delegation/delegationToMap.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index d77cd3ab7b1..fb57525ae14 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -9717,6 +9717,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/delegation"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); } + @TestMetadata("delegationDifferentModule.kt") + public void testDelegationDifferentModule() throws Exception { + runTest("compiler/testData/codegen/box/delegation/delegationDifferentModule.kt"); + } + @TestMetadata("delegationWithPrivateConstructor.kt") public void testDelegationWithPrivateConstructor() throws Exception { runTest("compiler/testData/codegen/box/delegation/delegationWithPrivateConstructor.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index b9c9f7f370e..13c82e2bf03 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -9138,6 +9138,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/delegation"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); } + @TestMetadata("delegationDifferentModule.kt") + public void testDelegationDifferentModule() throws Exception { + runTest("compiler/testData/codegen/box/delegation/delegationDifferentModule.kt"); + } + @TestMetadata("delegationWithPrivateConstructor.kt") public void testDelegationWithPrivateConstructor() throws Exception { runTest("compiler/testData/codegen/box/delegation/delegationWithPrivateConstructor.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index f2059f625a6..1cce88f4bc3 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -9138,6 +9138,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/delegation"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); } + @TestMetadata("delegationDifferentModule.kt") + public void testDelegationDifferentModule() throws Exception { + runTest("compiler/testData/codegen/box/delegation/delegationDifferentModule.kt"); + } + @TestMetadata("delegationWithPrivateConstructor.kt") public void testDelegationWithPrivateConstructor() throws Exception { runTest("compiler/testData/codegen/box/delegation/delegationWithPrivateConstructor.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index 8ec88e53801..8c8aaf1da3b 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -4282,6 +4282,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/delegation"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true); } + @TestMetadata("delegationDifferentModule.kt") + public void testDelegationDifferentModule() throws Exception { + runTest("compiler/testData/codegen/box/delegation/delegationDifferentModule.kt"); + } + @TestMetadata("delegationWithPrivateConstructor.kt") public void testDelegationWithPrivateConstructor() throws Exception { runTest("compiler/testData/codegen/box/delegation/delegationWithPrivateConstructor.kt");