IDEA-146122 Wrong 'can produce NPE' after comparing with enum constant

This commit is contained in:
peter
2015-10-12 13:33:38 +02:00
parent 67bfef7b1d
commit af07f88aef
3 changed files with 31 additions and 1 deletions
@@ -30,6 +30,7 @@ import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.UnorderedPair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiEnumConstant;
import com.intellij.psi.PsiPrimitiveType;
import com.intellij.psi.PsiType;
import com.intellij.psi.util.TypeConversionUtil;
@@ -833,7 +834,9 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
for (long encodedPair : myDistinctClasses.toArray()) {
EqClass c1 = myEqClasses.get(low(encodedPair));
EqClass c2 = myEqClasses.get(high(encodedPair));
if (c1.findConstant(false) != null && c2.findConstant(false) != null) {
DfaConstValue const1 = (DfaConstValue)c1.findConstant(false);
DfaConstValue const2 = (DfaConstValue)c2.findConstant(false);
if (const1 != null && const2 != null && !preserveConstantDistinction(const1.getValue(), const2.getValue())) {
myDistinctClasses.remove(encodedPair);
}
}
@@ -851,6 +854,11 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
return true;
}
private static boolean preserveConstantDistinction(final Object c1, final Object c2) {
return c1 == null && c2 instanceof PsiEnumConstant ||
c2 == null && c1 instanceof PsiEnumConstant;
}
private boolean areCompatibleConstants(int i1, int i2) {
Double dv1 = getDoubleValue(i1);
return dv1 != null && dv1.equals(getDoubleValue(i2));
@@ -0,0 +1,21 @@
import org.jetbrains.annotations.Nullable;
enum MyEnum {
ITEM,
ANOTHER_ITEM,
LOL_ITEM;
}
@SuppressWarnings({"UseOfSystemOutOrSystemErr", "unused"})
class Main {
void foo(@Nullable MyEnum myEnum) {
if (myEnum == null) return;
switch (myEnum) {
case ITEM:
case ANOTHER_ITEM:
System.out.println(myEnum == MyEnum.ITEM ? "item" : "another");
myEnum.name();
default:
}
}
}
@@ -94,6 +94,7 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
public void testEqualsEnumConstant() throws Throwable { doTest(); }
public void testSwitchEnumConstant() { doTest(); }
public void testEnumConstantNotNull() throws Throwable { doTest(); }
public void testCompareToEnumConstant() throws Throwable { doTest(); }
public void testEqualsConstant() throws Throwable { doTest(); }
public void testDontSaveTypeValue() { doTest(); }
public void testFinalLoopVariableInstanceof() throws Throwable { doTest(); }