[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.varargElementType.toIrType(),
|
||||||
varargArgumentsExpression.arguments.map { arg ->
|
varargArgumentsExpression.arguments.map { arg ->
|
||||||
convertToIrExpression(arg).run {
|
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
|
else this
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
+30
-27
@@ -133,34 +133,8 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
resultType = typeRef.substituteTypeRef(subCandidate)
|
resultType = typeRef.substituteTypeRef(subCandidate)
|
||||||
val argumentMapping = subCandidate.argumentMapping
|
|
||||||
val varargParameter = argumentMapping?.values?.firstOrNull { it.isVararg }
|
|
||||||
result.argumentList.transformArguments(this, subCandidate.createArgumentsMapping())
|
result.argumentList.transformArguments(this, subCandidate.createArgumentsMapping())
|
||||||
with(result.argumentList) call@{
|
subCandidate.handleVarargs(result.argumentList)
|
||||||
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.argumentMapping?.let {
|
subCandidate.argumentMapping?.let {
|
||||||
result.replaceArgumentList(buildResolvedArgumentList(it))
|
result.replaceArgumentList(buildResolvedArgumentList(it))
|
||||||
}
|
}
|
||||||
@@ -180,6 +154,34 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
return result.compose()
|
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(
|
private fun <D : FirExpression> D.replaceTypeRefWithSubstituted(
|
||||||
calleeReference: FirNamedReferenceWithCandidate,
|
calleeReference: FirNamedReferenceWithCandidate,
|
||||||
typeRef: FirResolvedTypeRef,
|
typeRef: FirResolvedTypeRef,
|
||||||
@@ -291,6 +293,7 @@ class FirCallCompletionResultsWriterTransformer(
|
|||||||
val subCandidate = calleeReference.candidate
|
val subCandidate = calleeReference.candidate
|
||||||
|
|
||||||
delegatedConstructorCall.argumentList.transformArguments(this, calleeReference.candidate.createArgumentsMapping())
|
delegatedConstructorCall.argumentList.transformArguments(this, calleeReference.candidate.createArgumentsMapping())
|
||||||
|
subCandidate.handleVarargs(delegatedConstructorCall.argumentList)
|
||||||
subCandidate.argumentMapping?.let {
|
subCandidate.argumentMapping?.let {
|
||||||
delegatedConstructorCall.replaceArgumentList(buildResolvedArgumentList(it))
|
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) {
|
open class SomeClass(val some: Double, val other: Int, vararg val args: String) {
|
||||||
fun result() = args[1]
|
fun result() = args[1]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// !LANGUAGE: +NewInference +MixedNamedArgumentsInTheirOwnPosition
|
// !LANGUAGE: +NewInference +MixedNamedArgumentsInTheirOwnPosition
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
|
|
||||||
fun foo1(
|
fun foo1(
|
||||||
vararg p1: Int,
|
vararg p1: Int,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// See also KT-6299
|
// See also KT-6299
|
||||||
public open class Outer private constructor(val s: String, vararg i: Int) {
|
public open class Outer private constructor(val s: String, vararg i: Int) {
|
||||||
class Inner: Outer("xyz")
|
class Inner: Outer("xyz")
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun join(x: Array<out String>): String {
|
fun join(x: Array<out String>): String {
|
||||||
var result = ""
|
var result = ""
|
||||||
for (i in x) {
|
for (i in x) {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun booleanVararg(vararg xs: Boolean) {
|
fun booleanVararg(vararg xs: Boolean) {
|
||||||
if (xs.size != 1 && xs[0] != true) throw AssertionError()
|
if (xs.size != 1 && xs[0] != true) throw AssertionError()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
if (test1() != "") return "fail 1"
|
if (test1() != "") return "fail 1"
|
||||||
if (test1(1) != "1") return "fail 2"
|
if (test1(1) != "1") return "fail 2"
|
||||||
|
|||||||
Reference in New Issue
Block a user