[FIR] add support for varargs in delegated constructor calls
Also add support for spread operators as named arguments.
This commit is contained in:
committed by
Dmitriy Novozhilov
parent
3652ac9354
commit
858731cac8
@@ -258,7 +258,9 @@ class Fir2IrVisitor(
|
||||
varargArgumentsExpression.varargElementType.toIrType(),
|
||||
varargArgumentsExpression.arguments.map { arg ->
|
||||
convertToIrExpression(arg).run {
|
||||
if (arg is FirSpreadArgumentExpression) IrSpreadElementImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, this)
|
||||
if (arg is FirSpreadArgumentExpression || arg is FirNamedArgumentExpression && arg.isSpread) {
|
||||
IrSpreadElementImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, this)
|
||||
}
|
||||
else this
|
||||
}
|
||||
})
|
||||
|
||||
+30
-27
@@ -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))
|
||||
}
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
open class SomeClass(val some: Double, val other: Int, vararg val args: String) {
|
||||
fun result() = args[1]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// !LANGUAGE: +NewInference +MixedNamedArgumentsInTheirOwnPosition
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
fun foo1(
|
||||
vararg p1: Int,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// See also KT-6299
|
||||
public open class Outer private constructor(val s: String, vararg i: Int) {
|
||||
class Inner: Outer("xyz")
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
fun join(x: Array<out String>): String {
|
||||
var result = ""
|
||||
for (i in x) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
fun booleanVararg(vararg xs: Boolean) {
|
||||
if (xs.size != 1 && xs[0] != true) throw AssertionError()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
fun box(): String {
|
||||
if (test1() != "") return "fail 1"
|
||||
if (test1(1) != "1") return "fail 2"
|
||||
|
||||
Reference in New Issue
Block a user