Remove MergeWhenIntention

Relates to #KT-31502
This commit is contained in:
Dmitry Gridin
2019-05-27 19:21:40 +07:00
parent 41daf99346
commit 2310826ec9
35 changed files with 0 additions and 850 deletions
@@ -983,11 +983,6 @@
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions.MergeWhenIntention</className>
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.kotlin.idea.intentions.RemoveUnnecessaryParenthesesIntention</className>
<category>Kotlin</category>
@@ -1,14 +0,0 @@
when (n) {
1 -> {
res = "one"
println("A")
}
2 -> {
res = "two"
println("B")
}
else -> {
res = "unknown"
println("C")
}
}
@@ -1,11 +0,0 @@
when (n) {
1 -> res = "one"
2 -> res = "two"
else -> res = "unknown"
}
when (n) {
1 -> println("A")
2 -> println("B")
else -> println("C")
}
@@ -1,5 +0,0 @@
<html>
<body>
This intention merges two successive <b>when</b> expressions with equivalent branches into a single <b>when</b>.
</body>
</html>
@@ -1,111 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiWhiteSpace
import org.jetbrains.kotlin.idea.core.appendElement
import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isStableVal
import org.jetbrains.kotlin.idea.util.psi.patternMatching.matches
import org.jetbrains.kotlin.idea.util.psi.patternMatching.toRange
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.blockExpressionsOrSingle
import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis
import org.jetbrains.kotlin.psi.psiUtil.siblings
class MergeWhenIntention : SelfTargetingRangeIntention<KtWhenExpression>(
KtWhenExpression::class.java,
"Merge with next 'when'",
"Merge 'when' expressions"
) {
override fun applicabilityRange(element: KtWhenExpression): TextRange? {
val next = element.nextWhen() ?: return null
val subject1 = element.subjectExpression
val subject2 = next.subjectExpression
if (!subject1.matches(subject2)) return null
if (subject1 != null && !subject1.isStableVal()) return null
val entries1 = element.entries
val entries2 = next.entries
if (entries1.size != entries2.size) return null
if (!entries1.zip(entries2).all { pair ->
conditionsMatch(pair.first, pair.second) && checkBodies(pair.first, pair.second)
}
) return null
return element.whenKeyword.textRange
}
private fun KtWhenExpression.nextWhen(): KtWhenExpression? {
return siblings(withItself = false)
.filter { it !is PsiWhiteSpace && it !is PsiComment && it.node.elementType != KtTokens.SEMICOLON }
.firstOrNull() as? KtWhenExpression
}
private fun conditionsMatch(e1: KtWhenEntry, e2: KtWhenEntry): Boolean =
e1.conditions.toList().toRange().matches(e2.conditions.toList().toRange())
private fun checkBodies(e1: KtWhenEntry, e2: KtWhenEntry): Boolean {
val names1 = e1.declarationNames()
val names2 = e2.declarationNames()
if (names1.any { it in names2 }) return false
return when (e1.expression?.lastBlockStatementOrThis()) {
is KtReturnExpression, is KtThrowExpression, is KtBreakExpression, is KtContinueExpression -> false
else -> true
}
}
private fun KtWhenEntry.declarationNames(): Set<String> =
expression?.blockExpressionsOrSingle()
?.filter { it is KtNamedDeclaration }
?.mapNotNull { it.name }
?.toSet() ?: emptySet()
override fun applyTo(element: KtWhenExpression, editor: Editor?) {
val nextWhen = element.nextWhen() ?: return
for ((entry1, entry2) in element.entries.zip(nextWhen.entries)) {
entry1.expression.mergeWith(entry2.expression)
}
val nextComment = element.siblings(withItself = false).takeWhile { it != nextWhen }.lastOrNull { it is PsiComment }
val nextSibling = nextComment?.nextSibling ?: element.nextSibling
element.parent.deleteChildRange(nextSibling, nextWhen)
}
private fun KtExpression?.mergeWith(that: KtExpression?): KtExpression? = when {
this == null -> that
that == null -> this
else -> {
val psiFactory = KtPsiFactory(this)
val block = this as? KtBlockExpression ?: replaced(psiFactory.createSingleStatementBlock(this))
for (element in that.blockExpressionsOrSingle()) {
val expression = block.appendElement(element)
block.addBefore(psiFactory.createNewLine(), expression)
}
block
}
}
}
@@ -1 +0,0 @@
org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions.MergeWhenIntention
@@ -1,15 +0,0 @@
fun <T> doSomething(a: T) {}
fun test(a: Int) {
<caret>when (a) {
0 -> doSomething("A")
1 -> doSomething("B")
}
// comment
when (a) {
0 -> doSomething("C")
1 -> doSomething("D")
}
}
@@ -1,16 +0,0 @@
fun <T> doSomething(a: T) {}
fun test(a: Int) {
<caret>when (a) {
0 -> {
doSomething("A")
doSomething("C")
}
1 -> {
doSomething("B")
doSomething("D")
}
}
// comment
}
@@ -1,13 +0,0 @@
fun <T> doSomething(a: T) {}
fun test(a: Int) {
<caret>when (a) {
0 -> doSomething("A")
1 -> doSomething("B")
};
when (a) {
0 -> doSomething("C")
1 -> doSomething("D")
}
}
@@ -1,14 +0,0 @@
fun <T> doSomething(a: T) {}
fun test(a: Int) {
<caret>when (a) {
0 -> {
doSomething("A")
doSomething("C")
}
1 -> {
doSomething("B")
doSomething("D")
}
}
}
@@ -1,35 +0,0 @@
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
<caret>when (n) {
1 -> {
res = "one"
doSomething("A")
}
2 -> {
res = "two"
doSomething("B")
}
else -> {
res = "unknown"
doSomething("C")
}
}
when (n) {
1 -> {
doSomething("A")
doSomething("AA")
}
2 -> {
doSomething("B")
doSomething("BB")
}
else -> {
doSomething("C")
doSomething("CC")
}
}
}
@@ -1,26 +0,0 @@
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
when (n) {
1 -> {
res = "one"
doSomething("A")
doSomething("A")
doSomething("AA")
}
2 -> {
res = "two"
doSomething("B")
doSomething("B")
doSomething("BB")
}
else -> {
res = "unknown"
doSomething("C")
doSomething("C")
doSomething("CC")
}
}
}
@@ -1,26 +0,0 @@
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
<caret>when (n) {
1 -> {
res = "one"
doSomething("A")
}
2 -> {
res = "two"
doSomething("B")
}
else -> {
res = "unknown"
doSomething("C")
}
}
when (n) {
1 -> doSomething("AA")
2 -> doSomething("BB")
else -> doSomething("CC")
}
}
@@ -1,23 +0,0 @@
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
<caret>when (n) {
1 -> {
res = "one"
doSomething("A")
doSomething("AA")
}
2 -> {
res = "two"
doSomething("B")
doSomething("BB")
}
else -> {
res = "unknown"
doSomething("C")
doSomething("CC")
}
}
}
@@ -1,40 +0,0 @@
// IS_APPLICABLE: false
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
<caret>when (n) {
1 -> {
res = "one"
val x = "A"
doSomething(x)
}
2 -> {
res = "two"
val x = "B"
doSomething(x)
}
else -> {
res = "unknown"
val x = "C"
doSomething(x)
}
}
when (n) {
1 -> {
val x = "AA"
doSomething(x)
}
2 -> {
val x = "BB"
doSomething(x)
}
else -> {
val x = "CC"
doSomething(x)
}
}
}
@@ -1,38 +0,0 @@
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
<caret>when (n) {
1 -> {
res = "one"
val x = "A"
doSomething(x)
}
2 -> {
res = "two"
val x = "B"
doSomething(x)
}
else -> {
res = "unknown"
val x = "C"
doSomething(x)
}
}
when (n) {
1 -> {
val y = "AA"
doSomething(y)
}
2 -> {
val y = "BB"
doSomething(y)
}
else -> {
val y = "CC"
doSomething(y)
}
}
}
@@ -1,29 +0,0 @@
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
when (n) {
1 -> {
res = "one"
val x = "A"
doSomething(x)
val y = "AA"
doSomething(y)
}
2 -> {
res = "two"
val x = "B"
doSomething(x)
val y = "BB"
doSomething(y)
}
else -> {
res = "unknown"
val x = "C"
doSomething(x)
val y = "CC"
doSomething(y)
}
}
}
@@ -1,20 +0,0 @@
fun <T> doSomething(a: T) {}
fun test(n: Int) {
var res: String = ""
<caret>when (n) {
1 -> doSomething("A")
2 -> doSomething("B")
else -> doSomething("C")
}
when (n) {
1 -> res = "one"
2 -> res = "two"
else -> {
res = "unknown"
return
}
}
}
@@ -1,21 +0,0 @@
fun <T> doSomething(a: T) {}
fun test(n: Int) {
var res: String = ""
<caret>when (n) {
1 -> {
doSomething("A")
res = "one"
}
2 -> {
doSomething("B")
res = "two"
}
else -> {
doSomething("C")
res = "unknown"
return
}
}
}
@@ -1,22 +0,0 @@
// IS_APPLICABLE: false
fun <T> doSomething(a: T) {}
fun test(n: Int) {
var res: String = ""
<caret>when (n) {
1 -> res = "one"
2 -> res = "two"
else -> {
res = "unknown"
return
}
}
when (n) {
1 -> doSomething("A")
2 -> doSomething("B")
else -> doSomething("C")
}
}
@@ -1,17 +0,0 @@
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
<caret>when (n) {
1 -> res = "one"
2 -> res = "two"
else -> res = "unknown"
}
when (n) {
1 -> doSomething("A")
2 -> doSomething("B")
else -> doSomething("C")
}
}
@@ -1,20 +0,0 @@
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
when (n) {
1 -> {
res = "one"
doSomething("A")
}
2 -> {
res = "two"
doSomething("B")
}
else -> {
res = "unknown"
doSomething("C")
}
}
}
@@ -1,17 +0,0 @@
// IS_APPLICABLE: false
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
<caret>when (n) {
1 -> res = "one"
2 -> res = "two"
else -> res = "unknown"
}
when (n) {
1 -> doSomething("A")
else -> doSomething("C")
}
}
@@ -1,19 +0,0 @@
// IS_APPLICABLE: false
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
<caret>when (n) {
1 -> res = "one"
2 -> res = "two"
else -> res = "unknown"
}
when (n) {
1 -> doSomething("A")
2 -> doSomething("B")
3 -> doSomething("D")
else -> doSomething("C")
}
}
@@ -1,18 +0,0 @@
// IS_APPLICABLE: false
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
<caret>when (n) {
1 -> res = "one"
2 -> res = "two"
else -> res = "unknown"
}
when (n) {
2 -> doSomething("B")
1 -> doSomething("A")
else -> doSomething("C")
}
}
@@ -1,17 +0,0 @@
// IS_APPLICABLE: false
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
<caret>when {
n == 1 -> res = "one"
n == 2 -> res = "two"
else -> res = "unknown"
}
when {
n == 1 -> doSomething("A")
else -> doSomething("C")
}
}
@@ -1,19 +0,0 @@
// IS_APPLICABLE: false
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
<caret>when {
n == 1 -> res = "one"
n == 2 -> res = "two"
else -> res = "unknown"
}
when {
n == 1 -> doSomething("A")
n == 2 -> doSomething("B")
n == 3 -> doSomething("D")
else -> doSomething("C")
}
}
@@ -1,18 +0,0 @@
// IS_APPLICABLE: false
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
<caret>when {
n == 1 -> res = "one"
n == 2 -> res = "two"
else -> res = "unknown"
}
when {
n == 2 -> doSomething("B")
n == 1 -> doSomething("A")
else -> doSomething("C")
}
}
@@ -1,18 +0,0 @@
// IS_APPLICABLE: false
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
<caret>when {
n == 1 -> res = "one"
n == 2 -> res = "two"
else -> res = "unknown"
}
when {
n + 1 == 2 -> doSomething("B")
n + 1 == 3 -> doSomething("A")
else -> doSomething("C")
}
}
@@ -1,18 +0,0 @@
// IS_APPLICABLE: false
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
<caret>when (n) {
1 -> res = "one"
2 -> res = "two"
else -> res = "unknown"
}
when {
n == 1 -> doSomething("A")
n == 2 -> doSomething("B")
else -> doSomething("C")
}
}
@@ -1,18 +0,0 @@
// IS_APPLICABLE: false
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
<caret>when (n) {
1 -> res = "one"
2 -> res = "two"
else -> res = "unknown"
}
when (n + 1) {
1 -> doSomething("A")
2 -> doSomething("B")
else -> doSomething("C")
}
}
@@ -1,16 +0,0 @@
// IS_APPLICABLE: false
fun <T> doSomething(a: T) {}
fun test() {
var n = 0
<caret>when (n) {
1 -> n = 2
2 -> n = 1
}
when (n) {
1 -> doSomething("A")
2 -> doSomething("B")
}
}
@@ -1,17 +0,0 @@
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
<caret>when {
n == 1 -> res = "one"
n == 2 -> res = "two"
else -> res = "unknown"
}
when {
n == 1 -> doSomething("A")
n == 2 -> doSomething("B")
else -> doSomething("C")
}
}
@@ -1,20 +0,0 @@
fun <T> doSomething(a: T) {}
fun test(n: Int) {
val res: String
<caret>when {
n == 1 -> {
res = "one"
doSomething("A")
}
n == 2 -> {
res = "two"
doSomething("B")
}
else -> {
res = "unknown"
doSomething("C")
}
}
}
@@ -3518,119 +3518,6 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
runTest("idea/testData/intentions/branched/when/flatten/flattenWithoutSubject.kt");
}
}
@TestMetadata("idea/testData/intentions/branched/when/merge")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Merge extends AbstractIntentionTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInMerge() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/branched/when/merge"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("hasCommentBetweenWhen.kt")
public void testHasCommentBetweenWhen() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/hasCommentBetweenWhen.kt");
}
@TestMetadata("hasSemicolonBetweenWhen.kt")
public void testHasSemicolonBetweenWhen() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/hasSemicolonBetweenWhen.kt");
}
@TestMetadata("mergeBlockWithBlock.kt")
public void testMergeBlockWithBlock() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeBlockWithBlock.kt");
}
@TestMetadata("mergeBlockWithSingle.kt")
public void testMergeBlockWithSingle() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeBlockWithSingle.kt");
}
@TestMetadata("mergeWithConflictingDeclarations.kt")
public void testMergeWithConflictingDeclarations() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeWithConflictingDeclarations.kt");
}
@TestMetadata("mergeWithDeclarations.kt")
public void testMergeWithDeclarations() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeWithDeclarations.kt");
}
@TestMetadata("mergeWithReturnAfter.kt")
public void testMergeWithReturnAfter() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeWithReturnAfter.kt");
}
@TestMetadata("mergeWithReturnBefore.kt")
public void testMergeWithReturnBefore() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeWithReturnBefore.kt");
}
@TestMetadata("mergeWithSubject.kt")
public void testMergeWithSubject() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeWithSubject.kt");
}
@TestMetadata("mergeWithUnmatchedConditions1.kt")
public void testMergeWithUnmatchedConditions1() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeWithUnmatchedConditions1.kt");
}
@TestMetadata("mergeWithUnmatchedConditions2.kt")
public void testMergeWithUnmatchedConditions2() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeWithUnmatchedConditions2.kt");
}
@TestMetadata("mergeWithUnmatchedConditions3.kt")
public void testMergeWithUnmatchedConditions3() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeWithUnmatchedConditions3.kt");
}
@TestMetadata("mergeWithUnmatchedConditions4.kt")
public void testMergeWithUnmatchedConditions4() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeWithUnmatchedConditions4.kt");
}
@TestMetadata("mergeWithUnmatchedConditions5.kt")
public void testMergeWithUnmatchedConditions5() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeWithUnmatchedConditions5.kt");
}
@TestMetadata("mergeWithUnmatchedConditions6.kt")
public void testMergeWithUnmatchedConditions6() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeWithUnmatchedConditions6.kt");
}
@TestMetadata("mergeWithUnmatchedConditions7.kt")
public void testMergeWithUnmatchedConditions7() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeWithUnmatchedConditions7.kt");
}
@TestMetadata("mergeWithUnmatchedSubjects1.kt")
public void testMergeWithUnmatchedSubjects1() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeWithUnmatchedSubjects1.kt");
}
@TestMetadata("mergeWithUnmatchedSubjects2.kt")
public void testMergeWithUnmatchedSubjects2() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeWithUnmatchedSubjects2.kt");
}
@TestMetadata("mergeWithVarSubject.kt")
public void testMergeWithVarSubject() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeWithVarSubject.kt");
}
@TestMetadata("mergeWithoutSubject.kt")
public void testMergeWithoutSubject() throws Exception {
runTest("idea/testData/intentions/branched/when/merge/mergeWithoutSubject.kt");
}
}
}
}