Do not access serializable property IrField if it is unbound

Fixes https://github.com/Kotlin/kotlinx.serialization/issues/1698
This commit is contained in:
Leonid Startsev
2021-09-24 19:58:15 +03:00
committed by Space
parent 9672b6b30d
commit f4eaf611c8
2 changed files with 5 additions and 4 deletions
@@ -327,7 +327,7 @@ interface IrBuilderExtension {
fun KotlinType.toIrType() = compilerContext.typeTranslator.translateType(this)
// note: this method should be used only for properties from current module. Fields from other modules are private and inaccessible.
val SerializableProperty.irField: IrField get() = compilerContext.symbolTable.referenceField(this.descriptor).owner
val SerializableProperty.irField: IrField? get() = compilerContext.symbolTable.referenceField(this.descriptor).let { if (it.isBound) it.owner else null }
fun IrClass.searchForProperty(descriptor: PropertyDescriptor): IrProperty {
// this API is used to reference both current module descriptors and external ones (because serializable class can be in any of them),
@@ -1260,11 +1260,12 @@ interface IrBuilderExtension {
// check for call to .shouldEncodeElementDefault
val encodeDefaults = property.getIrPropertyFrom(serializableIrClass).getEncodeDefaultAnnotationValue()
if (!property.optional || encodeDefaults == true) {
val field = property.irField // Nullable when property from another module; can't compare it with default value on JS or Native
if (!property.optional || encodeDefaults == true || field == null) {
// emit call right away
+elementCall
} else {
val partB = irNotEquals(property.irGet(), initializerAdapter(property.irField.initializer!!))
val partB = irNotEquals(property.irGet(), initializerAdapter(field.initializer!!))
val condition = if (encodeDefaults == false) {
// drop default without call to .shouldEncodeElementDefault
@@ -141,7 +141,7 @@ class SerializableIrGenerator(
val ifNotSeenExpr: IrExpression = if (prop.optional) {
val initializerBody =
requireNotNull(initializerAdapter(prop.irField.initializer!!)) { "Optional value without an initializer" } // todo: filter abstract here
requireNotNull(initializerAdapter(prop.irField?.initializer!!)) { "Optional value without an initializer" } // todo: filter abstract here
irSetField(irGet(thiz), backingFieldToAssign, initializerBody)
} else {
// property required