Generics serialization in IR
This commit is contained in:
+13
-6
@@ -30,7 +30,6 @@ abstract class SerializerCodegen(
|
|||||||
protected val serializerDescriptor: ClassDescriptor,
|
protected val serializerDescriptor: ClassDescriptor,
|
||||||
bindingContext: BindingContext
|
bindingContext: BindingContext
|
||||||
) : AbstractSerialGenerator(bindingContext, serializerDescriptor) {
|
) : AbstractSerialGenerator(bindingContext, serializerDescriptor) {
|
||||||
// protected val serializerDescriptor: ClassDescriptor = declaration.findClassDescriptor(bindingContext)
|
|
||||||
val serializableDescriptor: ClassDescriptor = getSerializableClassDescriptorBySerializer(serializerDescriptor)!!
|
val serializableDescriptor: ClassDescriptor = getSerializableClassDescriptorBySerializer(serializerDescriptor)!!
|
||||||
protected val serialName: String = serializableDescriptor.annotations.serialNameValue ?: serializableDescriptor.fqNameUnsafe.asString()
|
protected val serialName: String = serializableDescriptor.annotations.serialNameValue ?: serializableDescriptor.fqNameUnsafe.asString()
|
||||||
protected val properties = SerializableProperties(serializableDescriptor, bindingContext)
|
protected val properties = SerializableProperties(serializableDescriptor, bindingContext)
|
||||||
@@ -61,9 +60,7 @@ abstract class SerializerCodegen(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun generateChildSerializersGetter(function: FunctionDescriptor) {
|
protected abstract fun generateChildSerializersGetter(function: FunctionDescriptor)
|
||||||
// TODO()
|
|
||||||
}
|
|
||||||
|
|
||||||
protected val generatedSerialDescPropertyDescriptor = getPropertyToGenerate(
|
protected val generatedSerialDescPropertyDescriptor = getPropertyToGenerate(
|
||||||
serializerDescriptor, SerialEntityNames.SERIAL_DESC_FIELD,
|
serializerDescriptor, SerialEntityNames.SERIAL_DESC_FIELD,
|
||||||
@@ -73,9 +70,20 @@ abstract class SerializerCodegen(
|
|||||||
serializerDescriptor::checkSerializableClassPropertyResult
|
serializerDescriptor::checkSerializableClassPropertyResult
|
||||||
) { true }
|
) { true }
|
||||||
|
|
||||||
|
val localSerializersFieldsDescriptors: List<PropertyDescriptor> = findLocalSerializersFieldDescriptors()
|
||||||
|
|
||||||
|
private fun findLocalSerializersFieldDescriptors(): List<PropertyDescriptor> {
|
||||||
|
val count = serializableDescriptor.declaredTypeParameters.size
|
||||||
|
if (count == 0) return emptyList()
|
||||||
|
val propNames = (0 until count).map { "${SerialEntityNames.typeArgPrefix}$it" }
|
||||||
|
return propNames.mapNotNull { name ->
|
||||||
|
getPropertyToGenerate(serializerDescriptor, name) { isKSerializer(it.returnType) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract fun generateSerialDesc()
|
protected abstract fun generateSerialDesc()
|
||||||
|
|
||||||
protected abstract fun generateGenericFieldsAndConstructor(typedConstructorDescriptor: ConstructorDescriptor)
|
protected abstract fun generateGenericFieldsAndConstructor(typedConstructorDescriptor: ClassConstructorDescriptor)
|
||||||
|
|
||||||
protected abstract fun generateSerializableClassProperty(property: PropertyDescriptor)
|
protected abstract fun generateSerializableClassProperty(property: PropertyDescriptor)
|
||||||
|
|
||||||
@@ -129,7 +137,6 @@ abstract class SerializerCodegen(
|
|||||||
)
|
)
|
||||||
.singleOrNull { property ->
|
.singleOrNull { property ->
|
||||||
isKindOk(property.kind) &&
|
isKindOk(property.kind) &&
|
||||||
property.modality != Modality.FINAL &&
|
|
||||||
property.returnType != null &&
|
property.returnType != null &&
|
||||||
isReturnTypeOk(property)
|
isReturnTypeOk(property)
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-3
@@ -58,11 +58,19 @@ 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()
|
||||||
f.createParameterDeclarations()
|
if (!fromStubs) f.createParameterDeclarations(this.thisReceiver)
|
||||||
f.body = compilerContext.createIrBuilder(f.symbol).irBlockBody { bodyGen(f) }
|
f.body = compilerContext.createIrBuilder(f.symbol).irBlockBody { bodyGen(f) }
|
||||||
this.addMember(f)
|
this.addMember(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun IrClass.contributeCtor(descriptor: ClassConstructorDescriptor, bodyGen: IrBlockBodyBuilder.(IrFunction) -> Unit) {
|
||||||
|
val c = compilerContext.externalSymbols.referenceConstructor(descriptor).owner
|
||||||
|
c.parent = this
|
||||||
|
c.returnType = descriptor.returnType.toIrType()
|
||||||
|
c.body = compilerContext.createIrBuilder(c.symbol).irBlockBody { bodyGen(c) }
|
||||||
|
this.addMember(c)
|
||||||
|
}
|
||||||
|
|
||||||
fun IrClass.contributeConstructor(
|
fun IrClass.contributeConstructor(
|
||||||
descriptor: ClassConstructorDescriptor,
|
descriptor: ClassConstructorDescriptor,
|
||||||
bodyGen: IrBlockBodyBuilder.(IrConstructor) -> Unit
|
bodyGen: IrBlockBodyBuilder.(IrConstructor) -> Unit
|
||||||
@@ -369,7 +377,7 @@ interface IrBuilderExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun IrBuilderWithScope.serializerInstance(
|
fun IrBuilderWithScope.serializerInstance(
|
||||||
enclosingGenerator: AbstractSerialGenerator,
|
enclosingGenerator: SerializerIrGenerator,
|
||||||
serializableDescriptor: ClassDescriptor,
|
serializableDescriptor: ClassDescriptor,
|
||||||
serializerClass: ClassDescriptor?,
|
serializerClass: ClassDescriptor?,
|
||||||
module: ModuleDescriptor,
|
module: ModuleDescriptor,
|
||||||
@@ -380,7 +388,9 @@ interface IrBuilderExtension {
|
|||||||
compilerContext.externalSymbols.referenceClass(module.getClassFromInternalSerializationPackage(SpecialBuiltins.nullableSerializer))
|
compilerContext.externalSymbols.referenceClass(module.getClassFromInternalSerializationPackage(SpecialBuiltins.nullableSerializer))
|
||||||
if (serializerClass == null) {
|
if (serializerClass == null) {
|
||||||
if (genericIndex == null) return null
|
if (genericIndex == null) return null
|
||||||
TODO("Saved serializer for generic argument")
|
val thiz = enclosingGenerator.irClass.thisReceiver!!
|
||||||
|
val prop = enclosingGenerator.localSerializersFieldsDescriptors[genericIndex]
|
||||||
|
return irGetField(irGet(thiz), compilerContext.localSymbolTable.referenceField(prop).owner)
|
||||||
}
|
}
|
||||||
if (serializerClass.kind == ClassKind.OBJECT) {
|
if (serializerClass.kind == ClassKind.OBJECT) {
|
||||||
return irGetObject(serializerClass)
|
return irGetObject(serializerClass)
|
||||||
|
|||||||
+9
-7
@@ -3,6 +3,7 @@ package org.jetbrains.kotlinx.serialization.compiler.backend.ir
|
|||||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
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
|
||||||
@@ -11,10 +12,8 @@ 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.kotlinx.serialization.compiler.backend.common.SerializableCompanionCodegen
|
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializableCompanionCodegen
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.classSerializer
|
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.getSerializableClassDescriptorByCompanion
|
import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver.findSerializerConstructorForTypeArgumentsSerializers
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.isInternalSerializable
|
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.toClassDescriptor
|
|
||||||
|
|
||||||
class SerializableCompanionIrGenerator(
|
class SerializableCompanionIrGenerator(
|
||||||
val irClass: IrClass,
|
val irClass: IrClass,
|
||||||
@@ -40,13 +39,16 @@ class SerializableCompanionIrGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun generateSerializerGetter(methodDescriptor: FunctionDescriptor) =
|
override fun generateSerializerGetter(methodDescriptor: FunctionDescriptor) =
|
||||||
irClass.contributeFunction(methodDescriptor, fromStubs = true) { _ ->
|
irClass.contributeFunction(methodDescriptor, fromStubs = true) { getter ->
|
||||||
val serializer = serializableDescriptor.classSerializer?.toClassDescriptor!!
|
val serializer = serializableDescriptor.classSerializer?.toClassDescriptor!!
|
||||||
val expr = if (serializer.kind == ClassKind.OBJECT) {
|
val expr = if (serializer.kind == ClassKind.OBJECT) {
|
||||||
irGetObject(serializer)
|
irGetObject(serializer)
|
||||||
} else {
|
} else {
|
||||||
val ctor = compilerContext.externalSymbols.referenceConstructor(serializer.unsubstitutedPrimaryConstructor!!)
|
val desc = requireNotNull(
|
||||||
val args: List<IrExpression> = emptyList() // todo
|
KSerializerDescriptorResolver.findSerializerConstructorForTypeArgumentsSerializers(serializer)
|
||||||
|
) { "Generated serializer does not have constructor with required number of arguments" }
|
||||||
|
val ctor = compilerContext.externalSymbols.referenceConstructor(desc)
|
||||||
|
val args: List<IrExpression> = getter.valueParameters.map { irGet(it) }
|
||||||
irInvoke(null, ctor, *args.toTypedArray())
|
irInvoke(null, ctor, *args.toTypedArray())
|
||||||
}
|
}
|
||||||
+irReturn(expr)
|
+irReturn(expr)
|
||||||
|
|||||||
+32
-12
@@ -8,18 +8,15 @@ package org.jetbrains.kotlinx.serialization.compiler.backend.ir
|
|||||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.common.lower.irThrow
|
import org.jetbrains.kotlin.backend.common.lower.irThrow
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBranchImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.mapValueParameters
|
import org.jetbrains.kotlin.ir.expressions.mapValueParameters
|
||||||
import org.jetbrains.kotlin.ir.expressions.mapValueParametersIndexed
|
import org.jetbrains.kotlin.ir.expressions.mapValueParametersIndexed
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||||
@@ -69,12 +66,17 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
|
|||||||
introduceValueParameter(thisAsReceiverParameter)
|
introduceValueParameter(thisAsReceiverParameter)
|
||||||
prop = generateSimplePropertyWithBackingField(thisAsReceiverParameter.symbol, desc, irClass)
|
prop = generateSimplePropertyWithBackingField(thisAsReceiverParameter.symbol, desc, irClass)
|
||||||
irClass.addMember(prop)
|
irClass.addMember(prop)
|
||||||
|
|
||||||
|
localSerializersFieldsDescriptors.forEach {
|
||||||
|
irClass.addMember(generateSimplePropertyWithBackingField(thisAsReceiverParameter.symbol, it, irClass))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
compilerContext.localSymbolTable.declareAnonymousInitializer(
|
compilerContext.localSymbolTable.declareAnonymousInitializer(
|
||||||
irClass.startOffset, irClass.endOffset, SERIALIZABLE_PLUGIN_ORIGIN, irClass.descriptor
|
irClass.startOffset, irClass.endOffset, SERIALIZABLE_PLUGIN_ORIGIN, irClass.descriptor
|
||||||
).buildWithScope { initIrBody ->
|
).buildWithScope { initIrBody ->
|
||||||
val ctor = irClass.declarations.filterIsInstance<IrConstructor>().singleOrNull()
|
val ctor = irClass.declarations.filterIsInstance<IrConstructor>().find { it.isPrimary }
|
||||||
|
?: throw AssertionError("Serializer must have primary constructor")
|
||||||
val serialClassDescImplCtor = compilerContext.externalSymbols.referenceConstructor(serialDescImplConstructor)
|
val serialClassDescImplCtor = compilerContext.externalSymbols.referenceConstructor(serialDescImplConstructor)
|
||||||
compilerContext.localSymbolTable.withScope(initIrBody.descriptor) {
|
compilerContext.localSymbolTable.withScope(initIrBody.descriptor) {
|
||||||
initIrBody.body = compilerContext.createIrBuilder(initIrBody.symbol).irBlockBody {
|
initIrBody.body = compilerContext.createIrBuilder(initIrBody.symbol).irBlockBody {
|
||||||
@@ -106,16 +108,34 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext:
|
|||||||
irGet(localDesc)
|
irGet(localDesc)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// workaround for KT-25353
|
(ctor.body as? IrBlockBody)?.statements?.addAll(initIrBody.body.statements)
|
||||||
// irClass.addMember(initIrBody)
|
|
||||||
(ctor?.body as? IrBlockBody)?.statements?.addAll(initIrBody.body.statements)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun generateGenericFieldsAndConstructor(typedConstructorDescriptor: ConstructorDescriptor) {
|
override fun generateGenericFieldsAndConstructor(typedConstructorDescriptor: ClassConstructorDescriptor) =
|
||||||
// TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
irClass.contributeCtor(typedConstructorDescriptor) { ctor ->
|
||||||
}
|
// generate call to primary ctor to init serialClassDesc and super()
|
||||||
|
val primaryCtor = irClass.descriptor.unsubstitutedPrimaryConstructor
|
||||||
|
?: throw AssertionError("Serializer class must have primary constructor")
|
||||||
|
+IrDelegatingConstructorCallImpl(
|
||||||
|
startOffset,
|
||||||
|
endOffset,
|
||||||
|
compilerContext.irBuiltIns.unitType,
|
||||||
|
compilerContext.localSymbolTable.referenceConstructor(primaryCtor),
|
||||||
|
primaryCtor
|
||||||
|
)
|
||||||
|
|
||||||
|
// store type arguments serializers in fields
|
||||||
|
val thisAsReceiverParameter = irClass.thisReceiver!!
|
||||||
|
ctor.valueParameters.forEachIndexed { index, param ->
|
||||||
|
val localSerial = compilerContext.localSymbolTable.referenceField(localSerializersFieldsDescriptors[index])
|
||||||
|
+irSetField(generateReceiverExpressionForFieldAccess(
|
||||||
|
thisAsReceiverParameter.symbol,
|
||||||
|
localSerializersFieldsDescriptors[index]
|
||||||
|
), localSerial.owner, irGet(param))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun generateChildSerializersGetter(function: FunctionDescriptor) = irClass.contributeFunction(function) { irFun ->
|
override fun generateChildSerializersGetter(function: FunctionDescriptor) = irClass.contributeFunction(function) { irFun ->
|
||||||
val allSerializers = orderedProperties.map { requireNotNull(
|
val allSerializers = orderedProperties.map { requireNotNull(
|
||||||
|
|||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
package org.jetbrains.kotlinx.serialization.compiler.backend.ir
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.FieldDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple property descriptor with backing field without getters/setters for ir generation purposes
|
||||||
|
*/
|
||||||
|
class SimpleSyntheticPropertyDescriptor(
|
||||||
|
owner: ClassDescriptor,
|
||||||
|
name: String,
|
||||||
|
type: KotlinType,
|
||||||
|
isVar: Boolean = false,
|
||||||
|
visibility: Visibility = Visibilities.PRIVATE
|
||||||
|
) : PropertyDescriptorImpl(
|
||||||
|
owner,
|
||||||
|
null,
|
||||||
|
Annotations.EMPTY,
|
||||||
|
Modality.FINAL,
|
||||||
|
visibility,
|
||||||
|
isVar,
|
||||||
|
Name.identifier(name),
|
||||||
|
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||||
|
owner.source,
|
||||||
|
false, false, false, false, false, false
|
||||||
|
) {
|
||||||
|
|
||||||
|
private val _backingField = FieldDescriptorImpl(Annotations.EMPTY, this)
|
||||||
|
|
||||||
|
init {
|
||||||
|
super.setType(type, emptyList(), owner.thisAsReceiverParameter, null)
|
||||||
|
super.initialize(null, null, _backingField, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -107,7 +107,7 @@ class SerializerJsTranslator(descriptor: ClassDescriptor,
|
|||||||
translator.addProperty(propDesc, getterExpr, null)
|
translator.addProperty(propDesc, getterExpr, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun generateGenericFieldsAndConstructor(typedConstructorDescriptor: ConstructorDescriptor) {
|
override fun generateGenericFieldsAndConstructor(typedConstructorDescriptor: ClassConstructorDescriptor) {
|
||||||
val f = context.buildFunction(typedConstructorDescriptor) { jsFun, context ->
|
val f = context.buildFunction(typedConstructorDescriptor) { jsFun, context ->
|
||||||
val thiz = jsFun.scope.declareName(Namer.ANOTHER_THIS_PARAMETER_NAME).makeRef()
|
val thiz = jsFun.scope.declareName(Namer.ANOTHER_THIS_PARAMETER_NAME).makeRef()
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -50,7 +50,7 @@ class SerializerCodegenImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun generateGenericFieldsAndConstructor(typedConstructorDescriptor: ConstructorDescriptor) {
|
override fun generateGenericFieldsAndConstructor(typedConstructorDescriptor: ClassConstructorDescriptor) {
|
||||||
serializableDescriptor.declaredTypeParameters.forEachIndexed { i, _ ->
|
serializableDescriptor.declaredTypeParameters.forEachIndexed { i, _ ->
|
||||||
codegen.v.newField(
|
codegen.v.newField(
|
||||||
OtherOrigin(codegen.myClass.psiOrParent), ACC_PRIVATE or ACC_SYNTHETIC,
|
OtherOrigin(codegen.myClass.psiOrParent), ACC_PRIVATE or ACC_SYNTHETIC,
|
||||||
|
|||||||
+21
-4
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.types.TypeProjectionImpl
|
|||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.types.typeUtil.createProjection
|
import org.jetbrains.kotlin.types.typeUtil.createProjection
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||||
|
import org.jetbrains.kotlinx.serialization.compiler.backend.ir.SimpleSyntheticPropertyDescriptor
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.IMPL_NAME
|
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.IMPL_NAME
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.SERIALIZER_CLASS_NAME
|
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.SERIALIZER_CLASS_NAME
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.typeArgPrefix
|
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames.typeArgPrefix
|
||||||
@@ -133,9 +134,10 @@ object KSerializerDescriptorResolver {
|
|||||||
val classDescriptor = getSerializableClassDescriptorBySerializer(thisDescriptor) ?: return
|
val classDescriptor = getSerializableClassDescriptorBySerializer(thisDescriptor) ?: return
|
||||||
if (name == SerialEntityNames.SERIAL_DESC_FIELD_NAME && result.none(thisDescriptor::checkSerializableClassPropertyResult) &&
|
if (name == SerialEntityNames.SERIAL_DESC_FIELD_NAME && result.none(thisDescriptor::checkSerializableClassPropertyResult) &&
|
||||||
fromSupertypes.none { thisDescriptor.checkSerializableClassPropertyResult(it) && it.modality == Modality.FINAL }
|
fromSupertypes.none { thisDescriptor.checkSerializableClassPropertyResult(it) && it.modality == Modality.FINAL }
|
||||||
)
|
) {
|
||||||
result.add(createSerializableClassPropertyDescriptor(thisDescriptor, classDescriptor))
|
result.add(createSerializableClassPropertyDescriptor(thisDescriptor, classDescriptor))
|
||||||
|
}
|
||||||
|
result.addAll(createLocalSerializersFieldsDescriptors(classDescriptor, thisDescriptor))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateCompanionObjectMethods(
|
fun generateCompanionObjectMethods(
|
||||||
@@ -176,7 +178,7 @@ object KSerializerDescriptorResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createSerializableClassPropertyDescriptor(
|
private fun createSerializableClassPropertyDescriptor(
|
||||||
companionDescriptor: ClassDescriptor,
|
companionDescriptor: ClassDescriptor,
|
||||||
classDescriptor: ClassDescriptor
|
classDescriptor: ClassDescriptor
|
||||||
): PropertyDescriptor =
|
): PropertyDescriptor =
|
||||||
@@ -338,7 +340,7 @@ object KSerializerDescriptorResolver {
|
|||||||
return constrDesc
|
return constrDesc
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createSerializerGetterDescriptor(thisClass: ClassDescriptor, serializableClass: ClassDescriptor): SimpleFunctionDescriptor {
|
private fun createSerializerGetterDescriptor(thisClass: ClassDescriptor, serializableClass: ClassDescriptor): SimpleFunctionDescriptor {
|
||||||
val f = SimpleFunctionDescriptorImpl.create(
|
val f = SimpleFunctionDescriptorImpl.create(
|
||||||
thisClass,
|
thisClass,
|
||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
@@ -493,4 +495,19 @@ object KSerializerDescriptorResolver {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create properties typeSerial0, typeSerial1, etc... for storing generic arguments' serializers
|
||||||
|
private fun createLocalSerializersFieldsDescriptors(serializableDescriptor: ClassDescriptor, serializerDescriptor: ClassDescriptor): List<PropertyDescriptor> {
|
||||||
|
if (serializableDescriptor.declaredTypeParameters.isEmpty()) return emptyList()
|
||||||
|
val serializerClass = serializableDescriptor.getClassFromSerializationPackage(SerialEntityNames.KSERIALIZER_CLASS)
|
||||||
|
return serializerDescriptor.declaredTypeParameters.mapIndexed { index, param ->
|
||||||
|
val pType =
|
||||||
|
KotlinTypeFactory.simpleNotNullType(
|
||||||
|
Annotations.EMPTY,
|
||||||
|
serializerClass,
|
||||||
|
listOf(TypeProjectionImpl(param.defaultType))
|
||||||
|
)
|
||||||
|
SimpleSyntheticPropertyDescriptor(serializerDescriptor, "$typeArgPrefix$index", pType)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user