diff --git a/idea/resources/intentionDescriptions/AddWhenRemainingBranchesIntention/after.kt.template b/idea/resources/intentionDescriptions/AddWhenRemainingBranchesIntention/after.kt.template
new file mode 100644
index 00000000000..18050671af0
--- /dev/null
+++ b/idea/resources/intentionDescriptions/AddWhenRemainingBranchesIntention/after.kt.template
@@ -0,0 +1,12 @@
+enum class Entry {
+ FOO, BAR, BAZ
+}
+
+fun test(e: Entry): Int {
+ return when (e) {
+ Entry.FOO -> 1
+ Entry.BAR -> TODO()
+ Entry.BAZ -> TODO()
+ else -> 0
+ }
+}
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/AddWhenRemainingBranchesIntention/before.kt.template b/idea/resources/intentionDescriptions/AddWhenRemainingBranchesIntention/before.kt.template
new file mode 100644
index 00000000000..1821a49ec2c
--- /dev/null
+++ b/idea/resources/intentionDescriptions/AddWhenRemainingBranchesIntention/before.kt.template
@@ -0,0 +1,10 @@
+enum class Entry {
+ FOO, BAR, BAZ
+}
+
+fun test(e: Entry): Int {
+ return when (e) {
+ Entry.FOO -> 1
+ else -> 0
+ }
+}
\ No newline at end of file
diff --git a/idea/resources/intentionDescriptions/AddWhenRemainingBranchesIntention/description.html b/idea/resources/intentionDescriptions/AddWhenRemainingBranchesIntention/description.html
new file mode 100644
index 00000000000..4680d1b1d19
--- /dev/null
+++ b/idea/resources/intentionDescriptions/AddWhenRemainingBranchesIntention/description.html
@@ -0,0 +1,5 @@
+
+
+This intention adds remaining branches on a when expression.
+
+
diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index 3ca61100277..2084a17b018 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -1633,6 +1633,11 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.AddWhenRemainingBranchesIntention
+ Kotlin
+
+
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.AddWhenRemainingBranchesIntention
+ Kotlin
+
+
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.AddWhenRemainingBranchesIntention
+ Kotlin
+
+
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.AddWhenRemainingBranchesIntention
+ Kotlin
+
+
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.AddWhenRemainingBranchesIntention
+ Kotlin
+
+
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.AddWhenRemainingBranchesIntention
+ Kotlin
+
+
(
+ 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)
+ }
+}
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddWhenRemainingBranchesFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddWhenRemainingBranchesFix.kt
index 6a56036e34a..81a005148ea 100644
--- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddWhenRemainingBranchesFix.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddWhenRemainingBranchesFix.kt
@@ -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(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()
+ }
+ }
}
}
\ No newline at end of file
diff --git a/idea/testData/intentions/addWhenRemainingBranches/.intention b/idea/testData/intentions/addWhenRemainingBranches/.intention
new file mode 100644
index 00000000000..5ddf71e23da
--- /dev/null
+++ b/idea/testData/intentions/addWhenRemainingBranches/.intention
@@ -0,0 +1 @@
+org.jetbrains.kotlin.idea.intentions.AddWhenRemainingBranchesIntention
\ No newline at end of file
diff --git a/idea/testData/intentions/addWhenRemainingBranches/noElse.kt b/idea/testData/intentions/addWhenRemainingBranches/noElse.kt
new file mode 100644
index 00000000000..70f62167247
--- /dev/null
+++ b/idea/testData/intentions/addWhenRemainingBranches/noElse.kt
@@ -0,0 +1,11 @@
+// IS_APPLICABLE: false
+
+enum class Entry {
+ FOO, BAR, BAZ
+}
+
+fun test(e: Entry) {
+ when (e) {
+ Entry.FOO -> {}
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/addWhenRemainingBranches/noRemainingBranches.kt b/idea/testData/intentions/addWhenRemainingBranches/noRemainingBranches.kt
new file mode 100644
index 00000000000..b2eb648df55
--- /dev/null
+++ b/idea/testData/intentions/addWhenRemainingBranches/noRemainingBranches.kt
@@ -0,0 +1,13 @@
+// IS_APPLICABLE: false
+
+enum class Entry {
+ FOO, BAR, BAZ
+}
+
+fun test(e: Entry) {
+ when (e) {
+ Entry.FOO -> {}
+ Entry.BAR -> {}
+ Entry.BAZ -> {}
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/addWhenRemainingBranches/simple.kt b/idea/testData/intentions/addWhenRemainingBranches/simple.kt
new file mode 100644
index 00000000000..1c9eeb45a0b
--- /dev/null
+++ b/idea/testData/intentions/addWhenRemainingBranches/simple.kt
@@ -0,0 +1,12 @@
+// WITH_RUNTIME
+
+enum class Entry {
+ FOO, BAR, BAZ
+}
+
+fun test(e: Entry) {
+ when (e) {
+ Entry.FOO -> {}
+ else -> {}
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/addWhenRemainingBranches/simple.kt.after b/idea/testData/intentions/addWhenRemainingBranches/simple.kt.after
new file mode 100644
index 00000000000..c8924b4b8ac
--- /dev/null
+++ b/idea/testData/intentions/addWhenRemainingBranches/simple.kt.after
@@ -0,0 +1,14 @@
+// WITH_RUNTIME
+
+enum class Entry {
+ FOO, BAR, BAZ
+}
+
+fun test(e: Entry) {
+ when (e) {
+ Entry.FOO -> {}
+ Entry.BAR -> TODO()
+ Entry.BAZ -> TODO()
+ else -> {}
+ }
+}
\ 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 4809d8e4ac7..0f8b7e91db6 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
@@ -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)