Fix SimplifyBooleanWithConstantsIntention intention to avoid analyzing files created by JetPsiFactory

This commit is contained in:
Pavel V. Talanov
2014-07-20 19:09:34 +04:00
parent 1bc0a9dfd9
commit f44ba60d51
5 changed files with 39 additions and 17 deletions
@@ -96,6 +96,9 @@ public fun JetClass.isAbstract(): Boolean = isTrait() || hasModifier(JetTokens.A
[suppress("UNCHECKED_CAST")]
public fun <T: PsiElement> PsiElement.replaced(newElement: T): T = replace(newElement) as T
[suppress("UNCHECKED_CAST")]
public fun <T: PsiElement> T.copied(): T = copy() as T
public fun JetElement.blockExpressionsOrSingle(): Stream<JetElement> =
if (this is JetBlockExpression) getStatements().stream() else listOf(this).stream()
@@ -27,6 +27,8 @@ import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
import com.intellij.psi.tree.IElementType
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.jet.lang.psi.psiUtil.copied
import org.jetbrains.jet.lang.psi.psiUtil.replaced
public class SimplifyBooleanWithConstantsIntention : JetSelfTargetingIntention<JetBinaryExpression>(
"simplify.boolean.with.constants", javaClass()) {
@@ -54,7 +56,7 @@ public class SimplifyBooleanWithConstantsIntention : JetSelfTargetingIntention<J
override fun applyTo(element: JetBinaryExpression, editor: Editor) {
// we know from isApplicableTo that topParent is not null
val simplified = simplifyBoolean(topParent!!)
val simplified = toSimplifiedExpression(topParent!!)
if (simplified is JetParenthesizedExpression) {
val expr = simplified.getExpression()
if (expr != null) {
@@ -66,7 +68,7 @@ public class SimplifyBooleanWithConstantsIntention : JetSelfTargetingIntention<J
topParent!!.replace(simplified)
}
private fun simplifyBoolean(element: JetExpression) : JetExpression {
private fun toSimplifiedExpression(element: JetExpression): JetExpression {
val psiFactory = JetPsiFactory(element)
if (element.canBeReducedToTrue())
return psiFactory.createExpression("true")
@@ -76,40 +78,38 @@ public class SimplifyBooleanWithConstantsIntention : JetSelfTargetingIntention<J
is JetParenthesizedExpression -> {
val expr = element.getExpression()
if (expr == null) return element
val simplified = simplifyBoolean(expr)
if (expr == simplified) return element
if (simplified is JetBinaryExpression) {
val simpText = simplified.getText()
if (simpText == null) return element
val innerSimplified = toSimplifiedExpression(expr)
if (innerSimplified is JetBinaryExpression) {
val simpText = innerSimplified.getText() ?: return element.copied()
// wrap in new parentheses to keep the user's original format
return psiFactory.createExpression("($simpText)")
}
// if we now have a simpleName, constant, or parenthesized we don't need parentheses
return simplified
return innerSimplified
}
is JetBinaryExpression -> {
val left = element.getLeft()
val right = element.getRight()
val op = element.getOperationToken()
if (left == null || right == null || op == null || (op != JetTokens.ANDAND && op != JetTokens.OROR))
return element
return element.copied()
val simpleLeft = simplifyBoolean(left)
val simpleRight = simplifyBoolean(right)
val simpleLeft = simplifyExpression(left)
val simpleRight = simplifyExpression(right)
if (simpleLeft.canBeReducedToTrue() || simpleLeft.canBeReducedToFalse())
return simplifyBooleanBinaryExpressionWithConstantOperand(simpleLeft, simpleRight, op)
return toSimplifiedBooleanBinaryExpressionWithConstantOperand(simpleLeft, simpleRight, op)
if (simpleRight.canBeReducedToTrue() || simpleRight.canBeReducedToFalse())
return simplifyBooleanBinaryExpressionWithConstantOperand(simpleRight, simpleLeft, op)
return toSimplifiedBooleanBinaryExpressionWithConstantOperand(simpleRight, simpleLeft, op)
val opText = element.getOperationReference().getText()
if (opText == null) return element
if (opText == null) return element.copied()
return psiFactory.createBinaryExpression(simpleLeft, opText, simpleRight)
}
else -> return element
else -> return element.copied()
}
}
private fun simplifyBooleanBinaryExpressionWithConstantOperand(
private fun toSimplifiedBooleanBinaryExpressionWithConstantOperand(
booleanConstantOperand: JetExpression,
otherOperand: JetExpression,
operation: IElementType
@@ -120,7 +120,11 @@ public class SimplifyBooleanWithConstantsIntention : JetSelfTargetingIntention<J
return psiFactory.createExpression("true")
if (booleanConstantOperand.canBeReducedToFalse() && operation == JetTokens.ANDAND)
return psiFactory.createExpression("false")
return simplifyBoolean(otherOperand)
return toSimplifiedExpression(otherOperand)
}
private fun simplifyExpression(element: JetExpression): JetExpression {
return element.replaced(toSimplifiedExpression(element))
}
private fun JetExpression.canBeReducedToBooleanConstant(constant: Boolean?): Boolean {
@@ -0,0 +1,5 @@
fun foo() {
val x = true
val y = false
(((((x || false)) && y)) <caret>|| false)
}
@@ -0,0 +1,5 @@
fun foo() {
val x = true
val y = false
(x && y)
}
@@ -4514,6 +4514,11 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("idea/testData/intentions/simplifyBooleanWithConstants"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("deeplyParenthesized.kt")
public void testDeeplyParenthesized() throws Exception {
doTest("idea/testData/intentions/simplifyBooleanWithConstants/deeplyParenthesized.kt");
}
@TestMetadata("inapplicableNoConstants.kt")
public void testInapplicableNoConstants() throws Exception {
doTest("idea/testData/intentions/simplifyBooleanWithConstants/inapplicableNoConstants.kt");