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
This commit is contained in:
Leonid Startsev
2020-03-06 17:24:19 +03:00
parent 79fef09bf5
commit e20354926b
4 changed files with 14 additions and 20 deletions
@@ -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)
@@ -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)
@@ -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,
@@ -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<SerializableProperty> =