Fix false positive in +0.0 == -0.0 comparison simplification (KT-17735)
This commit is contained in:
+31
@@ -18,10 +18,13 @@ import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.psi2ir.deparenthesize
|
||||
import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode.PARTIAL
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.isFlexible
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
@@ -47,12 +50,40 @@ class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndependentInte
|
||||
if (areThereExpressionsToBeSimplified(element.left) && element.right.hasBooleanType()) return true
|
||||
if (areThereExpressionsToBeSimplified(element.right) && element.left.hasBooleanType()) return true
|
||||
}
|
||||
if (isPositiveNegativeZeroComparison(element)) return false
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return element.canBeReducedToBooleanConstant()
|
||||
}
|
||||
|
||||
private fun isPositiveNegativeZeroComparison(element: KtBinaryExpression): Boolean {
|
||||
val op = element.operationToken
|
||||
if (op != EQEQ && op != EQEQEQ) {
|
||||
return false
|
||||
}
|
||||
|
||||
val left = element.left?.deparenthesize() as? KtExpression ?: return false
|
||||
val right = element.right?.deparenthesize() as? KtExpression ?: return false
|
||||
|
||||
val context = element.analyze(PARTIAL)
|
||||
|
||||
fun KtExpression.getConstantValue() =
|
||||
ConstantExpressionEvaluator.getConstant(this, context)?.toConstantValue(TypeUtils.NO_EXPECTED_TYPE)?.value
|
||||
|
||||
val leftValue = left.getConstantValue()
|
||||
val rightValue = right.getConstantValue()
|
||||
|
||||
fun isPositiveZero(value: Any?) = value == +0.0 || value == +0.0f
|
||||
fun isNegativeZero(value: Any?) = value == -0.0 || value == -0.0f
|
||||
|
||||
val hasPositiveZero = isPositiveZero(leftValue) || isPositiveZero(rightValue)
|
||||
val hasNegativeZero = isNegativeZero(leftValue) || isNegativeZero(rightValue)
|
||||
|
||||
return hasPositiveZero && hasNegativeZero
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
|
||||
val topBinary = element.topBinary()
|
||||
val simplified = toSimplifiedExpression(topBinary)
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
fun foo() {
|
||||
-0.0 <caret>== +0.0
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
fun foo() {
|
||||
+0.0f <caret>== -0.0f
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun foo() {
|
||||
+0.0f <caret>== +0.0f
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun foo() {
|
||||
true
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
fun foo(y: Boolean) {
|
||||
0.0f <caret>=== -0.0f
|
||||
}
|
||||
@@ -15703,6 +15703,26 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
runTest("idea/testData/intentions/simplifyBooleanWithConstants/nullableComplex2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("positiveZeroNegativeZero1.kt")
|
||||
public void testPositiveZeroNegativeZero1() throws Exception {
|
||||
runTest("idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("positiveZeroNegativeZero2.kt")
|
||||
public void testPositiveZeroNegativeZero2() throws Exception {
|
||||
runTest("idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("positiveZeroNegativeZero3.kt")
|
||||
public void testPositiveZeroNegativeZero3() throws Exception {
|
||||
runTest("idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero3.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("positiveZeroNegativeZero4.kt")
|
||||
public void testPositiveZeroNegativeZero4() throws Exception {
|
||||
runTest("idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero4.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("reduceableBinary.kt")
|
||||
public void testReduceableBinary() throws Exception {
|
||||
runTest("idea/testData/intentions/simplifyBooleanWithConstants/reduceableBinary.kt");
|
||||
|
||||
Reference in New Issue
Block a user