From b76116a077efd1f45e5570058efc2619bf217c33 Mon Sep 17 00:00:00 2001 From: Leonid Startsev Date: Tue, 30 Oct 2018 16:14:49 +0300 Subject: [PATCH] Do not add any .childSerializers() stuff if user explicitly marked custom serializer as KSerializer todo: better design for user-provided descriptors and and schema hierarchy --- .../compiler/backend/common/SerializerCodegen.kt | 3 +++ .../compiler/backend/ir/SerializerIrGenerator.kt | 11 ++++++----- .../compiler/backend/js/SerializerJsTranslator.kt | 5 ++++- .../compiler/backend/jvm/SerializerCodegenImpl.kt | 5 ++++- .../compiler/resolve/KSerializerDescriptorResolver.kt | 1 + 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt index 0812742a4d2..5754d5d243a 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/common/SerializerCodegen.kt @@ -72,6 +72,9 @@ abstract class SerializerCodegen( val localSerializersFieldsDescriptors: List = findLocalSerializersFieldDescriptors() + // Can be false if user specified inheritance from KSerializer explicitly + protected val isGeneratedSerializer = serializerDescriptor.typeConstructor.supertypes.any(::isGeneratedKSerializer) + private fun findLocalSerializersFieldDescriptors(): List { val count = serializableDescriptor.declaredTypeParameters.size if (count == 0) return emptyList() diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt index 2e0d06f9daf..dee370417e3 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerIrGenerator.kt @@ -81,11 +81,12 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext: compilerContext.localSymbolTable.withScope(initIrBody.descriptor) { initIrBody.body = compilerContext.createIrBuilder(initIrBody.symbol).irBlockBody { val localDesc = irTemporary( - irInvoke(null, serialClassDescImplCtor, - irString(serialName), irGet(thisAsReceiverParameter), - typeHint = serialClassDescImplCtor.owner.returnType - ), - nameHint = "serialDesc" + irInvoke( + null, serialClassDescImplCtor, + irString(serialName), if (isGeneratedSerializer) irGet(thisAsReceiverParameter) else irNull(), + typeHint = serialClassDescImplCtor.owner.returnType + ), + nameHint = "serialDesc" ) fun addFieldCall(fieldName: String) = diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializerJsTranslator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializerJsTranslator.kt index 820ea16e6da..fc9d8261c6f 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializerJsTranslator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/js/SerializerJsTranslator.kt @@ -58,7 +58,10 @@ class SerializerJsTranslator(descriptor: ClassDescriptor, // this.serialDesc = new SerialDescImpl(...) val correctThis = context.getDispatchReceiver(JsDescriptorUtils.getReceiverParameterForDeclaration(desc.containingDeclaration)) - val value = JsNew(context.getInnerReference(serialDescImplConstructor), listOf(JsStringLiteral(serialName), correctThis)) + val value = JsNew( + context.getInnerReference(serialDescImplConstructor), + listOf(JsStringLiteral(serialName), if (isGeneratedSerializer) correctThis else JsNullLiteral()) + ) val assgmnt = TranslationUtils.assignmentToBackingField(context, desc, value) translator.addInitializerStatement(assgmnt.makeStmt()) diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerCodegenImpl.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerCodegenImpl.kt index e1b939548d8..8dfc1261235 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerCodegenImpl.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/jvm/SerializerCodegenImpl.kt @@ -80,7 +80,10 @@ class SerializerCodegenImpl( if (isStatic) { assert(serializerDescriptor.kind == ClassKind.OBJECT) { "Serializer for type without type parameters must be an object" } // static descriptor means serializer is an object. it is safer to get it from correct field - StackValue.singleton(serializerDescriptor, codegen.typeMapper).put(generatedSerializerType, this) + if (isGeneratedSerializer) + StackValue.singleton(serializerDescriptor, codegen.typeMapper).put(generatedSerializerType, this) + else + aconst(null) } else { load(0, serializerAsmType) } diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt index 8fbb2d93df4..b4750861453 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/KSerializerDescriptorResolver.kt @@ -176,6 +176,7 @@ object KSerializerDescriptorResolver { val isLoad = name == SerialEntityNames.LOAD_NAME && shouldAddSerializerFunction { classDescriptor.checkLoadMethodParameters(it.valueParameters) } val isDescriptorGetter = name == SerialEntityNames.GENERATED_DESCRIPTOR_GETTER && + thisDescriptor.typeConstructor.supertypes.any(::isGeneratedKSerializer) && shouldAddSerializerFunction { true /* TODO? */ } if (isSave || isLoad || isDescriptorGetter) {