[FIR2IR] Support argument reordering of constructor calls
This commit is contained in:
committed by
Mikhail Glukhikh
parent
bae41ddf6d
commit
e954aea4cc
+52
-35
@@ -305,31 +305,11 @@ internal class CallAndReferenceGenerator(
|
||||
val function =
|
||||
((call.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirFunctionSymbol<*>)?.fir
|
||||
val valueParameters = function?.valueParameters
|
||||
|
||||
if (valueParameters != null) {
|
||||
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@applyCallArguments)
|
||||
}
|
||||
} else {
|
||||
for ((argument, parameter) in argumentMapping) {
|
||||
val argumentExpression = visitor.convertToIrExpression(argument)
|
||||
putValueArgument(valueParameters.indexOf(parameter), argumentExpression)
|
||||
}
|
||||
return this
|
||||
}
|
||||
return applyArgumentsWithReordering(
|
||||
argumentMapping, valueParameters, visitor, conversionScope, declarationStorage
|
||||
)
|
||||
}
|
||||
}
|
||||
for ((index, argument) in call.arguments.withIndex()) {
|
||||
@@ -358,17 +338,6 @@ internal class CallAndReferenceGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
private fun needArgumentReordering(parametersInActualOrder: Collection<FirValueParameter>, valueParameters: List<FirValueParameter>): 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) {
|
||||
@@ -499,3 +468,51 @@ internal class CallAndReferenceGenerator(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun IrCallWithIndexedArgumentsBase.applyArgumentsWithReordering(
|
||||
argumentMapping: Map<FirExpression, FirValueParameter>,
|
||||
valueParameters: List<FirValueParameter>,
|
||||
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<FirValueParameter>,
|
||||
valueParameters: List<FirValueParameter>
|
||||
): Boolean {
|
||||
var lastValueParameterIndex = -1
|
||||
for (parameter in parametersInActualOrder) {
|
||||
val index = valueParameters.indexOf(parameter)
|
||||
if (index < lastValueParameterIndex) {
|
||||
return true
|
||||
}
|
||||
lastValueParameterIndex = index
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
+17
-4
@@ -12,6 +12,7 @@ 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
|
||||
@@ -238,10 +239,22 @@ internal class ClassMemberGenerator(
|
||||
constructedIrType,
|
||||
irConstructorSymbol
|
||||
)
|
||||
}.apply {
|
||||
for ((index, argument) in arguments.withIndex()) {
|
||||
val argumentExpression = visitor.convertToIrExpression(argument)
|
||||
putValueArgument(index, argumentExpression)
|
||||
}.let {
|
||||
val argumentMapping = mutableMapOf<FirExpression, FirValueParameter>()
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user