Do not access serializable property IrField if it is unbound
Fixes https://github.com/Kotlin/kotlinx.serialization/issues/1698
This commit is contained in:
+4
-3
@@ -327,7 +327,7 @@ interface IrBuilderExtension {
|
|||||||
fun KotlinType.toIrType() = compilerContext.typeTranslator.translateType(this)
|
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.
|
// 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 {
|
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),
|
// 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
|
// check for call to .shouldEncodeElementDefault
|
||||||
val encodeDefaults = property.getIrPropertyFrom(serializableIrClass).getEncodeDefaultAnnotationValue()
|
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
|
// emit call right away
|
||||||
+elementCall
|
+elementCall
|
||||||
} else {
|
} else {
|
||||||
val partB = irNotEquals(property.irGet(), initializerAdapter(property.irField.initializer!!))
|
val partB = irNotEquals(property.irGet(), initializerAdapter(field.initializer!!))
|
||||||
|
|
||||||
val condition = if (encodeDefaults == false) {
|
val condition = if (encodeDefaults == false) {
|
||||||
// drop default without call to .shouldEncodeElementDefault
|
// drop default without call to .shouldEncodeElementDefault
|
||||||
|
|||||||
+1
-1
@@ -141,7 +141,7 @@ class SerializableIrGenerator(
|
|||||||
|
|
||||||
val ifNotSeenExpr: IrExpression = if (prop.optional) {
|
val ifNotSeenExpr: IrExpression = if (prop.optional) {
|
||||||
val initializerBody =
|
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)
|
irSetField(irGet(thiz), backingFieldToAssign, initializerBody)
|
||||||
} else {
|
} else {
|
||||||
// property required
|
// property required
|
||||||
|
|||||||
Reference in New Issue
Block a user