From 1339410852d6da9c14875a8bd3cec84bd827ae17 Mon Sep 17 00:00:00 2001 From: Sonya Valchuk Date: Wed, 27 Nov 2024 11:27:02 +0000 Subject: [PATCH] [Parcelize] Use the new IR parameter API ^KT-73366 Fixed --- .../kotlin/parcelize/AndroidIrBuilder.kt | 30 ++--- .../kotlin/parcelize/AndroidSymbols.kt | 5 +- .../parcelize/IrParcelSerializerFactory.kt | 32 ++--- .../kotlin/parcelize/IrParcelSerializers.kt | 124 ++++++++---------- .../parcelize/ParcelizeFirIrTransformer.kt | 3 +- .../parcelize/ParcelizeIrTransformerBase.kt | 28 ++-- .../org/jetbrains/kotlin/parcelize/irUtils.kt | 35 +++-- 7 files changed, 113 insertions(+), 144 deletions(-) diff --git a/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/AndroidIrBuilder.kt b/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/AndroidIrBuilder.kt index 41227059fed4d..857824c8b027c 100644 --- a/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/AndroidIrBuilder.kt +++ b/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/AndroidIrBuilder.kt @@ -28,50 +28,50 @@ class AndroidIrBuilder internal constructor( fun parcelReadParcelable(receiver: IrExpression, loader: IrExpression): IrExpression { return irCall(androidSymbols.parcelReadParcelable).apply { - dispatchReceiver = receiver - putValueArgument(0, loader) + arguments[0] = receiver + arguments[1] = loader } } fun parcelReadString(receiver: IrExpression): IrExpression { return irCall(androidSymbols.parcelReadString).apply { - dispatchReceiver = receiver + arguments[0] = receiver } } fun parcelWriteInt(receiver: IrExpression, value: IrExpression): IrExpression { return irCall(androidSymbols.parcelWriteInt).apply { - dispatchReceiver = receiver - putValueArgument(0, value) + arguments[0] = receiver + arguments[1] = value } } fun parcelWriteParcelable(receiver: IrExpression, p: IrExpression, parcelableFlags: IrExpression): IrExpression { return irCall(androidSymbols.parcelWriteParcelable).apply { - dispatchReceiver = receiver - putValueArgument(0, p) - putValueArgument(1, parcelableFlags) + arguments[0] = receiver + arguments[1] = p + arguments[2] = parcelableFlags } } fun parcelWriteString(receiver: IrExpression, value: IrExpression): IrExpression { return irCall(androidSymbols.parcelWriteString).apply { - dispatchReceiver = receiver - putValueArgument(0, value) + arguments[0] = receiver + arguments[1] = value } } fun textUtilsWriteToParcel(cs: IrExpression, p: IrExpression, parcelableFlags: IrExpression): IrExpression { return irCall(androidSymbols.textUtilsWriteToParcel).apply { - putValueArgument(0, cs) - putValueArgument(1, p) - putValueArgument(2, parcelableFlags) + arguments[0] = cs + arguments[1] = p + arguments[2] = parcelableFlags } } fun classGetClassLoader(receiver: IrExpression): IrExpression { return irCall(androidSymbols.classGetClassLoader).apply { - dispatchReceiver = receiver + arguments[0] = receiver } } @@ -83,7 +83,7 @@ class AndroidIrBuilder internal constructor( return IrCallImpl.fromSymbolOwner(UNDEFINED_OFFSET, UNDEFINED_OFFSET, toType, androidSymbols.unsafeCoerceIntrinsic).apply { putTypeArgument(0, fromType) putTypeArgument(1, toType) - putValueArgument(0, value) + arguments[0] = value } } } diff --git a/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/AndroidSymbols.kt b/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/AndroidSymbols.kt index 7992df8791f7e..39640bbe755e6 100644 --- a/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/AndroidSymbols.kt +++ b/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/AndroidSymbols.kt @@ -521,10 +521,7 @@ class AndroidSymbols( ): IrSimpleFunctionSymbol { val callableId = CallableId(kotlinxCollectionsImmutable, Name.identifier(functionName)) return pluginContext.referenceFunctions(callableId) - .firstOrNull { - it.owner.extensionReceiverParameter?.type?.classFqName == receiver && - it.owner.valueParameters.isEmpty() - } + .firstOrNull { it.owner.parameters.singleOrNull()?.type?.classFqName == receiver } ?: error("Function from kotlinx.collections.immutable is not found on classpath: $callableId") } diff --git a/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/IrParcelSerializerFactory.kt b/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/IrParcelSerializerFactory.kt index 3d986f7864c2b..8a52aa7420d24 100644 --- a/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/IrParcelSerializerFactory.kt +++ b/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/IrParcelSerializerFactory.kt @@ -252,14 +252,10 @@ class IrParcelSerializerFactory(private val symbols: AndroidSymbols, private val val listSerializer = IrListParcelSerializer(classifier, elementType, getChild(elementType)) val actualSerializer = when (classifierFqName) { - in BuiltinParcelableTypes.IMMUTABLE_LIST_FQNAMES -> IrExtensionFunctionOnReadCallingSerializer( - delegated = listSerializer, - converterExtensionFunction = symbols.kotlinIterableToPersistentListExtension - ) - in BuiltinParcelableTypes.IMMUTABLE_SET_FQNAMES -> IrExtensionFunctionOnReadCallingSerializer( - delegated = listSerializer, - converterExtensionFunction = symbols.kotlinIterableToPersistentSetExtension - ) + in BuiltinParcelableTypes.IMMUTABLE_LIST_FQNAMES -> + listSerializer.withDeserializationPostprocessing(symbols.kotlinIterableToPersistentListExtension) + in BuiltinParcelableTypes.IMMUTABLE_SET_FQNAMES -> + listSerializer.withDeserializationPostprocessing(symbols.kotlinIterableToPersistentSetExtension) else -> listSerializer } @@ -276,14 +272,10 @@ class IrParcelSerializerFactory(private val symbols: AndroidSymbols, private val IrMapParcelSerializer(classifier, keyType, valueType, getChild(keyType), getChild(valueType)) val actualSerializer = - if (classifierFqName in BuiltinParcelableTypes.IMMUTABLE_MAP_FQNAMES) { - IrExtensionFunctionOnReadCallingSerializer( - mapSerializer, - symbols.kotlinMapToPersistentMapExtension - ) - } else { + if (classifierFqName in BuiltinParcelableTypes.IMMUTABLE_MAP_FQNAMES) + mapSerializer.withDeserializationPostprocessing(symbols.kotlinMapToPersistentMapExtension) + else mapSerializer - } return wrapNullableSerializerIfNeeded(irType, actualSerializer) } } @@ -358,19 +350,13 @@ class IrParcelSerializerFactory(private val symbols: AndroidSymbols, private val private val stringArraySerializer = IrSimpleParcelSerializer(symbols.parcelCreateStringArray, symbols.parcelWriteStringArray) private val stringListSerializer = IrSimpleParcelSerializer(symbols.parcelCreateStringArrayList, symbols.parcelWriteStringList) private val stringPersistentListSerializer by lazy { - IrExtensionFunctionOnReadCallingSerializer( - delegated = stringListSerializer, - converterExtensionFunction = symbols.kotlinIterableToPersistentListExtension, - ) + stringListSerializer.withDeserializationPostprocessing(symbols.kotlinIterableToPersistentListExtension) } private val iBinderSerializer = IrSimpleParcelSerializer(symbols.parcelReadStrongBinder, symbols.parcelWriteStrongBinder) private val iBinderArraySerializer = IrSimpleParcelSerializer(symbols.parcelCreateBinderArray, symbols.parcelWriteBinderArray) private val iBinderListSerializer = IrSimpleParcelSerializer(symbols.parcelCreateBinderArrayList, symbols.parcelWriteBinderList) private val iBinderPersistentListSerializer by lazy { - IrExtensionFunctionOnReadCallingSerializer( - delegated = iBinderListSerializer, - converterExtensionFunction = symbols.kotlinIterableToPersistentListExtension, - ) + iBinderListSerializer.withDeserializationPostprocessing(symbols.kotlinIterableToPersistentListExtension) } private val serializableSerializer = IrSimpleParcelSerializer(symbols.parcelReadSerializable, symbols.parcelWriteSerializable) private val stringSerializer = IrSimpleParcelSerializer(symbols.parcelReadString, symbols.parcelWriteString) diff --git a/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/IrParcelSerializers.kt b/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/IrParcelSerializers.kt index e7d3d5b0619ec..3dd1d61af1692 100644 --- a/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/IrParcelSerializers.kt +++ b/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/IrParcelSerializers.kt @@ -37,31 +37,25 @@ fun AndroidIrBuilder.writeParcelWith( return with(serializer) { writeParcel(parcel, flags, value) } } -class IrExtensionFunctionOnReadCallingSerializer( - private val delegated: IrParcelSerializer, - private val converterExtensionFunction: IrSimpleFunctionSymbol -) : IrParcelSerializer by delegated { - override fun AndroidIrBuilder.readParcel(parcel: IrValueDeclaration): IrExpression { - val delegatedResult = with(delegated) { - readParcel(parcel) - } - return irCall(converterExtensionFunction).apply { - extensionReceiver = delegatedResult +fun IrParcelSerializer.withDeserializationPostprocessing(mapper: IrSimpleFunctionSymbol): IrParcelSerializer = + object : IrParcelSerializer by this { + override fun AndroidIrBuilder.readParcel(parcel: IrValueDeclaration): IrExpression { + val readResult = with(this@withDeserializationPostprocessing) { readParcel(parcel) } + return irCall(mapper).apply { arguments[0] = readResult } } } -} // Creates a serializer from a pair of parcel methods of the form reader()T and writer(T)V. class IrSimpleParcelSerializer(private val reader: IrSimpleFunctionSymbol, private val writer: IrSimpleFunctionSymbol) : IrParcelSerializer { override fun AndroidIrBuilder.readParcel(parcel: IrValueDeclaration): IrExpression { - return irCall(reader).apply { dispatchReceiver = irGet(parcel) } + return irCall(reader).apply { arguments[0] = irGet(parcel) } } override fun AndroidIrBuilder.writeParcel(parcel: IrValueDeclaration, flags: IrValueDeclaration, value: IrExpression): IrExpression { return irCall(writer).apply { - dispatchReceiver = irGet(parcel) - putValueArgument(0, value) + arguments[0] = irGet(parcel) + arguments[1] = value } } } @@ -171,21 +165,19 @@ class IrNoParameterClassParcelSerializer(private val irClass: IrClass) : IrParce class IrEnumParcelSerializer(enumClass: IrClass) : IrParcelSerializer { override fun AndroidIrBuilder.readParcel(parcel: IrValueDeclaration): IrExpression { return irCall(enumValueOf).apply { - putValueArgument(0, parcelReadString(irGet(parcel))) + arguments[0] = parcelReadString(irGet(parcel)) } } override fun AndroidIrBuilder.writeParcel(parcel: IrValueDeclaration, flags: IrValueDeclaration, value: IrExpression): IrExpression { return parcelWriteString(irGet(parcel), irCall(enumName).apply { - dispatchReceiver = value + arguments[0] = value }) } private val enumValueOf: IrFunctionSymbol = enumClass.functions.single { function -> - function.name.asString() == "valueOf" && function.dispatchReceiverParameter == null - && function.extensionReceiverParameter == null && function.valueParameters.size == 1 - && function.valueParameters.single().type.isString() + function.name.asString() == "valueOf" && function.parameters.singleOrNull()?.type?.isString() == true }.symbol private val enumName: IrFunctionSymbol = enumClass.getPropertyGetter("name")!! @@ -233,7 +225,7 @@ class IrDataClassParcelSerializer( override fun AndroidIrBuilder.readParcel(parcel: IrValueDeclaration): IrExpression = irCall(type.classOrFail.owner.primaryConstructor!!.symbol, type).apply { properties.forEachIndexed { index, (_, serializer) -> - putValueArgument(index, readParcelWith(serializer, parcel)) + arguments[index] = readParcelWith(serializer, parcel) } } @@ -259,15 +251,15 @@ class IrParcelSerializerWithClassLoader( ) : IrParcelSerializer { override fun AndroidIrBuilder.readParcel(parcel: IrValueDeclaration): IrExpression { return irCall(reader).apply { - dispatchReceiver = irGet(parcel) - putValueArgument(0, classGetClassLoader(javaClassReference(parcelizeType))) + arguments[0] = irGet(parcel) + arguments[1] = classGetClassLoader(javaClassReference(parcelizeType)) } } override fun AndroidIrBuilder.writeParcel(parcel: IrValueDeclaration, flags: IrValueDeclaration, value: IrExpression): IrExpression { return irCall(writer).apply { - dispatchReceiver = irGet(parcel) - putValueArgument(0, value) + arguments[0] = irGet(parcel) + arguments[1] = value } } } @@ -294,13 +286,13 @@ class IrArrayParcelSerializer( val arrayConstructor: IrFunctionSymbol = if (arrayType.isBoxedArray) { context.irBuiltIns.arrayOfNulls } else { - arrayType.classOrNull!!.constructors.single { it.owner.valueParameters.size == 1 } + arrayType.classOrNull!!.constructors.single { it.owner.parameters.size == 1 } } return irCall(arrayConstructor, arrayType).apply { if (typeArgumentsCount != 0) putTypeArgument(0, elementType) - putValueArgument(0, size) + arguments[0] = size } } @@ -311,9 +303,9 @@ class IrArrayParcelSerializer( forUntil(irGet(arraySize)) { index -> val setter = arrayType.classOrNull!!.getSimpleFunction("set")!! +irCall(setter).apply { - dispatchReceiver = irGet(arrayTemporary) - putValueArgument(0, irGet(index)) - putValueArgument(1, readParcelWith(elementSerializer, parcel)) + arguments[0] = irGet(arrayTemporary) + arguments[1] = irGet(index) + arguments[2] = readParcelWith(elementSerializer, parcel) } } +irGet(arrayTemporary) @@ -333,8 +325,8 @@ class IrArrayParcelSerializer( forUntil(irGet(arraySize)) { index -> val getter = context.irBuiltIns.arrayClass.getSimpleFunction("get")!! val element = irCall(getter, elementType).apply { - dispatchReceiver = irGet(arrayTemporary) - putValueArgument(0, irGet(index)) + arguments[0] = irGet(arrayTemporary) + arguments[1] = irGet(index) } +writeParcelWith(elementSerializer, parcel, flags, element) } @@ -353,7 +345,7 @@ class IrSparseArrayParcelSerializer( val remainingSizeTemporary = irTemporary(parcelReadInt(irGet(parcel)), isMutable = true) val sparseArrayConstructor = sparseArrayClass.constructors.first { irConstructor -> - irConstructor.valueParameters.size == 1 && irConstructor.valueParameters.single().type.isInt() + irConstructor.parameters.singleOrNull()?.type?.isInt() == true } val constructorCall = if (sparseArrayClass.typeParameters.isEmpty()) @@ -362,24 +354,24 @@ class IrSparseArrayParcelSerializer( irCallConstructor(sparseArrayConstructor.symbol, listOf(elementType)) val arrayTemporary = irTemporary(constructorCall.apply { - putValueArgument(0, irGet(remainingSizeTemporary)) + arguments[0] = irGet(remainingSizeTemporary) }) +irWhile().apply { condition = irNotEquals(irGet(remainingSizeTemporary), irInt(0)) body = irBlock { val sparseArrayPut = sparseArrayClass.functions.first { function -> - function.name.asString() == "put" && function.valueParameters.size == 2 + function.name.asString() == "put" && function.parameters.size == 3 } +irCall(sparseArrayPut).apply { - dispatchReceiver = irGet(arrayTemporary) - putValueArgument(0, parcelReadInt(irGet(parcel))) - putValueArgument(1, readParcelWith(elementSerializer, parcel)) + arguments[0] = irGet(arrayTemporary) + arguments[1] = parcelReadInt(irGet(parcel)) + arguments[2] = readParcelWith(elementSerializer, parcel) } val dec = context.irBuiltIns.intClass.getSimpleFunction("dec")!! +irSet(remainingSizeTemporary.symbol, irCall(dec).apply { - dispatchReceiver = irGet(remainingSizeTemporary) + arguments[0] = irGet(remainingSizeTemporary) }) } } @@ -391,31 +383,31 @@ class IrSparseArrayParcelSerializer( override fun AndroidIrBuilder.writeParcel(parcel: IrValueDeclaration, flags: IrValueDeclaration, value: IrExpression): IrExpression { return irBlock { val sizeFunction = sparseArrayClass.functions.first { function -> - function.name.asString() == "size" && function.valueParameters.isEmpty() + function.name.asString() == "size" && function.parameters.size == 1 } val keyAtFunction = sparseArrayClass.functions.first { function -> - function.name.asString() == "keyAt" && function.valueParameters.size == 1 + function.name.asString() == "keyAt" && function.parameters.size == 2 } val valueAtFunction = sparseArrayClass.functions.first { function -> - function.name.asString() == "valueAt" && function.valueParameters.size == 1 + function.name.asString() == "valueAt" && function.parameters.size == 2 } val arrayTemporary = irTemporary(value) val sizeTemporary = irTemporary(irCall(sizeFunction).apply { - dispatchReceiver = irGet(arrayTemporary) + arguments[0] = irGet(arrayTemporary) }) +parcelWriteInt(irGet(parcel), irGet(sizeTemporary)) forUntil(irGet(sizeTemporary)) { index -> +parcelWriteInt(irGet(parcel), irCall(keyAtFunction).apply { - dispatchReceiver = irGet(arrayTemporary) - putValueArgument(0, irGet(index)) + arguments[0] = irGet(arrayTemporary) + arguments[1] = irGet(index) }) +writeParcelWith(elementSerializer, parcel, flags, irCall(valueAtFunction.symbol, elementType).apply { - dispatchReceiver = irGet(arrayTemporary) - putValueArgument(0, irGet(index)) + arguments[0] = irGet(arrayTemporary) + arguments[1] = irGet(index) }) } } @@ -439,15 +431,15 @@ class IrListParcelSerializer( return irBlock { val list = irTemporary(value) +parcelWriteInt(irGet(parcel), irCall(sizeFunction).apply { - dispatchReceiver = irGet(list) + arguments[0] = irGet(list) }) val iterator = irTemporary(irCall(iteratorFunction).apply { - dispatchReceiver = irGet(list) + arguments[0] = irGet(list) }) +irWhile().apply { condition = irCall(iteratorHasNext).apply { dispatchReceiver = irGet(iterator) } body = writeParcelWith(elementSerializer, parcel, flags, irCall(iteratorNext.symbol, elementType).apply { - dispatchReceiver = irGet(iterator) + arguments[0] = irGet(iterator) }) } } @@ -463,11 +455,11 @@ class IrListParcelSerializer( // the default constructor if none exist. if (!irClass.isJvmInterface) { val constructor = irClass.constructors.find { constructor -> - constructor.valueParameters.size == 1 && constructor.valueParameters.single().type.isInt() - } ?: irClass.constructors.first { constructor -> constructor.valueParameters.isEmpty() } + constructor.parameters.singleOrNull()?.type?.isInt() == true + } ?: irClass.constructors.first { constructor -> constructor.parameters.isEmpty() } val add = irClass.functions.first { function -> - function.name.asString() == "add" && function.valueParameters.size == 1 + function.name.asString() == "add" && function.parameters.size == 2 } return ListSymbols( @@ -504,13 +496,13 @@ class IrListParcelSerializer( val (constructorSymbol, addSymbol) = listSymbols(androidSymbols) val sizeTemporary = irTemporary(parcelReadInt(irGet(parcel))) val list = irTemporary(irCall(constructorSymbol).apply { - if (constructorSymbol.owner.valueParameters.isNotEmpty()) - putValueArgument(0, irGet(sizeTemporary)) + if (constructorSymbol.owner.parameters.isNotEmpty()) + arguments[0] = irGet(sizeTemporary) }) forUntil(irGet(sizeTemporary)) { +irCall(addSymbol).apply { - dispatchReceiver = irGet(list) - putValueArgument(0, readParcelWith(elementSerializer, parcel)) + arguments[0] = irGet(list) + arguments[1] = readParcelWith(elementSerializer, parcel) } } +irGet(list) @@ -577,13 +569,13 @@ class IrMapParcelSerializer( // the default constructor if none exist. if (!irClass.isJvmInterface) { val constructor = irClass.constructors.find { constructor -> - constructor.valueParameters.size == 1 && constructor.valueParameters.single().type.isInt() + constructor.parameters.singleOrNull()?.type?.isInt() == true } ?: irClass.constructors.find { constructor -> - constructor.valueParameters.isEmpty() + constructor.parameters.isEmpty() }!! val put = irClass.functions.first { function -> - function.name.asString() == "put" && function.valueParameters.size == 2 + function.name.asString() == "put" && function.parameters.size == 3 } return MapSymbols( @@ -614,14 +606,14 @@ class IrMapParcelSerializer( val (constructorSymbol, putSymbol) = mapSymbols(androidSymbols) val sizeTemporary = irTemporary(parcelReadInt(irGet(parcel))) val map = irTemporary(irCall(constructorSymbol).apply { - if (constructorSymbol.owner.valueParameters.isNotEmpty()) - putValueArgument(0, irGet(sizeTemporary)) + if (constructorSymbol.owner.parameters.isNotEmpty()) + arguments[0] = irGet(sizeTemporary) }) forUntil(irGet(sizeTemporary)) { +irCall(putSymbol).apply { - dispatchReceiver = irGet(map) - putValueArgument(0, readParcelWith(keySerializer, parcel)) - putValueArgument(1, readParcelWith(valueSerializer, parcel)) + arguments[0] = irGet(map) + arguments[1] = readParcelWith(keySerializer, parcel) + arguments[2] = readParcelWith(valueSerializer, parcel) } } +irGet(map) @@ -652,8 +644,8 @@ class IrRangeParcelSerializer( val constructorSymbol = irClass.primaryConstructor!!.symbol return irBlock { +irCall(constructorSymbol).apply { - putValueArgument(0, readParcelWith(underlyingTypeSerializer, parcel)) - putValueArgument(1, readParcelWith(underlyingTypeSerializer, parcel)) + arguments[0] = readParcelWith(underlyingTypeSerializer, parcel) + arguments[1] = readParcelWith(underlyingTypeSerializer, parcel) } } } diff --git a/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/ParcelizeFirIrTransformer.kt b/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/ParcelizeFirIrTransformer.kt index f4432196d3d37..371127f33d394 100644 --- a/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/ParcelizeFirIrTransformer.kt +++ b/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/ParcelizeFirIrTransformer.kt @@ -102,8 +102,7 @@ class ParcelizeFirIrTransformer( } ParcelizeSyntheticComponent.ComponentKind.WRITE_TO_PARCEL.methodName -> { function.apply { - val receiverParameter = dispatchReceiverParameter!! - val (parcelParameter, flagsParameter) = function.valueParameters + val (receiverParameter, parcelParameter, flagsParameter) = function.parameters // We need to defer the construction of the writer, since it may refer to the [writeToParcel] methods in other // @Parcelize classes in the current module, which might not be constructed yet at this point. diff --git a/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/ParcelizeIrTransformerBase.kt b/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/ParcelizeIrTransformerBase.kt index 63d174c21a60d..2bc63b1504f76 100644 --- a/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/ParcelizeIrTransformerBase.kt +++ b/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/ParcelizeIrTransformerBase.kt @@ -80,10 +80,10 @@ abstract class ParcelizeIrTransformerBase( } else -> { +irCall(writeToParcel).apply { - dispatchReceiver = irGet(receiverParameter) superQualifierSymbol = irClass.superClass?.symbol - putValueArgument(0, irGet(parcelParameter)) - putValueArgument(1, irGet(flagsParameter)) + arguments[0] = irGet(receiverParameter) + arguments[1] = irGet(parcelParameter) + arguments[2] = irGet(flagsParameter) } } } @@ -170,7 +170,7 @@ abstract class ParcelizeIrTransformerBase( parcelerNewArray(parcelerObject, sizeParameter) ?: irCall(context.irBuiltIns.arrayOfNulls, arrayType).apply { putTypeArgument(0, arrayType) - putValueArgument(0, irGet(sizeParameter)) + arguments[0] = irGet(sizeParameter) } ) } @@ -191,22 +191,20 @@ abstract class ParcelizeIrTransformerBase( parcelerCreate(parcelerObject, parcelParameter) // just to handle empty parcel case, we need some arguments other than marker to use the constructor - experimentalCodeGeneration && inheritanceConstructor != null && inheritanceConstructor.valueParameters.size > 1 -> { + experimentalCodeGeneration && inheritanceConstructor != null && inheritanceConstructor.parameters.size > 1 -> { val constructorArguments = declaration.inheritanceConstructorArguments() irCall(inheritanceConstructor).apply { constructorArguments.forEachIndexed { index, property -> - putValueArgument(index, readParcelWith(property.parceler, parcelParameter)) + arguments[index] = readParcelWith(property.parceler, parcelParameter) } - putValueArgument( - constructorArguments.size, irGetObject(androidSymbols.directInitializerMarker) - ) + arguments[constructorArguments.size] = irGetObject(androidSymbols.directInitializerMarker) } } parcelableProperties.isNotEmpty() -> irCall(declaration.primaryConstructor!!).apply { for (property in parcelableProperties) { - putValueArgument(property.index, readParcelWith(property.parceler, parcelParameter)) + arguments[property.index] = readParcelWith(property.parceler, parcelParameter) } } @@ -247,7 +245,7 @@ abstract class ParcelizeIrTransformerBase( val constructor = primaryConstructor ?: return emptyList() val topLevelScope = getParcelerScope() - return constructor.valueParameters.mapIndexedNotNull { index, parameter -> + return constructor.parameters.mapIndexedNotNull { index, parameter -> val property = properties.firstOrNull { it.name == parameter.name } if (property == null || property.hasAnyAnnotation(IGNORED_ON_PARCEL_FQ_NAMES)) { return@mapIndexedNotNull null @@ -306,9 +304,9 @@ abstract class ParcelizeIrTransformerBase( if (superClassConstructor != null) { +irDelegatingConstructorCall(superClassConstructor).apply { for (index in superCallArguments.indices) { - putValueArgument(index, irGet(constructor.valueParameters[index])) + arguments[index] = irGet(constructor.parameters[index]) } - putValueArgument(superCallArguments.size, irGet(constructor.valueParameters[markerValueArgumentIndex])) + arguments[superCallArguments.size] = irGet(constructor.parameters[markerValueArgumentIndex]) } } else { val constructorToCall = superClass.primaryConstructor ?: superClass.defaultConstructor @@ -316,13 +314,13 @@ abstract class ParcelizeIrTransformerBase( require(constructorToCall.isPrimary || superCallArguments.isEmpty()) +irDelegatingConstructorCall(constructorToCall).apply { for (i in superCallArguments.indices) { - putValueArgument(i, irGet(constructor.valueParameters[i])) + arguments[i] = irGet(constructor.parameters[i]) } } } parcelableProperties.forEachIndexed { index, property -> +irSetField( - irGet(irClass.thisReceiver!!), property.field, irGet(constructor.valueParameters[index + superCallArguments.size]) + irGet(irClass.thisReceiver!!), property.field, irGet(constructor.parameters[index + superCallArguments.size]) ) } +IrInstanceInitializerCallImpl(startOffset, endOffset, irClass.symbol, context.irBuiltIns.unitType) diff --git a/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/irUtils.kt b/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/irUtils.kt index 7636fd82e72a0..0aafc9082a177 100644 --- a/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/irUtils.kt +++ b/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/irUtils.kt @@ -57,17 +57,17 @@ fun IrBuilderWithScope.parcelerWrite( flags: IrValueDeclaration, value: IrExpression, ) = irCall(parceler.parcelerSymbolByName("write")!!).apply { - dispatchReceiver = irGetObject(parceler.symbol) - extensionReceiver = value - putValueArgument(0, irGet(parcel)) - putValueArgument(1, irGet(flags)) + arguments[0] = irGetObject(parceler.symbol) + arguments[1] = value + arguments[2] = irGet(parcel) + arguments[3] = irGet(flags) } // object P : Parceler { fun create(parcel: Parcel): T } fun IrBuilderWithScope.parcelerCreate(parceler: IrClass, parcel: IrValueDeclaration): IrExpression = irCall(parceler.parcelerSymbolByName("create")!!).apply { - dispatchReceiver = irGetObject(parceler.symbol) - putValueArgument(0, irGet(parcel)) + arguments[0] = irGetObject(parceler.symbol) + arguments[1] = irGet(parcel) } // object P: Parceler { fun newArray(size: Int): Array } @@ -78,8 +78,8 @@ fun IrBuilderWithScope.parcelerNewArray(parceler: IrClass?, size: IrValueDeclara !it.owner.isFakeOverride || it.owner.resolveFakeOverride()?.parentClassOrNull?.fqNameWhenAvailable != PARCELER_FQN }?.let { newArraySymbol -> irCall(newArraySymbol).apply { - dispatchReceiver = irGetObject(parceler.symbol) - putValueArgument(0, irGet(size)) + arguments[0] = irGetObject(parceler.symbol) + arguments[1] = irGet(size) } } @@ -95,9 +95,9 @@ fun IrBuilderWithScope.parcelableWriteToParcel( } return irCall(writeToParcel).apply { - dispatchReceiver = parcelable - putValueArgument(0, parcel) - putValueArgument(1, flags) + arguments[0] = parcelable + arguments[1] = parcel + arguments[2] = flags } } @@ -108,15 +108,13 @@ fun IrBuilderWithScope.parcelableCreatorCreateFromParcel(creator: IrExpression, } return irCall(createFromParcel).apply { - dispatchReceiver = creator - putValueArgument(0, parcel) + arguments[0] = creator + arguments[1] = parcel } } fun IrSimpleFunction.isParcelableCreatorIntrinsic(): Boolean = - dispatchReceiverParameter == null - && extensionReceiverParameter == null - && valueParameters.isEmpty() + parameters.isEmpty() && isInline && isTopLevelInPackage("parcelableCreator", FqName("kotlinx.parcelize")) && typeParameters.singleOrNull()?.let { @@ -178,7 +176,7 @@ private fun IrBuilderWithScope.kClassReference(classType: IrType): IrClassRefere private fun AndroidIrBuilder.kClassToJavaClass(kClassReference: IrExpression): IrCall = irGet(androidSymbols.javaLangClass.starProjectedType, null, androidSymbols.kotlinKClassJava.owner.getter!!.symbol).apply { - extensionReceiver = kClassReference + arguments[0] = kClassReference } // Produce a static reference to the java class of the given type. @@ -230,8 +228,7 @@ fun IrClass.getPropertyGetter(name: String): IrSimpleFunctionSymbol? = fun IrClass.getMethodWithoutArguments(name: String): IrSimpleFunction = functions.first { function -> - function.name.asString() == name && function.dispatchReceiverParameter != null - && function.extensionReceiverParameter == null && function.valueParameters.isEmpty() + function.name.asString() == name && function.parameters.singleOrNull()?.kind == IrParameterKind.DispatchReceiver } internal fun IrAnnotationContainer.hasAnyAnnotation(fqNames: List): Boolean {