From b42d6a3e857557b7565fe8a788ad11908cfc6921 Mon Sep 17 00:00:00 2001 From: Sergey Shanshin Date: Mon, 2 Aug 2021 16:27:03 +0000 Subject: [PATCH] Fix creating of lazy delegated property in kotlinx.serialization Fixes Kotlin/kotlinx.serialization#1616 --- .../compiler/backend/ir/GeneratorHelpers.kt | 43 +++++++------------ .../ir/SerializableCompanionIrGenerator.kt | 2 +- .../compiler/resolve/NamingConventions.kt | 1 - 3 files changed, 17 insertions(+), 29 deletions(-) diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt index edcb5dd92bc..4f478239f7b 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt @@ -10,15 +10,11 @@ import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder import org.jetbrains.kotlin.backend.common.lower.irIfThen import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.declarations.buildFun import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.descriptors.IrBuiltInsOverDescriptors -import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptorImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* -import org.jetbrains.kotlin.ir.interpreter.toIrConst import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.impl.* import org.jetbrains.kotlin.ir.types.* @@ -42,7 +38,6 @@ import org.jetbrains.kotlinx.serialization.compiler.backend.jvm.* import org.jetbrains.kotlinx.serialization.compiler.extensions.SerializationPluginContext import org.jetbrains.kotlinx.serialization.compiler.resolve.* import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationDependencies.FUNCTION0_FQ -import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationDependencies.KPROPERTY1_FQ import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationDependencies.LAZY_FQ import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationDependencies.LAZY_FUNC_FQ import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationDependencies.LAZY_MODE_FQ @@ -129,24 +124,17 @@ interface IrBuilderExtension { val publicationEntryDescriptor = lazySafeModeClassDescriptor.enumEntries().single { it.name == LAZY_PUBLICATION_MODE_NAME } val lazyIrClass = compilerContext.referenceClass(LAZY_FQ)!!.owner - val lazyKotlinType = lazyIrClass.defaultType.substitute(mapOf(lazyIrClass.typeParameters[0].symbol to targetIrType)).toKotlinType() - - val kPropertyIrClass = compilerContext.referenceClass(KPROPERTY1_FQ)!!.owner - val kPropertyKotlinType = kPropertyIrClass.defaultType.substitute( - mapOf( - kPropertyIrClass.typeParameters[0].symbol to targetIrType, - kPropertyIrClass.typeParameters[1].symbol to containingClass.defaultType, - ) - ).toKotlinType() - - val targetKotlinType = targetIrType.toKotlinType() + val lazyIrType = lazyIrClass.defaultType.substitute(mapOf(lazyIrClass.typeParameters[0].symbol to targetIrType)) val propertyDescriptor = - KSerializerDescriptorResolver.createValPropertyDescriptor(name, containingClass.descriptor, targetKotlinType) + KSerializerDescriptorResolver.createValPropertyDescriptor( + Name.identifier(name.asString() + "\$delegate"), + containingClass.descriptor, + lazyIrType.toKotlinType(), + createGetter = true + ) - val delegate = IrPropertyDelegateDescriptorImpl(propertyDescriptor, lazyKotlinType, kPropertyKotlinType) - - return generateSimplePropertyWithBackingField(delegate, containingClass, delegate.name).apply { + return generateSimplePropertyWithBackingField(propertyDescriptor, containingClass).apply { val builder = DeclarationIrBuilder(compilerContext, containingClass.symbol, startOffset, endOffset) val initializerBody = builder.run { val enumElement = IrGetEnumValueImpl( @@ -159,7 +147,7 @@ interface IrBuilderExtension { val lambdaExpression = containingClass.createLambdaExpression(targetIrType, initializerBuilder) irExprBody( - irInvoke(null, lazyFunctionSymbol, listOf(targetIrType), listOf(enumElement, lambdaExpression), targetIrType) + irInvoke(null, lazyFunctionSymbol, listOf(targetIrType), listOf(enumElement, lambdaExpression), lazyIrType) ) } backingField!!.initializer = initializerBody @@ -196,15 +184,16 @@ interface IrBuilderExtension { } } - fun IrBlockBodyBuilder.getLazyValueExpression(companionClass: IrClass, property: IrProperty): IrExpression { + fun IrBlockBodyBuilder.getLazyValueExpression(thisParam: IrValueParameter, property: IrProperty, type: IrType): IrExpression { val lazyIrClass = compilerContext.referenceClass(LAZY_FQ)!!.owner val valueGetter = lazyIrClass.getPropertyGetter("value")!! - val backingField = property.backingField!! - return irGet( - backingField.type, - irGetField(irGetObject(companionClass), backingField), - valueGetter + val propertyGetter = property.getter!! + + return irInvoke( + irGet(propertyGetter.returnType, irGet(thisParam), propertyGetter.symbol), + valueGetter, + typeHint = type ) } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableCompanionIrGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableCompanionIrGenerator.kt index 57a9337ec08..3f147edc90f 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableCompanionIrGenerator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableCompanionIrGenerator.kt @@ -122,7 +122,7 @@ class SerializableCompanionIrGenerator( } irClass.contributeFunction(methodDescriptor) { - +irReturn(getLazyValueExpression(irClass, property)) + +irReturn(getLazyValueExpression(it.dispatchReceiverParameter!!, property, targetIrType)) } generateSerializerFactoryIfNeeded(methodDescriptor) } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/NamingConventions.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/NamingConventions.kt index 99124d55a5c..e7ecd500118 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/NamingConventions.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/NamingConventions.kt @@ -139,7 +139,6 @@ internal object SerializationDependencies { val LAZY_FQ = FqName("kotlin.Lazy") val LAZY_FUNC_FQ = FqName("kotlin.lazy") val LAZY_MODE_FQ = FqName("kotlin.LazyThreadSafetyMode") - val KPROPERTY1_FQ = FqName("kotlin.reflect.KProperty1") val FUNCTION0_FQ = FqName("kotlin.Function0") val LAZY_PUBLICATION_MODE_NAME = Name.identifier("PUBLICATION") }