mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
IDEA-381915 [java-dfa] False positive nullability warning on Nullable private field previously checked for null
GitOrigin-RevId: 7c9af4821b2fd7cb867dc98633e63e1eef9e8aac
This commit is contained in:
committed by
intellij-monorepo-bot
parent
cd294aa27d
commit
023bbcde39
@@ -0,0 +1,19 @@
|
||||
package org.example;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
class PrivateFieldPureMethod {
|
||||
private @Nullable String myField;
|
||||
|
||||
void test() {
|
||||
boolean b = myField != null;
|
||||
if (isValid() && b) {
|
||||
System.out.println(myField.trim());
|
||||
}
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
public boolean isValid() {
|
||||
return Math.random() > 0.5;
|
||||
}
|
||||
}
|
||||
@@ -764,4 +764,5 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase {
|
||||
public void testClosureInConstructor() { doTest(); }
|
||||
|
||||
public void testHugeMethodFlow() { doTest(); }
|
||||
public void testPrivateFieldPureMethod() { doTest(); }
|
||||
}
|
||||
|
||||
+2
-1
@@ -187,7 +187,8 @@ public interface DfaMemoryState {
|
||||
void flushVariable(@NotNull DfaVariableValue variable);
|
||||
|
||||
/**
|
||||
* Flush all the variables for which filter returns true
|
||||
* Flush all the variables for which filter returns true. The type of unstable variables will be corrected,
|
||||
* like {@link #flushFields()} does (see {@link DfType#correctTypeOnFlush(DfType)}).
|
||||
*
|
||||
* @param filter filter to check whether the variable should be flushed
|
||||
*/
|
||||
|
||||
+9
-8
@@ -203,7 +203,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
if (var == value) return;
|
||||
|
||||
value = handleStackValueOnVariableFlush(value, var, null);
|
||||
flushVariable(var, var.getDfType().isMergeable(var.getInherentType()), true);
|
||||
flushVariable(var, var.getDfType().isMergeable(var.getInherentType()), true, false);
|
||||
flushQualifiedMethods(var);
|
||||
|
||||
DfType dfType = filterDfTypeOnAssignment(var, getDfType(value)).meet(var.getDfType());
|
||||
@@ -1410,20 +1410,20 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
|
||||
@Override
|
||||
public void flushVariable(@NotNull DfaVariableValue variable) {
|
||||
flushVariable(variable, true, true);
|
||||
flushVariable(variable, true, true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushVariables(@NotNull Predicate<? super @NotNull DfaVariableValue> filter) {
|
||||
flushVariables(filter, false);
|
||||
flushVariables(filter, false, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forgetVariables(@NotNull Predicate<? super @NotNull DfaVariableValue> filter) {
|
||||
flushVariables(filter, true);
|
||||
flushVariables(filter, true, false);
|
||||
}
|
||||
|
||||
private void flushVariables(@NotNull Predicate<? super @NotNull DfaVariableValue> filter, boolean onlyThis) {
|
||||
private void flushVariables(@NotNull Predicate<? super @NotNull DfaVariableValue> filter, boolean onlyThis, boolean markFlushed) {
|
||||
BitSet vars = new BitSet();
|
||||
for (EqClassImpl aClass : myEqClasses) {
|
||||
if (aClass != null) {
|
||||
@@ -1436,7 +1436,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
for (int id = vars.nextSetBit(0); id >= 0; id = vars.nextSetBit(id + 1)) {
|
||||
DfaVariableValue var = (DfaVariableValue)myFactory.getValue(id);
|
||||
if (filter.test(var)) {
|
||||
flushVariable(var, !onlyThis, !onlyThis);
|
||||
flushVariable(var, !onlyThis, !onlyThis, markFlushed && var.isFlushableByCalls());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1449,8 +1449,9 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
* about all known aliases as well. Flushing without canonicalization could be necessary only
|
||||
* to simplify memory state, if it's known that given variable is never used anymore.
|
||||
* @param flushDeps whether to flush dependencies
|
||||
* @param markFlushed whether to mark variable as flushed
|
||||
*/
|
||||
private void flushVariable(@NotNull DfaVariableValue variable, boolean canonicalize, boolean flushDeps) {
|
||||
private void flushVariable(@NotNull DfaVariableValue variable, boolean canonicalize, boolean flushDeps, boolean markFlushed) {
|
||||
DfaVariableValue canonical = canonicalize ? canonicalize(variable) : variable;
|
||||
EqClass eqClass = canonical.getDependentVariables().isEmpty() ? null : getEqClass(canonical);
|
||||
DfaVariableValue newCanonical =
|
||||
@@ -1459,7 +1460,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState {
|
||||
.orElse(null);
|
||||
myStack.replaceAll(value -> handleStackValueOnVariableFlush(value, canonical, newCanonical));
|
||||
|
||||
doFlush(canonical, false);
|
||||
doFlush(canonical, markFlushed);
|
||||
if (flushDeps) {
|
||||
flushDependencies(canonical);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user