IDEA-74518: Associations for variable negation haven't been cleared on flush.

This commit is contained in:
Maxim Shafirov
2011-11-25 21:11:25 +04:00
parent 2fb8ab2a61
commit 57a78b6fab
8 changed files with 63 additions and 7 deletions
@@ -198,6 +198,7 @@ public class DataFlowInspection extends BaseLocalInspectionTool {
}
else if (instruction instanceof BranchingInstruction) {
PsiElement psiAnchor = ((BranchingInstruction)instruction).getPsiAnchor();
boolean underBinary = isAtRHSOfBooleanAnd(psiAnchor);
if (instruction instanceof InstanceofInstruction && visitor.isInstanceofRedundant((InstanceofInstruction)instruction)) {
if (visitor.canBeNull((BinopInstruction)instruction)) {
holder.registerProblem(psiAnchor,
@@ -207,7 +208,7 @@ public class DataFlowInspection extends BaseLocalInspectionTool {
else {
final LocalQuickFix localQuickFix = createSimplifyBooleanExpressionFix(psiAnchor, true);
holder.registerProblem(psiAnchor,
InspectionsBundle.message("dataflow.message.constant.condition", Boolean.toString(true)),
InspectionsBundle.message(underBinary ? "dataflow.message.constant.condition.whenriched" : "dataflow.message.constant.condition", Boolean.toString(true)),
localQuickFix==null?null:new LocalQuickFix[]{localQuickFix});
}
}
@@ -227,7 +228,7 @@ public class DataFlowInspection extends BaseLocalInspectionTool {
boolean report = !(psiAnchor.getParent() instanceof PsiAssertStatement) || !DONT_REPORT_TRUE_ASSERT_STATEMENTS || !evaluatesToTrue;
if (report) {
final LocalQuickFix localQuickFix = createSimplifyBooleanExpressionFix(psiAnchor, evaluatesToTrue);
holder.registerProblem(psiAnchor, InspectionsBundle.message("dataflow.message.constant.condition",
holder.registerProblem(psiAnchor, InspectionsBundle.message(underBinary ? "dataflow.message.constant.condition.whenriched" : "dataflow.message.constant.condition",
Boolean.toString(evaluatesToTrue)),
localQuickFix == null ? null : new LocalQuickFix[]{localQuickFix});
}
@@ -279,6 +280,22 @@ public class DataFlowInspection extends BaseLocalInspectionTool {
}
}
private static boolean isAtRHSOfBooleanAnd(PsiElement expr) {
PsiElement cur = expr;
while (cur != null && !(cur instanceof PsiMember)) {
PsiElement parent = cur.getParent();
if (parent instanceof PsiBinaryExpression && cur == ((PsiBinaryExpression)parent).getROperand()) {
return true;
}
cur = parent;
}
return false;
}
private static boolean isCompileConstantInIfCondition(PsiElement element) {
if (!(element instanceof PsiReferenceExpression)) return false;
PsiElement resolved = ((PsiReferenceExpression)element).resolve();
@@ -683,6 +683,11 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
return;
}
doFlash(variable);
doFlash((DfaVariableValue)variable.createNegated());
}
private void doFlash(DfaVariableValue variable) {
final int id = variable.getID();
int size = myEqClasses.size();
int interruptCount = 0;
@@ -1,3 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems />
<problems>
<problem>
<file>NoWarnings.java</file>
<line>9</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Constant conditions &amp; exceptions</problem_class>
<description>Condition &lt;code&gt;i == 1&lt;/code&gt; is always &lt;code&gt;true&lt;/code&gt; when reached</description>
</problem>
</problems>
@@ -5,12 +5,17 @@ public class NoWarnings {
int i = 1;
boolean b = true;
while (i < 200) {
if (b && i == 1) { // Warning here: i == 1 is always true, but it is not so.
while (true) {
if (b && i == 1) {
b = false;
} else {
i++;
}
else {
i = g();
}
}
}
public int g() {
return 1;
}
}
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems/>
@@ -0,0 +1,17 @@
public abstract class NoWarnings {
public void f() {
boolean A = false;
boolean B = false;
while (true) {
boolean f = g();
A = A || f;
B = B || !f;
if (A && B) {
return;
}
}
}
public abstract boolean g();
}
@@ -79,6 +79,7 @@ public class DataFlowInspectionTest extends InspectionTestCase {
public void testconstantExpr() throws Exception { doTest(); }
public void testIDEADEV74518() throws Exception { doTest(); }
public void testIDEADEV74518_2() throws Exception { doTest(); }
public void testNotNullable() throws Exception { doTest15(); }
@@ -49,6 +49,7 @@ dataflow.message.npe.field.access=Dereference of <code>#ref</code> #loc may prod
dataflow.message.cce=Casting <code>{0}</code> to <code>#ref</code> #loc may produce <code>java.lang.ClassCastException</code>
dataflow.message.redundant.instanceof=Condition <code>#ref</code> #loc is redundant and can be replaced with <code>!= null</code>
dataflow.message.constant.condition=Condition <code>#ref</code> #loc is always <code>{0}</code>
dataflow.message.constant.condition.whenriched=Condition <code>#ref</code> #loc is always <code>{0}</code> when reached
dataflow.message.unreachable.switch.label=Switch label<code>#ref</code> #loc is unreachable
dataflow.message.pointless.assignment.expression=Condition <code>#ref</code> #loc at the left side of assignment expression is always <code>{0}</code>. Can be simplified to normal assignment
dataflow.message.passing.null.argument=Passing <code>null</code> argument to parameter annotated as @NotNull