mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
dfa: support non-initialized final field escaping in constructors (IDEA-137154)
This commit is contained in:
+11
-1
@@ -141,7 +141,8 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool {
|
||||
PsiClass containingClass = PsiTreeUtil.getParentOfType(scope, PsiClass.class);
|
||||
if (containingClass != null && PsiUtil.isLocalOrAnonymousClass(containingClass)) return;
|
||||
|
||||
final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner(TREAT_UNKNOWN_MEMBERS_AS_NULLABLE, true) {
|
||||
final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner(TREAT_UNKNOWN_MEMBERS_AS_NULLABLE, !isInsideConstructorOrInitializer(
|
||||
scope)) {
|
||||
@Override
|
||||
protected boolean shouldCheckTimeLimit() {
|
||||
if (!onTheFly) return false;
|
||||
@@ -151,6 +152,15 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool {
|
||||
analyzeDfaWithNestedClosures(scope, holder, dfaRunner, Arrays.asList(dfaRunner.createMemoryState()), onTheFly);
|
||||
}
|
||||
|
||||
private static boolean isInsideConstructorOrInitializer(PsiElement element) {
|
||||
while (element != null) {
|
||||
element = PsiTreeUtil.getParentOfType(element, PsiMethod.class, PsiClassInitializer.class);
|
||||
if (element instanceof PsiClassInitializer) return true;
|
||||
if (element instanceof PsiMethod && ((PsiMethod)element).isConstructor()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void analyzeDfaWithNestedClosures(PsiElement scope,
|
||||
ProblemsHolder holder,
|
||||
StandardDataFlowRunner dfaRunner,
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
class SomeClass {
|
||||
private final Object myField;
|
||||
|
||||
{
|
||||
if (<error descr="Variable 'myField' might not have been initialized">myField</error> != null) { // false-positive report 'condition is always true'
|
||||
System.out.println(myField.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public SomeClass(SomeOtherClass o) {
|
||||
o.invoke(new Runnable() {
|
||||
public void run() {
|
||||
if (myField != null) { // false-positive report 'condition is always true'
|
||||
System.out.println(myField.toString());
|
||||
}
|
||||
}
|
||||
});
|
||||
myField = "xxx";
|
||||
}
|
||||
}
|
||||
|
||||
class SomeOtherClass {
|
||||
public void invoke(Runnable r) {
|
||||
r.run();
|
||||
}
|
||||
}
|
||||
@@ -194,6 +194,7 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
|
||||
public void testRememberLocalTransientFieldState() { doTest(); }
|
||||
public void testFinalFieldDuringInitialization() { doTest(); }
|
||||
public void testFinalFieldDuringSuperInitialization() { doTest(); }
|
||||
public void testFinalFieldInConstructorAnonymous() { doTest(); }
|
||||
public void _testSymmetricUncheckedCast() { doTest(); } // https://youtrack.jetbrains.com/issue/IDEABKL-6871
|
||||
public void testNullCheckDoesntAffectUncheckedCast() { doTest(); }
|
||||
public void testThrowNull() { doTest(); }
|
||||
|
||||
Reference in New Issue
Block a user