diff --git a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ir/ParcelableIrTransformer.kt b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ir/ParcelableIrTransformer.kt index 604209c6d14..922642e580d 100644 --- a/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ir/ParcelableIrTransformer.kt +++ b/plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ir/ParcelableIrTransformer.kt @@ -16,24 +16,19 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.declarations.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl import org.jetbrains.kotlin.ir.expressions.IrCall -import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionReference -import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl -import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.* -import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid -import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid +import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -57,40 +52,32 @@ class ParcelableIrTransformer(private val context: IrPluginContext, private val deferredOperations.forEach { it() } // Remap broken stubs, which psi2ir generates for the synthetic descriptors coming from the ParcelizeResolveExtension. - moduleFragment.transformChildrenVoid(object : IrElementTransformerVoid() { - override fun visitCall(expression: IrCall): IrExpression { - val remappedSymbol = symbolMap[expression.symbol] - ?: return super.visitCall(expression) - return IrCallImpl( - expression.startOffset, expression.endOffset, expression.type, remappedSymbol, - expression.typeArgumentsCount, expression.valueArgumentsCount, expression.origin, - expression.superQualifierSymbol - ).apply { - copyTypeAndValueArgumentsFrom(expression) - } + moduleFragment.acceptChildrenVoid(object : IrElementVisitorVoid { + override fun visitElement(element: IrElement) { + element.acceptChildren(this, null) } - override fun visitFunctionReference(expression: IrFunctionReference): IrExpression { + override fun visitCall(expression: IrCall) { + expression.acceptChildren(this, null) + expression.symbol = symbolMap[expression.symbol] ?: return + } + + override fun visitFunctionReference(expression: IrFunctionReference) { + expression.acceptChildren(this, null) val remappedSymbol = symbolMap[expression.symbol] val remappedReflectionTarget = expression.reflectionTarget?.let { symbolMap[it] } - if (remappedSymbol == null && remappedReflectionTarget == null) - return super.visitFunctionReference(expression) + if (remappedSymbol == null && remappedReflectionTarget == null) return - return IrFunctionReferenceImpl( - expression.startOffset, expression.endOffset, expression.type, remappedSymbol ?: expression.symbol, - expression.typeArgumentsCount, expression.valueArgumentsCount, remappedReflectionTarget, - expression.origin - ).apply { - copyTypeAndValueArgumentsFrom(expression) - } + expression.symbol = remappedSymbol ?: expression.symbol + expression.reflectionTarget = remappedReflectionTarget } - override fun visitSimpleFunction(declaration: IrSimpleFunction): IrStatement { + override fun visitSimpleFunction(declaration: IrSimpleFunction) { + declaration.acceptChildren(this, null) // Remap overridden symbols, otherwise the code might break in BridgeLowering declaration.overriddenSymbols = declaration.overriddenSymbols.map { symbol -> symbolMap[symbol] ?: symbol } - return super.visitSimpleFunction(declaration) } }) } diff --git a/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/ParcelizeIrTransformer.kt b/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/ParcelizeIrTransformer.kt index fbc9c027916..802d3ed88f5 100644 --- a/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/ParcelizeIrTransformer.kt +++ b/plugins/parcelize/parcelize-compiler/parcelize.backend/src/org/jetbrains/kotlin/parcelize/ParcelizeIrTransformer.kt @@ -19,12 +19,9 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionReference -import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl -import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.companionObject -import org.jetbrains.kotlin.ir.util.copyTypeAndValueArgumentsFrom import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable import org.jetbrains.kotlin.ir.util.functions import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid @@ -51,18 +48,8 @@ class ParcelizeIrTransformer( // Replace the `parcelableCreator` intrinsic with a direct field access. moduleFragment.transformChildrenVoid(object : IrElementTransformerVoid() { override fun visitCall(expression: IrCall): IrExpression { - // Handle the `parcelableCreator` intrinsic val callee = expression.symbol.owner - if ( - callee.dispatchReceiverParameter == null - && callee.extensionReceiverParameter == null - && callee.valueParameters.isEmpty() - && callee.isInline - && callee.fqNameWhenAvailable?.asString() == "kotlinx.parcelize.ParcelableCreatorKt.parcelableCreator" - && callee.typeParameters.singleOrNull()?.let { - it.isReified && it.superTypes.singleOrNull()?.classFqName == PARCELABLE_FQN - } == true - ) { + if (callee.isParcelableCreatorIntrinsic()) { expression.getTypeArgument(0)?.getClass()?.let { parcelableClass -> androidSymbols.createBuilder(expression.symbol).apply { return getParcelableCreator(parcelableClass) @@ -71,30 +58,30 @@ class ParcelizeIrTransformer( } // Remap calls to `describeContents` and `writeToParcel` - val remappedSymbol = symbolMap[expression.symbol] - ?: return super.visitCall(expression) - return IrCallImpl( - expression.startOffset, expression.endOffset, expression.type, remappedSymbol, - expression.typeArgumentsCount, expression.valueArgumentsCount, expression.origin, - expression.superQualifierSymbol - ).apply { - copyTypeAndValueArgumentsFrom(expression) - } + expression.transformChildren(this, null) + expression.symbol = symbolMap[expression.symbol] ?: return expression + return expression } + private fun IrSimpleFunction.isParcelableCreatorIntrinsic(): Boolean = + dispatchReceiverParameter == null + && extensionReceiverParameter == null + && valueParameters.isEmpty() + && isInline + && fqNameWhenAvailable?.asString() == "kotlinx.parcelize.ParcelableCreatorKt.parcelableCreator" + && typeParameters.singleOrNull()?.let { + it.isReified && it.superTypes.singleOrNull()?.classFqName == PARCELABLE_FQN + } == true + override fun visitFunctionReference(expression: IrFunctionReference): IrExpression { + expression.transformChildren(this, null) val remappedSymbol = symbolMap[expression.symbol] val remappedReflectionTarget = expression.reflectionTarget?.let { symbolMap[it] } - if (remappedSymbol == null && remappedReflectionTarget == null) - return super.visitFunctionReference(expression) + if (remappedSymbol == null && remappedReflectionTarget == null) return expression - return IrFunctionReferenceImpl( - expression.startOffset, expression.endOffset, expression.type, remappedSymbol ?: expression.symbol, - expression.typeArgumentsCount, expression.valueArgumentsCount, remappedReflectionTarget, - expression.origin - ).apply { - copyTypeAndValueArgumentsFrom(expression) - } + expression.symbol = remappedSymbol ?: expression.symbol + expression.reflectionTarget = remappedReflectionTarget + return expression } override fun visitSimpleFunction(declaration: IrSimpleFunction): IrStatement {