Quick fix "add when remaining branches" refactoring + enum / sealed generated name w/o package name
This commit is contained in:
@@ -37,7 +37,6 @@ import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumClass
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import java.util.*
|
||||
|
||||
interface WhenMissingCase {
|
||||
@@ -132,7 +131,9 @@ private object WhenOnBooleanExhaustivenessChecker : WhenExhaustivenessChecker {
|
||||
private class ClassMissingCase(val descriptor: ClassDescriptor): WhenMissingCase {
|
||||
override fun toString() = descriptor.name.identifier.let { if (descriptor.kind.isSingleton) it else "is $it" }
|
||||
|
||||
override val branchConditionText = descriptor.fqNameSafe.asString().let { if (descriptor.kind.isSingleton) it else "is $it" }
|
||||
override val branchConditionText = DescriptorUtils.getFqNameFromTopLevelClass(descriptor).asString().let {
|
||||
if (descriptor.kind.isSingleton) it else "is $it"
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class WhenOnClassExhaustivenessChecker : WhenExhaustivenessChecker {
|
||||
|
||||
@@ -150,8 +150,6 @@ remove.val.var.from.parameter=Remove ''{0}'' from parameter
|
||||
add.override.to.equals.hashCode.toString=Add 'override' to equals, hashCode, toString in project
|
||||
add.when.else.branch.action.family.name=Add else branch
|
||||
add.when.else.branch.action=Add else branch
|
||||
add.when.remaining.branches.action.family.name=Add remaining branches
|
||||
add.when.remaining.branches.action=Add remaining branches
|
||||
move.when.else.branch.to.the.end.action=Move else branch to the end
|
||||
move.when.else.branch.to.the.end.family.name=Move else branch to the end
|
||||
change.to.property.name.family.name=Change to property name
|
||||
|
||||
@@ -16,20 +16,18 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.quickfix
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightUtilCore
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.cfg.WhenChecker
|
||||
import org.jetbrains.kotlin.cfg.hasUnknown
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.KtWhenEntry
|
||||
import org.jetbrains.kotlin.psi.KtWhenExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
|
||||
class AddWhenRemainingBranchesFix(expression: KtWhenExpression) : KotlinQuickFixAction<KtWhenExpression>(expression) {
|
||||
|
||||
@@ -37,10 +35,11 @@ class AddWhenRemainingBranchesFix(expression: KtWhenExpression) : KotlinQuickFix
|
||||
|
||||
override fun getText() = "Add remaining branches"
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
return super.isAvailable(project, editor, file) && element.closeBrace != null &&
|
||||
!WhenChecker.getNecessaryCases(element, element.analyze()).hasUnknown
|
||||
}
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean =
|
||||
super.isAvailable(project, editor, file) && element.closeBrace != null &&
|
||||
with(WhenChecker.getNecessaryCases(element, element.analyze())) {
|
||||
isNotEmpty() && !hasUnknown
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val necessaryCases = WhenChecker.getNecessaryCases(element, element.analyze())
|
||||
@@ -48,33 +47,18 @@ class AddWhenRemainingBranchesFix(expression: KtWhenExpression) : KotlinQuickFix
|
||||
val whenCloseBrace = element.closeBrace
|
||||
assert(whenCloseBrace != null) { "isAvailable should check if close brace exist" }
|
||||
val psiFactory = KtPsiFactory(file)
|
||||
var insertedBranch: PsiElement? = null
|
||||
|
||||
for (case in necessaryCases) {
|
||||
val entry = psiFactory.createWhenEntry("${case.branchConditionText} -> throw AssertionError(\"\")")
|
||||
insertedBranch = element.addBefore(entry, whenCloseBrace)
|
||||
val entry = psiFactory.createWhenEntry("${case.branchConditionText} -> TODO()")
|
||||
val insertedBranch = element.addBefore(entry, whenCloseBrace)
|
||||
element.addAfter(psiFactory.createNewLine(), insertedBranch)
|
||||
|
||||
}
|
||||
|
||||
if (insertedBranch != null) {
|
||||
val insertedWhenEntry = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(insertedBranch) as KtWhenEntry
|
||||
val textRange = insertedWhenEntry.textRange
|
||||
val indexOfOpenBrace = insertedWhenEntry.text.indexOf('{')
|
||||
editor!!.caretModel.moveToOffset(textRange.startOffset + indexOfOpenBrace + 1)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun createFactory(): KotlinSingleIntentionActionFactory {
|
||||
return object : KotlinSingleIntentionActionFactory() {
|
||||
public override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction<out PsiElement>? {
|
||||
val element = diagnostic.psiElement
|
||||
val whenExpression = PsiTreeUtil.getParentOfType(element, KtWhenExpression::class.java, false) ?: return null
|
||||
return AddWhenRemainingBranchesFix(whenExpression)
|
||||
}
|
||||
}
|
||||
companion object : KotlinSingleIntentionActionFactory() {
|
||||
override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction<out PsiElement>? {
|
||||
val whenExpression = diagnostic.psiElement.getNonStrictParentOfType<KtWhenExpression>() ?: return null
|
||||
return AddWhenRemainingBranchesFix(whenExpression)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,7 +189,7 @@ class QuickFixRegistrar : QuickFixContributor {
|
||||
|
||||
ELSE_MISPLACED_IN_WHEN.registerFactory(MoveWhenElseBranchFix.createFactory())
|
||||
NO_ELSE_IN_WHEN.registerFactory(AddWhenElseBranchFix.createFactory())
|
||||
NO_ELSE_IN_WHEN.registerFactory(AddWhenRemainingBranchesFix.createFactory())
|
||||
NO_ELSE_IN_WHEN.registerFactory(AddWhenRemainingBranchesFix)
|
||||
BREAK_OR_CONTINUE_IN_WHEN.registerFactory(AddLoopLabelFix)
|
||||
|
||||
NO_TYPE_ARGUMENTS_ON_RHS.registerFactory(AddStarProjectionsFix.createFactoryForIsExpression())
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// "Add remaining branches" "true"
|
||||
// ERROR: Unresolved reference: TODO
|
||||
fun test(b: Boolean) = wh<caret>en(b) {
|
||||
false -> 0
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// "Add remaining branches" "true"
|
||||
// ERROR: Unresolved reference: TODO
|
||||
fun test(b: Boolean) = when(b) {
|
||||
false -> 0
|
||||
true -> throw AssertionError("")
|
||||
true -> TODO()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// "Add remaining branches" "true"
|
||||
// ERROR: Unresolved reference: TODO
|
||||
// ERROR: Unresolved reference: TODO
|
||||
enum class Color { R, G, B }
|
||||
fun test(c: Color) = wh<caret>en(c) {
|
||||
Color.B -> 0xff
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
// "Add remaining branches" "true"
|
||||
// ERROR: Unresolved reference: TODO
|
||||
// ERROR: Unresolved reference: TODO
|
||||
enum class Color { R, G, B }
|
||||
fun test(c: Color) = when(c) {
|
||||
Color.B -> 0xff
|
||||
Color.R -> throw AssertionError("")
|
||||
Color.G -> throw AssertionError("")
|
||||
Color.R -> TODO()
|
||||
Color.G -> TODO()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Add remaining branches" "true"
|
||||
// ERROR: Unresolved reference: TODO
|
||||
// ERROR: Unresolved reference: TODO
|
||||
package test
|
||||
enum class Color { R, G, B }
|
||||
fun test(c: Color) = wh<caret>en(c) {
|
||||
Color.B -> 0xff
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Add remaining branches" "true"
|
||||
// ERROR: Unresolved reference: TODO
|
||||
// ERROR: Unresolved reference: TODO
|
||||
package test
|
||||
enum class Color { R, G, B }
|
||||
fun test(c: Color) = when(c) {
|
||||
Color.B -> 0xff
|
||||
Color.R -> TODO()
|
||||
Color.G -> TODO()
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
// "Add remaining branches" "true"
|
||||
// ERROR: Unresolved reference: TODO
|
||||
// ERROR: Unresolved reference: TODO
|
||||
// ERROR: Unresolved reference: TODO
|
||||
sealed class Variant {
|
||||
object Singleton : Variant()
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// "Add remaining branches" "true"
|
||||
// ERROR: Unresolved reference: TODO
|
||||
// ERROR: Unresolved reference: TODO
|
||||
// ERROR: Unresolved reference: TODO
|
||||
sealed class Variant {
|
||||
object Singleton : Variant()
|
||||
|
||||
@@ -8,7 +11,7 @@ sealed class Variant {
|
||||
}
|
||||
fun test(v: Variant?) = when(v) {
|
||||
Variant.Singleton -> "s"
|
||||
is Variant.Something -> throw AssertionError("")
|
||||
Variant.Another -> throw AssertionError("")
|
||||
null -> throw AssertionError("")
|
||||
is Variant.Something -> TODO()
|
||||
Variant.Another -> TODO()
|
||||
null -> TODO()
|
||||
}
|
||||
|
||||
@@ -7580,6 +7580,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("addRemainingBranchesInNonDefaultPackage.kt")
|
||||
public void testAddRemainingBranchesInNonDefaultPackage() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/when/addRemainingBranchesInNonDefaultPackage.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("addRemainingBranchesSealed.kt")
|
||||
public void testAddRemainingBranchesSealed() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/when/addRemainingBranchesSealed.kt");
|
||||
|
||||
Reference in New Issue
Block a user