Fix SimplifyBooleanWithConstantsIntention intention to avoid analyzing files created by JetPsiFactory
This commit is contained in:
@@ -96,6 +96,9 @@ public fun JetClass.isAbstract(): Boolean = isTrait() || hasModifier(JetTokens.A
|
|||||||
[suppress("UNCHECKED_CAST")]
|
[suppress("UNCHECKED_CAST")]
|
||||||
public fun <T: PsiElement> PsiElement.replaced(newElement: T): T = replace(newElement) as T
|
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> =
|
public fun JetElement.blockExpressionsOrSingle(): Stream<JetElement> =
|
||||||
if (this is JetBlockExpression) getStatements().stream() else listOf(this).stream()
|
if (this is JetBlockExpression) getStatements().stream() else listOf(this).stream()
|
||||||
|
|
||||||
|
|||||||
+21
-17
@@ -27,6 +27,8 @@ import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace
|
|||||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
||||||
import com.intellij.psi.tree.IElementType
|
import com.intellij.psi.tree.IElementType
|
||||||
import com.intellij.psi.util.PsiTreeUtil
|
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>(
|
public class SimplifyBooleanWithConstantsIntention : JetSelfTargetingIntention<JetBinaryExpression>(
|
||||||
"simplify.boolean.with.constants", javaClass()) {
|
"simplify.boolean.with.constants", javaClass()) {
|
||||||
@@ -54,7 +56,7 @@ public class SimplifyBooleanWithConstantsIntention : JetSelfTargetingIntention<J
|
|||||||
|
|
||||||
override fun applyTo(element: JetBinaryExpression, editor: Editor) {
|
override fun applyTo(element: JetBinaryExpression, editor: Editor) {
|
||||||
// we know from isApplicableTo that topParent is not null
|
// we know from isApplicableTo that topParent is not null
|
||||||
val simplified = simplifyBoolean(topParent!!)
|
val simplified = toSimplifiedExpression(topParent!!)
|
||||||
if (simplified is JetParenthesizedExpression) {
|
if (simplified is JetParenthesizedExpression) {
|
||||||
val expr = simplified.getExpression()
|
val expr = simplified.getExpression()
|
||||||
if (expr != null) {
|
if (expr != null) {
|
||||||
@@ -66,7 +68,7 @@ public class SimplifyBooleanWithConstantsIntention : JetSelfTargetingIntention<J
|
|||||||
topParent!!.replace(simplified)
|
topParent!!.replace(simplified)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun simplifyBoolean(element: JetExpression) : JetExpression {
|
private fun toSimplifiedExpression(element: JetExpression): JetExpression {
|
||||||
val psiFactory = JetPsiFactory(element)
|
val psiFactory = JetPsiFactory(element)
|
||||||
if (element.canBeReducedToTrue())
|
if (element.canBeReducedToTrue())
|
||||||
return psiFactory.createExpression("true")
|
return psiFactory.createExpression("true")
|
||||||
@@ -76,40 +78,38 @@ public class SimplifyBooleanWithConstantsIntention : JetSelfTargetingIntention<J
|
|||||||
is JetParenthesizedExpression -> {
|
is JetParenthesizedExpression -> {
|
||||||
val expr = element.getExpression()
|
val expr = element.getExpression()
|
||||||
if (expr == null) return element
|
if (expr == null) return element
|
||||||
val simplified = simplifyBoolean(expr)
|
val innerSimplified = toSimplifiedExpression(expr)
|
||||||
if (expr == simplified) return element
|
if (innerSimplified is JetBinaryExpression) {
|
||||||
if (simplified is JetBinaryExpression) {
|
val simpText = innerSimplified.getText() ?: return element.copied()
|
||||||
val simpText = simplified.getText()
|
|
||||||
if (simpText == null) return element
|
|
||||||
// wrap in new parentheses to keep the user's original format
|
// wrap in new parentheses to keep the user's original format
|
||||||
return psiFactory.createExpression("($simpText)")
|
return psiFactory.createExpression("($simpText)")
|
||||||
}
|
}
|
||||||
// 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
|
||||||
return simplified
|
return innerSimplified
|
||||||
}
|
}
|
||||||
is JetBinaryExpression -> {
|
is JetBinaryExpression -> {
|
||||||
val left = element.getLeft()
|
val left = element.getLeft()
|
||||||
val right = element.getRight()
|
val right = element.getRight()
|
||||||
val op = element.getOperationToken()
|
val op = element.getOperationToken()
|
||||||
if (left == null || right == null || op == null || (op != JetTokens.ANDAND && op != JetTokens.OROR))
|
if (left == null || right == null || op == null || (op != JetTokens.ANDAND && op != JetTokens.OROR))
|
||||||
return element
|
return element.copied()
|
||||||
|
|
||||||
val simpleLeft = simplifyBoolean(left)
|
val simpleLeft = simplifyExpression(left)
|
||||||
val simpleRight = simplifyBoolean(right)
|
val simpleRight = simplifyExpression(right)
|
||||||
if (simpleLeft.canBeReducedToTrue() || simpleLeft.canBeReducedToFalse())
|
if (simpleLeft.canBeReducedToTrue() || simpleLeft.canBeReducedToFalse())
|
||||||
return simplifyBooleanBinaryExpressionWithConstantOperand(simpleLeft, simpleRight, op)
|
return toSimplifiedBooleanBinaryExpressionWithConstantOperand(simpleLeft, simpleRight, op)
|
||||||
if (simpleRight.canBeReducedToTrue() || simpleRight.canBeReducedToFalse())
|
if (simpleRight.canBeReducedToTrue() || simpleRight.canBeReducedToFalse())
|
||||||
return simplifyBooleanBinaryExpressionWithConstantOperand(simpleRight, simpleLeft, op)
|
return toSimplifiedBooleanBinaryExpressionWithConstantOperand(simpleRight, simpleLeft, op)
|
||||||
|
|
||||||
val opText = element.getOperationReference().getText()
|
val opText = element.getOperationReference().getText()
|
||||||
if (opText == null) return element
|
if (opText == null) return element.copied()
|
||||||
return psiFactory.createBinaryExpression(simpleLeft, opText, simpleRight)
|
return psiFactory.createBinaryExpression(simpleLeft, opText, simpleRight)
|
||||||
}
|
}
|
||||||
else -> return element
|
else -> return element.copied()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun simplifyBooleanBinaryExpressionWithConstantOperand(
|
private fun toSimplifiedBooleanBinaryExpressionWithConstantOperand(
|
||||||
booleanConstantOperand: JetExpression,
|
booleanConstantOperand: JetExpression,
|
||||||
otherOperand: JetExpression,
|
otherOperand: JetExpression,
|
||||||
operation: IElementType
|
operation: IElementType
|
||||||
@@ -120,7 +120,11 @@ public class SimplifyBooleanWithConstantsIntention : JetSelfTargetingIntention<J
|
|||||||
return psiFactory.createExpression("true")
|
return psiFactory.createExpression("true")
|
||||||
if (booleanConstantOperand.canBeReducedToFalse() && operation == JetTokens.ANDAND)
|
if (booleanConstantOperand.canBeReducedToFalse() && operation == JetTokens.ANDAND)
|
||||||
return psiFactory.createExpression("false")
|
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 {
|
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);
|
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")
|
@TestMetadata("inapplicableNoConstants.kt")
|
||||||
public void testInapplicableNoConstants() throws Exception {
|
public void testInapplicableNoConstants() throws Exception {
|
||||||
doTest("idea/testData/intentions/simplifyBooleanWithConstants/inapplicableNoConstants.kt");
|
doTest("idea/testData/intentions/simplifyBooleanWithConstants/inapplicableNoConstants.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user