diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/SimplifyBooleanWithConstantsIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/SimplifyBooleanWithConstantsIntention.kt index b625a7c4017..15f60666d4f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/SimplifyBooleanWithConstantsIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/SimplifyBooleanWithConstantsIntention.kt @@ -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) diff --git a/idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero1.kt b/idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero1.kt new file mode 100644 index 00000000000..8e1945eb2ba --- /dev/null +++ b/idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero1.kt @@ -0,0 +1,5 @@ +// IS_APPLICABLE: false + +fun foo() { + -0.0 == +0.0 +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero2.kt b/idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero2.kt new file mode 100644 index 00000000000..7a022f6a470 --- /dev/null +++ b/idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero2.kt @@ -0,0 +1,5 @@ +// IS_APPLICABLE: false + +fun foo() { + +0.0f == -0.0f +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero3.kt b/idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero3.kt new file mode 100644 index 00000000000..a3c7d7cc1f6 --- /dev/null +++ b/idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero3.kt @@ -0,0 +1,3 @@ +fun foo() { + +0.0f == +0.0f +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero3.kt.after b/idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero3.kt.after new file mode 100644 index 00000000000..105b6ff2c0c --- /dev/null +++ b/idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero3.kt.after @@ -0,0 +1,3 @@ +fun foo() { + true +} \ No newline at end of file diff --git a/idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero4.kt b/idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero4.kt new file mode 100644 index 00000000000..62f10dbd372 --- /dev/null +++ b/idea/testData/intentions/simplifyBooleanWithConstants/positiveZeroNegativeZero4.kt @@ -0,0 +1,5 @@ +// IS_APPLICABLE: false + +fun foo(y: Boolean) { + 0.0f === -0.0f +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 911232e0c71..3023cd5673f 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -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");