diff --git a/plugins/kotlin/code-insight/intentions-k2/tests/test/org/jetbrains/kotlin/idea/k2/intentions/tests/K2IntentionTestGenerated.java b/plugins/kotlin/code-insight/intentions-k2/tests/test/org/jetbrains/kotlin/idea/k2/intentions/tests/K2IntentionTestGenerated.java index e82be6242d6a..c697699a898d 100644 --- a/plugins/kotlin/code-insight/intentions-k2/tests/test/org/jetbrains/kotlin/idea/k2/intentions/tests/K2IntentionTestGenerated.java +++ b/plugins/kotlin/code-insight/intentions-k2/tests/test/org/jetbrains/kotlin/idea/k2/intentions/tests/K2IntentionTestGenerated.java @@ -530,6 +530,11 @@ public abstract class K2IntentionTestGenerated extends AbstractK2IntentionTest { runTest("../../../idea/tests/testData/intentions/addNameToArgument/notResolved.kt"); } + @TestMetadata("onSwappedOrder.kt") + public void testOnSwappedOrder() throws Exception { + runTest("../../../idea/tests/testData/intentions/addNameToArgument/onSwappedOrder.kt"); + } + @TestMetadata("rangeForLambda1.kt") public void testRangeForLambda1() throws Exception { runTest("../../../idea/tests/testData/intentions/addNameToArgument/rangeForLambda1.kt"); diff --git a/plugins/kotlin/code-insight/utils/src/org/jetbrains/kotlin/idea/codeinsight/utils/NamedArgumentUtils.kt b/plugins/kotlin/code-insight/utils/src/org/jetbrains/kotlin/idea/codeinsight/utils/NamedArgumentUtils.kt index 886a9d2c454e..e2ec3d715fbd 100644 --- a/plugins/kotlin/code-insight/utils/src/org/jetbrains/kotlin/idea/codeinsight/utils/NamedArgumentUtils.kt +++ b/plugins/kotlin/code-insight/utils/src/org/jetbrains/kotlin/idea/codeinsight/utils/NamedArgumentUtils.kt @@ -5,9 +5,12 @@ import com.intellij.psi.PsiComment import com.intellij.psi.SmartPsiElementPointer import com.intellij.psi.createSmartPointer import org.jetbrains.kotlin.analysis.api.KaSession +import org.jetbrains.kotlin.analysis.api.resolution.KaErrorCallInfo import org.jetbrains.kotlin.analysis.api.resolution.KaFunctionCall +import org.jetbrains.kotlin.analysis.api.resolution.singleCallOrNull import org.jetbrains.kotlin.analysis.api.resolution.singleFunctionCallOrNull import org.jetbrains.kotlin.analysis.api.resolution.symbol +import org.jetbrains.kotlin.analysis.api.symbols.KaValueParameterSymbol import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings import org.jetbrains.kotlin.idea.base.psi.getCallElement @@ -65,13 +68,24 @@ object NamedArgumentUtils { context(KaSession) fun getStableNameFor(argument: KtValueArgument): Name? { val callElement: KtCallElement = getCallElement(argument) ?: return null - val resolvedCall = callElement.resolveToCall()?.singleFunctionCallOrNull() ?: return null + val resolveToCall = callElement.resolveToCall() + //((callElement.resolveToCall() as? KaErrorCallInfo).candidateCalls[0] as KaSimpleFunctionCall).symbol.hasStableParameterNames + val resolvedCall = + resolveToCall?.singleFunctionCallOrNull() ?: (resolveToCall as? KaErrorCallInfo)?.singleCallOrNull() ?: return null if (!resolvedCall.symbol.hasStableParameterNames) return null return getNameForNameableArgument(argument, resolvedCall) } private fun getNameForNameableArgument(argument: KtValueArgument, resolvedCall: KaFunctionCall<*>): Name? { - val valueParameterSymbol = resolvedCall.argumentMapping[argument.getArgumentExpression()]?.symbol ?: return null + val argumentMapping = resolvedCall.argumentMapping + val variableSignature = argumentMapping[argument.getArgumentExpression()] + if (variableSignature == null) { + val resolvedCallSignatures = argumentMapping.values.map { it.symbol to it }.toMap() + val name = + resolvedCall.symbol.valueParameters.filter { it !in resolvedCallSignatures }.firstOrNull()?.name + return name + } + val valueParameterSymbol = variableSignature.symbol if (valueParameterSymbol.isVararg) { if (argument.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitAssigningSingleElementsToVarargsInNamedForm) && !argument.isSpread @@ -85,7 +99,7 @@ object NamedArgumentUtils { // // foo(1, 2) // Can NOT add `i = ` to either argument // foo(1) // Can change to `i = 1` - val varargArgumentCount = resolvedCall.argumentMapping.values.count { it.symbol == valueParameterSymbol } + val varargArgumentCount = argumentMapping.values.count { it.symbol == valueParameterSymbol } if (varargArgumentCount != 1) { return null } diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/intentions/K1IntentionTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/intentions/K1IntentionTestGenerated.java index 5c144133dc02..c6ba3ae652ea 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/intentions/K1IntentionTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/intentions/K1IntentionTestGenerated.java @@ -1500,6 +1500,11 @@ public abstract class K1IntentionTestGenerated extends AbstractK1IntentionTest { runTest("testData/intentions/addNameToArgument/notResolved.kt"); } + @TestMetadata("onSwappedOrder.kt") + public void testOnSwappedOrder() throws Exception { + runTest("testData/intentions/addNameToArgument/onSwappedOrder.kt"); + } + @TestMetadata("rangeForLambda1.kt") public void testRangeForLambda1() throws Exception { runTest("testData/intentions/addNameToArgument/rangeForLambda1.kt"); diff --git a/plugins/kotlin/idea/tests/testData/intentions/addNameToArgument/onSwappedOrder.kt b/plugins/kotlin/idea/tests/testData/intentions/addNameToArgument/onSwappedOrder.kt new file mode 100644 index 000000000000..494847457255 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/intentions/addNameToArgument/onSwappedOrder.kt @@ -0,0 +1,20 @@ +// INTENTION_TEXT: "Add 'c =' to argument" +// IGNORE_K1 +// SKIP_ERRORS_BEFORE +// AFTER-WARNING: Parameter 'a' is never used +// AFTER-WARNING: Parameter 'b' is never used +// AFTER-WARNING: Parameter 'c' is never used + +fun foo( + a: Int?, + b: String?, + c: Boolean, +){} + +fun bar() { + foo( + b = "foo", + a = 2, + false, + ) +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/intentions/addNameToArgument/onSwappedOrder.kt.after b/plugins/kotlin/idea/tests/testData/intentions/addNameToArgument/onSwappedOrder.kt.after new file mode 100644 index 000000000000..acad28f7d61e --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/intentions/addNameToArgument/onSwappedOrder.kt.after @@ -0,0 +1,20 @@ +// INTENTION_TEXT: "Add 'c =' to argument" +// IGNORE_K1 +// SKIP_ERRORS_BEFORE +// AFTER-WARNING: Parameter 'a' is never used +// AFTER-WARNING: Parameter 'b' is never used +// AFTER-WARNING: Parameter 'c' is never used + +fun foo( + a: Int?, + b: String?, + c: Boolean, +){} + +fun bar() { + foo( + b = "foo", + a = 2, + c = false, + ) +} \ No newline at end of file