Skip to content

Commit 38c0a51

Browse files
gala377Space Cloud
authored andcommitted
[Parcelize] Fix a runtime error when all properties in the constructor are ignored
1 parent 8e3c6e8 commit 38c0a51

File tree

2 files changed

+29
-22
lines changed

2 files changed

+29
-22
lines changed

plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/ParcelizeIrTransformerBase.kt

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ import org.jetbrains.kotlin.parcelize.serializers.ParcelizeExtensionBase
2929
abstract class ParcelizeIrTransformerBase(
3030
protected val context: IrPluginContext,
3131
protected val androidSymbols: AndroidSymbols,
32-
protected val parcelizeAnnotations: List<FqName>
32+
protected val parcelizeAnnotations: List<FqName>,
3333
) : ParcelizeExtensionBase, IrElementVisitorVoid {
3434
private val irFactory: IrFactory = IrFactoryImpl
3535

3636
protected val deferredOperations = mutableListOf<() -> Unit>()
3737
protected fun defer(block: () -> Unit) = deferredOperations.add(block)
3838

39-
protected fun IrSimpleFunction.generateDescribeContentsBody(parcelableProperties: List<ParcelableProperty?>) {
40-
val flags = if (parcelableProperties.any { it != null && it.field.type.containsFileDescriptors }) 1 else 0
39+
protected fun IrSimpleFunction.generateDescribeContentsBody(parcelableProperties: List<ParcelableProperty>) {
40+
val flags = if (parcelableProperties.any { it.field.type.containsFileDescriptors }) 1 else 0
4141
body = context.createIrBuilder(symbol).run {
4242
irExprBody(irInt(flags))
4343
}
@@ -46,10 +46,10 @@ abstract class ParcelizeIrTransformerBase(
4646
protected fun IrSimpleFunction.generateWriteToParcelBody(
4747
irClass: IrClass,
4848
parcelerObject: IrClass?,
49-
parcelableProperties: List<ParcelableProperty?>,
49+
parcelableProperties: List<ParcelableProperty>,
5050
receiverParameter: IrValueParameter,
5151
parcelParameter: IrValueParameter,
52-
flagsParameter: IrValueParameter
52+
flagsParameter: IrValueParameter,
5353
) {
5454
body = androidSymbols.createBuilder(symbol).run {
5555
irBlockBody {
@@ -59,14 +59,12 @@ abstract class ParcelizeIrTransformerBase(
5959

6060
parcelableProperties.isNotEmpty() ->
6161
for (property in parcelableProperties) {
62-
if (property != null) {
63-
+writeParcelWith(
64-
property.parceler,
65-
parcelParameter,
66-
flagsParameter,
67-
irGetField(irGet(receiverParameter), property.field)
68-
)
69-
}
62+
+writeParcelWith(
63+
property.parceler,
64+
parcelParameter,
65+
flagsParameter,
66+
irGetField(irGet(receiverParameter), property.field)
67+
)
7068
}
7169

7270
else ->
@@ -81,7 +79,7 @@ abstract class ParcelizeIrTransformerBase(
8179
}
8280
}
8381

84-
protected fun generateCreator(declaration: IrClass, parcelerObject: IrClass?, parcelableProperties: List<ParcelableProperty?>) {
82+
protected fun generateCreator(declaration: IrClass, parcelerObject: IrClass?, parcelableProperties: List<ParcelableProperty>) {
8583
// Since the `CREATOR` object cannot refer to the type parameters of the parcelable class we use a star projected type
8684
val declarationType = declaration.symbol.starProjectedType
8785
val creatorType = androidSymbols.androidOsParcelableCreator.typeWith(declarationType)
@@ -139,10 +137,8 @@ abstract class ParcelizeIrTransformerBase(
139137

140138
parcelableProperties.isNotEmpty() ->
141139
irCall(declaration.primaryConstructor!!).apply {
142-
for ((index, property) in parcelableProperties.withIndex()) {
143-
if (property != null) {
144-
putValueArgument(index, readParcelWith(property.parceler, parcelParameter))
145-
}
140+
for (property in parcelableProperties) {
141+
putValueArgument(property.index, readParcelWith(property.parceler, parcelParameter))
146142
}
147143
}
148144

@@ -171,19 +167,19 @@ abstract class ParcelizeIrTransformerBase(
171167
serializerFactory.get(defaultType, parcelizeType = defaultType, strict = true, toplevel = true, scope = getParcelerScope())
172168
}
173169

174-
protected class ParcelableProperty(val field: IrField, parcelerThunk: () -> IrParcelSerializer) {
170+
protected class ParcelableProperty(val field: IrField, val index: Int, parcelerThunk: () -> IrParcelSerializer) {
175171
val parceler by lazy(parcelerThunk)
176172
}
177173

178174
private val serializerFactory = IrParcelSerializerFactory(androidSymbols, parcelizeAnnotations)
179175

180-
protected val IrClass.parcelableProperties: List<ParcelableProperty?>
176+
protected val IrClass.parcelableProperties: List<ParcelableProperty>
181177
get() {
182178
if (kind != ClassKind.CLASS) return emptyList()
183179

184180
val constructor = primaryConstructor ?: return emptyList()
185181
val topLevelScope = getParcelerScope()
186-
return constructor.valueParameters.map { parameter ->
182+
return constructor.valueParameters.mapIndexedNotNull { index, parameter ->
187183
val property = properties.firstOrNull { it.name == parameter.name }
188184
if (property == null || property.hasAnyAnnotation(IGNORED_ON_PARCEL_FQ_NAMES)) {
189185
null
@@ -193,7 +189,7 @@ abstract class ParcelizeIrTransformerBase(
193189
if (backingField == null) {
194190
null
195191
} else {
196-
ParcelableProperty(backingField) {
192+
ParcelableProperty(backingField, index) {
197193
serializerFactory.get(parameter.type, parcelizeType = defaultType, scope = localScope)
198194
}
199195
}

plugins/parcelize/parcelize-compiler/testData/box/ignoredOnParcel.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,23 +29,34 @@ object B : Parcelable {
2929
val x: T = T(2)
3030
}
3131

32+
@Parcelize
33+
class C(
34+
@IgnoredOnParcel
35+
val x: String = "default"
36+
): Parcelable
37+
3238
fun box() = parcelTest { parcel ->
3339
val a1 = A("X", "i1", T(0), "d")
40+
val c1 = C("X")
3441

3542
a1.writeToParcel(parcel, 0)
3643
B.writeToParcel(parcel, 0)
44+
c1.writeToParcel(parcel, 0)
3745

3846
val bytes = parcel.marshall()
3947
parcel.unmarshall(bytes, 0, bytes.size)
4048
parcel.setDataPosition(0)
4149

4250
val a2 = parcelableCreator<A>().createFromParcel(parcel)
4351
val b = parcelableCreator<B>().createFromParcel(parcel)
52+
val c2 = parcelableCreator<C>().createFromParcel(parcel)
4453

4554
assert(a1.x == a2.x)
55+
println(a2.i1)
4656
assert(a2.i1 == "default")
4757
assert(a2.i2.value == 10)
4858
assert(a1.d == a2.d)
4959
assert(a1.a == a2.a)
5060
assert(b == B)
61+
assert(c2.x == "default")
5162
}

0 commit comments

Comments
 (0)