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
|
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.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
@@ -34,10 +35,15 @@ abstract class SerializableCompanionCodegen(
|
|||||||
val serializerGetterDescriptor = companionDescriptor.unsubstitutedMemberScope.getContributedFunctions(
|
val serializerGetterDescriptor = companionDescriptor.unsubstitutedMemberScope.getContributedFunctions(
|
||||||
SERIALIZER_PROVIDER_NAME,
|
SERIALIZER_PROVIDER_NAME,
|
||||||
NoLookupLocation.FROM_BACKEND
|
NoLookupLocation.FROM_BACKEND
|
||||||
).first { func ->
|
).firstOrNull {
|
||||||
func.valueParameters.size == serializableDescriptor.declaredTypeParameters.size &&
|
it.valueParameters.size == serializableDescriptor.declaredTypeParameters.size
|
||||||
func.valueParameters.all { isKSerializer(it.type) }
|
&& 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)
|
generateSerializerGetter(serializerGetterDescriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializableCompanionCodegen
|
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializableCompanionCodegen
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
import org.jetbrains.kotlinx.serialization.compiler.resolve.*
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.resolve.KSerializerDescriptorResolver.findSerializerConstructorForTypeArgumentsSerializers
|
|
||||||
|
|
||||||
class SerializableCompanionIrGenerator(
|
class SerializableCompanionIrGenerator(
|
||||||
val irClass: IrClass,
|
val irClass: IrClass,
|
||||||
@@ -33,7 +32,7 @@ class SerializableCompanionIrGenerator(
|
|||||||
) {
|
) {
|
||||||
val companionDescriptor = irClass.descriptor
|
val companionDescriptor = irClass.descriptor
|
||||||
val serializableClass = getSerializableClassDescriptorByCompanion(companionDescriptor) ?: return
|
val serializableClass = getSerializableClassDescriptorByCompanion(companionDescriptor) ?: return
|
||||||
if (serializableClass.isInternalSerializable)
|
if (serializableClass.shouldHaveGeneratedMethodsInCompanion)
|
||||||
SerializableCompanionIrGenerator(irClass, context, bindingContext).generate()
|
SerializableCompanionIrGenerator(irClass, context, bindingContext).generate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -56,7 +56,7 @@ class SerializableCompanionJsTranslator(
|
|||||||
companion object {
|
companion object {
|
||||||
fun translate(declaration: KtPureClassOrObject, descriptor: ClassDescriptor, translator: DeclarationBodyVisitor, context: TranslationContext) {
|
fun translate(declaration: KtPureClassOrObject, descriptor: ClassDescriptor, translator: DeclarationBodyVisitor, context: TranslationContext) {
|
||||||
val serializableClass = getSerializableClassDescriptorByCompanion(descriptor) ?: return
|
val serializableClass = getSerializableClassDescriptorByCompanion(descriptor) ?: return
|
||||||
if (serializableClass.isInternalSerializable)
|
if (serializableClass.shouldHaveGeneratedMethodsInCompanion)
|
||||||
SerializableCompanionJsTranslator(descriptor, translator, context).generate()
|
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.codegen.ImplementationBodyCodegen
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
import org.jetbrains.kotlinx.serialization.compiler.backend.common.SerializableCompanionCodegen
|
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) :
|
class SerializableCompanionCodegenImpl(private val codegen: ImplementationBodyCodegen) :
|
||||||
SerializableCompanionCodegen(codegen.descriptor, codegen.bindingContext) {
|
SerializableCompanionCodegen(codegen.descriptor, codegen.bindingContext) {
|
||||||
@@ -29,7 +31,7 @@ class SerializableCompanionCodegenImpl(private val codegen: ImplementationBodyCo
|
|||||||
companion object {
|
companion object {
|
||||||
fun generateSerializableExtensions(codegen: ImplementationBodyCodegen) {
|
fun generateSerializableExtensions(codegen: ImplementationBodyCodegen) {
|
||||||
val serializableClass = getSerializableClassDescriptorByCompanion(codegen.descriptor) ?: return
|
val serializableClass = getSerializableClassDescriptorByCompanion(codegen.descriptor) ?: return
|
||||||
if (serializableClass.isInternalSerializable)
|
if (serializableClass.shouldHaveGeneratedMethodsInCompanion)
|
||||||
SerializableCompanionCodegenImpl(codegen).generate()
|
SerializableCompanionCodegenImpl(codegen).generate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -61,7 +61,7 @@ open class SerializationResolveExtension : SyntheticResolveExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getSyntheticCompanionObjectNameIfNeeded(thisDescriptor: ClassDescriptor): Name? =
|
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
|
else null
|
||||||
|
|
||||||
override fun addSyntheticSupertypes(thisDescriptor: ClassDescriptor, supertypes: MutableList<KotlinType>) {
|
override fun addSyntheticSupertypes(thisDescriptor: ClassDescriptor, supertypes: MutableList<KotlinType>) {
|
||||||
|
|||||||
+3
-1
@@ -97,6 +97,8 @@ val KotlinType?.toClassDescriptor: ClassDescriptor?
|
|||||||
@JvmName("toClassDescriptor")
|
@JvmName("toClassDescriptor")
|
||||||
get() = this?.constructor?.declarationDescriptor as? ClassDescriptor
|
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
|
val ClassDescriptor.isInternalSerializable: Boolean //todo normal checking
|
||||||
get() {
|
get() {
|
||||||
@@ -159,7 +161,7 @@ val KotlinType.genericIndex: Int?
|
|||||||
fun getSerializableClassDescriptorByCompanion(thisDescriptor: ClassDescriptor): ClassDescriptor? {
|
fun getSerializableClassDescriptorByCompanion(thisDescriptor: ClassDescriptor): ClassDescriptor? {
|
||||||
if (!thisDescriptor.isCompanionObject) return null
|
if (!thisDescriptor.isCompanionObject) return null
|
||||||
val classDescriptor = (thisDescriptor.containingDeclaration as? ClassDescriptor) ?: return null
|
val classDescriptor = (thisDescriptor.containingDeclaration as? ClassDescriptor) ?: return null
|
||||||
if (!classDescriptor.isInternalSerializable) return null
|
if (!classDescriptor.shouldHaveGeneratedMethodsInCompanion) return null
|
||||||
return classDescriptor
|
return classDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user