[java-dfa] Do not report variable is already assigned to this value for final field assignments (IDEA-258765)

GitOrigin-RevId: 0820f165cacbde79ced969d1ca8f1ba5910c99d6
This commit is contained in:
Tagir Valeev
2021-01-11 04:02:58 +00:00
committed by intellij-monorepo-bot
parent 2b620276e0
commit ca5da73932
2 changed files with 25 additions and 10 deletions
@@ -528,16 +528,22 @@ public abstract class DataFlowInspectionBase extends AbstractBaseJavaLocalInspec
if (context instanceof PsiForStatement && PsiTreeUtil.isAncestor(((PsiForStatement)context).getInitialization(), expr, true)) {
return;
}
if (context instanceof PsiClassInitializer && expr instanceof PsiReferenceExpression) {
if (assignment != null) {
Object constValue = ExpressionUtils.computeConstantExpression(assignment.getRExpression());
if (constValue == PsiTypesUtil.getDefaultValue(expr.getType())) {
PsiReferenceExpression ref = (PsiReferenceExpression)expr;
PsiElement target = ref.resolve();
if (target instanceof PsiField &&
(((PsiField)target).hasModifierProperty(PsiModifier.STATIC) || ExpressionUtil.isEffectivelyUnqualified(ref)) &&
((PsiField)target).getContainingClass() == ((PsiClassInitializer)context).getContainingClass()) {
return;
if (expr instanceof PsiReferenceExpression) {
PsiReferenceExpression ref = (PsiReferenceExpression)expr;
PsiField field = tryCast(ref.resolve(), PsiField.class);
if (field != null) {
// Final field assignment: even if redundant according to DFA model (e.g. this.field = null),
// it's necessary due to language semantics
if (field.hasModifierProperty(PsiModifier.FINAL)) return;
if (context instanceof PsiClassInitializer) {
if (assignment != null) {
Object constValue = ExpressionUtils.computeConstantExpression(assignment.getRExpression());
if (constValue == PsiTypesUtil.getDefaultValue(expr.getType())) {
if ((field.hasModifierProperty(PsiModifier.STATIC) || ExpressionUtil.isEffectivelyUnqualified(ref)) &&
field.getContainingClass() == ((PsiClassInitializer)context).getContainingClass()) {
return;
}
}
}
}
}
@@ -76,3 +76,12 @@ class TestConstant {
x = NONE;
}
}
// IDEA-258765
interface Intersection {
interface I { }
final class A { }
class Data<T extends A & I> {
final T value;
private Data(T value) { this.value = value; }
}
}