Insert correct dispatch receivers and type arguments for expression inside generated by plugin IR functions

This commit is contained in:
Leonid Startsev
2019-03-27 20:53:20 +03:00
parent 075a902ceb
commit 0ffded5bac
3 changed files with 99 additions and 53 deletions
@@ -18,9 +18,9 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.toKotlinType import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.typeWith import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
@@ -69,7 +69,7 @@ interface IrBuilderExtension {
) else compilerContext.externalSymbols.referenceSimpleFunction(descriptor).owner ) else compilerContext.externalSymbols.referenceSimpleFunction(descriptor).owner
f.parent = this f.parent = this
f.returnType = descriptor.returnType!!.toIrType() f.returnType = descriptor.returnType!!.toIrType()
if (!fromStubs) f.createParameterDeclarations(this.thisReceiver) if (!fromStubs) f.createParameterDeclarations(this.thisReceiver!!)
f.body = compilerContext.createIrBuilder(f.symbol).at(this).irBlockBody(this.startOffset, this.endOffset) { bodyGen(f) } f.body = compilerContext.createIrBuilder(f.symbol).at(this).irBlockBody(this.startOffset, this.endOffset) { bodyGen(f) }
this.addMember(f) this.addMember(f)
} }
@@ -87,7 +87,10 @@ interface IrBuilderExtension {
) else compilerContext.externalSymbols.referenceConstructor(descriptor).owner ) else compilerContext.externalSymbols.referenceConstructor(descriptor).owner
c.parent = this c.parent = this
c.returnType = descriptor.returnType.toIrType() c.returnType = descriptor.returnType.toIrType()
if (!fromStubs) c.createParameterDeclarations() if (!fromStubs) c.createParameterDeclarations(receiver = null)
if (c.typeParameters.isEmpty()) {
c.copyTypeParamsFromDescriptor()
}
c.body = compilerContext.createIrBuilder(c.symbol).at(this).irBlockBody(this.startOffset, this.endOffset) { bodyGen(c) } c.body = compilerContext.createIrBuilder(c.symbol).at(this).irBlockBody(this.startOffset, this.endOffset) { bodyGen(c) }
this.addMember(c) this.addMember(c)
} }
@@ -237,9 +240,9 @@ interface IrBuilderExtension {
irProperty.backingField = irProperty.backingField =
generatePropertyBackingField(propertyDescriptor, irProperty).apply { parent = propertyParent } generatePropertyBackingField(propertyDescriptor, irProperty).apply { parent = propertyParent }
val fieldSymbol = irProperty.backingField!!.symbol val fieldSymbol = irProperty.backingField!!.symbol
irProperty.getter = propertyDescriptor.getter?.let { generatePropertyAccessor(it, fieldSymbol, ownerSymbol) } irProperty.getter = propertyDescriptor.getter?.let { generatePropertyAccessor(it, fieldSymbol) }
?.apply { parent = propertyParent } ?.apply { parent = propertyParent }
irProperty.setter = propertyDescriptor.setter?.let { generatePropertyAccessor(it, fieldSymbol, ownerSymbol) } irProperty.setter = propertyDescriptor.setter?.let { generatePropertyAccessor(it, fieldSymbol) }
?.apply { parent = propertyParent } ?.apply { parent = propertyParent }
return irProperty return irProperty
} }
@@ -259,18 +262,17 @@ interface IrBuilderExtension {
fun generatePropertyAccessor( fun generatePropertyAccessor(
descriptor: PropertyAccessorDescriptor, descriptor: PropertyAccessorDescriptor,
fieldSymbol: IrFieldSymbol, fieldSymbol: IrFieldSymbol
ownerSymbol: IrValueSymbol
): IrSimpleFunction { ): IrSimpleFunction {
// Declaration can also be called from user code. Since we lookup descriptor getter in externalSymbols // Declaration can also be called from user code. Since we lookup descriptor getter in externalSymbols
// (see generateSave/generateLoad), seems it is correct approach to declare getter lazily there. // (see generateSave/generateLoad), seems it is correct approach to declare getter lazily there.
val declaration = compilerContext.externalSymbols.referenceSimpleFunction(descriptor).owner val declaration = compilerContext.externalSymbols.referenceSimpleFunction(descriptor).owner
return declaration.buildWithScope { irAccessor -> return declaration.buildWithScope { irAccessor ->
irAccessor.createParameterDeclarations((ownerSymbol as IrValueParameterSymbol).owner) // todo: neat this irAccessor.createParameterDeclarations(receiver = null)
irAccessor.returnType = irAccessor.descriptor.returnType!!.toIrType() irAccessor.returnType = irAccessor.descriptor.returnType!!.toIrType()
irAccessor.body = when (descriptor) { irAccessor.body = when (descriptor) {
is PropertyGetterDescriptor -> generateDefaultGetterBody(descriptor, irAccessor, ownerSymbol) is PropertyGetterDescriptor -> generateDefaultGetterBody(descriptor, irAccessor)
is PropertySetterDescriptor -> generateDefaultSetterBody(descriptor, irAccessor, ownerSymbol) is PropertySetterDescriptor -> generateDefaultSetterBody(descriptor, irAccessor)
else -> throw AssertionError("Should be getter or setter: $descriptor") else -> throw AssertionError("Should be getter or setter: $descriptor")
} }
} }
@@ -278,8 +280,7 @@ interface IrBuilderExtension {
private fun generateDefaultGetterBody( private fun generateDefaultGetterBody(
getter: PropertyGetterDescriptor, getter: PropertyGetterDescriptor,
irAccessor: IrSimpleFunction, irAccessor: IrSimpleFunction
ownerSymbol: IrValueSymbol
): IrBlockBody { ): IrBlockBody {
val property = getter.correspondingProperty val property = getter.correspondingProperty
@@ -287,7 +288,7 @@ interface IrBuilderExtension {
val endOffset = irAccessor.endOffset val endOffset = irAccessor.endOffset
val irBody = IrBlockBodyImpl(startOffset, endOffset) val irBody = IrBlockBodyImpl(startOffset, endOffset)
val receiver = generateReceiverExpressionForFieldAccess(ownerSymbol, property) val receiver = generateReceiverExpressionForFieldAccess(irAccessor.dispatchReceiverParameter!!.symbol, property)
irBody.statements.add( irBody.statements.add(
IrReturnImpl( IrReturnImpl(
@@ -306,8 +307,7 @@ interface IrBuilderExtension {
private fun generateDefaultSetterBody( private fun generateDefaultSetterBody(
setter: PropertySetterDescriptor, setter: PropertySetterDescriptor,
irAccessor: IrSimpleFunction, irAccessor: IrSimpleFunction
ownerSymbol: IrValueSymbol
): IrBlockBody { ): IrBlockBody {
val property = setter.correspondingProperty val property = setter.correspondingProperty
@@ -315,7 +315,7 @@ interface IrBuilderExtension {
val endOffset = irAccessor.endOffset val endOffset = irAccessor.endOffset
val irBody = IrBlockBodyImpl(startOffset, endOffset) val irBody = IrBlockBodyImpl(startOffset, endOffset)
val receiver = generateReceiverExpressionForFieldAccess(ownerSymbol, property) val receiver = generateReceiverExpressionForFieldAccess(irAccessor.dispatchReceiverParameter!!.symbol, property)
val irValueParameter = irAccessor.valueParameters.single() val irValueParameter = irAccessor.valueParameters.single()
irBody.statements.add( irBody.statements.add(
@@ -346,25 +346,28 @@ interface IrBuilderExtension {
} }
} }
// todo: delet zis fun IrFunction.createParameterDeclarations(receiver: IrValueParameter?) {
fun IrFunction.createParameterDeclarations(receiver: IrValueParameter? = null) {
fun ParameterDescriptor.irValueParameter() = IrValueParameterImpl( fun ParameterDescriptor.irValueParameter() = IrValueParameterImpl(
this@createParameterDeclarations.startOffset, this@createParameterDeclarations.endOffset, this@createParameterDeclarations.startOffset, this@createParameterDeclarations.endOffset,
SERIALIZABLE_PLUGIN_ORIGIN, SERIALIZABLE_PLUGIN_ORIGIN,
this, this,
type.toIrType(), type.toIrType(),
(this as? ValueParameterDescriptor)?.varargElementType?.toIrType() null
).also { ).also {
it.parent = this@createParameterDeclarations it.parent = this@createParameterDeclarations
} }
dispatchReceiverParameter = receiver ?: (descriptor.dispatchReceiverParameter?.irValueParameter()) dispatchReceiverParameter = descriptor.dispatchReceiverParameter?.irValueParameter()
extensionReceiverParameter = descriptor.extensionReceiverParameter?.irValueParameter() extensionReceiverParameter = descriptor.extensionReceiverParameter?.irValueParameter()
assert(valueParameters.isEmpty()) assert(valueParameters.isEmpty())
descriptor.valueParameters.mapTo(valueParameters) { it.irValueParameter() } descriptor.valueParameters.mapTo(valueParameters) { it.irValueParameter() }
assert(typeParameters.isEmpty()) assert(typeParameters.isEmpty())
copyTypeParamsFromDescriptor()
}
fun IrFunction.copyTypeParamsFromDescriptor() {
descriptor.typeParameters.mapTo(typeParameters) { descriptor.typeParameters.mapTo(typeParameters) {
IrTypeParameterImpl( IrTypeParameterImpl(
startOffset, endOffset, startOffset, endOffset,
@@ -376,8 +379,6 @@ interface IrBuilderExtension {
} }
} }
fun IrBuilderWithScope.classReference(classType: KotlinType): IrClassReference { fun IrBuilderWithScope.classReference(classType: KotlinType): IrClassReference {
val clazz = classType.toClassDescriptor!! val clazz = classType.toClassDescriptor!!
val kClass = clazz.module.findClassAcrossModuleDependencies(ClassId(FqName("kotlin.reflect"), Name.identifier("KClass")))!! val kClass = clazz.module.findClassAcrossModuleDependencies(ClassId(FqName("kotlin.reflect"), Name.identifier("KClass")))!!
@@ -424,7 +425,7 @@ interface IrBuilderExtension {
} }
// Does not use sti and therefore does not perform encoder calls optimization // Does not use sti and therefore does not perform encoder calls optimization
fun IrBuilderWithScope.serializerTower(generator: SerializerIrGenerator, property: SerializableProperty): IrExpression? { fun IrBuilderWithScope.serializerTower(generator: SerializerIrGenerator, dispatchReceiverParameter: IrValueParameter, property: SerializableProperty): IrExpression? {
val nullableSerClass = val nullableSerClass =
compilerContext.externalSymbols.referenceClass(property.module.getClassFromInternalSerializationPackage(SpecialBuiltins.nullableSerializer)) compilerContext.externalSymbols.referenceClass(property.module.getClassFromInternalSerializationPackage(SpecialBuiltins.nullableSerializer))
val serializer = val serializer =
@@ -435,19 +436,35 @@ interface IrBuilderExtension {
property.descriptor.annotations, property.descriptor.annotations,
property.descriptor.findPsi() property.descriptor.findPsi()
) else null ) else null
return serializerInstance(generator, generator.serializableDescriptor, serializer, property.module, property.type, property.genericIndex) return serializerInstance(generator, dispatchReceiverParameter, generator.serializableDescriptor, serializer, property.module, property.type, genericIndex = property.genericIndex)
?.let { expr -> wrapWithNullableSerializerIfNeeded(property.type, expr, nullableSerClass) } ?.let { expr -> wrapWithNullableSerializerIfNeeded(property.module, property.type, expr, nullableSerClass) }
} }
private fun IrBuilderWithScope.wrapWithNullableSerializerIfNeeded(type: KotlinType, expression: IrExpression, nullableSerializerClass: IrClassSymbol): IrExpression { private fun IrBuilderWithScope.wrapWithNullableSerializerIfNeeded(module: ModuleDescriptor, type: KotlinType, expression: IrExpression, nullableSerializerClass: IrClassSymbol): IrExpression {
return if (type.isMarkedNullable) return if (type.isMarkedNullable)
irInvoke(null, nullableSerializerClass.constructors.toList()[0], listOf(type.makeNotNullable().toIrType()), listOf(expression)) irInvoke(null, nullableSerializerClass.constructors.toList()[0],
typeArguments = listOf(type.makeNotNullable().toIrType()),
valueArguments = listOf(expression),
returnTypeHint = wrapIrTypeIntoKSerializerIrType(module, type.toIrType())
)
else else
expression expression
} }
fun wrapIrTypeIntoKSerializerIrType(module: ModuleDescriptor, type: IrType): IrType {
val kSerClass =
compilerContext.externalSymbols.referenceClass(module.getClassFromSerializationPackage(SerialEntityNames.KSERIALIZER_CLASS))
return IrSimpleTypeImpl(
kSerClass, hasQuestionMark = false, arguments = listOf(
makeTypeProjection(type, Variance.INVARIANT)
), annotations = emptyList()
)
}
fun IrBuilderWithScope.serializerInstance( fun IrBuilderWithScope.serializerInstance(
enclosingGenerator: SerializerIrGenerator, enclosingGenerator: SerializerIrGenerator,
dispatchReceiverParameter: IrValueParameter,
serializableDescriptor: ClassDescriptor, serializableDescriptor: ClassDescriptor,
serializerClassOriginal: ClassDescriptor?, serializerClassOriginal: ClassDescriptor?,
module: ModuleDescriptor, module: ModuleDescriptor,
@@ -460,17 +477,22 @@ interface IrBuilderExtension {
if (genericIndex == null) return null if (genericIndex == null) return null
val thiz = enclosingGenerator.irClass.thisReceiver!! val thiz = enclosingGenerator.irClass.thisReceiver!!
val prop = enclosingGenerator.localSerializersFieldsDescriptors[genericIndex] val prop = enclosingGenerator.localSerializersFieldsDescriptors[genericIndex]
return irGetField(irGet(thiz), compilerContext.localSymbolTable.referenceField(prop).owner) return irGetField(irGet(dispatchReceiverParameter), compilerContext.localSymbolTable.referenceField(prop).owner)
} }
if (serializerClassOriginal.kind == ClassKind.OBJECT) { if (serializerClassOriginal.kind == ClassKind.OBJECT) {
return irGetObject(serializerClassOriginal) return irGetObject(serializerClassOriginal)
} else { } else {
var serializerClass = serializerClassOriginal var serializerClass = serializerClassOriginal
var args: List<IrExpression> = when (serializerClassOriginal.classId) { var args: List<IrExpression>
contextSerializerId, polymorphicSerializerId -> listOf(classReference(kType)) var typeArgs: List<IrType?>
when (serializerClassOriginal.classId) {
contextSerializerId, polymorphicSerializerId -> {
args = listOf(classReference(kType))
typeArgs = listOf(kType.toIrType())
}
enumSerializerId -> { enumSerializerId -> {
serializerClass = serializableDescriptor.getClassFromInternalSerializationPackage("CommonEnumSerializer") serializerClass = serializableDescriptor.getClassFromInternalSerializationPackage("CommonEnumSerializer")
kType.toClassDescriptor!!.let { enumDesc -> args = kType.toClassDescriptor!!.let { enumDesc ->
listOf( listOf(
irString(enumDesc.name.toString()), irString(enumDesc.name.toString()),
irCall(findEnumValuesMethod(enumDesc)), irCall(findEnumValuesMethod(enumDesc)),
@@ -480,18 +502,25 @@ interface IrBuilderExtension {
) )
) )
} }
typeArgs = listOf(kType.toIrType())
} }
else -> kType.arguments.map { else -> {
val argSer = enclosingGenerator.findTypeSerializerOrContext(module, it.type, sourceElement = serializerClassOriginal.findPsi()) args = kType.arguments.map {
val expr = serializerInstance(enclosingGenerator, serializableDescriptor, argSer, module, it.type, it.type.genericIndex) val argSer = enclosingGenerator.findTypeSerializerOrContext(module, it.type, sourceElement = serializerClassOriginal.findPsi())
?: return null val expr = serializerInstance(enclosingGenerator, dispatchReceiverParameter, serializableDescriptor, argSer, module, it.type, it.type.genericIndex)
wrapWithNullableSerializerIfNeeded(it.type, expr, nullableSerClass) ?: return null
wrapWithNullableSerializerIfNeeded(module, it.type, expr, nullableSerClass)
}
typeArgs = kType.arguments.map { it.type.toIrType() }
} }
}
if (serializerClassOriginal.classId == referenceArraySerializerId)
args = listOf(classReference(kType.arguments[0].type)) + args
val typeArgs = kType.arguments.map { it.type.toIrType() } }
if (serializerClassOriginal.classId == referenceArraySerializerId) {
args = listOf(classReference(kType.arguments[0].type)) + args
typeArgs = listOf(typeArgs[0].makeNotNull()) + typeArgs
}
val serializable = getSerializableClassDescriptorBySerializer(serializerClass) val serializable = getSerializableClassDescriptorBySerializer(serializerClass)
val ctor = if (serializable?.declaredTypeParameters?.isNotEmpty() == true) { val ctor = if (serializable?.declaredTypeParameters?.isNotEmpty() == true) {
requireNotNull( requireNotNull(
@@ -501,7 +530,9 @@ interface IrBuilderExtension {
} else { } else {
compilerContext.externalSymbols.referenceConstructor(serializerClass.unsubstitutedPrimaryConstructor!!) compilerContext.externalSymbols.referenceConstructor(serializerClass.unsubstitutedPrimaryConstructor!!)
} }
return irInvoke(null, ctor, typeArgs, args) val propertyTypeHint = kType.toIrType()
val returnType = wrapIrTypeIntoKSerializerIrType(module, propertyTypeHint)
return irInvoke(null, ctor, typeArguments = typeArgs, valueArguments = args, returnTypeHint = returnType)
} }
} }
@@ -7,10 +7,14 @@ import org.jetbrains.kotlin.ir.builders.irGet
import org.jetbrains.kotlin.ir.builders.irReturn import org.jetbrains.kotlin.ir.builders.irReturn
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.types.IrTypeArgument
import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.TypeTranslator import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializableCompanionCodegen import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializableCompanionCodegen
import org.jetbrains.kotlinx.serialization.compiler.resolve.* import org.jetbrains.kotlinx.serialization.compiler.resolve.*
@@ -47,8 +51,9 @@ class SerializableCompanionIrGenerator(
irInvoke( irInvoke(
null, null,
compilerContext.externalSymbols.referenceConstructor(serializer.unsubstitutedPrimaryConstructor!!), compilerContext.externalSymbols.referenceConstructor(serializer.unsubstitutedPrimaryConstructor!!),
listOf(serializableType.toIrType()), typeArguments = listOf(serializableType.toIrType()),
listOf(classReference(serializableType)) valueArguments = listOf(classReference(serializableType)),
returnTypeHint = getter.returnType
) )
} }
else -> { else -> {
@@ -56,8 +61,9 @@ class SerializableCompanionIrGenerator(
KSerializerDescriptorResolver.findSerializerConstructorForTypeArgumentsSerializers(serializer) KSerializerDescriptorResolver.findSerializerConstructorForTypeArgumentsSerializers(serializer)
) { "Generated serializer does not have constructor with required number of arguments" } ) { "Generated serializer does not have constructor with required number of arguments" }
val ctor = compilerContext.externalSymbols.referenceConstructor(desc) val ctor = compilerContext.externalSymbols.referenceConstructor(desc)
val typeArgs = getter.typeParameters.map { it.defaultType }
val args: List<IrExpression> = getter.valueParameters.map { irGet(it) } val args: List<IrExpression> = getter.valueParameters.map { irGet(it) }
irInvoke(null, ctor, *args.toTypedArray()) irInvoke(null, ctor, typeArgs, args, returnTypeHint = getter.returnType)
} }
} }
+irReturn(expr) +irReturn(expr)
@@ -152,7 +152,11 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
endOffset, endOffset,
compilerContext.irBuiltIns.unitType, compilerContext.irBuiltIns.unitType,
primaryCtor.symbol primaryCtor.symbol
) ).apply {
ctor.typeParameters.forEachIndexed { index, irTypeParameter ->
putTypeArgument(index, irTypeParameter.defaultType)
}
}
// store type arguments serializers in fields // store type arguments serializers in fields
val thisAsReceiverParameter = irClass.thisReceiver!! val thisAsReceiverParameter = irClass.thisReceiver!!
@@ -163,15 +167,17 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
localSerializersFieldsDescriptors[index] localSerializersFieldsDescriptors[index]
), localSerial.owner, irGet(param)) ), localSerial.owner, irGet(param))
} }
} }
override fun generateChildSerializersGetter(function: FunctionDescriptor) = irClass.contributeFunction(function) { irFun -> override fun generateChildSerializersGetter(function: FunctionDescriptor) = irClass.contributeFunction(function) { irFun ->
val allSerializers = serializableProperties.map { requireNotNull( val allSerializers = serializableProperties.map { requireNotNull(
serializerTower(this@SerializerIrGenerator, it)) { "Property ${it.name} must have a serializer" } serializerTower(this@SerializerIrGenerator, irFun.dispatchReceiverParameter!!, it)) { "Property ${it.name} must have a serializer" }
} }
val kSer = serializableDescriptor.module.getClassFromSerializationPackage(KSERIALIZER_NAME.identifier) val kSer = serializableDescriptor.module.getClassFromSerializationPackage(KSERIALIZER_NAME.identifier)
val kSerType = compilerContext.externalSymbols.referenceClass(kSer).owner.defaultType val kSerType = ((irFun.returnType as IrSimpleType).arguments.first() as IrTypeProjection).type
val array = createArrayOfExpression(kSerType, allSerializers) val array = createArrayOfExpression(kSerType, allSerializers)
+irReturn(array) +irReturn(array)
} }
@@ -222,11 +228,12 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
val sti = getSerialTypeInfo(property) val sti = getSerialTypeInfo(property)
val innerSerial = serializerInstance( val innerSerial = serializerInstance(
this@SerializerIrGenerator, this@SerializerIrGenerator,
saveFunc.dispatchReceiverParameter!!,
serializableDescriptor, serializableDescriptor,
sti.serializer, sti.serializer,
property.module, property.module,
property.type, property.type,
property.genericIndex genericIndex = property.genericIndex
) )
val (writeFunc, args: List<IrExpression>) = if (innerSerial == null) { val (writeFunc, args: List<IrExpression>) = if (innerSerial == null) {
val f = val f =
@@ -351,11 +358,12 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
val sti = getSerialTypeInfo(property) val sti = getSerialTypeInfo(property)
val innerSerial = serializerInstance( val innerSerial = serializerInstance(
this@SerializerIrGenerator, this@SerializerIrGenerator,
loadFunc.dispatchReceiverParameter!!,
serializableDescriptor, serializableDescriptor,
sti.serializer, sti.serializer,
property.module, property.module,
property.type, property.type,
property.genericIndex genericIndex = property.genericIndex
) )
// todo: update // todo: update
val decodeFuncToCall = val decodeFuncToCall =
@@ -372,7 +380,7 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
// local$i = localInput.decode...(...) // local$i = localInput.decode...(...)
+irSetVar( +irSetVar(
localProps[index].symbol, localProps[index].symbol,
irInvoke(localInput.get(), decodeFuncToCall, typeArgs, args) irInvoke(localInput.get(), decodeFuncToCall, typeArgs, args, returnTypeHint = property.type.toIrType())
) )
// bitMask[i] |= 1 << x // bitMask[i] |= 1 << x
val bitPos = 1 shl (index % 32) val bitPos = 1 shl (index % 32)
@@ -412,6 +420,7 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
// todo: set properties in external deserialization // todo: set properties in external deserialization
var args: List<IrExpression> = localProps.map { it.get() } var args: List<IrExpression> = localProps.map { it.get() }
val typeArgs = (loadFunc.returnType as IrSimpleType).arguments.map { (it as IrTypeProjection).type }
val ctor: IrConstructorSymbol = if (serializableDescriptor.isInternalSerializable) { val ctor: IrConstructorSymbol = if (serializableDescriptor.isInternalSerializable) {
args = bitMasks.map { irGet(it) } + args + irNull() args = bitMasks.map { irGet(it) } + args + irNull()
serializableIrClass.serializableSyntheticConstructor() serializableIrClass.serializableSyntheticConstructor()
@@ -419,7 +428,7 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
compilerContext.externalSymbols.referenceConstructor(serializableDescriptor.unsubstitutedPrimaryConstructor!!) compilerContext.externalSymbols.referenceConstructor(serializableDescriptor.unsubstitutedPrimaryConstructor!!)
} }
+irReturn(irInvoke(null, ctor, *args.toTypedArray())) +irReturn(irInvoke(null, ctor, typeArgs, args))
} }
companion object { companion object {