mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
dfa: assume fields used before initialization are null (IDEA-110297)
This commit is contained in:
+15
@@ -25,6 +25,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.JavaConstantExpressionEvaluator;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -132,6 +133,10 @@ public class DfaExpressionFactory {
|
||||
}
|
||||
|
||||
if (DfaValueFactory.isEffectivelyUnqualified(refExpr)) {
|
||||
if (isFieldDereferenceBeforeInitialization(refExpr)) {
|
||||
return myFactory.getConstFactory().getNull();
|
||||
}
|
||||
|
||||
return myFactory.getVarFactory().createVariableValue(var, refExpr.getType(), false, null);
|
||||
}
|
||||
|
||||
@@ -145,6 +150,16 @@ public class DfaExpressionFactory {
|
||||
return myFactory.createTypeValue(type, DfaPsiUtil.getElementNullability(type, var));
|
||||
}
|
||||
|
||||
private static boolean isFieldDereferenceBeforeInitialization(PsiReferenceExpression ref) {
|
||||
PsiField placeField = PsiTreeUtil.getParentOfType(ref, PsiField.class, true, PsiClass.class, PsiLambdaExpression.class);
|
||||
if (placeField == null) return false;
|
||||
|
||||
PsiElement target = ref.resolve();
|
||||
return target instanceof PsiField &&
|
||||
placeField.getContainingClass() == ((PsiField)target).getContainingClass() &&
|
||||
((PsiField)target).getInitializer() == null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiModifierListOwner getAccessedVariableOrGetter(final PsiElement target) {
|
||||
if (target instanceof PsiVariable) {
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
class Foo {
|
||||
String field;
|
||||
String field2 = field.<warning descr="Method invocation 'substring' may produce 'java.lang.NullPointerException'">substring</warning>(1);
|
||||
int field3 = field2.length();
|
||||
Runnable r = new Runnable() {
|
||||
public void run() {
|
||||
System.out.println(field.hashCode());
|
||||
}
|
||||
};
|
||||
|
||||
Foo() {
|
||||
field = "x";
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
class Foo {
|
||||
String field;
|
||||
String field2;
|
||||
int hash = field.hashCode();
|
||||
int hash = field.<warning descr="Method invocation 'hashCode' may produce 'java.lang.NullPointerException'">hashCode</warning>();
|
||||
|
||||
Foo(String f2) {
|
||||
field2 = f2;
|
||||
|
||||
@@ -421,6 +421,8 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase {
|
||||
|
||||
public void testDivisionByZero() { doTestReportConstantReferences(); }
|
||||
|
||||
public void testFieldUsedBeforeInitialization() { doTest(); }
|
||||
|
||||
public void testImplicitlyInitializedField() {
|
||||
PlatformTestUtil.registerExtension(ImplicitUsageProvider.EP_NAME, new ImplicitUsageProvider() {
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user