mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-112358 'Constant Conditions' does not understand non-short-circuit 'or'
This commit is contained in:
+35
-6
@@ -998,14 +998,20 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
}
|
||||
PsiType type = expression.getType();
|
||||
if (op == JavaTokenType.ANDAND) {
|
||||
generateAndExpression(operands, type);
|
||||
generateAndExpression(operands, type, true);
|
||||
}
|
||||
else if (op == JavaTokenType.OROR) {
|
||||
generateOrExpression(operands, type);
|
||||
generateOrExpression(operands, type, true);
|
||||
}
|
||||
else if (op == JavaTokenType.XOR && PsiType.BOOLEAN.equals(type)) {
|
||||
generateXorExpression(expression, operands, type);
|
||||
}
|
||||
else if (op == JavaTokenType.AND && PsiType.BOOLEAN.equals(type)) {
|
||||
generateAndExpression(operands, type, false);
|
||||
}
|
||||
else if (op == JavaTokenType.OR && PsiType.BOOLEAN.equals(type)) {
|
||||
generateOrExpression(operands, type, false);
|
||||
}
|
||||
else {
|
||||
generateOther(expression, op, operands, type);
|
||||
}
|
||||
@@ -1104,11 +1110,18 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private void generateOrExpression(PsiExpression[] operands, final PsiType exprType) {
|
||||
private void generateOrExpression(PsiExpression[] operands, final PsiType exprType, boolean shortCircuit) {
|
||||
for (int i = 0; i < operands.length; i++) {
|
||||
PsiExpression operand = operands[i];
|
||||
operand.accept(this);
|
||||
generateBoxingUnboxingInstructionFor(operand, exprType);
|
||||
if (!shortCircuit) {
|
||||
if (i > 0) {
|
||||
combineStackBooleans(false, operand);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
PsiExpression nextOperand = i == operands.length - 1 ? null : operands[i + 1];
|
||||
if (nextOperand != null) {
|
||||
addInstruction(new ConditionalGotoInstruction(getStartOffset(nextOperand), true, operand));
|
||||
@@ -1125,7 +1138,11 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
lExpression.accept(this);
|
||||
generateBoxingUnboxingInstructionFor(lExpression, exprType);
|
||||
|
||||
ConditionalGotoInstruction toPopAndPushSuccess = new ConditionalGotoInstruction(-1, and, lExpression);
|
||||
combineStackBooleans(and, lExpression);
|
||||
}
|
||||
|
||||
private void combineStackBooleans(boolean and, PsiExpression anchor) {
|
||||
ConditionalGotoInstruction toPopAndPushSuccess = new ConditionalGotoInstruction(-1, and, anchor);
|
||||
addInstruction(toPopAndPushSuccess);
|
||||
GotoInstruction overPushSuccess = new GotoInstruction(-1);
|
||||
addInstruction(overPushSuccess);
|
||||
@@ -1140,17 +1157,29 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
overPushSuccess.setOffset(pushSuccess.getIndex() + 1);
|
||||
}
|
||||
|
||||
private void generateAndExpression(PsiExpression[] operands, final PsiType exprType) {
|
||||
private void generateAndExpression(PsiExpression[] operands, final PsiType exprType, boolean shortCircuit) {
|
||||
List<ConditionalGotoInstruction> branchToFail = new ArrayList<ConditionalGotoInstruction>();
|
||||
for (PsiExpression operand : operands) {
|
||||
for (int i = 0; i < operands.length; i++) {
|
||||
PsiExpression operand = operands[i];
|
||||
operand.accept(this);
|
||||
generateBoxingUnboxingInstructionFor(operand, exprType);
|
||||
|
||||
if (!shortCircuit) {
|
||||
if (i > 0) {
|
||||
combineStackBooleans(false, operand);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
ConditionalGotoInstruction onFail = new ConditionalGotoInstruction(-1, true, operand);
|
||||
branchToFail.add(onFail);
|
||||
addInstruction(onFail);
|
||||
}
|
||||
|
||||
if (!shortCircuit) {
|
||||
return;
|
||||
}
|
||||
|
||||
addInstruction(new PushInstruction(myFactory.getConstFactory().getTrue(), null));
|
||||
GotoInstruction toSuccess = new GotoInstruction(-1);
|
||||
addInstruction(toSuccess);
|
||||
|
||||
@@ -36,4 +36,9 @@
|
||||
<description>Condition <code>o</code> at the left side of assignment expression is always <code>false</code>. Can be simplified to normal assignment.</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>Test.java</file>
|
||||
<line>52</line>
|
||||
<description>Condition <code>o</code> is always <code>true</code></description>
|
||||
</problem>
|
||||
</problems>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
class X {
|
||||
|
||||
int foo(String d1, String d2) {
|
||||
if(d1 == null | d2 == null)
|
||||
return 0;
|
||||
return d1.compareTo(d2);
|
||||
|
||||
}
|
||||
void foo2(String d1, String d2) {
|
||||
if(<warning descr="Condition 'd1 == null & d1 != null' is always 'true'">d1 == null & d1 != null</warning>)
|
||||
System.out.println("impossible");
|
||||
|
||||
}
|
||||
void foo3(String d1, String d2) {
|
||||
if(d1 == null | <warning descr="Method invocation 'd1.compareTo(d2)' may produce 'java.lang.NullPointerException'">d1.compareTo(d2)</warning> > 0)
|
||||
System.out.println("impossible");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,4 +286,5 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
|
||||
public void testBoxingImpliesNotNull() { doTest(); }
|
||||
public void testLargeIntegersAreNotEqualWhenBoxed() { doTest(); }
|
||||
public void testNoGenericCCE() { doTest(); }
|
||||
public void testLongCircuitOperations() { doTest(); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user