Add .serializer() to enum companion and object with custom serializer
Fixes Kotlin/kotlinx.serialization#1386
This commit is contained in:
+3
-3
@@ -43,7 +43,7 @@ fun AbstractSerialGenerator.findAddOnSerializer(propertyType: KotlinType, module
|
||||
return null
|
||||
}
|
||||
|
||||
fun KotlinType.isSerializableObject() =
|
||||
fun KotlinType.isGeneratedSerializableObject() =
|
||||
toClassDescriptor?.run { kind == ClassKind.OBJECT && hasSerializableAnnotationWithoutArgs } == true
|
||||
|
||||
@Suppress("FunctionName", "LocalVariableName")
|
||||
@@ -151,7 +151,7 @@ fun findTypeSerializer(module: ModuleDescriptor, kType: KotlinType): ClassDescri
|
||||
if (userOverride != null) return userOverride.toClassDescriptor
|
||||
if (kType.isTypeParameter()) return null
|
||||
if (KotlinBuiltIns.isArray(kType)) return module.getClassFromInternalSerializationPackage(SpecialBuiltins.referenceArraySerializer)
|
||||
if (kType.isSerializableObject()) return module.getClassFromInternalSerializationPackage(SpecialBuiltins.objectSerializer)
|
||||
if (kType.isGeneratedSerializableObject()) return module.getClassFromInternalSerializationPackage(SpecialBuiltins.objectSerializer)
|
||||
val stdSer = findStandardKotlinTypeSerializer(module, kType) // see if there is a standard serializer
|
||||
?: findEnumTypeSerializer(module, kType)
|
||||
if (stdSer != null) return stdSer
|
||||
@@ -216,7 +216,7 @@ fun findStandardKotlinTypeSerializer(module: ModuleDescriptor, kType: KotlinType
|
||||
|
||||
fun findEnumTypeSerializer(module: ModuleDescriptor, kType: KotlinType): ClassDescriptor? {
|
||||
val classDescriptor = kType.toClassDescriptor ?: return null
|
||||
return if (classDescriptor.kind == ClassKind.ENUM_CLASS && !classDescriptor.isSerializableEnum())
|
||||
return if (classDescriptor.kind == ClassKind.ENUM_CLASS && !classDescriptor.isInternallySerializableEnum())
|
||||
module.findClassAcrossModuleDependencies(enumSerializerId)
|
||||
else null
|
||||
}
|
||||
|
||||
+1
-1
@@ -572,7 +572,7 @@ open class SerializerIrGenerator(
|
||||
) {
|
||||
val serializableDesc = getSerializableClassDescriptorBySerializer(irClass.symbol.descriptor) ?: return
|
||||
val generator = when {
|
||||
serializableDesc.isSerializableEnum() -> SerializerForEnumsGenerator(irClass, context, bindingContext, serialInfoJvmGenerator)
|
||||
serializableDesc.isInternallySerializableEnum() -> SerializerForEnumsGenerator(irClass, context, bindingContext, serialInfoJvmGenerator)
|
||||
serializableDesc.isInlineClass() -> SerializerForInlineClassGenerator(irClass, context, bindingContext, serialInfoJvmGenerator)
|
||||
else -> SerializerIrGenerator(irClass, context, bindingContext, metadataPlugin, serialInfoJvmGenerator)
|
||||
}
|
||||
|
||||
+2
-2
@@ -373,11 +373,11 @@ open class SerializerJsTranslator(
|
||||
metadataPlugin: SerializationDescriptorSerializerPlugin?
|
||||
) {
|
||||
val serializableDesc = getSerializableClassDescriptorBySerializer(descriptor) ?: return
|
||||
if (serializableDesc.isSerializableEnum()) {
|
||||
if (serializableDesc.isInternallySerializableEnum()) {
|
||||
SerializerForEnumsTranslator(descriptor, translator, context).generate()
|
||||
} else {
|
||||
SerializerJsTranslator(descriptor, translator, context, metadataPlugin).generate()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ open class SerializerCodegenImpl(
|
||||
companion object {
|
||||
fun generateSerializerExtensions(codegen: ImplementationBodyCodegen, metadataPlugin: SerializationDescriptorSerializerPlugin?) {
|
||||
val serializableClass = getSerializableClassDescriptorBySerializer(codegen.descriptor) ?: return
|
||||
val serializerCodegen = if (serializableClass.isSerializableEnum()) {
|
||||
val serializerCodegen = if (serializableClass.isInternallySerializableEnum()) {
|
||||
SerializerForEnumsCodegen(codegen, serializableClass)
|
||||
} else {
|
||||
SerializerCodegenImpl(codegen, serializableClass, metadataPlugin)
|
||||
|
||||
+13
-9
@@ -97,9 +97,12 @@ val KotlinType?.toClassDescriptor: ClassDescriptor?
|
||||
}
|
||||
|
||||
internal val ClassDescriptor.shouldHaveGeneratedMethodsInCompanion: Boolean
|
||||
get() = this.isSerializableObject || this.isSerializableEnum() || this.kind == ClassKind.CLASS && annotations.hasAnnotation(SerializationAnnotations.serializableAnnotationFqName)
|
||||
get() = this.isSerializableObject || this.isSerializableEnum() || this.kind == ClassKind.CLASS && hasSerializableAnnotation
|
||||
|
||||
internal val ClassDescriptor.isSerializableObject: Boolean
|
||||
get() = kind == ClassKind.OBJECT && hasSerializableAnnotation
|
||||
|
||||
internal val ClassDescriptor.isInternallySerializableObject: Boolean
|
||||
get() = kind == ClassKind.OBJECT && hasSerializableAnnotationWithoutArgs
|
||||
|
||||
internal val ClassDescriptor.isInternalSerializable: Boolean //todo normal checking
|
||||
@@ -108,14 +111,12 @@ internal val ClassDescriptor.isInternalSerializable: Boolean //todo normal check
|
||||
return hasSerializableAnnotationWithoutArgs
|
||||
}
|
||||
|
||||
internal fun ClassDescriptor.isSerializableEnum(): Boolean {
|
||||
if (this.kind != ClassKind.ENUM_CLASS) return false
|
||||
if (hasSerializableAnnotationWithoutArgs) return true
|
||||
return false
|
||||
}
|
||||
internal fun ClassDescriptor.isSerializableEnum(): Boolean = kind == ClassKind.ENUM_CLASS && hasSerializableAnnotation
|
||||
|
||||
internal fun ClassDescriptor.isInternallySerializableEnum(): Boolean = kind == ClassKind.ENUM_CLASS && hasSerializableAnnotationWithoutArgs
|
||||
|
||||
internal val ClassDescriptor.shouldHaveGeneratedSerializer: Boolean
|
||||
get() = (isInternalSerializable && (modality == Modality.FINAL || modality == Modality.OPEN)) || isSerializableEnum()
|
||||
get() = (isInternalSerializable && (modality == Modality.FINAL || modality == Modality.OPEN)) || isInternallySerializableEnum()
|
||||
|
||||
internal fun ClassDescriptor.enumEntries(): List<ClassDescriptor> {
|
||||
check(this.kind == ClassKind.ENUM_CLASS)
|
||||
@@ -128,9 +129,12 @@ internal fun ClassDescriptor.enumEntries(): List<ClassDescriptor> {
|
||||
internal val Annotations.hasAnySerialAnnotation: Boolean
|
||||
get() = serialNameValue != null || any { it.annotationClass?.isSerialInfoAnnotation == true }
|
||||
|
||||
private val ClassDescriptor.hasSerializableAnnotation
|
||||
get() = annotations.hasAnnotation(SerializationAnnotations.serializableAnnotationFqName)
|
||||
|
||||
internal val ClassDescriptor.hasSerializableAnnotationWithoutArgs: Boolean
|
||||
get() {
|
||||
if (!annotations.hasAnnotation(SerializationAnnotations.serializableAnnotationFqName)) return false
|
||||
if (!hasSerializableAnnotation) return false
|
||||
// If provided descriptor is lazy, carefully look at psi in order not to trigger full resolve which may be recursive.
|
||||
// Otherwise, this descriptor is deserialized from another module and it is OK to check value right away.
|
||||
val psi = findSerializableAnnotationDeclaration() ?: return (serializableWith == null)
|
||||
@@ -178,7 +182,7 @@ internal val ClassDescriptor?.classSerializer: ClassDescriptor?
|
||||
}
|
||||
|
||||
internal val ClassDescriptor.hasCompanionObjectAsSerializer: Boolean
|
||||
get() = isSerializableObject || companionObjectDescriptor?.serializerForClass == this.defaultType
|
||||
get() = isInternallySerializableObject || companionObjectDescriptor?.serializerForClass == this.defaultType
|
||||
|
||||
// returns only user-overriden Serializer
|
||||
internal val KotlinType.overridenSerializer: KotlinType?
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ class SerializableProperties(private val serializableClass: ClassDescriptor, val
|
||||
.let { unsort(serializableClass, it) }
|
||||
|
||||
isExternallySerializable =
|
||||
serializableClass.isSerializableEnum() || primaryConstructorParameters.size == primaryConstructorProperties.size
|
||||
serializableClass.isInternallySerializableEnum() || primaryConstructorParameters.size == primaryConstructorProperties.size
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user