FIR2IR: allow array expression as named argument for vararg

This commit is contained in:
Jinseong Jeon
2020-08-25 01:02:47 -07:00
committed by Mikhail Glukhikh
parent 54d3c5fb0a
commit 085e0dc1de
4 changed files with 34 additions and 22 deletions
@@ -611,8 +611,11 @@ class CallAndReferenceGenerator(
}
}
for ((index, argument) in call.arguments.withIndex()) {
val valueParameter = valueParameters?.get(index)
val argumentExpression =
visitor.convertToIrExpression(argument).applySamConversionIfNeeded(argument, valueParameters?.get(index))
visitor.convertToIrExpression(argument)
.applySamConversionIfNeeded(argument, valueParameter)
.applyAssigningArrayElementsToVarargInNamedForm(argument, valueParameter)
putValueArgument(index, argumentExpression)
}
}
@@ -650,7 +653,10 @@ class CallAndReferenceGenerator(
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).applySamConversionIfNeeded(argument, parameter)
val irArgument =
visitor.convertToIrExpression(argument)
.applySamConversionIfNeeded(argument, parameter)
.applyAssigningArrayElementsToVarargInNamedForm(argument, parameter)
if (irArgument.hasNoSideEffects()) {
putValueArgument(parameterIndex, irArgument)
} else {
@@ -668,6 +674,7 @@ class CallAndReferenceGenerator(
val argumentExpression =
visitor.convertToIrExpression(argument, annotationMode)
.applySamConversionIfNeeded(argument, parameter)
.applyAssigningArrayElementsToVarargInNamedForm(argument, parameter)
putValueArgument(valueParameters.indexOf(parameter), argumentExpression)
}
if (annotationMode) {
@@ -721,6 +728,30 @@ class CallAndReferenceGenerator(
return argument.isFunctional(session)
}
private fun IrExpression.applyAssigningArrayElementsToVarargInNamedForm(
argument: FirExpression,
parameter: FirValueParameter?
): IrExpression {
// TODO: Need to refer to language feature: AllowAssigningArrayElementsToVarargsInNamedFormForFunctions
if (this !is IrVarargImpl ||
parameter?.isVararg != true ||
argument !is FirVarargArgumentsExpression ||
argument.arguments.none { it is FirNamedArgumentExpression }
) {
return this
}
elements.forEachIndexed { i, irVarargElement ->
if (irVarargElement !is IrSpreadElement &&
argument.arguments[i] is FirNamedArgumentExpression &&
irVarargElement is IrExpression &&
irVarargElement.type.isArray()
) {
elements[i] = IrSpreadElementImpl(irVarargElement.startOffset, irVarargElement.endOffset, irVarargElement)
}
}
return this
}
private fun IrExpression.applyTypeArguments(access: FirQualifiedAccess): IrExpression {
return when (this) {
is IrMemberAccessExpression<*> -> {