method call should always flush fields (IDEA-93168)

This commit is contained in:
peter
2012-11-08 12:02:46 +01:00
parent dae16b944a
commit 38f38923bd
7 changed files with 27 additions and 23 deletions
@@ -60,6 +60,4 @@ public interface DfaMemoryState {
boolean isNotNull(DfaVariableValue dfaVar);
void flushVariableOutOfScope(DfaVariableValue variable);
void fieldReferenced();
}
@@ -50,7 +50,6 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
private TIntStack myOffsetStack;
private TLongHashSet myDistinctClasses;
private THashMap<DfaVariableValue,DfaVariableState> myVariableStates;
private boolean myHasDirtyFields = true;
public DfaMemoryStateImpl(final DfaValueFactory factory) {
myFactory = factory;
@@ -80,7 +79,6 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
newState.myStateSize = myStateSize;
newState.myVariableStates = new THashMap<DfaVariableValue, DfaVariableState>();
newState.myOffsetStack = new TIntStack(myOffsetStack);
newState.myHasDirtyFields = myHasDirtyFields;
for (int i = 0; i < myEqClasses.size(); i++) {
SortedIntSet aClass = myEqClasses.get(i);
@@ -111,7 +109,6 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
if (!myStack.equals(that.myStack)) return false;
if (!myOffsetStack.equals(that.myOffsetStack)) return false;
if (!myVariableStates.equals(that.myVariableStates)) return false;
if (myHasDirtyFields != that.myHasDirtyFields) return false;
int[] permutation = getPermutationToSortedState();
int[] thatPermutation = that.getPermutationToSortedState();
@@ -494,11 +491,6 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
myDistinctClasses.add(createPair(c1Index, c2Index));
}
@Override
public void fieldReferenced() {
myHasDirtyFields = true;
}
public boolean isNull(DfaValue dfaValue) {
if (dfaValue instanceof DfaNotNullValue) return false;
@@ -773,12 +765,11 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
}
public void flushFields(DataFlowRunner runner) {
if (!myHasDirtyFields) return;
myHasDirtyFields = false;
for (DfaVariableValue field : runner.getFields()) {
flushVariable(field);
getVariableState(field).setNullable(false);
if (myVariableStates.containsKey(field) || getEqClassIndex(field) >= 0) {
flushVariable(field);
getVariableState(field).setNullable(false);
}
}
}
@@ -150,9 +150,6 @@ public abstract class InstructionVisitor {
}
public DfaInstructionState[] visitPush(PushInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
if (instruction.isFieldReference()) {
memState.fieldReferenced();
}
memState.push(instruction.getValue());
return nextInstruction(instruction, runner, memState);
}
@@ -146,7 +146,6 @@ public class StandardInstructionVisitor extends InstructionVisitor {
@Override
public DfaInstructionState[] visitFieldReference(FieldReferenceInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
memState.fieldReferenced();
final DfaValue qualifier = memState.pop();
if (instruction.getExpression().isPhysical() && !memState.applyNotNull(qualifier)) {
onInstructionProducesNPE(instruction);
@@ -62,8 +62,4 @@ public class PushInstruction extends Instruction {
public String toString() {
return "PUSH " + myValue;
}
public boolean isFieldReference() {
return myPlace instanceof PsiReferenceExpression && ((PsiReferenceExpression)myPlace).resolve() instanceof PsiField;
}
}
@@ -0,0 +1,21 @@
import org.jetbrains.annotations.Nullable;
class Fun {
@Nullable
private Object foo;
public Fun() {
foo = new Object();
makeMagic();
if (null == foo) {
System.out.println("hello");
}
}
private void makeMagic() {
foo = null;
}
}
@@ -136,4 +136,6 @@ public class DataFlowInspectionFixtureTest extends JavaCodeInsightFixtureTestCas
public void _testMutableVolatileNullableFieldsTreatment() { doTest(); }
public void testMutableNotAnnotatedFieldsTreatment() { doTest(); }
public void testMethodCallFlushesField() { doTest(); }
}