mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-10 08:31:29 +00:00
Fix creating of lazy delegated property in kotlinx.serialization
Fixes Kotlin/kotlinx.serialization#1616
This commit is contained in:
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ class SerializableCompanionIrGenerator(
|
||||
}
|
||||
|
||||
irClass.contributeFunction(methodDescriptor) {
|
||||
+irReturn(getLazyValueExpression(irClass, property))
|
||||
+irReturn(getLazyValueExpression(it.dispatchReceiverParameter!!, property, targetIrType))
|
||||
}
|
||||
generateSerializerFactoryIfNeeded(methodDescriptor)
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user