mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-04 15:51:54 +00:00
Simplify boolean with constants intention supports now == (!=) true (false) cases #KT-13777 Fixed
This commit is contained in:
@@ -19,13 +19,15 @@ package org.jetbrains.kotlin.idea.intentions
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.core.copied
|
||||
import org.jetbrains.kotlin.idea.core.replaced
|
||||
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||
|
||||
class SimplifyBooleanWithConstantsInspection : IntentionBasedInspection<KtBinaryExpression>(SimplifyBooleanWithConstantsIntention::class)
|
||||
|
||||
@@ -43,12 +45,13 @@ class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndependentInte
|
||||
|
||||
is KtBinaryExpression -> {
|
||||
val op = element.operationToken
|
||||
if ((op == KtTokens.ANDAND || op == KtTokens.OROR) &&
|
||||
(areThereExpressionsToBeSimplified(element.left) ||
|
||||
areThereExpressionsToBeSimplified(element.right))) return true
|
||||
if (op == ANDAND || op == OROR || op == EQEQ || op == EXCLEQ) {
|
||||
if (areThereExpressionsToBeSimplified(element.left) && element.right.hasBooleanType()) return true
|
||||
if (areThereExpressionsToBeSimplified(element.right) && element.left.hasBooleanType()) return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return element.canBeReducedToBooleanConstant(null)
|
||||
return element.canBeReducedToBooleanConstant()
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
|
||||
@@ -88,7 +91,7 @@ class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndependentInte
|
||||
val left = expression.left
|
||||
val right = expression.right
|
||||
val op = expression.operationToken
|
||||
if (left != null && right != null && (op == KtTokens.ANDAND || op == KtTokens.OROR)) {
|
||||
if (left != null && right != null && (op == ANDAND || op == OROR || op == EQEQ || op == EXCLEQ)) {
|
||||
val simpleLeft = simplifyExpression(left)
|
||||
val simpleRight = simplifyExpression(right)
|
||||
return when {
|
||||
@@ -113,16 +116,30 @@ class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndependentInte
|
||||
}
|
||||
|
||||
private fun toSimplifiedBooleanBinaryExpressionWithConstantOperand(constantOperand: Boolean, otherOperand: KtExpression, operation: IElementType): KtExpression {
|
||||
return when {
|
||||
constantOperand && operation == KtTokens.OROR -> KtPsiFactory(otherOperand).createExpression("true")
|
||||
!constantOperand && operation == KtTokens.ANDAND -> KtPsiFactory(otherOperand).createExpression("false")
|
||||
else -> toSimplifiedExpression(otherOperand)
|
||||
val factory = KtPsiFactory(otherOperand)
|
||||
when (operation) {
|
||||
OROR -> {
|
||||
if (constantOperand) return factory.createExpression("true")
|
||||
}
|
||||
ANDAND -> {
|
||||
if (!constantOperand) return factory.createExpression("false")
|
||||
}
|
||||
EQEQ, EXCLEQ -> toSimplifiedExpression(otherOperand).let {
|
||||
return if (constantOperand == (operation == EQEQ)) it
|
||||
else factory.createExpressionByPattern("!$0", it)
|
||||
}
|
||||
}
|
||||
return toSimplifiedExpression(otherOperand)
|
||||
}
|
||||
|
||||
private fun simplifyExpression(expression: KtExpression) = expression.replaced(toSimplifiedExpression(expression))
|
||||
|
||||
private fun KtExpression.canBeReducedToBooleanConstant(constant: Boolean?): Boolean {
|
||||
private fun KtExpression?.hasBooleanType(): Boolean {
|
||||
val type = this?.getType(this.analyze()) ?: return false
|
||||
return KotlinBuiltIns.isBoolean(type)
|
||||
}
|
||||
|
||||
private fun KtExpression.canBeReducedToBooleanConstant(constant: Boolean? = null): Boolean {
|
||||
return CompileTimeConstantUtils.canBeReducedToBooleanConstant(this, this.analyze(), constant)
|
||||
}
|
||||
|
||||
|
||||
1
idea/testData/intentions/simplifyBooleanWithConstants/equalsConjunction.kt
vendored
Normal file
1
idea/testData/intentions/simplifyBooleanWithConstants/equalsConjunction.kt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
fun foo(x: Boolean): Boolean = <caret>true == (x && false)
|
||||
1
idea/testData/intentions/simplifyBooleanWithConstants/equalsConjunction.kt.after
vendored
Normal file
1
idea/testData/intentions/simplifyBooleanWithConstants/equalsConjunction.kt.after
vendored
Normal file
@@ -0,0 +1 @@
|
||||
fun foo(x: Boolean): Boolean = false
|
||||
1
idea/testData/intentions/simplifyBooleanWithConstants/equalsDisjunction.kt
vendored
Normal file
1
idea/testData/intentions/simplifyBooleanWithConstants/equalsDisjunction.kt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
fun foo(x: Boolean, y: Boolean): Boolean = <caret>(x || y) == false
|
||||
1
idea/testData/intentions/simplifyBooleanWithConstants/equalsDisjunction.kt.after
vendored
Normal file
1
idea/testData/intentions/simplifyBooleanWithConstants/equalsDisjunction.kt.after
vendored
Normal file
@@ -0,0 +1 @@
|
||||
fun foo(x: Boolean, y: Boolean): Boolean = !(x || y)
|
||||
5
idea/testData/intentions/simplifyBooleanWithConstants/equalsFalse.kt
vendored
Normal file
5
idea/testData/intentions/simplifyBooleanWithConstants/equalsFalse.kt
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
fun use(arg: Boolean) {
|
||||
if (false == <caret>arg) {
|
||||
|
||||
}
|
||||
}
|
||||
5
idea/testData/intentions/simplifyBooleanWithConstants/equalsFalse.kt.after
vendored
Normal file
5
idea/testData/intentions/simplifyBooleanWithConstants/equalsFalse.kt.after
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
fun use(arg: Boolean) {
|
||||
if (!arg) {
|
||||
|
||||
}
|
||||
}
|
||||
5
idea/testData/intentions/simplifyBooleanWithConstants/equalsTrue.kt
vendored
Normal file
5
idea/testData/intentions/simplifyBooleanWithConstants/equalsTrue.kt
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
fun use(arg: Boolean) {
|
||||
if (<caret>arg == true) {
|
||||
|
||||
}
|
||||
}
|
||||
5
idea/testData/intentions/simplifyBooleanWithConstants/equalsTrue.kt.after
vendored
Normal file
5
idea/testData/intentions/simplifyBooleanWithConstants/equalsTrue.kt.after
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
fun use(arg: Boolean) {
|
||||
if (arg) {
|
||||
|
||||
}
|
||||
}
|
||||
1
idea/testData/intentions/simplifyBooleanWithConstants/equalsTrueOrFalse.kt
vendored
Normal file
1
idea/testData/intentions/simplifyBooleanWithConstants/equalsTrueOrFalse.kt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
fun foo(arg: Boolean): Boolean = <caret>arg == true || arg == false
|
||||
1
idea/testData/intentions/simplifyBooleanWithConstants/equalsTrueOrFalse.kt.after
vendored
Normal file
1
idea/testData/intentions/simplifyBooleanWithConstants/equalsTrueOrFalse.kt.after
vendored
Normal file
@@ -0,0 +1 @@
|
||||
fun foo(arg: Boolean): Boolean = arg || !arg
|
||||
5
idea/testData/intentions/simplifyBooleanWithConstants/notEqualsFalse.kt
vendored
Normal file
5
idea/testData/intentions/simplifyBooleanWithConstants/notEqualsFalse.kt
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
fun use(arg: Boolean) {
|
||||
if (<caret>arg != false) {
|
||||
|
||||
}
|
||||
}
|
||||
5
idea/testData/intentions/simplifyBooleanWithConstants/notEqualsFalse.kt.after
vendored
Normal file
5
idea/testData/intentions/simplifyBooleanWithConstants/notEqualsFalse.kt.after
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
fun use(arg: Boolean) {
|
||||
if (arg) {
|
||||
|
||||
}
|
||||
}
|
||||
5
idea/testData/intentions/simplifyBooleanWithConstants/notEqualsTrue.kt
vendored
Normal file
5
idea/testData/intentions/simplifyBooleanWithConstants/notEqualsTrue.kt
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
fun use(arg: Boolean) {
|
||||
if (true != <caret>arg) {
|
||||
|
||||
}
|
||||
}
|
||||
5
idea/testData/intentions/simplifyBooleanWithConstants/notEqualsTrue.kt.after
vendored
Normal file
5
idea/testData/intentions/simplifyBooleanWithConstants/notEqualsTrue.kt.after
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
fun use(arg: Boolean) {
|
||||
if (!arg) {
|
||||
|
||||
}
|
||||
}
|
||||
3
idea/testData/intentions/simplifyBooleanWithConstants/nullableBoolean.kt
vendored
Normal file
3
idea/testData/intentions/simplifyBooleanWithConstants/nullableBoolean.kt
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
fun foo(arg: Boolean?): Boolean = <caret>arg == true
|
||||
3
idea/testData/intentions/simplifyBooleanWithConstants/nullableComplex.kt
vendored
Normal file
3
idea/testData/intentions/simplifyBooleanWithConstants/nullableComplex.kt
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
fun foo(arg: Boolean?): Boolean = <caret>arg == true || arg == false
|
||||
@@ -1,3 +1,7 @@
|
||||
fun bar(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
fun foo(y: Boolean) {
|
||||
<caret>true && () && y
|
||||
<caret>true && (bar()) && y
|
||||
}
|
||||
@@ -1,3 +1,7 @@
|
||||
fun bar(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
fun foo(y: Boolean) {
|
||||
() && y
|
||||
bar() && y
|
||||
}
|
||||
@@ -12729,6 +12729,36 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("equalsConjunction.kt")
|
||||
public void testEqualsConjunction() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyBooleanWithConstants/equalsConjunction.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("equalsDisjunction.kt")
|
||||
public void testEqualsDisjunction() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyBooleanWithConstants/equalsDisjunction.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("equalsFalse.kt")
|
||||
public void testEqualsFalse() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyBooleanWithConstants/equalsFalse.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("equalsTrue.kt")
|
||||
public void testEqualsTrue() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyBooleanWithConstants/equalsTrue.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("equalsTrueOrFalse.kt")
|
||||
public void testEqualsTrueOrFalse() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyBooleanWithConstants/equalsTrueOrFalse.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inapplicableNoConstants.kt")
|
||||
public void testInapplicableNoConstants() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyBooleanWithConstants/inapplicableNoConstants.kt");
|
||||
@@ -12759,6 +12789,30 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("notEqualsFalse.kt")
|
||||
public void testNotEqualsFalse() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyBooleanWithConstants/notEqualsFalse.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("notEqualsTrue.kt")
|
||||
public void testNotEqualsTrue() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyBooleanWithConstants/notEqualsTrue.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nullableBoolean.kt")
|
||||
public void testNullableBoolean() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyBooleanWithConstants/nullableBoolean.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nullableComplex.kt")
|
||||
public void testNullableComplex() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyBooleanWithConstants/nullableComplex.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("reduceableBinary.kt")
|
||||
public void testReduceableBinary() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyBooleanWithConstants/reduceableBinary.kt");
|
||||
|
||||
Reference in New Issue
Block a user