From d4bdb0eedc0ee99558ae31a2cb9dbcbf449fa252 Mon Sep 17 00:00:00 2001 From: Leonid Startsev Date: Tue, 22 Sep 2020 18:25:19 +0300 Subject: [PATCH] Remove requirement on 'Serializable class must have single primary constructor' #KT-38868 Fixed #KT-41627 Fixed Fixes https://github.com/Kotlin/kotlinx.serialization/issues/396 Fixes https://github.com/Kotlin/kotlinx.serialization/issues/1049 --- .../compiler/backend/ir/GeneratorHelpers.kt | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt index 6d6f0497721..b11fd6ae8ff 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/backend/ir/GeneratorHelpers.kt @@ -442,12 +442,17 @@ interface IrBuilderExtension { fun IrBuilderWithScope.classReference(classType: KotlinType): IrClassReference = createClassReference(classType, startOffset, endOffset) - fun buildInitializersRemapping(irClass: IrClass): (IrField) -> IrExpression? { + private fun extractDefaultValuesFromConstructor(irClass: IrClass?): Map { + if (irClass == null) return emptyMap() val original = irClass.constructors.singleOrNull { it.isPrimary } - ?: throw IllegalStateException("Serializable class must have single primary constructor") // default arguments of original constructor val defaultsMap: Map = - original.valueParameters.associate { it.descriptor to it.defaultValue?.expression } + original?.valueParameters?.associate { it.descriptor to it.defaultValue?.expression } ?: emptyMap() + return defaultsMap + extractDefaultValuesFromConstructor(irClass.getSuperClassNotAny()) + } + + fun buildInitializersRemapping(irClass: IrClass): (IrField) -> IrExpression? { + val defaultsMap = extractDefaultValuesFromConstructor(irClass) return fun(f: IrField): IrExpression? { val i = f.initializer?.expression ?: return null val irExpression = @@ -744,10 +749,12 @@ interface IrBuilderExtension { return forClass.declarations.filterIsInstance().single { it.isSerializationCtor() }.symbol } - fun IrClass.getSuperClassOrAny(): IrClass { + fun IrClass.getSuperClassOrAny(): IrClass = getSuperClassNotAny() ?: compilerContext.irBuiltIns.anyClass.owner + + fun IrClass.getSuperClassNotAny(): IrClass? { val superClasses = superTypes.mapNotNull { it.classOrNull }.map { it.owner } - return superClasses.singleOrNull { it.kind == ClassKind.CLASS } ?: compilerContext.irBuiltIns.anyClass.owner + return superClasses.singleOrNull { it.kind == ClassKind.CLASS } } } \ No newline at end of file