"Simplify boolean expression": handle Boolean? comparison correctly
So #KT-23377 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
a495c2e5ea
commit
f91819ace7
+12
-7
@@ -35,14 +35,15 @@ import org.jetbrains.kotlin.types.isFlexible
|
|||||||
|
|
||||||
class SimplifyBooleanWithConstantsInspection : IntentionBasedInspection<KtBinaryExpression>(SimplifyBooleanWithConstantsIntention::class)
|
class SimplifyBooleanWithConstantsInspection : IntentionBasedInspection<KtBinaryExpression>(SimplifyBooleanWithConstantsIntention::class)
|
||||||
|
|
||||||
class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(KtBinaryExpression::class.java, "Simplify boolean expression") {
|
class SimplifyBooleanWithConstantsIntention :
|
||||||
|
SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(KtBinaryExpression::class.java, "Simplify boolean expression") {
|
||||||
|
|
||||||
override fun isApplicableTo(element: KtBinaryExpression): Boolean {
|
override fun isApplicableTo(element: KtBinaryExpression): Boolean {
|
||||||
val topBinary = PsiTreeUtil.getTopmostParentOfType(element, KtBinaryExpression::class.java) ?: element
|
val topBinary = PsiTreeUtil.getTopmostParentOfType(element, KtBinaryExpression::class.java) ?: element
|
||||||
return areThereExpressionsToBeSimplified(topBinary)
|
return areThereExpressionsToBeSimplified(topBinary)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun areThereExpressionsToBeSimplified(element: KtExpression?) : Boolean {
|
private fun areThereExpressionsToBeSimplified(element: KtExpression?): Boolean {
|
||||||
if (element == null) return false
|
if (element == null) return false
|
||||||
when (element) {
|
when (element) {
|
||||||
is KtParenthesizedExpression -> return areThereExpressionsToBeSimplified(element.expression)
|
is KtParenthesizedExpression -> return areThereExpressionsToBeSimplified(element.expression)
|
||||||
@@ -70,14 +71,14 @@ class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndependentInte
|
|||||||
val fqName = callExpression.getCallableDescriptor()?.fqNameOrNull()
|
val fqName = callExpression.getCallableDescriptor()?.fqNameOrNull()
|
||||||
val valueArguments = callExpression.valueArguments
|
val valueArguments = callExpression.valueArguments
|
||||||
val isRedundant = fqName?.asString() == "kotlin.assert" &&
|
val isRedundant = fqName?.asString() == "kotlin.assert" &&
|
||||||
valueArguments.singleOrNull()?.getArgumentExpression().isTrueConstant()
|
valueArguments.singleOrNull()?.getArgumentExpression().isTrueConstant()
|
||||||
if (isRedundant) callExpression.delete()
|
if (isRedundant) callExpression.delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toSimplifiedExpression(expression: KtExpression): KtExpression {
|
private fun toSimplifiedExpression(expression: KtExpression): KtExpression {
|
||||||
val psiFactory = KtPsiFactory(expression)
|
val psiFactory = KtPsiFactory(expression)
|
||||||
|
|
||||||
when {
|
when {
|
||||||
expression.canBeReducedToTrue() -> {
|
expression.canBeReducedToTrue() -> {
|
||||||
return psiFactory.createExpression("true")
|
return psiFactory.createExpression("true")
|
||||||
}
|
}
|
||||||
@@ -93,8 +94,7 @@ class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndependentInte
|
|||||||
return if (simplified is KtBinaryExpression) {
|
return if (simplified is KtBinaryExpression) {
|
||||||
// wrap in new parentheses to keep the user's original format
|
// wrap in new parentheses to keep the user's original format
|
||||||
psiFactory.createExpressionByPattern("($0)", simplified)
|
psiFactory.createExpressionByPattern("($0)", simplified)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// if we now have a simpleName, constant, or parenthesized we don't need parentheses
|
// if we now have a simpleName, constant, or parenthesized we don't need parentheses
|
||||||
simplified
|
simplified
|
||||||
}
|
}
|
||||||
@@ -102,6 +102,7 @@ class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndependentInte
|
|||||||
}
|
}
|
||||||
|
|
||||||
expression is KtBinaryExpression -> {
|
expression is KtBinaryExpression -> {
|
||||||
|
if (!areThereExpressionsToBeSimplified(expression)) return expression.copied()
|
||||||
val left = expression.left
|
val left = expression.left
|
||||||
val right = expression.right
|
val right = expression.right
|
||||||
val op = expression.operationToken
|
val op = expression.operationToken
|
||||||
@@ -129,7 +130,11 @@ class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndependentInte
|
|||||||
return expression.copied()
|
return expression.copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toSimplifiedBooleanBinaryExpressionWithConstantOperand(constantOperand: Boolean, otherOperand: KtExpression, operation: IElementType): KtExpression {
|
private fun toSimplifiedBooleanBinaryExpressionWithConstantOperand(
|
||||||
|
constantOperand: Boolean,
|
||||||
|
otherOperand: KtExpression,
|
||||||
|
operation: IElementType
|
||||||
|
): KtExpression {
|
||||||
val factory = KtPsiFactory(otherOperand)
|
val factory = KtPsiFactory(otherOperand)
|
||||||
when (operation) {
|
when (operation) {
|
||||||
OROR -> {
|
OROR -> {
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
data class Test(val notnull: Boolean, val nullable: Boolean?)
|
||||||
|
|
||||||
|
fun test(a: Test, b: Test?) {
|
||||||
|
<caret>a.notnull == true || a.nullable == true || b?.notnull == true || b?.nullable == true
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
data class Test(val notnull: Boolean, val nullable: Boolean?)
|
||||||
|
|
||||||
|
fun test(a: Test, b: Test?) {
|
||||||
|
a.notnull || a.nullable == true || b?.notnull == true || b?.nullable == true
|
||||||
|
}
|
||||||
@@ -15399,6 +15399,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("nullableComplex2.kt")
|
||||||
|
public void testNullableComplex2() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyBooleanWithConstants/nullableComplex2.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("reduceableBinary.kt")
|
@TestMetadata("reduceableBinary.kt")
|
||||||
public void testReduceableBinary() throws Exception {
|
public void testReduceableBinary() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyBooleanWithConstants/reduceableBinary.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyBooleanWithConstants/reduceableBinary.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user