Parcelable: Allow custom describeContents() implementation

This commit is contained in:
Yan Zhulanow
2017-06-29 18:57:11 +03:00
parent 4197380621
commit 96c9bcd820
6 changed files with 69 additions and 3 deletions
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.android.parcel
import kotlinx.android.parcel.MagicParcel
import org.jetbrains.kotlin.android.parcel.ParcelableSyntheticComponent.ComponentKind.*
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
@@ -78,7 +79,7 @@ class ParcelableResolveExtension : SyntheticResolveExtension {
fromSupertypes: List<SimpleFunctionDescriptor>,
result: MutableCollection<SimpleFunctionDescriptor>
) {
if (name.asString() == DESCRIBE_CONTENTS.methodName && clazz.isMagicParcelable) {
if (name.asString() == DESCRIBE_CONTENTS.methodName && clazz.isMagicParcelable && result.none { it.isDescribeContents() }) {
result += createMethod(clazz, DESCRIBE_CONTENTS, clazz.builtIns.intType)
} else if (name.asString() == WRITE_TO_PARCEL.methodName && clazz.isMagicParcelable) {
val builtIns = clazz.builtIns
@@ -86,6 +87,10 @@ class ParcelableResolveExtension : SyntheticResolveExtension {
result += createMethod(clazz, WRITE_TO_PARCEL, builtIns.unitType, "parcel" to parcelClassType, "flags" to builtIns.intType)
}
}
private fun SimpleFunctionDescriptor.isDescribeContents(): Boolean {
return typeParameters.isEmpty() && valueParameters.isEmpty() && returnType?.let { type -> KotlinBuiltIns.isInt(type) } == true
}
}
interface ParcelableSyntheticComponent {
@@ -0,0 +1,9 @@
// CURIOUS_ABOUT describeContents
import kotlinx.android.parcel.*
import android.os.Parcelable
@MagicParcel
class User(val firstName: String, val lastName: String, val age: Int, val isProUser: Boolean) : Parcelable {
override fun describeContents() = 100
}
@@ -0,0 +1,41 @@
public static class User$CREATOR : java/lang/Object, android/os/Parcelable$Creator {
public void <init>()
public final User createFromParcel(android.os.Parcel p0)
public final User[] newArray(int p0)
}
public final class User : java/lang/Object, android/os/Parcelable {
public final static User$CREATOR CREATOR
private final int age
private final java.lang.String firstName
private final boolean isProUser
private final java.lang.String lastName
static void <clinit>()
public void <init>(java.lang.String p0, java.lang.String p1, int p2, boolean p3)
public int describeContents() {
LABEL (L0)
LINENUMBER (8)
BIPUSH (100)
IRETURN
LABEL (L1)
}
public final int getAge()
public final java.lang.String getFirstName()
public final java.lang.String getLastName()
public final boolean isProUser()
public final void writeToParcel(android.os.Parcel p0, int p1)
}
@@ -1,4 +1,4 @@
// CURIOUS_ABOUT writeToParcel, createFromParcel, <clinit>
// CURIOUS_ABOUT writeToParcel, createFromParcel, <clinit>, describeContents
import kotlinx.android.parcel.*
import android.os.Parcelable
@@ -45,7 +45,12 @@ public final class User : java/lang/Object, android/os/Parcelable {
public void <init>(java.lang.String p0, java.lang.String p1, int p2, boolean p3)
public final int describeContents()
public final int describeContents() {
LABEL (L0)
LDC (0)
IRETURN
LABEL (L1)
}
public final int getAge()
@@ -36,6 +36,12 @@ public class ParcelBytecodeListingTestGenerated extends AbstractParcelBytecodeLi
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("plugins/android-extensions/android-extensions-compiler/testData/parcel/codegen"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("customDescribeContents.kt")
public void testCustomDescribeContents() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("plugins/android-extensions/android-extensions-compiler/testData/parcel/codegen/customDescribeContents.kt");
doTest(fileName);
}
@TestMetadata("listInsideList.kt")
public void testListInsideList() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("plugins/android-extensions/android-extensions-compiler/testData/parcel/codegen/listInsideList.kt");