Introduce "Add remaining when branches" intention #KT-23306 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
bde9a57c9e
commit
2c59f96ca4
+12
@@ -0,0 +1,12 @@
|
||||
enum class Entry {
|
||||
FOO, BAR, BAZ
|
||||
}
|
||||
|
||||
fun test(e: Entry): Int {
|
||||
return when (e) {
|
||||
<spot>Entry.FOO -> 1
|
||||
Entry.BAR -> TODO()
|
||||
Entry.BAZ -> TODO()
|
||||
else -> 0</spot>
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
enum class Entry {
|
||||
FOO, BAR, BAZ
|
||||
}
|
||||
|
||||
fun test(e: Entry): Int {
|
||||
return when (e) {
|
||||
<spot>Entry.FOO -> 1
|
||||
else -> 0</spot>
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This intention adds remaining branches on a <b>when</b> expression.
|
||||
</body>
|
||||
</html>
|
||||
@@ -1633,6 +1633,11 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.kotlin.idea.intentions.AddWhenRemainingBranchesIntention</className>
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.intentions.ObjectLiteralToLambdaInspection"
|
||||
displayName="Object literal can be converted to lambda"
|
||||
groupPath="Kotlin"
|
||||
|
||||
@@ -1633,6 +1633,11 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.kotlin.idea.intentions.AddWhenRemainingBranchesIntention</className>
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.intentions.ObjectLiteralToLambdaInspection"
|
||||
displayName="Object literal can be converted to lambda"
|
||||
groupPath="Kotlin"
|
||||
|
||||
@@ -1633,6 +1633,11 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.kotlin.idea.intentions.AddWhenRemainingBranchesIntention</className>
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.intentions.ObjectLiteralToLambdaInspection"
|
||||
displayName="Object literal can be converted to lambda"
|
||||
groupPath="Kotlin"
|
||||
|
||||
@@ -1634,6 +1634,11 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.kotlin.idea.intentions.AddWhenRemainingBranchesIntention</className>
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.intentions.ObjectLiteralToLambdaInspection"
|
||||
displayName="Object literal can be converted to lambda"
|
||||
groupPath="Kotlin"
|
||||
|
||||
@@ -1633,6 +1633,11 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.kotlin.idea.intentions.AddWhenRemainingBranchesIntention</className>
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.intentions.ObjectLiteralToLambdaInspection"
|
||||
displayName="Object literal can be converted to lambda"
|
||||
groupPath="Kotlin"
|
||||
|
||||
@@ -1633,6 +1633,11 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.kotlin.idea.intentions.AddWhenRemainingBranchesIntention</className>
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.intentions.ObjectLiteralToLambdaInspection"
|
||||
displayName="Object literal can be converted to lambda"
|
||||
groupPath="Kotlin"
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import org.jetbrains.kotlin.idea.quickfix.AddWhenRemainingBranchesFix
|
||||
import org.jetbrains.kotlin.psi.KtWhenExpression
|
||||
|
||||
class AddWhenRemainingBranchesIntention : SelfTargetingIntention<KtWhenExpression>(
|
||||
KtWhenExpression::class.java, "Add remaining branches"
|
||||
) {
|
||||
override fun isApplicableTo(element: KtWhenExpression, caretOffset: Int): Boolean {
|
||||
if (element.entries.none { it.isElse }) return false
|
||||
return AddWhenRemainingBranchesFix.isAvailable(element)
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtWhenExpression, editor: Editor?) {
|
||||
AddWhenRemainingBranchesFix.addRemainingBranches(element)
|
||||
}
|
||||
}
|
||||
@@ -31,8 +31,8 @@ import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
|
||||
class AddWhenRemainingBranchesFix(
|
||||
expression: KtWhenExpression,
|
||||
val withImport: Boolean = false
|
||||
expression: KtWhenExpression,
|
||||
val withImport: Boolean = false
|
||||
) : KotlinQuickFixAction<KtWhenExpression>(expression) {
|
||||
|
||||
override fun getFamilyName() = text
|
||||
@@ -40,48 +40,11 @@ class AddWhenRemainingBranchesFix(
|
||||
override fun getText() = "Add remaining branches" + if (withImport) " with import" else ""
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: KtFile): Boolean {
|
||||
val element = element ?: return false
|
||||
return element.closeBrace != null &&
|
||||
with(WhenChecker.getMissingCases(element, element.analyze())) { isNotEmpty() && !hasUnknown }
|
||||
return isAvailable(element)
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val element = element ?: return
|
||||
val missingCases = WhenChecker.getMissingCases(element, element.analyze())
|
||||
|
||||
val whenCloseBrace = element.closeBrace ?: throw AssertionError("isAvailable should check if close brace exist")
|
||||
val psiFactory = KtPsiFactory(file)
|
||||
|
||||
for (case in missingCases) {
|
||||
val branchConditionText = when (case) {
|
||||
UnknownMissingCase, NullMissingCase, is BooleanMissingCase ->
|
||||
case.branchConditionText
|
||||
is ClassMissingCase ->
|
||||
if (case.classIsSingleton) {
|
||||
case.classFqName.quoteIfNeeded().asString()
|
||||
}
|
||||
else {
|
||||
"is " + case.classFqName.quoteIfNeeded().asString()
|
||||
}
|
||||
}
|
||||
val entry = psiFactory.createWhenEntry("$branchConditionText -> TODO()")
|
||||
element.addBefore(entry, whenCloseBrace)
|
||||
}
|
||||
|
||||
if (withImport) {
|
||||
importAllEntries(element)
|
||||
}
|
||||
}
|
||||
|
||||
private fun importAllEntries(element: KtWhenExpression) {
|
||||
with (ImportAllMembersIntention) {
|
||||
element.entries
|
||||
.map { it.conditions.toList() }
|
||||
.flatten()
|
||||
.firstNotNullResult {
|
||||
(it as? KtWhenConditionWithExpression)?.expression as? KtDotQualifiedExpression
|
||||
}?.importReceiverMembers()
|
||||
}
|
||||
addRemainingBranches(element, withImport)
|
||||
}
|
||||
|
||||
companion object : KotlinIntentionActionsFactory() {
|
||||
@@ -99,5 +62,54 @@ class AddWhenRemainingBranchesFix(
|
||||
}
|
||||
return actions
|
||||
}
|
||||
|
||||
fun isAvailable(element: KtWhenExpression?): Boolean {
|
||||
if (element == null) return false
|
||||
return element.closeBrace != null &&
|
||||
with(WhenChecker.getMissingCases(element, element.analyze())) { isNotEmpty() && !hasUnknown }
|
||||
}
|
||||
|
||||
fun addRemainingBranches(element: KtWhenExpression?, withImport: Boolean = false) {
|
||||
if (element == null) return
|
||||
val missingCases = WhenChecker.getMissingCases(element, element.analyze())
|
||||
|
||||
val whenCloseBrace = element.closeBrace ?: throw AssertionError("isAvailable should check if close brace exist")
|
||||
val elseBranch = element.entries.find { it.isElse }
|
||||
val psiFactory = KtPsiFactory(element)
|
||||
|
||||
for (case in missingCases) {
|
||||
val branchConditionText = when (case) {
|
||||
UnknownMissingCase, NullMissingCase, is BooleanMissingCase ->
|
||||
case.branchConditionText
|
||||
is ClassMissingCase ->
|
||||
if (case.classIsSingleton) {
|
||||
case.classFqName.quoteIfNeeded().asString()
|
||||
} else {
|
||||
"is " + case.classFqName.quoteIfNeeded().asString()
|
||||
}
|
||||
}
|
||||
val entry = psiFactory.createWhenEntry("$branchConditionText -> TODO()")
|
||||
if (elseBranch != null) {
|
||||
element.addBefore(entry, elseBranch)
|
||||
} else {
|
||||
element.addBefore(entry, whenCloseBrace)
|
||||
}
|
||||
}
|
||||
|
||||
if (withImport) {
|
||||
importAllEntries(element)
|
||||
}
|
||||
}
|
||||
|
||||
private fun importAllEntries(element: KtWhenExpression) {
|
||||
with(ImportAllMembersIntention) {
|
||||
element.entries
|
||||
.map { it.conditions.toList() }
|
||||
.flatten()
|
||||
.firstNotNullResult {
|
||||
(it as? KtWhenConditionWithExpression)?.expression as? KtDotQualifiedExpression
|
||||
}?.importReceiverMembers()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.idea.intentions.AddWhenRemainingBranchesIntention
|
||||
@@ -0,0 +1,11 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
enum class Entry {
|
||||
FOO, BAR, BAZ
|
||||
}
|
||||
|
||||
fun test(e: Entry) {
|
||||
<caret>when (e) {
|
||||
Entry.FOO -> {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
enum class Entry {
|
||||
FOO, BAR, BAZ
|
||||
}
|
||||
|
||||
fun test(e: Entry) {
|
||||
<caret>when (e) {
|
||||
Entry.FOO -> {}
|
||||
Entry.BAR -> {}
|
||||
Entry.BAZ -> {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
enum class Entry {
|
||||
FOO, BAR, BAZ
|
||||
}
|
||||
|
||||
fun test(e: Entry) {
|
||||
<caret>when (e) {
|
||||
Entry.FOO -> {}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
enum class Entry {
|
||||
FOO, BAR, BAZ
|
||||
}
|
||||
|
||||
fun test(e: Entry) {
|
||||
<caret>when (e) {
|
||||
Entry.FOO -> {}
|
||||
Entry.BAR -> TODO()
|
||||
Entry.BAZ -> TODO()
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
@@ -1671,6 +1671,34 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/addWhenRemainingBranches")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class AddWhenRemainingBranches extends AbstractIntentionTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInAddWhenRemainingBranches() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/addWhenRemainingBranches"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("noElse.kt")
|
||||
public void testNoElse() throws Exception {
|
||||
runTest("idea/testData/intentions/addWhenRemainingBranches/noElse.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noRemainingBranches.kt")
|
||||
public void testNoRemainingBranches() throws Exception {
|
||||
runTest("idea/testData/intentions/addWhenRemainingBranches/noRemainingBranches.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("idea/testData/intentions/addWhenRemainingBranches/simple.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/anonymousFunctionToLambda")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user