Don't mark signature as inapplicable when argument is empty/incomplete

This will improve the usability when using named arguments where
incomplete arguments can't be mapped to a parameter simply by position.

^KT-24172 Fixed
This commit is contained in:
cketti
2020-09-03 19:45:32 +02:00
committed by Vladimir Dolzhenko
parent 343010a833
commit 78493395c3
7 changed files with 75 additions and 3 deletions
@@ -519,14 +519,41 @@ abstract class KotlinParameterInfoWithCallHandlerBase<TArgumentList : KtElement,
return (callToUse.getArgumentMapping(argument) as? ArgumentMatch)?.valueParameter
}
val highlightParameterIndex = argumentToParameter(currentArgument)?.index
val currentParameter = argumentToParameter(currentArgument)
val highlightParameterIndex = currentParameter?.index
val argumentsBeforeCurrent = arguments.subList(0, currentArgumentIndex)
if ((argumentsBeforeCurrent + currentArgument).any { argumentToParameter(it) == null }) {
// some of arguments before the current one (or the current one) are not mapped to any of the parameters
if (argumentsBeforeCurrent.any { argumentToParameter(it) == null }) {
// some of arguments before the current one are not mapped to any of the parameters
return SignatureInfo(resultingDescriptor, ::argumentToParameter, highlightParameterIndex, isGrey = true)
}
if (currentParameter == null) {
if (currentArgumentIndex < arguments.lastIndex) {
// the current argument is not the last one and it is not mapped to any of the parameters
return SignatureInfo(resultingDescriptor, ::argumentToParameter, highlightParameterIndex, isGrey = true)
}
val usedParameters = argumentsBeforeCurrent.mapNotNull { argumentToParameter(it) }
val availableParameters = if (call.callType == Call.CallType.ARRAY_SET_METHOD) {
resultingDescriptor.valueParameters.dropLast(1)
} else {
resultingDescriptor.valueParameters
}
val noUnusedParametersLeft = (availableParameters - usedParameters).isEmpty()
if (currentArgument == info.dummyArgument) {
val supportsTrailingCommas = call.callElement.languageVersionSettings.supportsFeature(LanguageFeature.TrailingCommas)
if (!supportsTrailingCommas && noUnusedParametersLeft) {
// current argument is empty but there are no unused parameters left and trailing commas are not supported
return SignatureInfo(resultingDescriptor, ::argumentToParameter, highlightParameterIndex, isGrey = true)
}
} else if (noUnusedParametersLeft) {
// there are no unused parameters left to which this argument could be matched
return SignatureInfo(resultingDescriptor, ::argumentToParameter, highlightParameterIndex, isGrey = true)
}
}
// grey out if not all arguments before the current are matched
val isGrey = info.isGreyArgumentIndex in 0 until currentArgumentIndex
return SignatureInfo(resultingDescriptor, ::argumentToParameter, highlightParameterIndex, isGrey)
@@ -0,0 +1,10 @@
open class A(x: Int) {
fun m(x: Int, y: Boolean) = 1
fun d(x: Int) {
m(y = false, <caret>)
}
}
/*
Text: ([y: Boolean], [x: Int]), Disabled: false, Strikeout: false, Green: true
*/
@@ -1,3 +1,4 @@
// COMPILER_ARGUMENTS: -XXLanguage:-TrailingCommas
open class A(x: Int) {
fun m(x: Int, y: Boolean) = 2
@@ -0,0 +1,8 @@
open class A(x: Int) {
fun m(x: Int, y: Int) = 2
fun d(x: Int) {
m(1, 2, 3<caret>)
}
}
//Text: (x: Int, y: Int), Disabled: true, Strikeout: false, Green: true
@@ -0,0 +1,10 @@
open class A(x: Int) {
fun m(x: Int, y: Boolean) = 1
fun d(x: Int) {
m(1, false,<caret>)
}
}
/*
Text: (x: Int, y: Boolean), Disabled: false, Strikeout: false, Green: true
*/
@@ -1,3 +1,4 @@
// COMPILER_ARGUMENTS: -XXLanguage:-TrailingCommas
// See KT-14484
class C {
@@ -221,6 +221,11 @@ public class ParameterInfoTestGenerated extends AbstractParameterInfoTest {
runTest("idea/testData/parameterInfo/functionCall/NamedParameter2.kt");
}
@TestMetadata("NamedParameter3.kt")
public void testNamedParameter3() throws Exception {
runTest("idea/testData/parameterInfo/functionCall/NamedParameter3.kt");
}
@TestMetadata("NoAnnotations.kt")
public void testNoAnnotations() throws Exception {
runTest("idea/testData/parameterInfo/functionCall/NoAnnotations.kt");
@@ -346,6 +351,16 @@ public class ParameterInfoTestGenerated extends AbstractParameterInfoTest {
runTest("idea/testData/parameterInfo/functionCall/TooManyArgs.kt");
}
@TestMetadata("TooManyArgs2.kt")
public void testTooManyArgs2() throws Exception {
runTest("idea/testData/parameterInfo/functionCall/TooManyArgs2.kt");
}
@TestMetadata("TrailingComma.kt")
public void testTrailingComma() throws Exception {
runTest("idea/testData/parameterInfo/functionCall/TrailingComma.kt");
}
@TestMetadata("TwoFunctions.kt")
public void testTwoFunctions() throws Exception {
runTest("idea/testData/parameterInfo/functionCall/TwoFunctions.kt");