simplify boolean: xor (IDEA-92131)

This commit is contained in:
anna
2012-10-19 18:44:40 +02:00
parent ca44510f34
commit 90c6a12e7f
9 changed files with 128 additions and 16 deletions
@@ -26,15 +26,20 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class SimplifyBooleanExpressionFix implements IntentionAction {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.SimplifyBooleanExpression");
@@ -254,27 +259,62 @@ public class SimplifyBooleanExpressionFix implements IntentionAction {
PsiExpression[] operands = expression.getOperands();
PsiExpression lExpr = operands[0];
IElementType tokenType = expression.getOperationTokenType();
for (int i = 1; i < operands.length; i++) {
Boolean l = getConstBoolean(lExpr);
PsiExpression operand = operands[i];
Boolean r = getConstBoolean(operand);
if (l != null) {
simplifyBinary(tokenType, l, operand);
if (JavaTokenType.XOR == tokenType) {
boolean negate = false;
List<PsiExpression> expressions = new ArrayList<PsiExpression>();
for (PsiExpression operand : operands) {
final Boolean constBoolean = getConstBoolean(operand);
if (constBoolean != null) {
markAndCheckCreateResult();
if (constBoolean == Boolean.TRUE) {
negate = !negate;
}
continue;
}
expressions.add(operand);
}
else if (r != null) {
simplifyBinary(tokenType, r, lExpr);
if (expressions.isEmpty()) {
resultExpression = negate ? trueExpression : falseExpression;
} else {
String simplifiedText = StringUtil.join(expressions, new Function<PsiExpression, String>() {
@Override
public String fun(PsiExpression expression) {
return expression.getText();
}
}, " ^ ");
if (negate) {
if (expressions.size() > 1) {
simplifiedText = "!(" + simplifiedText + ")";
} else {
simplifiedText = "!" + simplifiedText;
}
}
resultExpression = JavaPsiFacade.getElementFactory(expression.getProject()).createExpressionFromText(simplifiedText, expression);
}
else {
final PsiJavaToken javaToken = expression.getTokenBeforeOperand(operand);
if (javaToken != null && !PsiTreeUtil.hasErrorElements(operand) && !PsiTreeUtil.hasErrorElements(lExpr)) {
resultExpression = JavaPsiFacade.getElementFactory(expression.getProject()).createExpressionFromText(lExpr.getText() + javaToken.getText() + operand.getText(), expression);
} else {
for (int i = 1; i < operands.length; i++) {
Boolean l = getConstBoolean(lExpr);
PsiExpression operand = operands[i];
Boolean r = getConstBoolean(operand);
if (l != null) {
simplifyBinary(tokenType, l, operand);
}
else if (r != null) {
simplifyBinary(tokenType, r, lExpr);
}
else {
resultExpression = null;
final PsiJavaToken javaToken = expression.getTokenBeforeOperand(operand);
if (javaToken != null && !PsiTreeUtil.hasErrorElements(operand) && !PsiTreeUtil.hasErrorElements(lExpr)) {
resultExpression = JavaPsiFacade.getElementFactory(expression.getProject()).createExpressionFromText(lExpr.getText() + javaToken.getText() + operand.getText(), expression);
}
else {
resultExpression = null;
}
}
if (resultExpression != null) {
lExpr = resultExpression;
}
}
if (resultExpression != null) {
lExpr = resultExpression;
}
}
}
@@ -0,0 +1,9 @@
// "Simplify boolean expression" "true"
class A {
boolean a = true;
boolean b = true;
boolean x = a; // intention "simplify boolean expression" does nothing here, expected: boolean x = a;
boolean x1 = a ^ true; // expected: boolean x1 = !a; fails, does nothing
boolean y = a ^ true ^ b; // intention replaces with a ^ b, expected !(a ^ b) fails
boolean y1 = a ^ false ^ b; // expected boolean y1 = a ^ b works correctly;
}
@@ -0,0 +1,9 @@
// "Simplify boolean expression" "true"
class A {
boolean a = true;
boolean b = true;
boolean x = a ^ false; // intention "simplify boolean expression" does nothing here, expected: boolean x = a;
boolean x1 = !a; // expected: boolean x1 = !a; fails, does nothing
boolean y = a ^ true ^ b; // intention replaces with a ^ b, expected !(a ^ b) fails
boolean y1 = a ^ false ^ b; // expected boolean y1 = a ^ b works correctly;
}
@@ -0,0 +1,9 @@
// "Simplify boolean expression" "true"
class A {
boolean a = true;
boolean b = true;
boolean x = a ^ false; // intention "simplify boolean expression" does nothing here, expected: boolean x = a;
boolean x1 = a ^ true; // expected: boolean x1 = !a; fails, does nothing
boolean y = !(a ^ b); // intention replaces with a ^ b, expected !(a ^ b) fails
boolean y1 = a ^ false ^ b; // expected boolean y1 = a ^ b works correctly;
}
@@ -0,0 +1,9 @@
// "Simplify boolean expression" "true"
class A {
boolean a = true;
boolean b = true;
boolean x = a ^ false; // intention "simplify boolean expression" does nothing here, expected: boolean x = a;
boolean x1 = a ^ true; // expected: boolean x1 = !a; fails, does nothing
boolean y = a ^ true ^ b; // intention replaces with a ^ b, expected !(a ^ b) fails
boolean y1 = a ^ b; // expected boolean y1 = a ^ b works correctly;
}
@@ -0,0 +1,9 @@
// "Simplify boolean expression" "true"
class A {
boolean a = true;
boolean b = true;
boolean x = a <caret>^ false; // intention "simplify boolean expression" does nothing here, expected: boolean x = a;
boolean x1 = a ^ true; // expected: boolean x1 = !a; fails, does nothing
boolean y = a ^ true ^ b; // intention replaces with a ^ b, expected !(a ^ b) fails
boolean y1 = a ^ false ^ b; // expected boolean y1 = a ^ b works correctly;
}
@@ -0,0 +1,9 @@
// "Simplify boolean expression" "true"
class A {
boolean a = true;
boolean b = true;
boolean x = a ^ false; // intention "simplify boolean expression" does nothing here, expected: boolean x = a;
boolean x1 = a <caret>^ true; // expected: boolean x1 = !a; fails, does nothing
boolean y = a ^ true ^ b; // intention replaces with a ^ b, expected !(a ^ b) fails
boolean y1 = a ^ false ^ b; // expected boolean y1 = a ^ b works correctly;
}
@@ -0,0 +1,9 @@
// "Simplify boolean expression" "true"
class A {
boolean a = true;
boolean b = true;
boolean x = a ^ false; // intention "simplify boolean expression" does nothing here, expected: boolean x = a;
boolean x1 = a ^ true; // expected: boolean x1 = !a; fails, does nothing
boolean y = a ^ <caret>true ^ b; // intention replaces with a ^ b, expected !(a ^ b) fails
boolean y1 = a ^ false ^ b; // expected boolean y1 = a ^ b works correctly;
}
@@ -0,0 +1,9 @@
// "Simplify boolean expression" "true"
class A {
boolean a = true;
boolean b = true;
boolean x = a ^ false; // intention "simplify boolean expression" does nothing here, expected: boolean x = a;
boolean x1 = a ^ true; // expected: boolean x1 = !a; fails, does nothing
boolean y = a ^ true ^ b; // intention replaces with a ^ b, expected !(a ^ b) fails
boolean y1 = a ^ <caret>false ^ b; // expected boolean y1 = a ^ b works correctly;
}