Add synthetic companion with .serializer() getter even if default serializer is overridden. (kotlinx.serialization/228)
This commit is contained in:
+10
-4
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlinx.serialization.compiler.backend.common
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
@@ -34,10 +35,15 @@ abstract class SerializableCompanionCodegen(
|
||||
val serializerGetterDescriptor = companionDescriptor.unsubstitutedMemberScope.getContributedFunctions(
|
||||
SERIALIZER_PROVIDER_NAME,
|
||||
NoLookupLocation.FROM_BACKEND
|
||||
).first { func ->
|
||||
func.valueParameters.size == serializableDescriptor.declaredTypeParameters.size &&
|
||||
func.valueParameters.all { isKSerializer(it.type) }
|
||||
}
|
||||
).firstOrNull {
|
||||
it.valueParameters.size == serializableDescriptor.declaredTypeParameters.size
|
||||
&& it.kind == CallableMemberDescriptor.Kind.SYNTHESIZED
|
||||
&& it.valueParameters.all { p -> isKSerializer(p.type) }
|
||||
&& it.returnType != null && isKSerializer(it.returnType)
|
||||
} ?: throw IllegalStateException(
|
||||
"Can't find synthesized 'Companion.serializer()' function to generate, " +
|
||||
"probably clash with user-defined function has occurred"
|
||||
)
|
||||
generateSerializerGetter(serializerGetterDescriptor)
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializableCompanionCodegen
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver.findSerializerConstructorForTypeArgumentsSerializers
|
||||
|
||||
class SerializableCompanionIrGenerator(
|
||||
val irClass: IrClass,
|
||||
@@ -33,7 +32,7 @@ class SerializableCompanionIrGenerator(
|
||||
) {
|
||||
val companionDescriptor = irClass.descriptor
|
||||
val serializableClass = getSerializableClassDescriptorByCompanion(companionDescriptor) ?: return
|
||||
if (serializableClass.isInternalSerializable)
|
||||
if (serializableClass.shouldHaveGeneratedMethodsInCompanion)
|
||||
SerializableCompanionIrGenerator(irClass, context, bindingContext).generate()
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ class SerializableCompanionJsTranslator(
|
||||
companion object {
|
||||
fun translate(declaration: KtPureClassOrObject, descriptor: ClassDescriptor, translator: DeclarationBodyVisitor, context: TranslationContext) {
|
||||
val serializableClass = getSerializableClassDescriptorByCompanion(descriptor) ?: return
|
||||
if (serializableClass.isInternalSerializable)
|
||||
if (serializableClass.shouldHaveGeneratedMethodsInCompanion)
|
||||
SerializableCompanionJsTranslator(descriptor, translator, context).generate()
|
||||
}
|
||||
}
|
||||
|
||||
+5
-3
@@ -18,10 +18,12 @@ package org.jetbrains.kotlinx.serialization.compiler.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.codegen.ImplementationBodyCodegen
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializableCompanionCodegen
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.classSerializer
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.getSerializableClassDescriptorByCompanion
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.shouldHaveGeneratedMethodsInCompanion
|
||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.toClassDescriptor
|
||||
|
||||
class SerializableCompanionCodegenImpl(private val codegen: ImplementationBodyCodegen) :
|
||||
SerializableCompanionCodegen(codegen.descriptor, codegen.bindingContext) {
|
||||
@@ -29,7 +31,7 @@ class SerializableCompanionCodegenImpl(private val codegen: ImplementationBodyCo
|
||||
companion object {
|
||||
fun generateSerializableExtensions(codegen: ImplementationBodyCodegen) {
|
||||
val serializableClass = getSerializableClassDescriptorByCompanion(codegen.descriptor) ?: return
|
||||
if (serializableClass.isInternalSerializable)
|
||||
if (serializableClass.shouldHaveGeneratedMethodsInCompanion)
|
||||
SerializableCompanionCodegenImpl(codegen).generate()
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -61,7 +61,7 @@ open class SerializationResolveExtension : SyntheticResolveExtension {
|
||||
}
|
||||
|
||||
override fun getSyntheticCompanionObjectNameIfNeeded(thisDescriptor: ClassDescriptor): Name? =
|
||||
if (thisDescriptor.isInternalSerializable) SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT
|
||||
if (thisDescriptor.shouldHaveGeneratedMethodsInCompanion) SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT
|
||||
else null
|
||||
|
||||
override fun addSyntheticSupertypes(thisDescriptor: ClassDescriptor, supertypes: MutableList<KotlinType>) {
|
||||
|
||||
+3
-1
@@ -97,6 +97,8 @@ val KotlinType?.toClassDescriptor: ClassDescriptor?
|
||||
@JvmName("toClassDescriptor")
|
||||
get() = this?.constructor?.declarationDescriptor as? ClassDescriptor
|
||||
|
||||
internal val ClassDescriptor.shouldHaveGeneratedMethodsInCompanion: Boolean
|
||||
get() = this.kind == ClassKind.CLASS && annotations.hasAnnotation(SerializationAnnotations.serializableAnnotationFqName)
|
||||
|
||||
val ClassDescriptor.isInternalSerializable: Boolean //todo normal checking
|
||||
get() {
|
||||
@@ -159,7 +161,7 @@ val KotlinType.genericIndex: Int?
|
||||
fun getSerializableClassDescriptorByCompanion(thisDescriptor: ClassDescriptor): ClassDescriptor? {
|
||||
if (!thisDescriptor.isCompanionObject) return null
|
||||
val classDescriptor = (thisDescriptor.containingDeclaration as? ClassDescriptor) ?: return null
|
||||
if (!classDescriptor.isInternalSerializable) return null
|
||||
if (!classDescriptor.shouldHaveGeneratedMethodsInCompanion) return null
|
||||
return classDescriptor
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user