From 58fca659a29d92f6b9ad1cb820ed85cd56f5c8fa Mon Sep 17 00:00:00 2001 From: "Anastasia.Nekrasova" Date: Mon, 15 May 2023 18:14:37 +0300 Subject: [PATCH] [IR] Fix private methods with default parameters It is required for methods with default parameters to pass a dispatchReceiver (if the IrCall has one) as an argument, because the method generated bytecode expects it. In the case where the function has both receivers (dispatchReceiver and extensionReceiver), only the extensionReceiver should be added. Related to KTIJ-24564 --- .../backend/jvm/lower/ReflectiveAccess.kt | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/ReflectiveAccess.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/ReflectiveAccess.kt index c864d6846a4..3ededb8a50c 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/ReflectiveAccess.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/ReflectiveAccess.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.backend.jvm.ir.* import org.jetbrains.kotlin.backend.jvm.lower.SyntheticAccessorLowering.Companion.isAccessible import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.* +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.expressions.* @@ -305,22 +306,34 @@ internal class ReflectiveAccessLowering( private fun IrFunctionAccessExpression.valueParameterTypes(): List = symbol.owner.valueParameters.map { it.type } - private fun generateReflectiveMethodInvocation(call: IrCall): IrExpression = - generateReflectiveMethodInvocation( + private fun generateReflectiveMethodInvocation(call: IrCall): IrExpression { + val parameterTypes = mutableListOf() + val arguments = mutableListOf() + + when { + call.extensionReceiver != null -> { + call.symbol.owner.extensionReceiverParameter?.let { parameterTypes.add(it.type) } + call.extensionReceiver?.let { arguments.add(it) } + } + call.dispatchReceiver != null && call.symbol.owner.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER -> { + call.symbol.owner.dispatchReceiverParameter?.let { parameterTypes.add(it.type) } + call.dispatchReceiver?.let { arguments.add(it) } + } + } + + parameterTypes.addAll(call.valueParameterTypes()) + arguments.addAll(call.getValueArguments()) + + return generateReflectiveMethodInvocation( call.superQualifierSymbol?.defaultType ?: call.dispatchReceiver?.type ?: call.symbol.owner.parentAsClass.defaultType, call.symbol.owner.name.asString(), - mutableListOf().apply { - call.symbol.owner.extensionReceiverParameter?.let { add(it.type) } - addAll(call.valueParameterTypes()) - }, + parameterTypes, call.dispatchReceiver, - mutableListOf().apply { - call.extensionReceiver?.let { add(it) } - addAll(call.getValueArguments()) - }, + arguments, call.type, call.symbol ) + } private fun generateReflectiveStaticCall(call: IrCall): IrExpression { assert(call.dispatchReceiver == null) { "Assumed-to-be static call with a dispatch receiver" }