[KxSerialization] Fix SERIALIZER_NOT_FOUND diagnostic for enums

Fixes #KT-56738

Merge-request: KT-MR-8938
Merged-by: Sergey Shanshin <Sergey.Shanshin@jetbrains.com>
This commit is contained in:
Sergey.Shanshin
2023-02-22 19:38:18 +00:00
committed by Space Team
parent 4ccad00c11
commit 63025030e3
3 changed files with 24 additions and 10 deletions
@@ -63,7 +63,17 @@ internal fun IrClass.findPluginGeneratedMethod(name: String, afterK2: Boolean):
}
}
internal fun IrClass.isEnumWithLegacyGeneratedSerializer(context: SerializationBaseContext): Boolean = isInternallySerializableEnum() && !context.runtimeHasEnumSerializerFactoryFunctions
internal fun IrClass.isEnumWithLegacyGeneratedSerializer(): Boolean {
return findEnumLegacySerializer() != null
}
internal fun IrClass.findEnumLegacySerializer(): IrClass? {
return if (kind == ClassKind.ENUM_CLASS) {
declarations.filterIsInstance<IrClass>().singleOrNull { it.name == SerialEntityNames.SERIALIZER_CLASS_NAME }
} else {
null
}
}
internal val IrClass.isSealedSerializableInterface: Boolean
get() = kind == ClassKind.INTERFACE && modality == Modality.SEALED && hasSerializableOrMetaAnnotation()
@@ -102,9 +112,9 @@ internal val IrClass.isSerialInfoAnnotation: Boolean
internal val IrClass.isInheritableSerialInfoAnnotation: Boolean
get() = annotations.hasAnnotation(SerializationAnnotations.inheritableSerialInfoFqName)
internal fun IrClass.shouldHaveGeneratedSerializer(context: SerializationBaseContext): Boolean
= (isInternalSerializable && (modality == Modality.FINAL || modality == Modality.OPEN))
|| isEnumWithLegacyGeneratedSerializer(context)
internal fun IrClass.shouldHaveGeneratedSerializer(): Boolean =
(isInternalSerializable && (modality == Modality.FINAL || modality == Modality.OPEN))
|| isEnumWithLegacyGeneratedSerializer()
internal val IrClass.shouldHaveGeneratedMethodsInCompanion: Boolean
get() = this.isSerializableObject || this.isSerializableEnum() || (this.kind == ClassKind.CLASS && hasSerializableOrMetaAnnotation()) || this.isSealedSerializableInterface
@@ -630,7 +630,7 @@ open class SerializerIrGenerator(
) {
val serializableDesc = context.getSerializableClassDescriptorBySerializer(irClass) ?: return
val generator = when {
serializableDesc.isEnumWithLegacyGeneratedSerializer(context) -> SerializerForEnumsGenerator(
serializableDesc.isEnumWithLegacyGeneratedSerializer() -> SerializerForEnumsGenerator(
irClass,
context
)
@@ -127,9 +127,13 @@ fun findTypeSerializer(context: SerializationBaseContext, type: IrType): IrClass
fun findEnumTypeSerializer(context: SerializationBaseContext, type: IrType): IrClassSymbol? {
val classSymbol = type.classOrNull?.owner ?: return null
return if (classSymbol.kind == ClassKind.ENUM_CLASS && !classSymbol.isEnumWithLegacyGeneratedSerializer(context))
context.referenceClassId(enumSerializerId)
else null
// in any case, the function returns the serializer for the enum
if (classSymbol.kind != ClassKind.ENUM_CLASS) return null
val legacySerializer = classSymbol.findEnumLegacySerializer()
// $serializer for legacy compiled enums, or EnumSerializer for factories
return legacySerializer?.symbol ?: context.referenceClassId(enumSerializerId)
}
internal fun IrClass?.classSerializer(context: SerializationBaseContext): IrClassSymbol? = this?.let {
@@ -140,7 +144,7 @@ internal fun IrClass?.classSerializer(context: SerializationBaseContext): IrClas
// can infer @Poly?
polymorphicSerializerIfApplicableAutomatically(context)?.let { return it }
// default serializable?
if (shouldHaveGeneratedSerializer(context)) {
if (shouldHaveGeneratedSerializer()) {
// $serializer nested class
return this.declarations
.filterIsInstance<IrClass>()
@@ -237,7 +241,7 @@ internal fun SerializationBaseContext.getSerializableClassDescriptorBySerializer
)
) return null
val classDescriptor = (serializer.parent as? IrClass) ?: return null
if (!classDescriptor.shouldHaveGeneratedSerializer(this)) return null
if (!classDescriptor.shouldHaveGeneratedSerializer()) return null
return classDescriptor
}