diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ChopParameterListIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ChopParameterListIntention.kt index 0dd9ad699c1..e21d475cec3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ChopParameterListIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ChopParameterListIntention.kt @@ -8,31 +8,33 @@ package org.jetbrains.kotlin.idea.intentions import com.intellij.application.options.CodeStyle import com.intellij.openapi.editor.Editor import com.intellij.psi.PsiDocumentManager +import com.intellij.psi.PsiElement import com.intellij.psi.PsiWhiteSpace import com.intellij.psi.codeStyle.CodeStyleManager import com.intellij.psi.codeStyle.CommonCodeStyleSettings import org.jetbrains.kotlin.idea.KotlinBundle +import org.jetbrains.kotlin.idea.inspections.findExistingEditor import org.jetbrains.kotlin.idea.formatter.kotlinCommonSettings import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.allChildren -import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer -import org.jetbrains.kotlin.psi.psiUtil.siblings -import org.jetbrains.kotlin.psi.psiUtil.startOffset +import org.jetbrains.kotlin.psi.psiUtil.* abstract class AbstractChopListIntention( listClass: Class, private val elementClass: Class, textGetter: () -> String -) : SelfTargetingOffsetIndependentIntention(listClass, textGetter) { +) : SelfTargetingIntention(listClass, textGetter) { + override fun allowCaretInsideElement(element: PsiElement) = + element !is KtValueArgument && super.allowCaretInsideElement(element) open fun leftParOnNewLine(commonCodeStyleSettings: CommonCodeStyleSettings): Boolean = false open fun rightParOnNewLine(commonCodeStyleSettings: CommonCodeStyleSettings): Boolean = false - override fun isApplicableTo(element: TList): Boolean { + override fun isApplicableTo(element: TList, caretOffset: Int): Boolean { val elements = element.elements() if (elements.size <= 1) return false + if (!isApplicableCaretOffset(caretOffset, element)) return false if (elements.dropLast(1).all { hasLineBreakAfter(it) }) return false return true } @@ -82,6 +84,12 @@ abstract class AbstractChopListIntention( @@ -89,9 +97,9 @@ class ChopParameterListIntention : AbstractChopListIntention, textGetter: () -> String ) : AbstractChopListIntention(listClass, elementClass, textGetter) { - override fun isApplicableTo(element: TList): Boolean { + override fun isApplicableTo(element: TList, caretOffset: Int): Boolean { val elements = element.elements() if (elements.isEmpty()) return false + if (!isApplicableCaretOffset(caretOffset, element)) return false return (hasLineBreakBefore(elements.first()) || elements.any { hasLineBreakAfter(it) }) && element.allChildren.none { it is PsiComment && it.node.elementType == KtTokens.EOL_COMMENT } } @@ -53,9 +54,9 @@ class JoinParameterListIntention : AbstractJoinListIntention + 3, + 4, + 5 + ), 3) +} + +fun f(a: Int, b: Int, c: Int, d: Int): Int = 0 + +fun g(a: Int, b: Int, c: Int): Int = 0 \ No newline at end of file diff --git a/idea/testData/intentions/chop/argumentList/onNestedArgumentList2.kt b/idea/testData/intentions/chop/argumentList/onNestedArgumentList2.kt new file mode 100644 index 00000000000..5fd2e86cc9b --- /dev/null +++ b/idea/testData/intentions/chop/argumentList/onNestedArgumentList2.kt @@ -0,0 +1,12 @@ +// IS_APPLICABLE: false +fun foo() { + f(1, 2, g( + 3, + 4, + 5 + ), 3) +} + +fun f(a: Int, b: Int, c: Int, d: Int): Int = 0 + +fun g(a: Int, b: Int, c: Int): Int = 0 \ No newline at end of file diff --git a/idea/testData/intentions/chop/argumentList/onNestedArgumentList3.kt b/idea/testData/intentions/chop/argumentList/onNestedArgumentList3.kt new file mode 100644 index 00000000000..b928c9c916b --- /dev/null +++ b/idea/testData/intentions/chop/argumentList/onNestedArgumentList3.kt @@ -0,0 +1,12 @@ +// IS_APPLICABLE: false +fun foo() { + f(1, 2, g( + 3, + 4, + 5 + ), 3) +} + +fun f(a: Int, b: Int, c: Int, d: Int): Int = 0 + +fun g(a: Int, b: Int, c: Int): Int = 0 \ No newline at end of file diff --git a/idea/testData/intentions/chop/argumentList/onNestedArgumentList4.kt b/idea/testData/intentions/chop/argumentList/onNestedArgumentList4.kt new file mode 100644 index 00000000000..5efef56b809 --- /dev/null +++ b/idea/testData/intentions/chop/argumentList/onNestedArgumentList4.kt @@ -0,0 +1,12 @@ +fun foo() { + f( + 1, + 2, + g(3, 4, 5), + 3 + ) +} + +fun f(a: Int, b: Int, c: Int, d: Int): Int = 0 + +fun g(a: Int, b: Int, c: Int): Int = 0 \ No newline at end of file diff --git a/idea/testData/intentions/chop/argumentList/onNestedArgumentList4.kt.after b/idea/testData/intentions/chop/argumentList/onNestedArgumentList4.kt.after new file mode 100644 index 00000000000..ef2ffdd9e18 --- /dev/null +++ b/idea/testData/intentions/chop/argumentList/onNestedArgumentList4.kt.after @@ -0,0 +1,16 @@ +fun foo() { + f( + 1, + 2, + g( + 3, + 4, + 5 + ), + 3 + ) +} + +fun f(a: Int, b: Int, c: Int, d: Int): Int = 0 + +fun g(a: Int, b: Int, c: Int): Int = 0 \ No newline at end of file diff --git a/idea/testData/intentions/chop/argumentList/onRightParenthesis.kt b/idea/testData/intentions/chop/argumentList/onRightParenthesis.kt new file mode 100644 index 00000000000..601a64a39f6 --- /dev/null +++ b/idea/testData/intentions/chop/argumentList/onRightParenthesis.kt @@ -0,0 +1,11 @@ +fun foo() { + f(1, 2, g( + 3, + 4, + 5 + ), 3) +} + +fun f(a: Int, b: Int, c: Int, d: Int): Int = 0 + +fun g(a: Int, b: Int, c: Int): Int = 0 \ No newline at end of file diff --git a/idea/testData/intentions/chop/argumentList/onRightParenthesis.kt.after b/idea/testData/intentions/chop/argumentList/onRightParenthesis.kt.after new file mode 100644 index 00000000000..ef2ffdd9e18 --- /dev/null +++ b/idea/testData/intentions/chop/argumentList/onRightParenthesis.kt.after @@ -0,0 +1,16 @@ +fun foo() { + f( + 1, + 2, + g( + 3, + 4, + 5 + ), + 3 + ) +} + +fun f(a: Int, b: Int, c: Int, d: Int): Int = 0 + +fun g(a: Int, b: Int, c: Int): Int = 0 \ No newline at end of file diff --git a/idea/testData/intentions/joinArgumentList/onNestedArgumentList.kt b/idea/testData/intentions/joinArgumentList/onNestedArgumentList.kt new file mode 100644 index 00000000000..6226834329e --- /dev/null +++ b/idea/testData/intentions/joinArgumentList/onNestedArgumentList.kt @@ -0,0 +1,13 @@ +// IS_APPLICABLE: false +fun foo() { + f( + 1, + 2, + g(3, 4, 5), + 3 + ) +} + +fun f(a: Int, b: Int, c: Int, d: Int): Int = 0 + +fun g(a: Int, b: Int, c: Int): Int = 0 \ No newline at end of file diff --git a/idea/testData/intentions/joinArgumentList/onNestedArgumentList2.kt b/idea/testData/intentions/joinArgumentList/onNestedArgumentList2.kt new file mode 100644 index 00000000000..d0ce17718b4 --- /dev/null +++ b/idea/testData/intentions/joinArgumentList/onNestedArgumentList2.kt @@ -0,0 +1,13 @@ +// IS_APPLICABLE: false +fun foo() { + f( + 1, + 2, + g(3, 4, 5), + 3 + ) +} + +fun f(a: Int, b: Int, c: Int, d: Int): Int = 0 + +fun g(a: Int, b: Int, c: Int): Int = 0 \ No newline at end of file diff --git a/idea/testData/intentions/joinArgumentList/onNestedArgumentList3.kt b/idea/testData/intentions/joinArgumentList/onNestedArgumentList3.kt new file mode 100644 index 00000000000..0c212207c34 --- /dev/null +++ b/idea/testData/intentions/joinArgumentList/onNestedArgumentList3.kt @@ -0,0 +1,13 @@ +// IS_APPLICABLE: false +fun foo() { + f( + 1, + 2, + g(3, 4, 5), + 3 + ) +} + +fun f(a: Int, b: Int, c: Int, d: Int): Int = 0 + +fun g(a: Int, b: Int, c: Int): Int = 0 \ No newline at end of file diff --git a/idea/testData/intentions/joinArgumentList/onNestedArgumentList4.kt b/idea/testData/intentions/joinArgumentList/onNestedArgumentList4.kt new file mode 100644 index 00000000000..6771a0ba1fc --- /dev/null +++ b/idea/testData/intentions/joinArgumentList/onNestedArgumentList4.kt @@ -0,0 +1,11 @@ +fun foo() { + f(1, 2, g( + 3, + 4, + 5 + ), 3) +} + +fun f(a: Int, b: Int, c: Int, d: Int): Int = 0 + +fun g(a: Int, b: Int, c: Int): Int = 0 \ No newline at end of file diff --git a/idea/testData/intentions/joinArgumentList/onNestedArgumentList4.kt.after b/idea/testData/intentions/joinArgumentList/onNestedArgumentList4.kt.after new file mode 100644 index 00000000000..2dbde3e6469 --- /dev/null +++ b/idea/testData/intentions/joinArgumentList/onNestedArgumentList4.kt.after @@ -0,0 +1,7 @@ +fun foo() { + f(1, 2, g(3, 4, 5), 3) +} + +fun f(a: Int, b: Int, c: Int, d: Int): Int = 0 + +fun g(a: Int, b: Int, c: Int): Int = 0 \ No newline at end of file diff --git a/idea/testData/intentions/joinArgumentList/onRightParenthesis.kt b/idea/testData/intentions/joinArgumentList/onRightParenthesis.kt new file mode 100644 index 00000000000..d2d7bac68ab --- /dev/null +++ b/idea/testData/intentions/joinArgumentList/onRightParenthesis.kt @@ -0,0 +1,12 @@ +fun foo() { + f( + 1, + 2, + g(3, 4, 5), + 3 + ) +} + +fun f(a: Int, b: Int, c: Int, d: Int): Int = 0 + +fun g(a: Int, b: Int, c: Int): Int = 0 \ No newline at end of file diff --git a/idea/testData/intentions/joinArgumentList/onRightParenthesis.kt.after b/idea/testData/intentions/joinArgumentList/onRightParenthesis.kt.after new file mode 100644 index 00000000000..2dbde3e6469 --- /dev/null +++ b/idea/testData/intentions/joinArgumentList/onRightParenthesis.kt.after @@ -0,0 +1,7 @@ +fun foo() { + f(1, 2, g(3, 4, 5), 3) +} + +fun f(a: Int, b: Int, c: Int, d: Int): Int = 0 + +fun g(a: Int, b: Int, c: Int): Int = 0 \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index aada917c937..2511560132d 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -3763,6 +3763,31 @@ public class IntentionTestGenerated extends AbstractIntentionTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/intentions/chop/argumentList"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), null, true); } + @TestMetadata("onNestedArgumentList.kt") + public void testOnNestedArgumentList() throws Exception { + runTest("idea/testData/intentions/chop/argumentList/onNestedArgumentList.kt"); + } + + @TestMetadata("onNestedArgumentList2.kt") + public void testOnNestedArgumentList2() throws Exception { + runTest("idea/testData/intentions/chop/argumentList/onNestedArgumentList2.kt"); + } + + @TestMetadata("onNestedArgumentList3.kt") + public void testOnNestedArgumentList3() throws Exception { + runTest("idea/testData/intentions/chop/argumentList/onNestedArgumentList3.kt"); + } + + @TestMetadata("onNestedArgumentList4.kt") + public void testOnNestedArgumentList4() throws Exception { + runTest("idea/testData/intentions/chop/argumentList/onNestedArgumentList4.kt"); + } + + @TestMetadata("onRightParenthesis.kt") + public void testOnRightParenthesis() throws Exception { + runTest("idea/testData/intentions/chop/argumentList/onRightParenthesis.kt"); + } + @TestMetadata("leftParOnSameLine.kt") public void testLeftParOnSameLine() throws Exception { runTest("idea/testData/intentions/chop/argumentList/leftParOnSameLine.kt"); @@ -10668,6 +10693,31 @@ public class IntentionTestGenerated extends AbstractIntentionTest { runTest("idea/testData/intentions/joinArgumentList/noLineBreak.kt"); } + @TestMetadata("onNestedArgumentList.kt") + public void testOnNestedArgumentList() throws Exception { + runTest("idea/testData/intentions/joinArgumentList/onNestedArgumentList.kt"); + } + + @TestMetadata("onNestedArgumentList2.kt") + public void testOnNestedArgumentList2() throws Exception { + runTest("idea/testData/intentions/joinArgumentList/onNestedArgumentList2.kt"); + } + + @TestMetadata("onNestedArgumentList3.kt") + public void testOnNestedArgumentList3() throws Exception { + runTest("idea/testData/intentions/joinArgumentList/onNestedArgumentList3.kt"); + } + + @TestMetadata("onNestedArgumentList4.kt") + public void testOnNestedArgumentList4() throws Exception { + runTest("idea/testData/intentions/joinArgumentList/onNestedArgumentList4.kt"); + } + + @TestMetadata("onRightParenthesis.kt") + public void testOnRightParenthesis() throws Exception { + runTest("idea/testData/intentions/joinArgumentList/onRightParenthesis.kt"); + } + @TestMetadata("oneArg.kt") public void testOneArg() throws Exception { runTest("idea/testData/intentions/joinArgumentList/oneArg.kt");