diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveArgumentNameIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveArgumentNameIntention.kt index 894d2579219..d0be91b11df 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveArgumentNameIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveArgumentNameIntention.kt @@ -19,16 +19,12 @@ package org.jetbrains.kotlin.idea.intentions import com.intellij.openapi.editor.Editor import com.intellij.openapi.util.TextRange import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall -import org.jetbrains.kotlin.psi.KtCallElement -import org.jetbrains.kotlin.psi.KtPsiFactory -import org.jetbrains.kotlin.psi.KtValueArgument -import org.jetbrains.kotlin.psi.KtValueArgumentList +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.startOffset +import org.jetbrains.kotlin.resolve.calls.components.isVararg import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch -class RemoveArgumentNameIntention - : SelfTargetingRangeIntention(KtValueArgument::class.java, "Remove argument name") { - +class RemoveArgumentNameIntention : SelfTargetingRangeIntention(KtValueArgument::class.java, "Remove argument name") { override fun applicabilityRange(element: KtValueArgument): TextRange? { if (!element.isNamed()) return null @@ -37,8 +33,7 @@ class RemoveArgumentNameIntention if (arguments.asSequence().takeWhile { it != element }.any { it.isNamed() }) return null val callExpr = argumentList.parent as? KtCallElement ?: return null - val resolvedCall = callExpr.resolveToCall() ?: return null - val argumentMatch = resolvedCall.getArgumentMapping(element) as? ArgumentMatch ?: return null + val argumentMatch = callExpr.resolveToArgumentMatch(element) ?: return null if (argumentMatch.valueParameter.index != arguments.indexOf(element)) return null val expression = element.getArgumentExpression() ?: return null @@ -46,7 +41,23 @@ class RemoveArgumentNameIntention } override fun applyTo(element: KtValueArgument, editor: Editor?) { - val newArgument = KtPsiFactory(element).createArgument(element.getArgumentExpression()!!, null, element.getSpreadElement() != null) - element.replace(newArgument) + val argumentExpr = element.getArgumentExpression() ?: return + val argumentList = element.parent as? KtValueArgumentList ?: return + val callExpr = argumentList.parent as? KtCallElement ?: return + val psiFactory = KtPsiFactory(element) + if (argumentExpr is KtCollectionLiteralExpression && callExpr.resolveToArgumentMatch(element)?.valueParameter?.isVararg == true) { + argumentExpr.getInnerExpressions() + .map { psiFactory.createArgument(it) } + .reversed() + .forEach { argumentList.addArgumentAfter(it, element) } + argumentList.removeArgument(element) + } else { + val newArgument = psiFactory.createArgument(argumentExpr, null, element.getSpreadElement() != null) + element.replace(newArgument) + } + } + + private fun KtCallElement.resolveToArgumentMatch(element: KtValueArgument): ArgumentMatch? { + return resolveToCall()?.getArgumentMapping(element) as? ArgumentMatch ?: return null } } \ No newline at end of file diff --git a/idea/testData/intentions/removeArgumentName/arrayLiteral.kt b/idea/testData/intentions/removeArgumentName/arrayLiteral.kt new file mode 100644 index 00000000000..f73d1a78b86 --- /dev/null +++ b/idea/testData/intentions/removeArgumentName/arrayLiteral.kt @@ -0,0 +1,6 @@ +annotation class AnnWithArray(val value: Array) + +interface Result { + @AnnWithArray(value = ["foo", "bar"]) + val res1: Any +} diff --git a/idea/testData/intentions/removeArgumentName/arrayLiteral.kt.after b/idea/testData/intentions/removeArgumentName/arrayLiteral.kt.after new file mode 100644 index 00000000000..7c6307891c9 --- /dev/null +++ b/idea/testData/intentions/removeArgumentName/arrayLiteral.kt.after @@ -0,0 +1,6 @@ +annotation class AnnWithArray(val value: Array) + +interface Result { + @AnnWithArray(["foo", "bar"]) + val res1: Any +} diff --git a/idea/testData/intentions/removeArgumentName/arrayLiteralForVararg.kt b/idea/testData/intentions/removeArgumentName/arrayLiteralForVararg.kt new file mode 100644 index 00000000000..d133ab166f5 --- /dev/null +++ b/idea/testData/intentions/removeArgumentName/arrayLiteralForVararg.kt @@ -0,0 +1,6 @@ +annotation class AnnWithVararg(vararg val value: String, val s: String) + +interface Result { + @AnnWithVararg(value = ["foo", "bar"], s = "") + val res2: Any +} diff --git a/idea/testData/intentions/removeArgumentName/arrayLiteralForVararg.kt.after b/idea/testData/intentions/removeArgumentName/arrayLiteralForVararg.kt.after new file mode 100644 index 00000000000..525d011c87c --- /dev/null +++ b/idea/testData/intentions/removeArgumentName/arrayLiteralForVararg.kt.after @@ -0,0 +1,6 @@ +annotation class AnnWithVararg(vararg val value: String, val s: String) + +interface Result { + @AnnWithVararg("foo", "bar", s = "") + val res2: Any +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index e29810026aa..8305e7d7e78 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -12618,6 +12618,16 @@ public class IntentionTestGenerated extends AbstractIntentionTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/removeArgumentName"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true); } + @TestMetadata("arrayLiteral.kt") + public void testArrayLiteral() throws Exception { + runTest("idea/testData/intentions/removeArgumentName/arrayLiteral.kt"); + } + + @TestMetadata("arrayLiteralForVararg.kt") + public void testArrayLiteralForVararg() throws Exception { + runTest("idea/testData/intentions/removeArgumentName/arrayLiteralForVararg.kt"); + } + @TestMetadata("namedArgumentBefore.kt") public void testNamedArgumentBefore() throws Exception { runTest("idea/testData/intentions/removeArgumentName/namedArgumentBefore.kt");