From 7c942af13db7f54d006a66ce428cb3f14b1f6788 Mon Sep 17 00:00:00 2001 From: Leonid Startsev Date: Mon, 26 Nov 2018 18:38:43 +0300 Subject: [PATCH] Add synthetic companion with .serializer() getter even if default serializer is overridden. (kotlinx.serialization/228) --- .../backend/common/SerializableCompanionCodegen.kt | 14 ++++++++++---- .../backend/ir/SerializableCompanionIrGenerator.kt | 3 +-- .../js/SerializableCompanionJsTranslator.kt | 2 +- .../jvm/SerializableCompanionCodegenImpl.kt | 8 +++++--- .../extensions/SerializationResolveExtension.kt | 2 +- .../compiler/resolve/KSerializationUtil.kt | 4 +++- 6 files changed, 21 insertions(+), 12 deletions(-) diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializableCompanionCodegen.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializableCompanionCodegen.kt index ea0aacda38a..f3f34da5eae 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializableCompanionCodegen.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializableCompanionCodegen.kt @@ -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) } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableCompanionIrGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableCompanionIrGenerator.kt index 21455c45c92..f32e776b3e8 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableCompanionIrGenerator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializableCompanionIrGenerator.kt @@ -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() } } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializableCompanionJsTranslator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializableCompanionJsTranslator.kt index 73a595a5cb4..692431b7035 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializableCompanionJsTranslator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializableCompanionJsTranslator.kt @@ -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() } } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializableCompanionCodegenImpl.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializableCompanionCodegenImpl.kt index c53d4ec5e47..f47bc9283ba 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializableCompanionCodegenImpl.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializableCompanionCodegenImpl.kt @@ -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() } } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationResolveExtension.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationResolveExtension.kt index 52d784797f3..ec5cb42b7f6 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationResolveExtension.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationResolveExtension.kt @@ -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) { diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializationUtil.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializationUtil.kt index 5647871791c..1800942a742 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializationUtil.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializationUtil.kt @@ -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 }