FIR: introduce & resolve spread named arguments #KT-31575 Fixed

This commit is contained in:
Mikhail Glukhikh
2019-05-24 23:48:36 +03:00
parent 806d2d628c
commit 2db8409d85
18 changed files with 117 additions and 47 deletions
@@ -83,7 +83,7 @@ abstract class AbstractAnnotationDeserializer(
val parameter = parameterByName[name] ?: return@mapNotNull null
val value = resolveValue(parameter.returnTypeRef, it.value, nameResolver) ?: return@mapNotNull null
FirNamedArgumentExpressionImpl(
session, null, name, value
session, null, name, false, value
)
}
}
@@ -54,18 +54,7 @@ fun resolveArgumentExpression(
is FirCallableReferenceAccess -> Unit
// TODO:!
//TODO: Collection literal
is FirLambdaArgumentExpression -> resolveArgumentExpression(
csBuilder,
argument.expression,
expectedType,
expectedTypeRef,
sink,
isReceiver,
isSafeCall,
acceptLambdaAtoms,
typeProvider
)
is FirNamedArgumentExpression -> resolveArgumentExpression(
is FirWrappedArgumentExpression -> resolveArgumentExpression(
csBuilder,
argument.expression,
expectedType,
@@ -180,7 +169,7 @@ internal fun FirExpression.getExpectedType(
// if (this.isSpread || this.isArrayAssignedAsNamedArgumentInAnnotation(parameter, languageVersionSettings)) {
// parameter.type.unwrap()
// } else {
if (parameter.isVararg) {
if (parameter.isVararg && (this !is FirWrappedArgumentExpression || !isSpread)) {
parameter.returnTypeRef.coneTypeUnsafe<ConeKotlinType>().varargElementType(session)
} else {
parameter.returnTypeRef.coneTypeUnsafe()
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.fir.resolve.calls
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.FirExpression
@@ -13,8 +12,6 @@ import org.jetbrains.kotlin.fir.expressions.FirLambdaArgumentExpression
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
import org.jetbrains.kotlin.fir.expressions.FirWrappedArgumentExpression
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.types.ConeClassType
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
class FirCallArgumentsProcessor(
private val function: FirFunction,
@@ -25,7 +22,7 @@ class FirCallArgumentsProcessor(
fun process(): Result {
var currentState: State = State.PositionalOnly(function.valueParameters)
for (argument in arguments) {
if (argument is FirWrappedArgumentExpression) {
if (argument is FirNamedArgumentExpression || argument is FirLambdaArgumentExpression) {
currentState = State.PositionalThenNamed(
function.valueParameters,
currentState.argumentMap,
@@ -65,21 +62,19 @@ class FirCallArgumentsProcessor(
val currentParameter get() = valueParameters.getOrNull(currentParameterIndex)
fun nextParameter() {
val currentParameter = currentParameter ?: return
if (currentParameter.isVararg) return
usedParameters += currentParameter
currentParameterIndex++
}
override fun processArgument(argument: FirExpression): MappingStatus {
require(argument !is FirNamedArgumentExpression) {
"Positional-only argument processor state should not receiver ${argument.render()}"
"Positional-only argument processor state should not receive ${argument.render()}"
}
val currentParameter = currentParameter ?: return MappingStatus.ERROR
argumentMap[argument] = currentParameter
nextParameter()
if (!currentParameter.isVararg ||
argument is FirWrappedArgumentExpression && argument.isSpread
) {
usedParameters += currentParameter
currentParameterIndex++
}
return MappingStatus.SUCCESS
}
@@ -1166,17 +1166,10 @@ private object ReplaceInArguments : FirTransformer<Map<FirElement, FirElement>>(
return (functionCall.transformChildren(this, data) as FirStatement).compose()
}
override fun transformNamedArgumentExpression(
namedArgumentExpression: FirNamedArgumentExpression,
override fun transformWrappedArgumentExpression(
wrappedArgumentExpression: FirWrappedArgumentExpression,
data: Map<FirElement, FirElement>
): CompositeTransformResult<FirStatement> {
return (namedArgumentExpression.transformChildren(this, data) as FirStatement).compose()
}
override fun transformLambdaArgumentExpression(
lambdaArgumentExpression: FirLambdaArgumentExpression,
data: Map<FirElement, FirElement>
): CompositeTransformResult<FirStatement> {
return (lambdaArgumentExpression.transformChildren(this, data) as FirStatement).compose()
return (wrappedArgumentExpression.transformChildren(this, data) as FirStatement).compose()
}
}
@@ -5,6 +5,7 @@ fun test() {
foo(1)
foo(1, "")
foo(1, "my", "yours")
foo(1, *arrayOf("my", "yours"))
foo("")
foo(1, 2)
+2 -1
View File
@@ -7,9 +7,10 @@ FILE: vararg.kt
R|/foo|(Int(1))
R|/foo|(Int(1), String())
R|/foo|(Int(1), String(my), String(yours))
R|/foo|(Int(1), *R|kotlin/arrayOf|<R|kotlin/String|>(String(my), String(yours)))
<Inapplicable(INAPPLICABLE): [/foo]>#(String())
<Inapplicable(INAPPLICABLE): [/foo]>#(Int(1), Int(2))
R|/bar|(Int(1), z = Boolean(true), y = R|kotlin/arrayOf|<R|TypeVariable(T)|>(String(my), String(yours)))
R|/bar|(Int(1), z = Boolean(true), y = *R|kotlin/arrayOf|<R|kotlin/String|>(String(my), String(yours)))
<Inapplicable(PARAMETER_MAPPING_ERROR): [/bar]>#(Int(0), z = Boolean(false), y = String(), y = String(other))
<Inapplicable(PARAMETER_MAPPING_ERROR): [/bar]>#(Int(0), String(), Boolean(true))
}