[java-analysis] Check field finality when deciding whether class is immutable

Fixes IDEA-293687 Incorrectly claims "expression is always false"

GitOrigin-RevId: 74a3d8f7b3b0a66a974aa35d55147cbc3336393f
This commit is contained in:
Tagir Valeev
2022-05-10 16:03:02 +00:00
committed by intellij-monorepo-bot
parent 6e7fe05f5c
commit 6522175598
3 changed files with 29 additions and 2 deletions
@@ -0,0 +1,25 @@
// IDEA-293687
public class FieldUpdateViaSetter {
private static final MutableBoolean flag = new MutableBoolean();
public static void main(String[] args) {
for (int i = 0; i < 10; ++i) {
if (flag.value && i == 0) {
break;
}
if (flag.value && i == 3) {
System.out.println("IDEA thinks we can't get here");
break;
}
flag.setValue(true);
}
}
private static final class MutableBoolean {
private boolean value;
public void setValue(boolean newValue) {
value = newValue;
}
}
}
@@ -697,6 +697,7 @@ public class DataFlowInspectionTest extends DataFlowInspectionTestCase {
public void testBoxedDivisionComparison() { doTest(); }
public void testUnknownComparedToNullable() { doTest(); }
public void testCastInCatch() { doTest(); }
public void testFieldUpdateViaSetter() { doTest(); }
public void testInitArrayInConstructor() { doTest(); }
public void testGetterNullityAfterCheck() { doTest(); }
public void testInferenceNullityMismatch() { doTestWith(insp -> insp.SUGGEST_NULLABLE_ANNOTATIONS = false); }
@@ -152,8 +152,9 @@ public final class ClassUtils {
return aClass.hasModifierProperty(PsiModifier.FINAL) &&
Arrays.stream(aClass.getAllFields())
.filter(field -> !field.hasModifierProperty(PsiModifier.STATIC))
.map(field -> field.getType())
.allMatch(type -> TypeConversionUtil.isPrimitiveAndNotNull(type) || immutableTypes.contains(type.getCanonicalText()));
.allMatch(field -> field.hasModifierProperty(PsiModifier.FINAL) &&
(TypeConversionUtil.isPrimitiveAndNotNull(field.getType()) ||
immutableTypes.contains(field.getType().getCanonicalText())));
}
public static boolean inSamePackage(@Nullable PsiElement element1, @Nullable PsiElement element2) {