From 7c8b34fe1cca58888936e5369f8b6e90693f81e6 Mon Sep 17 00:00:00 2001 From: Leonid Startsev Date: Fri, 30 Nov 2018 16:10:07 +0300 Subject: [PATCH] Fix unresolved symbol to SerialDescriptor in KSerializer if it was referenced from user custom serializer code (kotlinx.serialization/290) --- .../compiler/backend/common/SerializerCodegen.kt | 3 ++- .../compiler/backend/ir/GeneratorHelpers.kt | 14 ++++---------- .../compiler/backend/ir/SerializerIrGenerator.kt | 4 ++-- 3 files changed, 8 insertions(+), 13 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 69ed47dd75d..03f0b8fe406 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 @@ -65,7 +65,8 @@ abstract class SerializerCodegen( protected val generatedSerialDescPropertyDescriptor = getPropertyToGenerate( serializerDescriptor, SerialEntityNames.SERIAL_DESC_FIELD, - serializerDescriptor::checkSerializableClassPropertyResult) + serializerDescriptor::checkSerializableClassPropertyResult + ) protected val anySerialDescProperty = getProperty( serializerDescriptor, SerialEntityNames.SERIAL_DESC_FIELD, serializerDescriptor::checkSerializableClassPropertyResult 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 689db92bcd7..bef330438e7 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 @@ -192,11 +192,6 @@ interface IrBuilderExtension { val SerializableProperty.irField: IrField get() = compilerContext.externalSymbols.referenceField(this.descriptor).owner -// get () { -// val symb = compilerContext.localSymbolTable.referenceField(this.descriptor) -// return if (symb.isBound) symb.owner -// else compilerContext.localSymbolTable.declareField() -// } /* The rest of the file is mainly copied from FunctionGenerator. @@ -252,10 +247,10 @@ interface IrBuilderExtension { fieldSymbol: IrFieldSymbol, ownerSymbol: IrValueSymbol ): IrSimpleFunction { - return compilerContext.localSymbolTable.declareSimpleFunctionWithOverrides( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, - SERIALIZABLE_PLUGIN_ORIGIN, descriptor - ).buildWithScope { irAccessor -> + // Declaration can also be called from user code. Since we lookup descriptor getter in externalSymbols + // (see generateSave/generateLoad), seems it is correct approach to declare getter lazily there. + val declaration = compilerContext.externalSymbols.referenceSimpleFunction(descriptor).owner + return declaration.buildWithScope { irAccessor -> irAccessor.createParameterDeclarations((ownerSymbol as IrValueParameterSymbol).owner) // todo: neat this irAccessor.returnType = irAccessor.descriptor.returnType!!.toIrType() irAccessor.body = when (descriptor) { @@ -264,7 +259,6 @@ interface IrBuilderExtension { else -> throw AssertionError("Should be getter or setter: $descriptor") } } - } private fun generateDefaultGetterBody( 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 dee370417e3..06150494f76 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 @@ -167,7 +167,7 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext: val kOutputClass = serializerDescriptor.getClassFromSerializationPackage(STRUCTURE_ENCODER_CLASS) val kOutputSmallClass = serializerDescriptor.getClassFromSerializationPackage(ENCODER_CLASS) - val descriptorGetterSymbol = compilerContext.localSymbolTable.referenceFunction(anySerialDescProperty?.getter!!) //??? + val descriptorGetterSymbol = compilerContext.externalSymbols.referenceFunction(anySerialDescProperty?.getter!!) //??? val localSerialDesc = irTemporary(irGet(descriptorGetterSymbol.owner.returnType, irThis(), descriptorGetterSymbol), "desc") @@ -268,7 +268,7 @@ class SerializerIrGenerator(val irClass: IrClass, override val compilerContext: val inputClass = serializerDescriptor.getClassFromSerializationPackage(STRUCTURE_DECODER_CLASS) val inputSmallClass = serializerDescriptor.getClassFromSerializationPackage(DECODER_CLASS) - val descriptorGetterSymbol = compilerContext.localSymbolTable.referenceFunction(anySerialDescProperty?.getter!!) //??? + val descriptorGetterSymbol = compilerContext.externalSymbols.referenceFunction(anySerialDescProperty?.getter!!) //??? val localSerialDesc = irTemporary(irGet(descriptorGetterSymbol.owner.returnType, irThis(), descriptorGetterSymbol), "desc") // workaround due to unavailability of labels (KT-25386)