From e20354926bff777e0547686fbe56b2475057471e Mon Sep 17 00:00:00 2001 From: Leonid Startsev Date: Fri, 6 Mar 2020 17:24:19 +0300 Subject: [PATCH] Do not check 'no ctor parameters' for serializable enums fixes https://github.com/Kotlin/kotlinx.serialization/issues/742 Do not use serializableIrClass if it is not bound (this may happen in case we're generating external serializer for library class) fixes https://github.com/Kotlin/kotlinx.serialization/issues/744 --- .../backend/ir/SerializerForEnumsGenerator.kt | 2 ++ .../backend/ir/SerializerIrGenerator.kt | 10 ++++++---- .../SerializationPluginErrorsRendering.kt | 4 ++-- .../compiler/resolve/SerializableProperties.kt | 18 ++++-------------- 4 files changed, 14 insertions(+), 20 deletions(-) diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForEnumsGenerator.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForEnumsGenerator.kt index 6fcd2e9d7e2..fdf855a769f 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForEnumsGenerator.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/SerializerForEnumsGenerator.kt @@ -39,6 +39,7 @@ class SerializerForEnumsGenerator( val encodeEnum = encoderClass.referenceMethod(CallingConventions.encodeEnum) val serialDescGetter = irGet(descriptorGetterSymbol.owner.returnType, irThis(), descriptorGetterSymbol) + val serializableIrClass = requireNotNull(serializableIrClass) { "Enums do not support external serialization" } val ordinalProp = serializableIrClass.properties.single { it.name == Name.identifier("ordinal") }.getter!! val getOrdinal = irInvoke(irGet(saveFunc.valueParameters[1]), ordinalProp.symbol) val call = irInvoke(irGet(saveFunc.valueParameters[0]), encodeEnum, serialDescGetter, getOrdinal) @@ -54,6 +55,7 @@ class SerializerForEnumsGenerator( val decode = decoderClass.referenceMethod(CallingConventions.decodeEnum) val serialDescGetter = irGet(descriptorGetterSymbol.owner.returnType, irThis(), descriptorGetterSymbol) + val serializableIrClass = requireNotNull(serializableIrClass) { "Enums do not support external serialization" } val valuesF = serializableIrClass.functions.single { it.name == DescriptorUtils.ENUM_VALUES } val getValues = irInvoke(dispatchReceiver = null, callee = valuesF.symbol) 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 69929e2be98..1a445308317 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 @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -40,7 +40,7 @@ object SERIALIZABLE_PLUGIN_ORIGIN : IrDeclarationOriginImpl("SERIALIZER") open class SerializerIrGenerator(val irClass: IrClass, final override val compilerContext: SerializationPluginContext, bindingContext: BindingContext) : SerializerCodegen(irClass.descriptor, bindingContext), IrBuilderExtension { - protected val serializableIrClass = compilerContext.symbolTable.referenceClass(serializableDescriptor).owner + protected val serializableIrClass = compilerContext.symbolTable.referenceClass(serializableDescriptor).takeIf { it.isBound }?.owner override fun generateSerialDesc() { val desc: PropertyDescriptor = generatedSerialDescPropertyDescriptor ?: return @@ -81,7 +81,7 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil addElementsContentToDescriptor(serialDescImplClass, localDesc, addFuncS) // add class annotations copySerialInfoAnnotationsToDescriptor( - serializableIrClass.annotations, + serializableIrClass?.annotations.orEmpty(), localDesc, serialDescImplClass.referenceMethod(CallingConventions.addClassAnnotation) ) @@ -201,7 +201,9 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil override fun generateSave(function: FunctionDescriptor) = irClass.contributeFunction(function) { saveFunc -> val fieldInitializer: (SerializableProperty) -> IrExpression? = - buildInitializersRemapping(serializableIrClass).run { { invoke(it.irField) } } + buildInitializersRemapping( + serializableIrClass ?: error("Please provide implementation of .deserialize method for external class") + ).run { { invoke(it.irField) } } fun irThis(): IrExpression = IrGetValueImpl(startOffset, endOffset, saveFunc.dispatchReceiverParameter!!.symbol) diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginErrorsRendering.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginErrorsRendering.kt index e6de411bd1c..0289440de4d 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginErrorsRendering.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/diagnostic/SerializationPluginErrorsRendering.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -38,7 +38,7 @@ object SerializationPluginErrorsRendering : DefaultErrorMessages.Extension { ) MAP.put( SerializationErrors.PRIMARY_CONSTRUCTOR_PARAMETER_IS_NOT_A_PROPERTY, - "This class is not serializable automatically because it has primary constructor parameters of which are not properties" + "This class is not serializable automatically because it has primary constructor parameters that are not properties" ) MAP.put( SerializationErrors.DUPLICATE_SERIAL_NAME, diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperties.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperties.kt index 459903200bc..eefdc19e0f2 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperties.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/resolve/SerializableProperties.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlinx.serialization.compiler.resolve @@ -67,7 +56,8 @@ class SerializableProperties(private val serializableClass: ClassDescriptor, val else SerializableProperties(supers, bindingContext).serializableProperties + first + second } - isExternallySerializable = primaryConstructorParameters.size == primaryConstructorProperties.size + isExternallySerializable = + serializableClass.isSerializableEnum() || primaryConstructorParameters.size == primaryConstructorProperties.size } val serializableConstructorProperties: List =