"Simplify comparison": remove if when possible after applying quickfix

#KT-25995 Fixed
This commit is contained in:
Toshiaki Kameyama
2018-08-28 05:39:04 +03:00
committed by Mikhail Glukhikh
parent 688fc386b6
commit 5c83c247d7
6 changed files with 58 additions and 33 deletions
@@ -26,13 +26,17 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class ConstantConditionIfInspection : AbstractKotlinInspection() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return ifExpressionVisitor(fun(expression) {
val condition = expression.condition ?: return
return ifExpressionVisitor { expression -> collectFixesAndRegisterProblem(expression, holder) }
}
companion object {
private fun collectFixesAndRegisterProblem(expression: KtIfExpression, holder: ProblemsHolder?): List<ConstantConditionIfFix> {
val condition = expression.condition ?: return emptyList()
val context = condition.analyze(BodyResolveMode.PARTIAL_WITH_CFA)
val constantValue = condition.constantBooleanValue(context) ?: return
val constantValue = condition.constantBooleanValue(context) ?: return emptyList()
val fixes = mutableListOf<LocalQuickFix>()
val fixes = mutableListOf<ConstantConditionIfFix>()
if (expression.branch(constantValue) != null) {
val keepBraces = expression.isElseIf() && expression.branch(constantValue) is KtBlockExpression
@@ -43,39 +47,57 @@ class ConstantConditionIfInspection : AbstractKotlinInspection() {
fixes += RemoveFix()
}
holder.registerProblem(condition,
"Condition is always '$constantValue'",
*fixes.toTypedArray())
})
holder?.registerProblem(
condition,
"Condition is always '$constantValue'",
*fixes.toTypedArray()
)
return fixes
}
fun applyFixIfSingle(ifExpression: KtIfExpression) {
collectFixesAndRegisterProblem(ifExpression, null).singleOrNull()?.applyFix(ifExpression)
}
}
private interface ConstantConditionIfFix : LocalQuickFix {
fun applyFix(ifExpression: KtIfExpression)
}
private class SimplifyFix(
private val conditionValue: Boolean,
private val isUsedAsExpression: Boolean,
private val keepBraces: Boolean
) : LocalQuickFix {
private val conditionValue: Boolean,
private val isUsedAsExpression: Boolean,
private val keepBraces: Boolean
) : ConstantConditionIfFix {
override fun getFamilyName() = name
override fun getName() = "Simplify expression"
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val ifExpression = descriptor.psiElement.getParentOfType<KtIfExpression>(strict = true) ?: return
applyFix(ifExpression)
}
override fun applyFix(ifExpression: KtIfExpression) {
val branch = ifExpression.branch(conditionValue)?.let {
if (keepBraces) it else it.unwrapBlockOrParenthesis()
} ?: return
ifExpression.replaceWithBranch(branch, isUsedAsExpression, keepBraces)
}
}
private class RemoveFix : LocalQuickFix {
private class RemoveFix : ConstantConditionIfFix {
override fun getFamilyName() = name
override fun getName() = "Delete expression"
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val ifExpression = descriptor.psiElement.getParentOfType<KtIfExpression>(strict = true) ?: return
applyFix(ifExpression)
}
override fun applyFix(ifExpression: KtIfExpression) {
ifExpression.delete()
}
}
@@ -103,8 +125,7 @@ fun KtExpression.replaceWithBranch(branch: KtExpression, isUsedAsExpression: Boo
if (firstChildSibling != lastChild) {
if (keepBraces) {
parent.addAfter(branch, this)
}
else {
} else {
parent.addRangeAfter(firstChildSibling, lastChild.prevSibling, this)
}
}
@@ -22,12 +22,11 @@ import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticWithParameters2
import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.inspections.ConstantConditionIfInspection
import org.jetbrains.kotlin.idea.intentions.SimplifyBooleanWithConstantsIntention
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
class SimplifyComparisonFix(element: KtExpression, val value: Boolean) : KotlinQuickFixAction<KtExpression>(element) {
override fun getFamilyName() = "Simplify $element to '$value'"
@@ -43,10 +42,12 @@ class SimplifyComparisonFix(element: KtExpression, val value: Boolean) : KotlinQ
val simplifyIntention = SimplifyBooleanWithConstantsIntention()
if (booleanExpression != null && simplifyIntention.isApplicableTo(booleanExpression)) {
simplifyIntention.applyTo(booleanExpression, editor)
}
else {
} else {
simplifyIntention.removeRedundantAssertion(result)
}
val ifExpression = result.getStrictParentOfType<KtIfExpression>()?.takeIf { it.condition == result }
if (ifExpression != null) ConstantConditionIfInspection.applyFixIfSingle(ifExpression)
}
companion object : KotlinSingleIntentionActionFactory() {
+4 -2
View File
@@ -5,7 +5,9 @@ fun foo(x: String?) {
}
else {
if (<caret>x == null) {
bar()
}
}
}
}
fun bar() {}
@@ -4,8 +4,7 @@ fun foo(x: String?) {
}
else {
if (false) {
}
}
}
}
fun bar() {}
+4 -2
View File
@@ -1,6 +1,8 @@
// "Simplify comparison" "true"
fun foo(x: Int) {
if (<caret>x != null) {
bar()
}
}
}
fun bar() {}
+3 -3
View File
@@ -1,6 +1,6 @@
// "Simplify comparison" "true"
fun foo(x: Int) {
if (true) {
bar()
}
}
}
fun bar() {}