"Simplify comparison": remove if when possible after applying quickfix
#KT-25995 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
688fc386b6
commit
5c83c247d7
@@ -26,13 +26,17 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
|||||||
class ConstantConditionIfInspection : AbstractKotlinInspection() {
|
class ConstantConditionIfInspection : AbstractKotlinInspection() {
|
||||||
|
|
||||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
|
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
|
||||||
return ifExpressionVisitor(fun(expression) {
|
return ifExpressionVisitor { expression -> collectFixesAndRegisterProblem(expression, holder) }
|
||||||
val condition = expression.condition ?: return
|
}
|
||||||
|
|
||||||
|
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 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) {
|
if (expression.branch(constantValue) != null) {
|
||||||
val keepBraces = expression.isElseIf() && expression.branch(constantValue) is KtBlockExpression
|
val keepBraces = expression.isElseIf() && expression.branch(constantValue) is KtBlockExpression
|
||||||
@@ -43,39 +47,57 @@ class ConstantConditionIfInspection : AbstractKotlinInspection() {
|
|||||||
fixes += RemoveFix()
|
fixes += RemoveFix()
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.registerProblem(condition,
|
holder?.registerProblem(
|
||||||
"Condition is always '$constantValue'",
|
condition,
|
||||||
*fixes.toTypedArray())
|
"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 class SimplifyFix(
|
||||||
private val conditionValue: Boolean,
|
private val conditionValue: Boolean,
|
||||||
private val isUsedAsExpression: Boolean,
|
private val isUsedAsExpression: Boolean,
|
||||||
private val keepBraces: Boolean
|
private val keepBraces: Boolean
|
||||||
) : LocalQuickFix {
|
) : ConstantConditionIfFix {
|
||||||
override fun getFamilyName() = name
|
override fun getFamilyName() = name
|
||||||
|
|
||||||
override fun getName() = "Simplify expression"
|
override fun getName() = "Simplify expression"
|
||||||
|
|
||||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||||
val ifExpression = descriptor.psiElement.getParentOfType<KtIfExpression>(strict = true) ?: return
|
val ifExpression = descriptor.psiElement.getParentOfType<KtIfExpression>(strict = true) ?: return
|
||||||
|
applyFix(ifExpression)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun applyFix(ifExpression: KtIfExpression) {
|
||||||
val branch = ifExpression.branch(conditionValue)?.let {
|
val branch = ifExpression.branch(conditionValue)?.let {
|
||||||
if (keepBraces) it else it.unwrapBlockOrParenthesis()
|
if (keepBraces) it else it.unwrapBlockOrParenthesis()
|
||||||
} ?: return
|
} ?: return
|
||||||
|
|
||||||
ifExpression.replaceWithBranch(branch, isUsedAsExpression, keepBraces)
|
ifExpression.replaceWithBranch(branch, isUsedAsExpression, keepBraces)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RemoveFix : LocalQuickFix {
|
private class RemoveFix : ConstantConditionIfFix {
|
||||||
override fun getFamilyName() = name
|
override fun getFamilyName() = name
|
||||||
|
|
||||||
override fun getName() = "Delete expression"
|
override fun getName() = "Delete expression"
|
||||||
|
|
||||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||||
val ifExpression = descriptor.psiElement.getParentOfType<KtIfExpression>(strict = true) ?: return
|
val ifExpression = descriptor.psiElement.getParentOfType<KtIfExpression>(strict = true) ?: return
|
||||||
|
applyFix(ifExpression)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun applyFix(ifExpression: KtIfExpression) {
|
||||||
ifExpression.delete()
|
ifExpression.delete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,8 +125,7 @@ fun KtExpression.replaceWithBranch(branch: KtExpression, isUsedAsExpression: Boo
|
|||||||
if (firstChildSibling != lastChild) {
|
if (firstChildSibling != lastChild) {
|
||||||
if (keepBraces) {
|
if (keepBraces) {
|
||||||
parent.addAfter(branch, this)
|
parent.addAfter(branch, this)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
parent.addRangeAfter(firstChildSibling, lastChild.prevSibling, this)
|
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.Diagnostic
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticWithParameters2
|
import org.jetbrains.kotlin.diagnostics.DiagnosticWithParameters2
|
||||||
import org.jetbrains.kotlin.idea.core.replaced
|
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.idea.intentions.SimplifyBooleanWithConstantsIntention
|
||||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
|
||||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
|
|
||||||
class SimplifyComparisonFix(element: KtExpression, val value: Boolean) : KotlinQuickFixAction<KtExpression>(element) {
|
class SimplifyComparisonFix(element: KtExpression, val value: Boolean) : KotlinQuickFixAction<KtExpression>(element) {
|
||||||
override fun getFamilyName() = "Simplify $element to '$value'"
|
override fun getFamilyName() = "Simplify $element to '$value'"
|
||||||
@@ -43,10 +42,12 @@ class SimplifyComparisonFix(element: KtExpression, val value: Boolean) : KotlinQ
|
|||||||
val simplifyIntention = SimplifyBooleanWithConstantsIntention()
|
val simplifyIntention = SimplifyBooleanWithConstantsIntention()
|
||||||
if (booleanExpression != null && simplifyIntention.isApplicableTo(booleanExpression)) {
|
if (booleanExpression != null && simplifyIntention.isApplicableTo(booleanExpression)) {
|
||||||
simplifyIntention.applyTo(booleanExpression, editor)
|
simplifyIntention.applyTo(booleanExpression, editor)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
simplifyIntention.removeRedundantAssertion(result)
|
simplifyIntention.removeRedundantAssertion(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val ifExpression = result.getStrictParentOfType<KtIfExpression>()?.takeIf { it.condition == result }
|
||||||
|
if (ifExpression != null) ConstantConditionIfInspection.applyFixIfSingle(ifExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object : KotlinSingleIntentionActionFactory() {
|
companion object : KotlinSingleIntentionActionFactory() {
|
||||||
|
|||||||
+4
-2
@@ -5,7 +5,9 @@ fun foo(x: String?) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (<caret>x == null) {
|
if (<caret>x == null) {
|
||||||
|
bar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun bar() {}
|
||||||
@@ -4,8 +4,7 @@ fun foo(x: String?) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (false) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun bar() {}
|
||||||
+4
-2
@@ -1,6 +1,8 @@
|
|||||||
// "Simplify comparison" "true"
|
// "Simplify comparison" "true"
|
||||||
fun foo(x: Int) {
|
fun foo(x: Int) {
|
||||||
if (<caret>x != null) {
|
if (<caret>x != null) {
|
||||||
|
bar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun bar() {}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
// "Simplify comparison" "true"
|
// "Simplify comparison" "true"
|
||||||
fun foo(x: Int) {
|
fun foo(x: Int) {
|
||||||
if (true) {
|
bar()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
fun bar() {}
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user