[FIR2IR] Support argument reordering of constructor calls

This commit is contained in:
Juan Chen
2020-04-10 16:05:22 -07:00
committed by Mikhail Glukhikh
parent bae41ddf6d
commit e954aea4cc
10 changed files with 94 additions and 54 deletions
@@ -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
}
@@ -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
}
}
}