diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt index f98360eeb14..2e42ba90d48 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt @@ -168,7 +168,8 @@ fun IrClass.addFunction( this.origin = origin }.apply { if (!isStatic) { - dispatchReceiverParameter = parentAsClass.thisReceiver!!.copyTo(this) + val thisReceiver = parentAsClass.thisReceiver!! + dispatchReceiverParameter = thisReceiver.copyTo(this, type = thisReceiver.type) } } diff --git a/plugins/parcelize/parcelize-compiler/src/org/jetbrains/kotlin/parcelize/ParcelizeCodegenExtension.kt b/plugins/parcelize/parcelize-compiler/src/org/jetbrains/kotlin/parcelize/ParcelizeCodegenExtension.kt index 13e25be12cd..4f65535c98f 100644 --- a/plugins/parcelize/parcelize-compiler/src/org/jetbrains/kotlin/parcelize/ParcelizeCodegenExtension.kt +++ b/plugins/parcelize/parcelize-compiler/src/org/jetbrains/kotlin/parcelize/ParcelizeCodegenExtension.kt @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections import org.jetbrains.org.objectweb.asm.Opcodes.* import org.jetbrains.org.objectweb.asm.Type @@ -220,7 +221,7 @@ open class ParcelizeCodegenExtension : ParcelizeExtensionBase, ExpressionCodegen createMethod( creatorClass, CREATE_FROM_PARCEL, Modality.FINAL, - parcelableClass.defaultType, "in" to parcelClassType + parcelableClass.defaultType.replaceArgumentsWithStarProjections(), "in" to parcelClassType ).write(codegen, overriddenFunction) { if (parcelerObject != null) { val (companionAsmType, companionFieldName) = getCompanionClassType(containerAsmType, parcelerObject) @@ -368,7 +369,7 @@ open class ParcelizeCodegenExtension : ParcelizeExtensionBase, ExpressionCodegen createMethod( creatorClass, NEW_ARRAY, Modality.FINAL, - builtIns.getArrayType(Variance.INVARIANT, parcelableClass.defaultType), + builtIns.getArrayType(Variance.INVARIANT, parcelableClass.defaultType.replaceArgumentsWithStarProjections()), "size" to builtIns.intType ).write(codegen, overriddenFunction) { if (parcelerObject != null) { diff --git a/plugins/parcelize/parcelize-compiler/testData/box/generics.kt b/plugins/parcelize/parcelize-compiler/testData/box/generics.kt new file mode 100644 index 00000000000..3d9ec8fb6fe --- /dev/null +++ b/plugins/parcelize/parcelize-compiler/testData/box/generics.kt @@ -0,0 +1,27 @@ +// WITH_RUNTIME + +@file:JvmName("TestKt") +package test + +import kotlinx.parcelize.* +import android.os.Parcel +import android.os.Parcelable + +@Parcelize +data class Foo(val value: Int) : Parcelable + +@Parcelize +data class Box(val box: T) : Parcelable + +fun box() = parcelTest { parcel -> + val foo = Foo(42) + val box = Box(foo) + box.writeToParcel(parcel, 0) + + val bytes = parcel.marshall() + parcel.unmarshall(bytes, 0, bytes.size) + parcel.setDataPosition(0) + + val boxLoaded = readFromParcel>(parcel) + assert(box == boxLoaded) +} \ No newline at end of file diff --git a/plugins/parcelize/parcelize-compiler/testData/codegen/generics.ir.txt b/plugins/parcelize/parcelize-compiler/testData/codegen/generics.ir.txt new file mode 100644 index 00000000000..bad5e36bceb --- /dev/null +++ b/plugins/parcelize/parcelize-compiler/testData/codegen/generics.ir.txt @@ -0,0 +1,72 @@ +public final class Box$Creator : java/lang/Object, android/os/Parcelable$Creator { + public void () + + public final Box createFromParcel(android.os.Parcel parcel) { + LABEL (L0) + ALOAD (1) + LDC (parcel) + INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V) + NEW + DUP + ALOAD (1) + LDC (LBox;) + INVOKEVIRTUAL (java/lang/Class, getClassLoader, ()Ljava/lang/ClassLoader;) + INVOKEVIRTUAL (android/os/Parcel, readParcelable, (Ljava/lang/ClassLoader;)Landroid/os/Parcelable;) + INVOKESPECIAL (Box, , (Landroid/os/Parcelable;)V) + ARETURN + LABEL (L1) + } + + public java.lang.Object createFromParcel(android.os.Parcel source) { + LABEL (L0) + ALOAD (0) + ALOAD (1) + INVOKEVIRTUAL (Box$Creator, createFromParcel, (Landroid/os/Parcel;)LBox;) + ARETURN + LABEL (L1) + } + + public final Box[] newArray(int size) + + public java.lang.Object[] newArray(int size) +} + +public final class Box : java/lang/Object, android/os/Parcelable { + public final static android.os.Parcelable$Creator CREATOR + + private final android.os.Parcelable box + + static void () + + public void (android.os.Parcelable box) + + public final android.os.Parcelable component1() + + public final Box copy(android.os.Parcelable box) + + public static Box copy$default(Box p0, android.os.Parcelable p1, int p2, java.lang.Object p3) + + public int describeContents() + + public boolean equals(java.lang.Object other) + + public final android.os.Parcelable getBox() + + public int hashCode() + + public java.lang.String toString() + + public void writeToParcel(android.os.Parcel out, int flags) { + LABEL (L0) + ALOAD (1) + LDC (out) + INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V) + ALOAD (1) + ALOAD (0) + GETFIELD (box, Landroid/os/Parcelable;) + ILOAD (2) + INVOKEVIRTUAL (android/os/Parcel, writeParcelable, (Landroid/os/Parcelable;I)V) + RETURN + LABEL (L1) + } +} diff --git a/plugins/parcelize/parcelize-compiler/testData/codegen/generics.kt b/plugins/parcelize/parcelize-compiler/testData/codegen/generics.kt new file mode 100644 index 00000000000..f31138e1923 --- /dev/null +++ b/plugins/parcelize/parcelize-compiler/testData/codegen/generics.kt @@ -0,0 +1,8 @@ +// CURIOUS_ABOUT writeToParcel, createFromParcel +// WITH_RUNTIME + +import kotlinx.parcelize.* +import android.os.Parcelable + +@Parcelize +data class Box(val box: T) : Parcelable diff --git a/plugins/parcelize/parcelize-compiler/testData/codegen/generics.txt b/plugins/parcelize/parcelize-compiler/testData/codegen/generics.txt new file mode 100644 index 00000000000..5154afa5390 --- /dev/null +++ b/plugins/parcelize/parcelize-compiler/testData/codegen/generics.txt @@ -0,0 +1,72 @@ +public final class Box$Creator : java/lang/Object, android/os/Parcelable$Creator { + public void () + + public final Box createFromParcel(android.os.Parcel in) { + LABEL (L0) + ALOAD (1) + LDC (in) + INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V) + NEW + DUP + ALOAD (1) + LDC (LBox;) + INVOKEVIRTUAL (java/lang/Class, getClassLoader, ()Ljava/lang/ClassLoader;) + INVOKEVIRTUAL (android/os/Parcel, readParcelable, (Ljava/lang/ClassLoader;)Landroid/os/Parcelable;) + INVOKESPECIAL (Box, , (Landroid/os/Parcelable;)V) + ARETURN + LABEL (L1) + } + + public java.lang.Object createFromParcel(android.os.Parcel p0) { + LABEL (L0) + LINENUMBER (8) + ALOAD (0) + ALOAD (1) + INVOKEVIRTUAL (Box$Creator, createFromParcel, (Landroid/os/Parcel;)LBox;) + ARETURN + } + + public final Box[] newArray(int size) + + public java.lang.Object[] newArray(int p0) +} + +public final class Box : java/lang/Object, android/os/Parcelable { + public final static android.os.Parcelable$Creator CREATOR + + private final android.os.Parcelable box + + static void () + + public void (android.os.Parcelable box) + + public final android.os.Parcelable component1() + + public final Box copy(android.os.Parcelable box) + + public static Box copy$default(Box p0, android.os.Parcelable p1, int p2, java.lang.Object p3) + + public int describeContents() + + public boolean equals(java.lang.Object p0) + + public final android.os.Parcelable getBox() + + public int hashCode() + + public java.lang.String toString() + + public void writeToParcel(android.os.Parcel parcel, int flags) { + LABEL (L0) + ALOAD (1) + LDC (parcel) + INVOKESTATIC (kotlin/jvm/internal/Intrinsics, checkNotNullParameter, (Ljava/lang/Object;Ljava/lang/String;)V) + ALOAD (1) + ALOAD (0) + GETFIELD (box, Landroid/os/Parcelable;) + ILOAD (2) + INVOKEVIRTUAL (android/os/Parcel, writeParcelable, (Landroid/os/Parcelable;I)V) + RETURN + LABEL (L1) + } +} 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 4b64f286f96..d925874e8c4 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 @@ -120,6 +120,11 @@ public class ParcelizeBoxTestGenerated extends AbstractParcelizeBoxTest { runTest("plugins/parcelize/parcelize-compiler/testData/box/functions.kt"); } + @TestMetadata("generics.kt") + public void testGenerics() throws Exception { + runTest("plugins/parcelize/parcelize-compiler/testData/box/generics.kt"); + } + @TestMetadata("intArray.kt") public void testIntArray() throws Exception { runTest("plugins/parcelize/parcelize-compiler/testData/box/intArray.kt"); diff --git a/plugins/parcelize/parcelize-compiler/tests/org/jetbrains/kotlin/parcelize/test/ParcelizeBytecodeListingTestGenerated.java b/plugins/parcelize/parcelize-compiler/tests/org/jetbrains/kotlin/parcelize/test/ParcelizeBytecodeListingTestGenerated.java index 8c0a40e1c8a..b911563ed58 100644 --- a/plugins/parcelize/parcelize-compiler/tests/org/jetbrains/kotlin/parcelize/test/ParcelizeBytecodeListingTestGenerated.java +++ b/plugins/parcelize/parcelize-compiler/tests/org/jetbrains/kotlin/parcelize/test/ParcelizeBytecodeListingTestGenerated.java @@ -70,6 +70,11 @@ public class ParcelizeBytecodeListingTestGenerated extends AbstractParcelizeByte runTest("plugins/parcelize/parcelize-compiler/testData/codegen/efficientParcelable.kt"); } + @TestMetadata("generics.kt") + public void testGenerics() throws Exception { + runTest("plugins/parcelize/parcelize-compiler/testData/codegen/generics.kt"); + } + @TestMetadata("IBinderIInterface.kt") public void testIBinderIInterface() throws Exception { runTest("plugins/parcelize/parcelize-compiler/testData/codegen/IBinderIInterface.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 cf4ba8134ec..6a2385d51e8 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 @@ -120,6 +120,11 @@ public class ParcelizeIrBoxTestGenerated extends AbstractParcelizeIrBoxTest { runTest("plugins/parcelize/parcelize-compiler/testData/box/functions.kt"); } + @TestMetadata("generics.kt") + public void testGenerics() throws Exception { + runTest("plugins/parcelize/parcelize-compiler/testData/box/generics.kt"); + } + @TestMetadata("intArray.kt") public void testIntArray() throws Exception { runTest("plugins/parcelize/parcelize-compiler/testData/box/intArray.kt"); diff --git a/plugins/parcelize/parcelize-compiler/tests/org/jetbrains/kotlin/parcelize/test/ParcelizeIrBytecodeListingTestGenerated.java b/plugins/parcelize/parcelize-compiler/tests/org/jetbrains/kotlin/parcelize/test/ParcelizeIrBytecodeListingTestGenerated.java index a9b3944abc1..60ebcfeff55 100644 --- a/plugins/parcelize/parcelize-compiler/tests/org/jetbrains/kotlin/parcelize/test/ParcelizeIrBytecodeListingTestGenerated.java +++ b/plugins/parcelize/parcelize-compiler/tests/org/jetbrains/kotlin/parcelize/test/ParcelizeIrBytecodeListingTestGenerated.java @@ -70,6 +70,11 @@ public class ParcelizeIrBytecodeListingTestGenerated extends AbstractParcelizeIr runTest("plugins/parcelize/parcelize-compiler/testData/codegen/efficientParcelable.kt"); } + @TestMetadata("generics.kt") + public void testGenerics() throws Exception { + runTest("plugins/parcelize/parcelize-compiler/testData/codegen/generics.kt"); + } + @TestMetadata("IBinderIInterface.kt") public void testIBinderIInterface() throws Exception { runTest("plugins/parcelize/parcelize-compiler/testData/codegen/IBinderIInterface.kt");