Fix adaptation for references with default values after varargs

After vararg argument it's possible to pass values only by name, so
 here we modulate this behavior

 #KT-37721 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2020-06-26 05:39:10 +03:00
parent c5a2ab2512
commit c2c139ef4f
10 changed files with 92 additions and 3 deletions
@@ -292,7 +292,7 @@ class CallableReferencesCandidateFactory(
val expectedArgumentCount = inputOutputTypes.inputTypes.size - unboundReceiverCount
if (expectedArgumentCount < 0) return null
val fakeArguments = (0 until expectedArgumentCount).map { FakeKotlinCallArgumentForCallableReference(it) }
val fakeArguments = createFakeArgumentsForReference(descriptor, expectedArgumentCount, inputOutputTypes, unboundReceiverCount)
val argumentMapping =
callComponents.argumentsToParametersMapper.mapArguments(fakeArguments, externalArgument = null, descriptor = descriptor)
if (argumentMapping.diagnostics.any { !it.candidateApplicability.isSuccess }) return null
@@ -387,6 +387,36 @@ class CallableReferencesCandidateFactory(
)
}
private fun createFakeArgumentsForReference(
descriptor: FunctionDescriptor,
expectedArgumentCount: Int,
inputOutputTypes: InputOutputTypes,
unboundReceiverCount: Int
): List<FakeKotlinCallArgumentForCallableReference> {
var afterVararg = false
var varargComponentType: UnwrappedType? = null
var vararg = false
return (0 until expectedArgumentCount).map { index ->
val inputType = inputOutputTypes.inputTypes.getOrNull(index + unboundReceiverCount)
if (vararg && varargComponentType != inputType) {
afterVararg = true
}
val valueParameter = descriptor.valueParameters.getOrNull(index)
val name =
if (afterVararg && valueParameter?.declaresDefaultValue() == true)
valueParameter.name
else
null
if (valueParameter?.isVararg == true) {
varargComponentType = inputType
vararg = true
}
FakeKotlinCallArgumentForCallableReference(index, name)
}
}
private fun varargParameterTypeByExpectedParameter(
expectedParameterType: KotlinType,
substitutedParameter: ValueParameterDescriptor,
@@ -22,10 +22,11 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.prepareReceiverRegardingCap
class FakeKotlinCallArgumentForCallableReference(
val index: Int
val index: Int,
val name: Name?
) : KotlinCallArgument {
override val isSpread: Boolean get() = false
override val argumentName: Name? get() = null
override val argumentName: Name? get() = name
}
class ReceiverExpressionKotlinCallArgument private constructor(