Introduce GeneratedSerializer and childSerializers

Descriptors passing on JVM
This commit is contained in:
Leonid Startsev
2018-09-21 20:32:42 +03:00
committed by Leonid Startsev
parent f0e81c6eb8
commit e40383b1ce
6 changed files with 193 additions and 79 deletions
@@ -42,6 +42,7 @@ abstract class SerializerCodegen(
val prop = generateSerializableClassPropertyIfNeeded() val prop = generateSerializableClassPropertyIfNeeded()
val save = generateSaveIfNeeded() val save = generateSaveIfNeeded()
val load = generateLoadIfNeeded() val load = generateLoadIfNeeded()
generateDescriptorGetterIfNeeded()
// if (save || load || prop) // if (save || load || prop)
// generateSerialDesc() // generateSerialDesc()
if (serializableDescriptor.declaredTypeParameters.isNotEmpty() && typedSerializerConstructorNotDeclared()) { if (serializableDescriptor.declaredTypeParameters.isNotEmpty() && typedSerializerConstructorNotDeclared()) {
@@ -49,6 +50,19 @@ abstract class SerializerCodegen(
} }
} }
private fun generateDescriptorGetterIfNeeded(): Boolean {
val function = getMemberToGenerate(
serializerDescriptor, SerialEntityNames.GENERATED_DESCRIPTOR_GETTER.identifier,
{ true }, { true }
) ?: return false
generateChildSerializersGetter(function)
return true
}
protected open fun generateChildSerializersGetter(function: FunctionDescriptor) {
// TODO()
}
// checks if user didn't declared constructor (KSerializer<T0>, KSerializer<T1>...) on a KSerializer<T<T0, T1...>> // checks if user didn't declared constructor (KSerializer<T0>, KSerializer<T1>...) on a KSerializer<T<T0, T1...>>
private fun typedSerializerConstructorNotDeclared(): Boolean { private fun typedSerializerConstructorNotDeclared(): Boolean {
val serializableImplementationTypeArguments = extractKSerializerArgumentFromImplementation(serializerDescriptor)?.arguments val serializableImplementationTypeArguments = extractKSerializerArgumentFromImplementation(serializerDescriptor)?.arguments
@@ -55,6 +55,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
// todo: extract packages constants too? // todo: extract packages constants too?
internal val descType = Type.getObjectType("kotlinx/serialization/$SERIAL_DESCRIPTOR_CLASS") internal val descType = Type.getObjectType("kotlinx/serialization/$SERIAL_DESCRIPTOR_CLASS")
internal val descImplType = Type.getObjectType("kotlinx/serialization/internal/$SERIAL_DESCRIPTOR_CLASS_IMPL") internal val descImplType = Type.getObjectType("kotlinx/serialization/internal/$SERIAL_DESCRIPTOR_CLASS_IMPL")
internal val generatedSerializerType = Type.getObjectType("kotlinx/serialization/internal/${SerialEntityNames.GENERATED_SERIALIZER_CLASS}")
internal val kOutputType = Type.getObjectType("kotlinx/serialization/$STRUCTURE_ENCODER_CLASS") internal val kOutputType = Type.getObjectType("kotlinx/serialization/$STRUCTURE_ENCODER_CLASS")
internal val encoderType = Type.getObjectType("kotlinx/serialization/$ENCODER_CLASS") internal val encoderType = Type.getObjectType("kotlinx/serialization/$ENCODER_CLASS")
internal val decoderType = Type.getObjectType("kotlinx/serialization/$DECODER_CLASS") internal val decoderType = Type.getObjectType("kotlinx/serialization/$DECODER_CLASS")
@@ -168,6 +169,32 @@ internal fun InstructionAdapter.stackValueSerializerInstanceFromClass(
} }
} }
internal fun InstructionAdapter.stackValueSerializerInstanceFromSerializerWithoutSti(
codegen: ClassBodyCodegen,
property: SerializableProperty,
serializerCodegen: AbstractSerialGenerator
): Boolean {
val serializer =
property.serializableWith?.toClassDescriptor
?: if (!property.type.isTypeParameter()) serializerCodegen.findTypeSerializerOrContext(
property.module,
property.type,
property.descriptor.annotations,
property.descriptor.findPsi()
) else null
return serializerCodegen.stackValueSerializerInstance(
codegen,
property.module,
property.type,
serializer,
this,
property.genericIndex
) { idx ->
load(0, kSerializerType)
getfield(codegen.typeMapper.mapClass(codegen.descriptor).internalName, "$typeArgPrefix$idx", kSerializerType.descriptor)
}.also { if (it && property.type.isMarkedNullable) wrapStackValueIntoNullableSerializer() }
}
internal fun InstructionAdapter.stackValueSerializerInstanceFromSerializer(codegen: ClassBodyCodegen, sti: JVMSerialTypeInfo, serializerCodegen: AbstractSerialGenerator): Boolean { internal fun InstructionAdapter.stackValueSerializerInstanceFromSerializer(codegen: ClassBodyCodegen, sti: JVMSerialTypeInfo, serializerCodegen: AbstractSerialGenerator): Boolean {
return serializerCodegen.stackValueSerializerInstance( return serializerCodegen.stackValueSerializerInstance(
codegen, sti.property.module, sti.property.type, codegen, sti.property.module, sti.property.type,
@@ -240,13 +267,19 @@ internal fun AbstractSerialGenerator.stackValueSerializerInstance(codegen: Class
} }
// all serializers get arguments with serializers of their generic types // all serializers get arguments with serializers of their generic types
argSerializers.forEach { (argType, argSerializer) -> argSerializers.forEach { (argType, argSerializer) ->
assert(stackValueSerializerInstance(codegen, module, argType, argSerializer, this, argType.genericIndex, genericSerializerFieldGetter)) assert(
stackValueSerializerInstance(
codegen,
module,
argType,
argSerializer,
this,
argType.genericIndex,
genericSerializerFieldGetter
)
)
// wrap into nullable serializer if argType is nullable // wrap into nullable serializer if argType is nullable
if (argType.isMarkedNullable) { if (argType.isMarkedNullable) wrapStackValueIntoNullableSerializer()
invokestatic("kotlinx/serialization/internal/NullableSerializerKt", "makeNullable", // todo: extract?
"(" + kSerializerType.descriptor + ")" + kSerializerType.descriptor, false)
}
signature.append(kSerializerType.descriptor) signature.append(kSerializerType.descriptor)
} }
signature.append(")V") signature.append(")V")
@@ -256,6 +289,12 @@ internal fun AbstractSerialGenerator.stackValueSerializerInstance(codegen: Class
return true return true
} }
fun InstructionAdapter.wrapStackValueIntoNullableSerializer() =
invokestatic(
"kotlinx/serialization/internal/NullableSerializerKt", "makeNullable",
"(" + kSerializerType.descriptor + ")" + kSerializerType.descriptor, false
)
// //
// ======= Serializers Resolving ======= // ======= Serializers Resolving =======
// //
@@ -291,11 +330,13 @@ fun AbstractSerialGenerator.getSerialTypeInfo(property: SerializableProperty, ty
// reference elements // reference elements
serializer = property.module.findClassAcrossModuleDependencies(referenceArraySerializerId) serializer = property.module.findClassAcrossModuleDependencies(referenceArraySerializerId)
} }
// primitive elements are not supported yet // primitive elements are not supported yet
} }
} }
return JVMSerialTypeInfo(property, Type.getType("Ljava/lang/Object;"), return JVMSerialTypeInfo(
if (property.type.isMarkedNullable) "Nullable" else "", serializer) property, Type.getType("Ljava/lang/Object;"),
if (property.type.isMarkedNullable) "Nullable" else "", serializer
)
} }
OBJECT -> { OBJECT -> {
// no explicit serializer for this property. Check other built in types // no explicit serializer for this property. Check other built in types
@@ -312,8 +353,10 @@ fun AbstractSerialGenerator.getSerialTypeInfo(property: SerializableProperty, ty
property.descriptor.annotations, property.descriptor.annotations,
property.descriptor.findPsi() property.descriptor.findPsi()
) )
return JVMSerialTypeInfo(property, Type.getType("Ljava/lang/Object;"), return JVMSerialTypeInfo(
if (property.type.isMarkedNullable) "Nullable" else "", serializer) property, Type.getType("Ljava/lang/Object;"),
if (property.type.isMarkedNullable) "Nullable" else "", serializer
)
} }
else -> throw AssertionError("Unexpected sort for $type") // should not happen else -> throw AssertionError("Unexpected sort for $type") // should not happen
} }
@@ -40,6 +40,9 @@ class SerializerCodegenImpl(
private val serializerAsmType = codegen.typeMapper.mapClass(codegen.descriptor) private val serializerAsmType = codegen.typeMapper.mapClass(codegen.descriptor)
private val serializableAsmType = codegen.typeMapper.mapClass(serializableClass) private val serializableAsmType = codegen.typeMapper.mapClass(serializableClass)
// if we have type parameters, descriptor initializing must be performed in constructor
private val staticDescriptor = serializableDescriptor.declaredTypeParameters.isEmpty()
companion object { companion object {
fun generateSerializerExtensions(codegen: ImplementationBodyCodegen) { fun generateSerializerExtensions(codegen: ImplementationBodyCodegen) {
val serializableClass = getSerializableClassDescriptorBySerializer(codegen.descriptor) ?: return val serializableClass = getSerializableClassDescriptorBySerializer(codegen.descriptor) ?: return
@@ -55,64 +58,86 @@ class SerializerCodegenImpl(
) )
} }
codegen.generateMethod(typedConstructorDescriptor) { _, _ -> var locals: Int = 0
codegen.generateMethod(typedConstructorDescriptor) { _, exprGen ->
load(0, serializerAsmType) load(0, serializerAsmType)
invokespecial("java/lang/Object", "<init>", "()V", false) invokespecial("java/lang/Object", "<init>", "()V", false)
serializableDescriptor.declaredTypeParameters.forEachIndexed { i, _ -> serializableDescriptor.declaredTypeParameters.forEachIndexed { i, _ ->
load(0, serializerAsmType) load(0, serializerAsmType)
load(i+1, kSerializerType) load(++locals, kSerializerType)
putfield(serializerAsmType.internalName, "$typeArgPrefix$i", kSerializerType.descriptor) putfield(serializerAsmType.internalName, "$typeArgPrefix$i", kSerializerType.descriptor)
} }
if (!staticDescriptor) exprGen.generateSerialDescriptor(++locals, false)
areturn(Type.VOID_TYPE) areturn(Type.VOID_TYPE)
} }
} }
override fun generateSerialDesc() { private fun ExpressionCodegen.generateSerialDescriptor(descriptorVar: Int, isStatic: Boolean) = with(v) {
codegen.v.newField(OtherOrigin(codegen.myClass.psiOrParent), ACC_PRIVATE or ACC_STATIC or ACC_FINAL or ACC_SYNTHETIC, anew(descImplType)
serialDescField, descType.descriptor, null, null) dup()
// todo: lazy initialization of $$serialDesc that is performed only when save/load is invoked first time aconst(serialName)
val expr = codegen.createOrGetClInitCodegen() if (isStatic) {
with(expr.v) { assert(serializerDescriptor.kind == ClassKind.OBJECT) { "Serializer for type without type parameters must be an object" }
val classDescVar = 0 // static descriptor means serializer is an object. it is safer to get it from correct field
anew(descImplType) StackValue.singleton(serializerDescriptor, codegen.typeMapper).put(generatedSerializerType, this)
dup() } else {
aconst(serialName) load(0, serializerAsmType)
invokespecial(descImplType.internalName, "<init>", "(Ljava/lang/String;)V", false) }
store(classDescVar, descImplType) invokespecial(descImplType.internalName, "<init>", "(Ljava/lang/String;${generatedSerializerType.descriptor})V", false)
for (property in orderedProperties) { store(descriptorVar, descImplType)
if (property.transient) continue for (property in orderedProperties) {
load(classDescVar, descImplType) if (property.transient) continue
aconst(property.name) load(descriptorVar, descImplType)
invokevirtual(descImplType.internalName, CallingConventions.addElement, "(Ljava/lang/String;)V", false) aconst(property.name)
// pushing annotations iconst(if (property.optional) 1 else 0)
for ((annotationClass, args, consParams) in property.annotationsWithArguments) { invokevirtual(descImplType.internalName, CallingConventions.addElement, "(Ljava/lang/String;Z)V", false)
if (args.size != consParams.size) throw IllegalArgumentException("Can't use arguments with defaults for serializable annotations yet") // pushing annotations
load(classDescVar, descImplType) for ((annotationClass, args, consParams) in property.annotationsWithArguments) {
expr.generateSyntheticAnnotationOnStack(annotationClass, args, consParams)
invokevirtual(
descImplType.internalName,
CallingConventions.addAnnotation,
"(Ljava/lang/annotation/Annotation;)V",
false
)
}
}
// add annotations on class itself
for ((annotationClass, args, consParams) in serializableDescriptor.annotationsWithArguments()) {
if (args.size != consParams.size) throw IllegalArgumentException("Can't use arguments with defaults for serializable annotations yet") if (args.size != consParams.size) throw IllegalArgumentException("Can't use arguments with defaults for serializable annotations yet")
load(classDescVar, descImplType) load(descriptorVar, descImplType)
expr.generateSyntheticAnnotationOnStack(annotationClass, args, consParams) generateSyntheticAnnotationOnStack(annotationClass, args, consParams)
invokevirtual( invokevirtual(
descImplType.internalName, descImplType.internalName,
CallingConventions.addClassAnnotation, CallingConventions.addAnnotation,
"(Ljava/lang/annotation/Annotation;)V", "(Ljava/lang/annotation/Annotation;)V",
false false
) )
} }
load(classDescVar, descImplType)
putstatic(serializerAsmType.internalName, serialDescField, descType.descriptor)
} }
// add annotations on class itself
for ((annotationClass, args, consParams) in serializableDescriptor.annotationsWithArguments()) {
if (args.size != consParams.size) throw IllegalArgumentException("Can't use arguments with defaults for serializable annotations yet")
load(descriptorVar, descImplType)
generateSyntheticAnnotationOnStack(annotationClass, args, consParams)
invokevirtual(
descImplType.internalName,
CallingConventions.addClassAnnotation,
"(Ljava/lang/annotation/Annotation;)V",
false
)
}
if (isStatic) {
load(descriptorVar, descImplType)
putstatic(serializerAsmType.internalName, serialDescField, descType.descriptor)
} else {
load(0, serializerAsmType)
load(descriptorVar, descImplType)
putfield(serializerAsmType.internalName, serialDescField, descType.descriptor)
}
}
override fun generateSerialDesc() {
var flags = ACC_PRIVATE or ACC_FINAL or ACC_SYNTHETIC
if (staticDescriptor) flags = flags or ACC_STATIC
codegen.v.newField(
OtherOrigin(codegen.myClass.psiOrParent), flags,
serialDescField, descType.descriptor, null, null
)
// todo: lazy initialization of $$serialDesc ?
if (!staticDescriptor) return
val expr = codegen.createOrGetClInitCodegen()
expr.generateSerialDescriptor(0, true)
} }
private fun ExpressionCodegen.generateSyntheticAnnotationOnStack( private fun ExpressionCodegen.generateSyntheticAnnotationOnStack(
@@ -139,18 +164,44 @@ class SerializerCodegenImpl(
} }
} }
private fun InstructionAdapter.serialCLassDescToLocalVar(classDescVar: Int) { // use null to put value on stack, use number to store it to var
getstatic(serializerAsmType.internalName, serialDescField, descType.descriptor) private fun InstructionAdapter.stackSerialClassDesc(classDescVar: Int?) {
store(classDescVar, descType) if (staticDescriptor)
getstatic(serializerAsmType.internalName, serialDescField, descType.descriptor)
else {
load(0, serializerAsmType)
getfield(serializerAsmType.internalName, serialDescField, descType.descriptor)
}
classDescVar?.let { store(it, descType) }
} }
override fun generateSerializableClassProperty(property: PropertyDescriptor) { override fun generateSerializableClassProperty(property: PropertyDescriptor) {
codegen.generateMethod(property.getter!!) { _, _ -> codegen.generateMethod(property.getter!!) { _, _ ->
getstatic(serializerAsmType.internalName, serialDescField, descType.descriptor) stackSerialClassDesc(null)
areturn(descType) areturn(descType)
} }
} }
override fun generateChildSerializersGetter(function: FunctionDescriptor) {
codegen.generateMethod(function) { _, _ ->
val size = orderedProperties.size
iconst(size)
newarray(kSerializerType)
for (i in 0 until size) {
dup() // array
iconst(i) // index
val prop = orderedProperties[i]
stackValueSerializerInstanceFromSerializerWithoutSti(
codegen,
prop,
this@SerializerCodegenImpl
)
astore(kSerializerType)
}
areturn(kSerializerArrayType)
}
}
override fun generateSave( override fun generateSave(
function: FunctionDescriptor function: FunctionDescriptor
) { ) {
@@ -159,7 +210,7 @@ class SerializerCodegenImpl(
val outputVar = 1 val outputVar = 1
val objVar = 2 val objVar = 2
val descVar = 3 val descVar = 3
serialCLassDescToLocalVar(descVar) stackSerialClassDesc(descVar)
val objType = signature.valueParameters[1].asmType val objType = signature.valueParameters[1].asmType
// output = output.writeBegin(classDesc, new KSerializer[0]) // output = output.writeBegin(classDesc, new KSerializer[0])
load(outputVar, encoderType) load(outputVar, encoderType)
@@ -236,7 +287,7 @@ class SerializerCodegenImpl(
val blocksCnt = orderedProperties.size / OPT_MASK_BITS + 1 val blocksCnt = orderedProperties.size / OPT_MASK_BITS + 1
fun bitMaskOff(i: Int) = bitMaskBase + (i / OPT_MASK_BITS) * OPT_MASK_TYPE.size fun bitMaskOff(i: Int) = bitMaskBase + (i / OPT_MASK_BITS) * OPT_MASK_TYPE.size
val propsStartVar = bitMaskBase + OPT_MASK_TYPE.size * blocksCnt val propsStartVar = bitMaskBase + OPT_MASK_TYPE.size * blocksCnt
serialCLassDescToLocalVar(descVar) stackSerialClassDesc(descVar)
// boolean readAll = false // boolean readAll = false
iconst(0) iconst(0)
store(readAllVar, Type.BOOLEAN_TYPE) store(readAllVar, Type.BOOLEAN_TYPE)
@@ -35,21 +35,26 @@ import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackage
fun isKSerializer(type: KotlinType?): Boolean = fun isKSerializer(type: KotlinType?): Boolean =
type != null && KotlinBuiltIns.isConstructedFromGivenClass(type, SerialEntityNames.KSERIALIZER_NAME_FQ) type != null && KotlinBuiltIns.isConstructedFromGivenClass(type, SerialEntityNames.KSERIALIZER_NAME_FQ)
fun isGeneratedKSerializer(type: KotlinType?): Boolean =
type != null && KotlinBuiltIns.isConstructedFromGivenClass(type, SerialEntityNames.GENERATED_SERIALIZER_FQ)
fun ClassDescriptor.getKSerializerDescriptor(): ClassDescriptor = fun ClassDescriptor.getKSerializerDescriptor(): ClassDescriptor =
module.findClassAcrossModuleDependencies(ClassId(packageFqName, SerialEntityNames.KSERIALIZER_NAME))!! module.getClassFromInternalSerializationPackage(SerialEntityNames.GENERATED_SERIALIZER_CLASS.identifier)
fun ClassDescriptor.getKSerializerType(argument: SimpleType): SimpleType { fun ClassDescriptor.createGeneratedSerializerTypeFor(argument: SimpleType): SimpleType {
val projectionType = Variance.INVARIANT val projectionType = Variance.INVARIANT
val types = listOf(TypeProjectionImpl(projectionType, argument)) val types = listOf(TypeProjectionImpl(projectionType, argument))
return KotlinTypeFactory.simpleNotNullType(Annotations.EMPTY, getKSerializerDescriptor(), types) return KotlinTypeFactory.simpleNotNullType(Annotations.EMPTY, getKSerializerDescriptor(), types)
} }
internal fun extractKSerializerArgumentFromImplementation(implementationClass: ClassDescriptor): KotlinType? { internal fun extractKSerializerArgumentFromImplementation(implementationClass: ClassDescriptor): KotlinType? {
val kSerializerSupertype = implementationClass.typeConstructor.supertypes val supertypes = implementationClass.typeConstructor.supertypes
.find { isKSerializer(it) } ?: return null val kSerializerSupertype = supertypes.find { isGeneratedKSerializer(it) }
?: supertypes.find { isKSerializer(it) }
?: return null
return kSerializerSupertype.arguments.first().type return kSerializerSupertype.arguments.first().type
} }
@@ -140,7 +145,11 @@ fun getSerializableClassDescriptorByCompanion(thisDescriptor: ClassDescriptor):
fun getSerializableClassDescriptorBySerializer(serializerDescriptor: ClassDescriptor): ClassDescriptor? { fun getSerializableClassDescriptorBySerializer(serializerDescriptor: ClassDescriptor): ClassDescriptor? {
val serializerForClass = serializerDescriptor.annotations.serializerForClass val serializerForClass = serializerDescriptor.annotations.serializerForClass
if (serializerForClass != null) return serializerForClass.toClassDescriptor if (serializerForClass != null) return serializerForClass.toClassDescriptor
if (serializerDescriptor.name != SerialEntityNames.SERIALIZER_CLASS_NAME) return null if (serializerDescriptor.name !in setOf(
SerialEntityNames.SERIALIZER_CLASS_NAME,
SerialEntityNames.GENERATED_SERIALIZER_CLASS
)
) return null
val classDescriptor = (serializerDescriptor.containingDeclaration as? ClassDescriptor) ?: return null val classDescriptor = (serializerDescriptor.containingDeclaration as? ClassDescriptor) ?: return null
if (!classDescriptor.isInternalSerializable) return null if (!classDescriptor.isInternalSerializable) return null
return classDescriptor return classDescriptor
@@ -187,7 +196,7 @@ private fun ModuleDescriptor.getFromPackage(packageFqName: FqName, classSimpleNa
Name.identifier(classSimpleName) Name.identifier(classSimpleName)
) )
) )
) { "Can't locate class $classSimpleName" } ) { "Can't locate class $classSimpleName from package $packageFqName" }
fun ClassDescriptor.getClassFromSerializationPackage(classSimpleName: String) = fun ClassDescriptor.getClassFromSerializationPackage(classSimpleName: String) =
requireNotNull(module.findClassAcrossModuleDependencies(ClassId(packageFqName, Name.identifier(classSimpleName)))) {"Can't locate class $classSimpleName"} requireNotNull(module.findClassAcrossModuleDependencies(ClassId(packageFqName, Name.identifier(classSimpleName)))) {"Can't locate class $classSimpleName"}
@@ -57,7 +57,7 @@ object KSerializerDescriptorResolver {
fun addSerializerSupertypes(classDescriptor: ClassDescriptor, supertypes: MutableList<KotlinType>) { fun addSerializerSupertypes(classDescriptor: ClassDescriptor, supertypes: MutableList<KotlinType>) {
val serializableClassDescriptor = getSerializableClassDescriptorBySerializer(classDescriptor) ?: return val serializableClassDescriptor = getSerializableClassDescriptorBySerializer(classDescriptor) ?: return
if (supertypes.none(::isKSerializer)) { if (supertypes.none(::isKSerializer)) {
supertypes.add(classDescriptor.getKSerializerType(serializableClassDescriptor.defaultType)) supertypes.add(classDescriptor.createGeneratedSerializerTypeFor(serializableClassDescriptor.defaultType))
} }
} }
@@ -157,16 +157,15 @@ object KSerializerDescriptorResolver {
fromSupertypes.none { checkParameters(it) && it.modality == Modality.FINAL } fromSupertypes.none { checkParameters(it) && it.modality == Modality.FINAL }
} }
if (name == SerialEntityNames.SAVE_NAME && val isSave = name == SerialEntityNames.SAVE_NAME &&
shouldAddSerializerFunction { classDescriptor.checkSaveMethodParameters(it.valueParameters) } shouldAddSerializerFunction { classDescriptor.checkSaveMethodParameters(it.valueParameters) }
) { val isLoad = name == SerialEntityNames.LOAD_NAME &&
result.add(createSaveFunctionDescriptor(thisDescriptor)) shouldAddSerializerFunction { classDescriptor.checkLoadMethodParameters(it.valueParameters) }
} val isDescriptorGetter = name == SerialEntityNames.GENERATED_DESCRIPTOR_GETTER &&
shouldAddSerializerFunction { true /* TODO? */ }
if (name == SerialEntityNames.LOAD_NAME && if (isSave || isLoad || isDescriptorGetter) {
shouldAddSerializerFunction { classDescriptor.checkLoadMethodParameters(it.valueParameters) } result.add(doCreateSerializerFunction(thisDescriptor, name))
) {
result.add(createLoadFunctionDescriptor(thisDescriptor))
} }
} }
@@ -176,12 +175,6 @@ object KSerializerDescriptorResolver {
): PropertyDescriptor = ): PropertyDescriptor =
doCreateSerializerProperty(companionDescriptor, classDescriptor, SerialEntityNames.SERIAL_DESC_FIELD_NAME) doCreateSerializerProperty(companionDescriptor, classDescriptor, SerialEntityNames.SERIAL_DESC_FIELD_NAME)
fun createSaveFunctionDescriptor(companionDescriptor: ClassDescriptor): SimpleFunctionDescriptor =
doCreateSerializerFunction(companionDescriptor, SerialEntityNames.SAVE_NAME)
fun createLoadFunctionDescriptor(companionDescriptor: ClassDescriptor): SimpleFunctionDescriptor =
doCreateSerializerFunction(companionDescriptor, SerialEntityNames.LOAD_NAME)
private fun doCreateSerializerProperty( private fun doCreateSerializerProperty(
companionDescriptor: ClassDescriptor, companionDescriptor: ClassDescriptor,
classDescriptor: ClassDescriptor, classDescriptor: ClassDescriptor,
@@ -38,6 +38,9 @@ object SerialEntityNames {
val SERIALIZER_CLASS_NAME = Name.identifier(SERIALIZER_CLASS) val SERIALIZER_CLASS_NAME = Name.identifier(SERIALIZER_CLASS)
val IMPL_NAME = Name.identifier("Impl") val IMPL_NAME = Name.identifier("Impl")
val GENERATED_SERIALIZER_CLASS = Name.identifier("GeneratedSerializer")
val GENERATED_SERIALIZER_FQ = SerializationPackages.internalPackageFqName.child(GENERATED_SERIALIZER_CLASS)
const val ENCODER_CLASS = "Encoder" const val ENCODER_CLASS = "Encoder"
const val STRUCTURE_ENCODER_CLASS = "CompositeEncoder" const val STRUCTURE_ENCODER_CLASS = "CompositeEncoder"
const val DECODER_CLASS = "Decoder" const val DECODER_CLASS = "Decoder"
@@ -58,6 +61,7 @@ object SerialEntityNames {
val SERIAL_DESC_FIELD_NAME = Name.identifier(SERIAL_DESC_FIELD) val SERIAL_DESC_FIELD_NAME = Name.identifier(SERIAL_DESC_FIELD)
val SAVE_NAME = Name.identifier(SAVE) val SAVE_NAME = Name.identifier(SAVE)
val LOAD_NAME = Name.identifier(LOAD) val LOAD_NAME = Name.identifier(LOAD)
val GENERATED_DESCRIPTOR_GETTER = Name.identifier("childSerializers")
val WRITE_SELF_NAME = Name.identifier("write\$Self") val WRITE_SELF_NAME = Name.identifier("write\$Self")
val SERIALIZER_PROVIDER_NAME = Name.identifier("serializer") val SERIALIZER_PROVIDER_NAME = Name.identifier("serializer")