Parcelable: Migrate to canonical NEW-DUP-INVOKESPECIAL form (KT-20545)
This commit is contained in:
+1
-10
@@ -75,11 +75,6 @@ class UninitializedStoresProcessor(
|
|||||||
private val methodNode: MethodNode,
|
private val methodNode: MethodNode,
|
||||||
private val shouldPreserveClassInitialization: Boolean
|
private val shouldPreserveClassInitialization: Boolean
|
||||||
) {
|
) {
|
||||||
companion object {
|
|
||||||
val AVOID_UNINITIALIZED_OBJECT_COPYING_CHECK_ANNOTATION_DESCRIPTOR =
|
|
||||||
"Lkotlin/internal/annotations/AvoidUninitializedObjectCopyingCheck;"
|
|
||||||
}
|
|
||||||
|
|
||||||
// <init> method is "special", because it will invoke <init> from this class or from a base class for #0
|
// <init> method is "special", because it will invoke <init> from this class or from a base class for #0
|
||||||
//
|
//
|
||||||
// <clinit> method is "special", because <clinit> for singleton objects is generated as:
|
// <clinit> method is "special", because <clinit> for singleton objects is generated as:
|
||||||
@@ -88,11 +83,7 @@ class UninitializedStoresProcessor(
|
|||||||
// and the newly created value is dropped.
|
// and the newly created value is dropped.
|
||||||
private val isInSpecialMethod = methodNode.name == "<init>" || methodNode.name == "<clinit>"
|
private val isInSpecialMethod = methodNode.name == "<init>" || methodNode.name == "<clinit>"
|
||||||
|
|
||||||
private val shouldCheckUninitializedObjectCopy = !methodNode.invisibleAnnotations.orEmpty()
|
|
||||||
.any { it.desc == AVOID_UNINITIALIZED_OBJECT_COPYING_CHECK_ANNOTATION_DESCRIPTOR }
|
|
||||||
|
|
||||||
fun run() {
|
fun run() {
|
||||||
if (!shouldCheckUninitializedObjectCopy) return
|
|
||||||
val interpreter = UninitializedNewValueMarkerInterpreter(methodNode.instructions)
|
val interpreter = UninitializedNewValueMarkerInterpreter(methodNode.instructions)
|
||||||
|
|
||||||
val frames = CustomFramesMethodAnalyzer(
|
val frames = CustomFramesMethodAnalyzer(
|
||||||
@@ -183,7 +174,7 @@ class UninitializedStoresProcessor(
|
|||||||
assert(insn.opcode == Opcodes.INVOKESPECIAL) { "Expected opcode Opcodes.INVOKESPECIAL for <init>, but ${insn.opcode} found" }
|
assert(insn.opcode == Opcodes.INVOKESPECIAL) { "Expected opcode Opcodes.INVOKESPECIAL for <init>, but ${insn.opcode} found" }
|
||||||
val paramsCountIncludingReceiver = Type.getArgumentTypes((insn as MethodInsnNode).desc).size + 1
|
val paramsCountIncludingReceiver = Type.getArgumentTypes((insn as MethodInsnNode).desc).size + 1
|
||||||
val newValue = peek(paramsCountIncludingReceiver) as? UninitializedNewValue ?:
|
val newValue = peek(paramsCountIncludingReceiver) as? UninitializedNewValue ?:
|
||||||
if (isInSpecialMethod || !shouldCheckUninitializedObjectCopy)
|
if (isInSpecialMethod)
|
||||||
return null
|
return null
|
||||||
else
|
else
|
||||||
error("Expected value generated with NEW")
|
error("Expected value generated with NEW")
|
||||||
|
|||||||
+23
-17
@@ -18,36 +18,34 @@ package org.jetbrains.kotlin.android.parcel
|
|||||||
|
|
||||||
import kotlinx.android.parcel.TypeParceler
|
import kotlinx.android.parcel.TypeParceler
|
||||||
import org.jetbrains.kotlin.android.parcel.ParcelableResolveExtension.Companion.createMethod
|
import org.jetbrains.kotlin.android.parcel.ParcelableResolveExtension.Companion.createMethod
|
||||||
|
import org.jetbrains.kotlin.android.parcel.serializers.*
|
||||||
import org.jetbrains.kotlin.android.parcel.ParcelableSyntheticComponent.ComponentKind.*
|
import org.jetbrains.kotlin.android.parcel.ParcelableSyntheticComponent.ComponentKind.*
|
||||||
import org.jetbrains.kotlin.android.parcel.serializers.PARCEL_TYPE
|
|
||||||
import org.jetbrains.kotlin.android.parcel.serializers.ParcelSerializer
|
|
||||||
import org.jetbrains.kotlin.android.parcel.serializers.TypeParcelerMapping
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.codegen.*
|
||||||
|
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.FunctionGenerationStrategy.CodegenBased
|
import org.jetbrains.kotlin.codegen.FunctionGenerationStrategy.CodegenBased
|
||||||
import org.jetbrains.kotlin.codegen.ImplementationBodyCodegen
|
import org.jetbrains.kotlin.codegen.ImplementationBodyCodegen
|
||||||
import org.jetbrains.kotlin.codegen.OwnerKind
|
import org.jetbrains.kotlin.codegen.OwnerKind
|
||||||
import org.jetbrains.kotlin.codegen.context.ClassContext
|
import org.jetbrains.kotlin.codegen.context.ClassContext
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.UninitializedStoresProcessor
|
|
||||||
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
|
|
||||||
import org.jetbrains.kotlin.codegen.writeSyntheticClassMetadata
|
import org.jetbrains.kotlin.codegen.writeSyntheticClassMetadata
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
@@ -104,8 +102,6 @@ open class ParcelableCodegenExtension : ExpressionCodegenExtension {
|
|||||||
val containerAsmType = codegen.typeMapper.mapType(this.defaultType)
|
val containerAsmType = codegen.typeMapper.mapType(this.defaultType)
|
||||||
|
|
||||||
return findFunction(WRITE_TO_PARCEL)?.write(codegen) {
|
return findFunction(WRITE_TO_PARCEL)?.write(codegen) {
|
||||||
v.visitAnnotation(UninitializedStoresProcessor.AVOID_UNINITIALIZED_OBJECT_COPYING_CHECK_ANNOTATION_DESCRIPTOR, false)
|
|
||||||
|
|
||||||
if (parcelerObject != null) {
|
if (parcelerObject != null) {
|
||||||
val (companionAsmType, companionFieldName) = getCompanionClassType(containerAsmType, parcelerObject)
|
val (companionAsmType, companionFieldName) = getCompanionClassType(containerAsmType, parcelerObject)
|
||||||
|
|
||||||
@@ -117,7 +113,13 @@ open class ParcelableCodegenExtension : ExpressionCodegenExtension {
|
|||||||
"(${containerAsmType.descriptor}${PARCEL_TYPE.descriptor}I)V", false)
|
"(${containerAsmType.descriptor}${PARCEL_TYPE.descriptor}I)V", false)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val globalContext = ParcelSerializer.ParcelSerializerContext(codegen.typeMapper, containerAsmType, emptyList())
|
val frameMap = FrameMap().apply {
|
||||||
|
enterTemp(containerAsmType)
|
||||||
|
enterTemp(PARCEL_TYPE)
|
||||||
|
enterTemp(Type.INT_TYPE)
|
||||||
|
}
|
||||||
|
|
||||||
|
val globalContext = ParcelSerializer.ParcelSerializerContext(codegen.typeMapper, containerAsmType, emptyList(), frameMap)
|
||||||
|
|
||||||
for ((fieldName, type, parcelers) in properties) {
|
for ((fieldName, type, parcelers) in properties) {
|
||||||
val asmType = codegen.typeMapper.mapType(type)
|
val asmType = codegen.typeMapper.mapType(type)
|
||||||
@@ -188,10 +190,9 @@ open class ParcelableCodegenExtension : ExpressionCodegenExtension {
|
|||||||
properties: List<PropertyToSerialize>
|
properties: List<PropertyToSerialize>
|
||||||
) {
|
) {
|
||||||
val containerAsmType = codegen.typeMapper.mapType(parcelableClass)
|
val containerAsmType = codegen.typeMapper.mapType(parcelableClass)
|
||||||
|
val creatorAsmType = codegen.typeMapper.mapType(creatorClass)
|
||||||
|
|
||||||
createMethod(creatorClass, CREATE_FROM_PARCEL, parcelableClass.builtIns.anyType, "in" to parcelClassType).write(codegen) {
|
createMethod(creatorClass, CREATE_FROM_PARCEL, parcelableClass.builtIns.anyType, "in" to parcelClassType).write(codegen) {
|
||||||
v.visitAnnotation(UninitializedStoresProcessor.AVOID_UNINITIALIZED_OBJECT_COPYING_CHECK_ANNOTATION_DESCRIPTOR, false)
|
|
||||||
|
|
||||||
if (parcelerObject != null) {
|
if (parcelerObject != null) {
|
||||||
val (companionAsmType, companionFieldName) = getCompanionClassType(containerAsmType, parcelerObject)
|
val (companionAsmType, companionFieldName) = getCompanionClassType(containerAsmType, parcelerObject)
|
||||||
|
|
||||||
@@ -204,7 +205,12 @@ open class ParcelableCodegenExtension : ExpressionCodegenExtension {
|
|||||||
v.dup()
|
v.dup()
|
||||||
|
|
||||||
val asmConstructorParameters = StringBuilder()
|
val asmConstructorParameters = StringBuilder()
|
||||||
val globalContext = ParcelSerializer.ParcelSerializerContext(codegen.typeMapper, containerAsmType, emptyList())
|
val frameMap = FrameMap().apply {
|
||||||
|
enterTemp(creatorAsmType)
|
||||||
|
enterTemp(PARCEL_TYPE)
|
||||||
|
}
|
||||||
|
|
||||||
|
val globalContext = ParcelSerializer.ParcelSerializerContext(codegen.typeMapper, containerAsmType, emptyList(), frameMap)
|
||||||
|
|
||||||
for ((_, type, parcelers) in properties) {
|
for ((_, type, parcelers) in properties) {
|
||||||
val asmType = codegen.typeMapper.mapType(type)
|
val asmType = codegen.typeMapper.mapType(type)
|
||||||
|
|||||||
+7
-1
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.android.parcel.serializers.isParcelable
|
|||||||
import org.jetbrains.kotlin.android.synthetic.diagnostic.DefaultErrorMessagesAndroid
|
import org.jetbrains.kotlin.android.synthetic.diagnostic.DefaultErrorMessagesAndroid
|
||||||
import org.jetbrains.kotlin.android.synthetic.diagnostic.ErrorsAndroid
|
import org.jetbrains.kotlin.android.synthetic.diagnostic.ErrorsAndroid
|
||||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
||||||
|
import org.jetbrains.kotlin.codegen.FrameMap
|
||||||
import org.jetbrains.kotlin.codegen.state.IncompatibleClassTracker
|
import org.jetbrains.kotlin.codegen.state.IncompatibleClassTracker
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
@@ -214,7 +215,12 @@ class ParcelableDeclarationChecker : SimpleDeclarationChecker {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
val parcelers = getTypeParcelers(descriptor.annotations) + getTypeParcelers(containerClass.annotations)
|
val parcelers = getTypeParcelers(descriptor.annotations) + getTypeParcelers(containerClass.annotations)
|
||||||
val context = ParcelSerializer.ParcelSerializerContext(typeMapper, typeMapper.mapType(containerClass.defaultType), parcelers)
|
val context = ParcelSerializer.ParcelSerializerContext(
|
||||||
|
typeMapper,
|
||||||
|
typeMapper.mapType(containerClass.defaultType),
|
||||||
|
parcelers,
|
||||||
|
FrameMap())
|
||||||
|
|
||||||
ParcelSerializer.get(type, asmType, context, strict = true)
|
ParcelSerializer.get(type, asmType, context, strict = true)
|
||||||
}
|
}
|
||||||
catch (e: IllegalArgumentException) {
|
catch (e: IllegalArgumentException) {
|
||||||
|
|||||||
+8
-6
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.android.parcel.serializers
|
|||||||
|
|
||||||
import kotlinx.android.parcel.WriteWith
|
import kotlinx.android.parcel.WriteWith
|
||||||
import org.jetbrains.kotlin.android.parcel.isParcelize
|
import org.jetbrains.kotlin.android.parcel.isParcelize
|
||||||
|
import org.jetbrains.kotlin.codegen.FrameMap
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
@@ -54,7 +55,8 @@ interface ParcelSerializer {
|
|||||||
data class ParcelSerializerContext(
|
data class ParcelSerializerContext(
|
||||||
val typeMapper: KotlinTypeMapper,
|
val typeMapper: KotlinTypeMapper,
|
||||||
val containerClassType: Type,
|
val containerClassType: Type,
|
||||||
val typeParcelers: List<TypeParcelerMapping>
|
val typeParcelers: List<TypeParcelerMapping>,
|
||||||
|
val frameMap: FrameMap
|
||||||
) {
|
) {
|
||||||
fun findParcelerClass(type: KotlinType): KotlinType? {
|
fun findParcelerClass(type: KotlinType): KotlinType? {
|
||||||
return typeParcelers.firstOrNull { it.first == type }?.second
|
return typeParcelers.firstOrNull { it.first == type }?.second
|
||||||
@@ -152,7 +154,7 @@ interface ParcelSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val elementSerializer = get(elementType, elementAsmType, context, forceBoxed = true, strict = strict())
|
val elementSerializer = get(elementType, elementAsmType, context, forceBoxed = true, strict = strict())
|
||||||
wrapToNullAwareIfNeeded(type, ListSetParcelSerializer(asmType, elementSerializer))
|
wrapToNullAwareIfNeeded(type, ListSetParcelSerializer(asmType, elementSerializer, context.frameMap))
|
||||||
}
|
}
|
||||||
|
|
||||||
className == Map::class.java.canonicalName
|
className == Map::class.java.canonicalName
|
||||||
@@ -168,7 +170,7 @@ interface ParcelSerializer {
|
|||||||
keyType.type, typeMapper.mapTypeSafe(keyType.type, forceBoxed = true), context, forceBoxed = true, strict = strict())
|
keyType.type, typeMapper.mapTypeSafe(keyType.type, forceBoxed = true), context, forceBoxed = true, strict = strict())
|
||||||
val valueSerializer = get(
|
val valueSerializer = get(
|
||||||
valueType.type, typeMapper.mapTypeSafe(valueType.type, forceBoxed = true), context, forceBoxed = true, strict = strict())
|
valueType.type, typeMapper.mapTypeSafe(valueType.type, forceBoxed = true), context, forceBoxed = true, strict = strict())
|
||||||
wrapToNullAwareIfNeeded(type, MapParcelSerializer(asmType, keySerializer, valueSerializer))
|
wrapToNullAwareIfNeeded(type, MapParcelSerializer(asmType, keySerializer, valueSerializer, context.frameMap))
|
||||||
}
|
}
|
||||||
|
|
||||||
asmType.isBoxedPrimitive() -> wrapToNullAwareIfNeeded(type, BoxedPrimitiveTypeParcelSerializer.forBoxedType(asmType))
|
asmType.isBoxedPrimitive() -> wrapToNullAwareIfNeeded(type, BoxedPrimitiveTypeParcelSerializer.forBoxedType(asmType))
|
||||||
@@ -206,16 +208,16 @@ interface ParcelSerializer {
|
|||||||
Method("readSparseBooleanArray"))
|
Method("readSparseBooleanArray"))
|
||||||
|
|
||||||
asmType.isSparseIntArray() -> wrapToNullAwareIfNeeded(type, SparseArrayParcelSerializer(
|
asmType.isSparseIntArray() -> wrapToNullAwareIfNeeded(type, SparseArrayParcelSerializer(
|
||||||
asmType, PrimitiveTypeParcelSerializer.getInstance(Type.INT_TYPE)))
|
asmType, PrimitiveTypeParcelSerializer.getInstance(Type.INT_TYPE), context.frameMap))
|
||||||
|
|
||||||
asmType.isSparseLongArray() -> wrapToNullAwareIfNeeded(type, SparseArrayParcelSerializer(
|
asmType.isSparseLongArray() -> wrapToNullAwareIfNeeded(type, SparseArrayParcelSerializer(
|
||||||
asmType, PrimitiveTypeParcelSerializer.getInstance(Type.LONG_TYPE)))
|
asmType, PrimitiveTypeParcelSerializer.getInstance(Type.LONG_TYPE), context.frameMap))
|
||||||
|
|
||||||
asmType.isSparseArray() -> {
|
asmType.isSparseArray() -> {
|
||||||
val elementType = type.arguments.single().type
|
val elementType = type.arguments.single().type
|
||||||
val elementSerializer = get(
|
val elementSerializer = get(
|
||||||
elementType, typeMapper.mapTypeSafe(elementType, forceBoxed = true), context, forceBoxed = true, strict = strict())
|
elementType, typeMapper.mapTypeSafe(elementType, forceBoxed = true), context, forceBoxed = true, strict = strict())
|
||||||
wrapToNullAwareIfNeeded(type, SparseArrayParcelSerializer(asmType, elementSerializer))
|
wrapToNullAwareIfNeeded(type, SparseArrayParcelSerializer(asmType, elementSerializer, context.frameMap))
|
||||||
}
|
}
|
||||||
|
|
||||||
type.isCharSequence() -> CharSequenceParcelSerializer(asmType)
|
type.isCharSequence() -> CharSequenceParcelSerializer(asmType)
|
||||||
|
|||||||
+44
-32
@@ -19,9 +19,10 @@ package org.jetbrains.kotlin.android.parcel.serializers
|
|||||||
import kotlinx.android.parcel.Parceler
|
import kotlinx.android.parcel.Parceler
|
||||||
import org.jetbrains.kotlin.android.parcel.serializers.BoxedPrimitiveTypeParcelSerializer.Companion.BOXED_VALUE_METHOD_NAMES
|
import org.jetbrains.kotlin.android.parcel.serializers.BoxedPrimitiveTypeParcelSerializer.Companion.BOXED_VALUE_METHOD_NAMES
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||||
|
import org.jetbrains.kotlin.codegen.FrameMap
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
|
import org.jetbrains.kotlin.codegen.useTmpVar
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.org.objectweb.asm.Label
|
import org.jetbrains.org.objectweb.asm.Label
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
@@ -186,8 +187,9 @@ internal fun InstructionAdapter.castIfNeeded(targetType: Type) {
|
|||||||
|
|
||||||
internal class ListSetParcelSerializer(
|
internal class ListSetParcelSerializer(
|
||||||
asmType: Type,
|
asmType: Type,
|
||||||
elementSerializer: ParcelSerializer
|
elementSerializer: ParcelSerializer,
|
||||||
) : AbstractCollectionParcelSerializer(asmType, elementSerializer) {
|
frameMap: FrameMap
|
||||||
|
) : AbstractCollectionParcelSerializer(asmType, elementSerializer, frameMap) {
|
||||||
override fun getSize(v: InstructionAdapter) {
|
override fun getSize(v: InstructionAdapter) {
|
||||||
v.invokeinterface("java/util/Collection", "size", "()I")
|
v.invokeinterface("java/util/Collection", "size", "()I")
|
||||||
}
|
}
|
||||||
@@ -216,8 +218,9 @@ internal class ListSetParcelSerializer(
|
|||||||
internal class MapParcelSerializer(
|
internal class MapParcelSerializer(
|
||||||
asmType: Type,
|
asmType: Type,
|
||||||
private val keySerializer: ParcelSerializer,
|
private val keySerializer: ParcelSerializer,
|
||||||
elementSerializer: ParcelSerializer
|
elementSerializer: ParcelSerializer,
|
||||||
) : AbstractCollectionParcelSerializer(asmType, elementSerializer) {
|
frameMap: FrameMap
|
||||||
|
) : AbstractCollectionParcelSerializer(asmType, elementSerializer, frameMap) {
|
||||||
override fun getSize(v: InstructionAdapter) {
|
override fun getSize(v: InstructionAdapter) {
|
||||||
v.invokeinterface("java/util/Map", "size", "()I")
|
v.invokeinterface("java/util/Map", "size", "()I")
|
||||||
}
|
}
|
||||||
@@ -260,7 +263,8 @@ internal class MapParcelSerializer(
|
|||||||
|
|
||||||
abstract internal class AbstractCollectionParcelSerializer(
|
abstract internal class AbstractCollectionParcelSerializer(
|
||||||
final override val asmType: Type,
|
final override val asmType: Type,
|
||||||
protected val elementSerializer: ParcelSerializer
|
protected val elementSerializer: ParcelSerializer,
|
||||||
|
private val frameMap: FrameMap
|
||||||
) : ParcelSerializer {
|
) : ParcelSerializer {
|
||||||
protected val collectionType: Type = Type.getObjectType(when (asmType.internalName) {
|
protected val collectionType: Type = Type.getObjectType(when (asmType.internalName) {
|
||||||
"java/util/List" -> "java/util/ArrayList"
|
"java/util/List" -> "java/util/ArrayList"
|
||||||
@@ -331,27 +335,27 @@ abstract internal class AbstractCollectionParcelSerializer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun readValue(v: InstructionAdapter) {
|
override fun readValue(v: InstructionAdapter) {
|
||||||
|
frameMap.useTmpVar(Type.INT_TYPE) { sizeVarIndex ->
|
||||||
|
v.invokevirtual(PARCEL_TYPE.internalName, "readInt", "()I", false) // -> size
|
||||||
|
v.store(sizeVarIndex, Type.INT_TYPE)
|
||||||
|
|
||||||
|
v.anew(collectionType) // -> list
|
||||||
|
v.dup() // -> list, list
|
||||||
|
|
||||||
|
if (hasConstructorWithCapacity) {
|
||||||
|
v.load(sizeVarIndex, Type.INT_TYPE)
|
||||||
|
v.invokespecial(collectionType.internalName, "<init>", "(I)V", false) // -> list
|
||||||
|
} else {
|
||||||
|
v.invokespecial(collectionType.internalName, "<init>", "()V", false) // -> list
|
||||||
|
}
|
||||||
|
|
||||||
|
v.load(sizeVarIndex, Type.INT_TYPE) // -> list, size
|
||||||
|
}
|
||||||
|
|
||||||
val nextLoopIteration = Label()
|
val nextLoopIteration = Label()
|
||||||
val loopIsOver = Label()
|
val loopIsOver = Label()
|
||||||
|
|
||||||
// Read list size
|
|
||||||
v.invokevirtual(PARCEL_TYPE.internalName, "readInt", "()I", false) // -> size
|
|
||||||
v.dup() // -> size, size
|
|
||||||
|
|
||||||
v.anew(collectionType) // -> size, size, list
|
|
||||||
v.dupX1() // -> size, list, size, list
|
|
||||||
v.swap() // -> size, list, list, size
|
|
||||||
|
|
||||||
if (hasConstructorWithCapacity) {
|
|
||||||
v.invokespecial(collectionType.internalName, "<init>", "(I)V", false) // -> size, list
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
v.pop() // -> size, list, list
|
|
||||||
v.invokespecial(collectionType.internalName, "<init>", "()V", false) // -> size, list
|
|
||||||
}
|
|
||||||
|
|
||||||
v.visitLabel(nextLoopIteration)
|
v.visitLabel(nextLoopIteration)
|
||||||
v.swap() // -> list, size
|
|
||||||
v.dupX1() // -> size, list, size
|
v.dupX1() // -> size, list, size
|
||||||
v.ifeq(loopIsOver) // -> size, list
|
v.ifeq(loopIsOver) // -> size, list
|
||||||
v.dup() // -> size, list, list
|
v.dup() // -> size, list, list
|
||||||
@@ -362,16 +366,19 @@ abstract internal class AbstractCollectionParcelSerializer(
|
|||||||
v.aconst(-1) // -> list, size, (-1)
|
v.aconst(-1) // -> list, size, (-1)
|
||||||
v.add(Type.INT_TYPE) // -> list, (size - 1)
|
v.add(Type.INT_TYPE) // -> list, (size - 1)
|
||||||
|
|
||||||
v.swap() // -> size, list
|
|
||||||
v.goTo(nextLoopIteration)
|
v.goTo(nextLoopIteration)
|
||||||
|
|
||||||
v.visitLabel(loopIsOver)
|
v.visitLabel(loopIsOver)
|
||||||
v.swap()
|
v.swap() // -> list, size
|
||||||
v.pop()
|
v.pop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class SparseArrayParcelSerializer(override val asmType: Type, private val valueSerializer: ParcelSerializer) : ParcelSerializer {
|
internal class SparseArrayParcelSerializer(
|
||||||
|
override val asmType: Type,
|
||||||
|
private val valueSerializer: ParcelSerializer,
|
||||||
|
private val frameMap: FrameMap
|
||||||
|
) : ParcelSerializer {
|
||||||
private val valueType = (valueSerializer as? PrimitiveTypeParcelSerializer)?.asmType ?: Type.getObjectType("java/lang/Object")
|
private val valueType = (valueSerializer as? PrimitiveTypeParcelSerializer)?.asmType ?: Type.getObjectType("java/lang/Object")
|
||||||
|
|
||||||
override fun writeValue(v: InstructionAdapter) {
|
override fun writeValue(v: InstructionAdapter) {
|
||||||
@@ -421,12 +428,17 @@ internal class SparseArrayParcelSerializer(override val asmType: Type, private v
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun readValue(v: InstructionAdapter) {
|
override fun readValue(v: InstructionAdapter) {
|
||||||
v.invokevirtual(PARCEL_TYPE.internalName, "readInt", "()I", false) // -> size
|
frameMap.useTmpVar(Type.INT_TYPE) { sizeVarIndex ->
|
||||||
v.dup() // -> size, size
|
v.invokevirtual(PARCEL_TYPE.internalName, "readInt", "()I", false) // -> size
|
||||||
v.anew(asmType) // -> size, size, arr
|
v.store(sizeVarIndex, Type.INT_TYPE) // -> (empty)
|
||||||
v.dupX2() // -> arr, size, size, arr
|
|
||||||
v.swap() // -> arr, size, arr, size
|
v.anew(asmType) // -> arr
|
||||||
v.invokespecial(asmType.internalName, "<init>", "(I)V", false) // -> arr, size
|
v.dup() // -> arr, arr
|
||||||
|
v.load(sizeVarIndex, Type.INT_TYPE) // -> arr, arr, size
|
||||||
|
v.invokespecial(asmType.internalName, "<init>", "(I)V", false) // -> arr
|
||||||
|
|
||||||
|
v.load(sizeVarIndex, Type.INT_TYPE) // -> arr, size
|
||||||
|
}
|
||||||
|
|
||||||
val nextLoopIteration = Label()
|
val nextLoopIteration = Label()
|
||||||
val loopIsOver = Label()
|
val loopIsOver = Label()
|
||||||
|
|||||||
plugins/android-extensions/android-extensions-compiler/testData/parcel/codegen/IBinderIInterface.txt
Vendored
+4
-5
@@ -18,13 +18,13 @@ public final class User$Creator : java/lang/Object, android/os/Parcelable$Creato
|
|||||||
CHECKCAST
|
CHECKCAST
|
||||||
ALOAD (1)
|
ALOAD (1)
|
||||||
INVOKEVIRTUAL (android/os/Parcel, readInt, ()I)
|
INVOKEVIRTUAL (android/os/Parcel, readInt, ()I)
|
||||||
DUP
|
ISTORE (2)
|
||||||
NEW
|
NEW
|
||||||
DUP_X1
|
DUP
|
||||||
SWAP
|
ILOAD (2)
|
||||||
INVOKESPECIAL (java/util/ArrayList, <init>, (I)V)
|
INVOKESPECIAL (java/util/ArrayList, <init>, (I)V)
|
||||||
|
ILOAD (2)
|
||||||
LABEL (L2)
|
LABEL (L2)
|
||||||
SWAP
|
|
||||||
DUP_X1
|
DUP_X1
|
||||||
IFEQ (L3)
|
IFEQ (L3)
|
||||||
DUP
|
DUP
|
||||||
@@ -35,7 +35,6 @@ public final class User$Creator : java/lang/Object, android/os/Parcelable$Creato
|
|||||||
SWAP
|
SWAP
|
||||||
LDC (-1)
|
LDC (-1)
|
||||||
IADD
|
IADD
|
||||||
SWAP
|
|
||||||
GOTO (L2)
|
GOTO (L2)
|
||||||
LABEL (L3)
|
LABEL (L3)
|
||||||
SWAP
|
SWAP
|
||||||
|
|||||||
@@ -75,8 +75,6 @@ class KaptJavaLog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun report(diagnostic: JCDiagnostic) {
|
override fun report(diagnostic: JCDiagnostic) {
|
||||||
System.err.println("Diagnostic code: ${diagnostic.code}")
|
|
||||||
|
|
||||||
if (diagnostic.type == JCDiagnostic.DiagnosticType.ERROR && diagnostic.code in IGNORED_DIAGNOSTICS) {
|
if (diagnostic.type == JCDiagnostic.DiagnosticType.ERROR && diagnostic.code in IGNORED_DIAGNOSTICS) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user