Respect @Serializable(with) on properties on JS too.
Don't generate constructor for passing generic serializers if user already defined proper one.
This commit is contained in:
+21
-4
@@ -19,15 +19,13 @@ package org.jetbrains.kotlinx.serialization.compiler.backend.common
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil.getMemberToGenerate
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtPureClassOrObject
|
||||
import org.jetbrains.kotlin.psi.synthetics.findClassDescriptor
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver.createTypedSerializerConstructorDescriptor
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializableProperties
|
||||
|
||||
abstract class SerializerCodegen(declaration: KtPureClassOrObject, bindingContext: BindingContext) {
|
||||
protected val serializerDescriptor: ClassDescriptor = declaration.findClassDescriptor(bindingContext)
|
||||
@@ -43,11 +41,30 @@ abstract class SerializerCodegen(declaration: KtPureClassOrObject, bindingContex
|
||||
val load = generateLoadIfNeeded()
|
||||
if (save || load || prop)
|
||||
generateSerialDesc()
|
||||
if (serializableDescriptor.declaredTypeParameters.isNotEmpty()) {
|
||||
if (serializableDescriptor.declaredTypeParameters.isNotEmpty() && typedSerializerConstructorNotDeclared()) {
|
||||
generateGenericFieldsAndConstructor(createTypedSerializerConstructorDescriptor(serializerDescriptor, serializableDescriptor))
|
||||
}
|
||||
}
|
||||
|
||||
// checks if user didn't declared constructor (KSerializer<T0>, KSerializer<T1>...) on a KSerializer<T<T0, T1...>>
|
||||
private fun typedSerializerConstructorNotDeclared(): Boolean {
|
||||
val kSerializerSupertype = serializerDescriptor.typeConstructor.supertypes
|
||||
.find { isKSerializer(it) } ?: throw AssertionError("Serializer does not implement KSerializer??")
|
||||
val serializableImplementationTypeArguments = kSerializerSupertype.arguments.first().type.arguments
|
||||
|
||||
val typeParamsCount = serializableImplementationTypeArguments.size
|
||||
if (typeParamsCount == 0) return false //don't need it
|
||||
val ctors = serializerDescriptor.constructors
|
||||
val found =
|
||||
ctors.any {
|
||||
it.valueParameters.size == typeParamsCount && it.valueParameters.foldIndexed(false) { index, flag, parameterDescriptor ->
|
||||
val type = parameterDescriptor.type
|
||||
flag || (isKSerializer(type) && type.arguments.first() == serializableImplementationTypeArguments[index])
|
||||
}
|
||||
}
|
||||
return !found
|
||||
}
|
||||
|
||||
protected val serialDescPropertyDescriptor = getPropertyToGenerate(serializerDescriptor, KSerializerDescriptorResolver.SERIAL_DESC_FIELD,
|
||||
serializerDescriptor::checkSerializableClassPropertyResult)
|
||||
protected abstract fun generateSerialDesc()
|
||||
|
||||
+3
-2
@@ -47,6 +47,8 @@ open class SerialTypeInfo(
|
||||
|
||||
fun getSerialTypeInfo(property: SerializableProperty): SerialTypeInfo {
|
||||
val T = property.type
|
||||
val serializableWith = property.serializableWith?.toClassDescriptor
|
||||
if (serializableWith != null) return SerialTypeInfo(property, if (property.type.isMarkedNullable) "Nullable" else "", serializableWith)
|
||||
return when {
|
||||
T.isTypeParameter() -> SerialTypeInfo(property, if (property.type.isMarkedNullable) "Nullable" else "", null)
|
||||
T.isPrimitiveNumberType() or T.isBoolean() -> SerialTypeInfo(
|
||||
@@ -63,8 +65,7 @@ fun getSerialTypeInfo(property: SerializableProperty): SerialTypeInfo {
|
||||
SerialTypeInfo(property, if (property.type.isMarkedNullable) "Nullable" else "", serializer)
|
||||
}
|
||||
T.toClassDescriptor?.kind == ClassKind.ENUM_CLASS -> {
|
||||
val serializer =
|
||||
property.serializableWith?.toClassDescriptor ?: property.module.findClassAcrossModuleDependencies(enumSerializerId)
|
||||
val serializer = property.module.findClassAcrossModuleDependencies(enumSerializerId)
|
||||
SerialTypeInfo(property, if (property.type.isMarkedNullable) "Nullable" else "", serializer)
|
||||
}
|
||||
else -> {
|
||||
|
||||
Reference in New Issue
Block a user