[FIR] add support for varargs in delegated constructor calls

Also add support for spread operators as named arguments.
This commit is contained in:
Juan Chen
2020-05-12 17:53:16 -07:00
committed by Dmitriy Novozhilov
parent 3652ac9354
commit 858731cac8
8 changed files with 33 additions and 34 deletions
@@ -133,34 +133,8 @@ class FirCallCompletionResultsWriterTransformer(
}
else -> {
resultType = typeRef.substituteTypeRef(subCandidate)
val argumentMapping = subCandidate.argumentMapping
val varargParameter = argumentMapping?.values?.firstOrNull { it.isVararg }
result.argumentList.transformArguments(this, subCandidate.createArgumentsMapping())
with(result.argumentList) call@{
if (varargParameter != null) {
// Create a FirVarargArgumentExpression for the vararg arguments
val varargParameterTypeRef = varargParameter.returnTypeRef
val resolvedArrayType = varargParameterTypeRef.substitute(subCandidate)
val resolvedElementType = resolvedArrayType.arrayElementType(session)
var firstIndex = this@call.arguments.size
val newArgumentMapping = mutableMapOf<FirExpression, FirValueParameter>()
val varargArgument = buildVarargArgumentsExpression {
varargElementType = varargParameterTypeRef.withReplacedConeType(resolvedElementType)
this.typeRef = varargParameterTypeRef.withReplacedConeType(resolvedArrayType)
for ((i, arg) in this@call.arguments.withIndex()) {
val valueParameter = argumentMapping[arg] ?: continue
if (valueParameter.isVararg) {
firstIndex = min(firstIndex, i)
arguments += arg
} else {
newArgumentMapping[arg] = valueParameter
}
}
}
newArgumentMapping[varargArgument] = varargParameter
subCandidate.argumentMapping = newArgumentMapping
}
}
subCandidate.handleVarargs(result.argumentList)
subCandidate.argumentMapping?.let {
result.replaceArgumentList(buildResolvedArgumentList(it))
}
@@ -180,6 +154,34 @@ class FirCallCompletionResultsWriterTransformer(
return result.compose()
}
private fun Candidate.handleVarargs(argumentList: FirArgumentList) {
val argumentMapping = this.argumentMapping
val varargParameter = argumentMapping?.values?.firstOrNull { it.isVararg }
if (varargParameter != null) {
// Create a FirVarargArgumentExpression for the vararg arguments
val varargParameterTypeRef = varargParameter.returnTypeRef
val resolvedArrayType = varargParameterTypeRef.substitute(this)
val resolvedElementType = resolvedArrayType.arrayElementType(session)
var firstIndex = argumentList.arguments.size
val newArgumentMapping = mutableMapOf<FirExpression, FirValueParameter>()
val varargArgument = buildVarargArgumentsExpression {
varargElementType = varargParameterTypeRef.withReplacedConeType(resolvedElementType)
this.typeRef = varargParameterTypeRef.withReplacedConeType(resolvedArrayType)
for ((i, arg) in argumentList.arguments.withIndex()) {
val valueParameter = argumentMapping[arg] ?: continue
if (valueParameter.isVararg) {
firstIndex = min(firstIndex, i)
arguments += arg
} else {
newArgumentMapping[arg] = valueParameter
}
}
}
newArgumentMapping[varargArgument] = varargParameter
this.argumentMapping = newArgumentMapping
}
}
private fun <D : FirExpression> D.replaceTypeRefWithSubstituted(
calleeReference: FirNamedReferenceWithCandidate,
typeRef: FirResolvedTypeRef,
@@ -291,6 +293,7 @@ class FirCallCompletionResultsWriterTransformer(
val subCandidate = calleeReference.candidate
delegatedConstructorCall.argumentList.transformArguments(this, calleeReference.candidate.createArgumentsMapping())
subCandidate.handleVarargs(delegatedConstructorCall.argumentList)
subCandidate.argumentMapping?.let {
delegatedConstructorCall.replaceArgumentList(buildResolvedArgumentList(it))
}