diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index d5479be0c6a..545af58654b 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -62,10 +62,10 @@ class Fir2IrVisitor( private val conversionScope = Fir2IrConversionScope() - private val memberGenerator = ClassMemberGenerator(components, this, conversionScope, fakeOverrideMode) - private val callGenerator = CallAndReferenceGenerator(components, this, conversionScope) + private val memberGenerator = ClassMemberGenerator(components, this, conversionScope, callGenerator, fakeOverrideMode) + private fun FirTypeRef.toIrType(): IrType = with(typeConverter) { toIrType() } private fun applyParentFromStackTo(declaration: T): T = conversionScope.applyParentFromStackTo(declaration) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt index d9501573132..b50457e4111 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.ir.types.classifierOrNull import org.jetbrains.kotlin.ir.types.makeNotNull import org.jetbrains.kotlin.psi.KtPropertyDelegate import org.jetbrains.kotlin.psi2ir.generators.hasNoSideEffects +import java.lang.IllegalArgumentException internal class CallAndReferenceGenerator( private val components: Fir2IrComponents, @@ -292,7 +293,7 @@ internal class CallAndReferenceGenerator( } } - private fun IrExpression.applyCallArguments(call: FirCall?): IrExpression { + internal fun IrExpression.applyCallArguments(call: FirCall?): IrExpression { if (call == null) return this return when (this) { is IrCallWithIndexedArgumentsBase -> { @@ -301,15 +302,16 @@ internal class CallAndReferenceGenerator( apply { val argumentMapping = call.argumentMapping if (argumentMapping != null && argumentMapping.isNotEmpty()) { - require(call is FirFunctionCall) - val function = - ((call.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirFunctionSymbol<*>)?.fir + val calleeReference = when (call) { + is FirFunctionCall -> call.calleeReference + is FirDelegatedConstructorCall -> call.calleeReference + else -> throw IllegalArgumentException("Unsupported call: ${call.render()}") + } as? FirResolvedNamedReference + val function = (calleeReference?.resolvedSymbol as? FirFunctionSymbol<*>)?.fir val valueParameters = function?.valueParameters if (valueParameters != null) { - return applyArgumentsWithReordering( - argumentMapping, valueParameters, visitor, conversionScope, declarationStorage - ) + return applyArgumentsWithReorderingIfNeeded(argumentMapping, valueParameters) } } for ((index, argument) in call.arguments.withIndex()) { @@ -338,6 +340,50 @@ internal class CallAndReferenceGenerator( } } + private fun IrCallWithIndexedArgumentsBase.applyArgumentsWithReorderingIfNeeded( + argumentMapping: Map, + valueParameters: List, + ): IrExpressionBase { + if (needArgumentReordering(argumentMapping.values, valueParameters)) { + return IrBlockImpl(startOffset, endOffset, type, IrStatementOrigin.ARGUMENTS_REORDERING_FOR_CALL).apply { + for ((argument, parameter) in argumentMapping) { + val parameterIndex = valueParameters.indexOf(parameter) + val irArgument = visitor.convertToIrExpression(argument) + if (irArgument.hasNoSideEffects()) { + putValueArgument(parameterIndex, irArgument) + } else { + val tempVar = declarationStorage.declareTemporaryVariable(irArgument, parameter.name.asString()).apply { + parent = conversionScope.parentFromStack() + } + this.statements.add(tempVar) + putValueArgument(parameterIndex, IrGetValueImpl(startOffset, endOffset, tempVar.symbol, null)) + } + } + this.statements.add(this@applyArgumentsWithReorderingIfNeeded) + } + } else { + for ((argument, parameter) in argumentMapping) { + val argumentExpression = visitor.convertToIrExpression(argument) + putValueArgument(valueParameters.indexOf(parameter), argumentExpression) + } + return this + } + } + + private fun needArgumentReordering( + parametersInActualOrder: Collection, + valueParameters: List + ): Boolean { + var lastValueParameterIndex = -1 + for (parameter in parametersInActualOrder) { + val index = valueParameters.indexOf(parameter) + if (index < lastValueParameterIndex) { + return true + } + lastValueParameterIndex = index + } + return false + } private fun IrExpression.applyTypeArguments(access: FirQualifiedAccess): IrExpression { return when (this) { @@ -469,50 +515,3 @@ internal class CallAndReferenceGenerator( } } -internal fun IrCallWithIndexedArgumentsBase.applyArgumentsWithReordering( - argumentMapping: Map, - valueParameters: List, - visitor: Fir2IrVisitor, - conversionScope: Fir2IrConversionScope, - declarationStorage: Fir2IrDeclarationStorage -): IrExpressionBase { - if (needArgumentReordering(argumentMapping.values, valueParameters)) { - return IrBlockImpl(startOffset, endOffset, type, IrStatementOrigin.ARGUMENTS_REORDERING_FOR_CALL).apply { - for ((argument, parameter) in argumentMapping) { - val parameterIndex = valueParameters.indexOf(parameter) - val irArgument = visitor.convertToIrExpression(argument) - if (irArgument.hasNoSideEffects()) { - putValueArgument(parameterIndex, irArgument) - } else { - val tempVar = declarationStorage.declareTemporaryVariable(irArgument, parameter.name.asString()).apply { - parent = conversionScope.parentFromStack() - } - this.statements.add(tempVar) - putValueArgument(parameterIndex, IrGetValueImpl(startOffset, endOffset, tempVar.symbol, null)) - } - } - this.statements.add(this@applyArgumentsWithReordering) - } - } else { - for ((argument, parameter) in argumentMapping) { - val argumentExpression = visitor.convertToIrExpression(argument) - putValueArgument(valueParameters.indexOf(parameter), argumentExpression) - } - return this - } -} - -private fun needArgumentReordering( - parametersInActualOrder: Collection, - valueParameters: List -): Boolean { - var lastValueParameterIndex = -1 - for (parameter in parametersInActualOrder) { - val index = valueParameters.indexOf(parameter) - if (index < lastValueParameterIndex) { - return true - } - lastValueParameterIndex = index - } - return false -} diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt index 44d349116f5..66d8f54f0a3 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt @@ -12,13 +12,12 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall import org.jetbrains.kotlin.fir.expressions.FirExpression -import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression -import org.jetbrains.kotlin.fir.expressions.arguments import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrConstructorCall +import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol @@ -29,6 +28,7 @@ internal class ClassMemberGenerator( private val components: Fir2IrComponents, private val visitor: Fir2IrVisitor, private val conversionScope: Fir2IrConversionScope, + private val callGenerator: CallAndReferenceGenerator, fakeOverrideMode: FakeOverrideMode ) : Fir2IrComponents by components { @@ -211,7 +211,7 @@ internal class ClassMemberGenerator( return this } - private fun FirDelegatedConstructorCall.toIrDelegatingConstructorCall(): IrExpressionBase { + private fun FirDelegatedConstructorCall.toIrDelegatingConstructorCall(): IrExpression { val constructedIrType = constructedTypeRef.toIrType() val constructorSymbol = (this.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirConstructorSymbol ?: return convertWithOffsets { startOffset, endOffset -> @@ -240,21 +240,8 @@ internal class ClassMemberGenerator( irConstructorSymbol ) }.let { - val argumentMapping = mutableMapOf() - val valueParameters = constructorSymbol.fir.valueParameters - for (argument in arguments) { - if (argument is FirNamedArgumentExpression) { - valueParameters.firstOrNull { it.name == argument.name }?.let { argumentMapping[argument] = it } - } - } - if (argumentMapping.size == valueParameters.size) { - it.applyArgumentsWithReordering(argumentMapping, valueParameters, visitor, conversionScope, declarationStorage) - } else { - for ((index, argument) in arguments.withIndex()) { - val argumentExpression = visitor.convertToIrExpression(argument) - it.putValueArgument(index, argumentExpression) - } - it + with(callGenerator) { + it.applyCallArguments(this@toIrDelegatingConstructorCall) } } } diff --git a/compiler/testData/codegen/box/defaultArguments/constructor/enumWithOneDefArg.kt b/compiler/testData/codegen/box/defaultArguments/constructor/enumWithOneDefArg.kt index d5eb390e0dd..339ab868c0d 100644 --- a/compiler/testData/codegen/box/defaultArguments/constructor/enumWithOneDefArg.kt +++ b/compiler/testData/codegen/box/defaultArguments/constructor/enumWithOneDefArg.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR enum class Foo(val a: Int = 1, val b: String) { B(2, "b"), C(b = "b") diff --git a/compiler/testData/codegen/box/defaultArguments/constructor/enumWithTwoDefArgs.kt b/compiler/testData/codegen/box/defaultArguments/constructor/enumWithTwoDefArgs.kt index 6f4bd337549..7a7d6db0814 100644 --- a/compiler/testData/codegen/box/defaultArguments/constructor/enumWithTwoDefArgs.kt +++ b/compiler/testData/codegen/box/defaultArguments/constructor/enumWithTwoDefArgs.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR enum class Foo(val a: Int = 1, val b: String = "a") { A(), B(2, "b"), diff --git a/compiler/testData/codegen/box/defaultArguments/constructor/enumWithTwoDoubleDefArgs.kt b/compiler/testData/codegen/box/defaultArguments/constructor/enumWithTwoDoubleDefArgs.kt index 44fa5df7a88..e461fd6a32e 100644 --- a/compiler/testData/codegen/box/defaultArguments/constructor/enumWithTwoDoubleDefArgs.kt +++ b/compiler/testData/codegen/box/defaultArguments/constructor/enumWithTwoDoubleDefArgs.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR enum class Foo(val a: Double = 1.0, val b: Double = 1.0) { A(), B(2.0, 2.0), diff --git a/compiler/testData/codegen/box/secondaryConstructors/callFromPrimaryWithNamedArgs.kt b/compiler/testData/codegen/box/secondaryConstructors/callFromPrimaryWithNamedArgs.kt index cd6a52613e5..30fc0208f2c 100644 --- a/compiler/testData/codegen/box/secondaryConstructors/callFromPrimaryWithNamedArgs.kt +++ b/compiler/testData/codegen/box/secondaryConstructors/callFromPrimaryWithNamedArgs.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR open class A(val result: String) { constructor(x: Int = 11, y: Int = 22, z: Int = 33) : this("$x$y$z") }