diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java index 3403ed5584d9..70f2902849f5 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java @@ -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, diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/FinalFieldInConstructorAnonymous.java b/java/java-tests/testData/inspection/dataFlow/fixture/FinalFieldInConstructorAnonymous.java new file mode 100644 index 000000000000..3ae7943d010b --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/FinalFieldInConstructorAnonymous.java @@ -0,0 +1,26 @@ +class SomeClass { + private final Object myField; + + { + if (myField != 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(); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java index c65376379e40..16f34a8d7449 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java @@ -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(); }