From 714d17ac63dba2af0bcf35bbedd91039943b7f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steven=20Sch=C3=A4fer?= Date: Tue, 6 Oct 2020 11:31:01 +0200 Subject: [PATCH] Parcelize, JVM IR: Handle star projected and nullable arrays. --- .../jetbrains/kotlin/ir/types/IrTypeUtils.kt | 13 +++++++-- .../parcelize/ir/IrParcelSerializerFactory.kt | 5 +++- .../testData/box/kt41553.kt | 29 +++++++++++++++++++ .../testData/box/kt41553_2.kt | 29 +++++++++++++++++++ .../test/ParcelizeBoxTestGenerated.java | 10 +++++++ .../test/ParcelizeIrBoxTestGenerated.java | 10 +++++++ 6 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 plugins/parcelize/parcelize-compiler/testData/box/kt41553.kt create mode 100644 plugins/parcelize/parcelize-compiler/testData/box/kt41553_2.kt diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeUtils.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeUtils.kt index 03ccaa0ec6e..93e047ba5b4 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeUtils.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeUtils.kt @@ -50,9 +50,16 @@ val IrType.isBoxedArray: Boolean get() = classOrNull?.owner?.fqNameWhenAvailable == StandardNames.FqNames.array.toSafe() fun IrType.getArrayElementType(irBuiltIns: IrBuiltIns): IrType = - if (isBoxedArray) - ((this as IrSimpleType).arguments.single() as IrTypeProjection).type - else { + if (isBoxedArray) { + when (val argument = (this as IrSimpleType).arguments.singleOrNull()) { + is IrTypeProjection -> + argument.type + is IrStarProjection -> + irBuiltIns.anyNType + else -> + error("Unexpected array argument type: $argument") + } + } else { val classifier = this.classOrNull!! irBuiltIns.primitiveArrayElementTypes[classifier] ?: throw AssertionError("Primitive array expected: $classifier") diff --git a/plugins/parcelize/parcelize-compiler/src/org/jetbrains/kotlin/parcelize/ir/IrParcelSerializerFactory.kt b/plugins/parcelize/parcelize-compiler/src/org/jetbrains/kotlin/parcelize/ir/IrParcelSerializerFactory.kt index 85e6dfb0346..20db59e9fd1 100644 --- a/plugins/parcelize/parcelize-compiler/src/org/jetbrains/kotlin/parcelize/ir/IrParcelSerializerFactory.kt +++ b/plugins/parcelize/parcelize-compiler/src/org/jetbrains/kotlin/parcelize/ir/IrParcelSerializerFactory.kt @@ -119,7 +119,10 @@ class IrParcelSerializerFactory(symbols: AndroidSymbols) { val arrayType = if (classifier.defaultType.isPrimitiveArray()) classifier.defaultType else irBuiltIns.arrayClass.typeWith(elementType) - return IrArrayParcelSerializer(arrayType, elementType, get(elementType, scope, parcelizeType, strict())) + return wrapNullableSerializerIfNeeded( + irType, + IrArrayParcelSerializer(arrayType, elementType, get(elementType, scope, parcelizeType, strict())) + ) } // This will only be hit if we have a custom serializer for booleans diff --git a/plugins/parcelize/parcelize-compiler/testData/box/kt41553.kt b/plugins/parcelize/parcelize-compiler/testData/box/kt41553.kt new file mode 100644 index 00000000000..955fc5ba663 --- /dev/null +++ b/plugins/parcelize/parcelize-compiler/testData/box/kt41553.kt @@ -0,0 +1,29 @@ +// WITH_RUNTIME + +@file:JvmName("TestKt") +package test + +import kotlinx.parcelize.* +import android.os.Parcel +import android.os.Parcelable +import java.util.Arrays + +@Parcelize +data class A(val params: @RawValue Array<*>? = null): Parcelable + +fun box() = parcelTest { parcel -> + val a1 = A(arrayOf(1,2,3)) + val b1 = A() + a1.writeToParcel(parcel, 0) + b1.writeToParcel(parcel, 0) + + val bytes = parcel.marshall() + parcel.unmarshall(bytes, 0, bytes.size) + parcel.setDataPosition(0) + + val a2 = readFromParcel(parcel) + assert(a2.params != null) + assert(Arrays.equals(a1.params!!, a2.params!!)) + val b2 = readFromParcel(parcel) + assert(b1 == b2) +} diff --git a/plugins/parcelize/parcelize-compiler/testData/box/kt41553_2.kt b/plugins/parcelize/parcelize-compiler/testData/box/kt41553_2.kt new file mode 100644 index 00000000000..b1abaddf833 --- /dev/null +++ b/plugins/parcelize/parcelize-compiler/testData/box/kt41553_2.kt @@ -0,0 +1,29 @@ +// WITH_RUNTIME + +@file:JvmName("TestKt") +package test + +import kotlinx.parcelize.* +import android.os.Parcel +import android.os.Parcelable +import java.util.Arrays + +@Parcelize +data class A(val params: Array? = null): Parcelable + +fun box() = parcelTest { parcel -> + val a1 = A(arrayOf(1,2,3)) + val b1 = A() + a1.writeToParcel(parcel, 0) + b1.writeToParcel(parcel, 0) + + val bytes = parcel.marshall() + parcel.unmarshall(bytes, 0, bytes.size) + parcel.setDataPosition(0) + + val a2 = readFromParcel(parcel) + assert(a2.params != null) + assert(Arrays.equals(a1.params!!, a2.params!!)) + val b2 = readFromParcel(parcel) + assert(b1 == b2) +} diff --git a/plugins/parcelize/parcelize-compiler/tests/org/jetbrains/kotlin/parcelize/test/ParcelizeBoxTestGenerated.java b/plugins/parcelize/parcelize-compiler/tests/org/jetbrains/kotlin/parcelize/test/ParcelizeBoxTestGenerated.java index ba536a97711..fec50b63271 100644 --- a/plugins/parcelize/parcelize-compiler/tests/org/jetbrains/kotlin/parcelize/test/ParcelizeBoxTestGenerated.java +++ b/plugins/parcelize/parcelize-compiler/tests/org/jetbrains/kotlin/parcelize/test/ParcelizeBoxTestGenerated.java @@ -199,6 +199,16 @@ public class ParcelizeBoxTestGenerated extends AbstractParcelizeBoxTest { runTest("plugins/parcelize/parcelize-compiler/testData/box/kt39981.kt"); } + @TestMetadata("kt41553.kt") + public void testKt41553() throws Exception { + runTest("plugins/parcelize/parcelize-compiler/testData/box/kt41553.kt"); + } + + @TestMetadata("kt41553_2.kt") + public void testKt41553_2() throws Exception { + runTest("plugins/parcelize/parcelize-compiler/testData/box/kt41553_2.kt"); + } + @TestMetadata("listKinds.kt") public void testListKinds() throws Exception { runTest("plugins/parcelize/parcelize-compiler/testData/box/listKinds.kt"); diff --git a/plugins/parcelize/parcelize-compiler/tests/org/jetbrains/kotlin/parcelize/test/ParcelizeIrBoxTestGenerated.java b/plugins/parcelize/parcelize-compiler/tests/org/jetbrains/kotlin/parcelize/test/ParcelizeIrBoxTestGenerated.java index 01f5a4e5b6c..ecde6ffbbc7 100644 --- a/plugins/parcelize/parcelize-compiler/tests/org/jetbrains/kotlin/parcelize/test/ParcelizeIrBoxTestGenerated.java +++ b/plugins/parcelize/parcelize-compiler/tests/org/jetbrains/kotlin/parcelize/test/ParcelizeIrBoxTestGenerated.java @@ -199,6 +199,16 @@ public class ParcelizeIrBoxTestGenerated extends AbstractParcelizeIrBoxTest { runTest("plugins/parcelize/parcelize-compiler/testData/box/kt39981.kt"); } + @TestMetadata("kt41553.kt") + public void testKt41553() throws Exception { + runTest("plugins/parcelize/parcelize-compiler/testData/box/kt41553.kt"); + } + + @TestMetadata("kt41553_2.kt") + public void testKt41553_2() throws Exception { + runTest("plugins/parcelize/parcelize-compiler/testData/box/kt41553_2.kt"); + } + @TestMetadata("listKinds.kt") public void testListKinds() throws Exception { runTest("plugins/parcelize/parcelize-compiler/testData/box/listKinds.kt");