diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalAnnotator.java b/java/java-analysis-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalAnnotator.java index 0c5a9cd96057..1728e8888578 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalAnnotator.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalAnnotator.java @@ -90,7 +90,6 @@ class CanBeFinalAnnotator extends RefGraphAnnotatorEx { } } - @Override public void onMarkReferenced(RefElement refWhat, RefElement refFrom, @@ -98,18 +97,24 @@ class CanBeFinalAnnotator extends RefGraphAnnotatorEx { boolean forReading, boolean forWriting, PsiElement referenceElement) { + if (!forWriting) return; if (!(refWhat instanceof RefField)) return; - if (!(refFrom instanceof RefMethod) || - !((RefMethod)refFrom).isConstructor() || - ((RefField)refWhat).getUastElement().getUastInitializer() != null || - ((RefMethod)refFrom).getOwnerClass() != ((RefField)refWhat).getOwnerClass() || - ((RefField)refWhat).isStatic()) { - if (forWriting && - !(referencedFromClassInitializer && PsiTreeUtil.getParentOfType(referenceElement, PsiLambdaExpression.class, true) == null)) { + final RefField refField = (RefField)refWhat; + if (refFrom instanceof RefClass && refField.getOwnerClass() != refFrom) { + ((RefFieldImpl)refWhat).setFlag(false, CAN_BE_FINAL_MASK); + } + else if (refField.getUastElement().getUastInitializer() != null) { + ((RefFieldImpl)refWhat).setFlag(false, CAN_BE_FINAL_MASK); + } + else if (!(refFrom instanceof RefMethod) || + !((RefMethod)refFrom).isConstructor() || + ((RefMethod)refFrom).getOwnerClass() != refField.getOwnerClass() || + refField.isStatic()) { + if (!referencedFromClassInitializer || PsiTreeUtil.getParentOfType(referenceElement, PsiLambdaExpression.class, true) != null) { ((RefFieldImpl)refWhat).setFlag(false, CAN_BE_FINAL_MASK); } } - else if (forWriting && PsiTreeUtil.getParentOfType(referenceElement, PsiLambdaExpression.class, true) != null) { + else if (PsiTreeUtil.getParentOfType(referenceElement, PsiLambdaExpression.class, true) != null) { ((RefFieldImpl)refWhat).setFlag(false, CAN_BE_FINAL_MASK); } } diff --git a/java/java-tests/testData/inspection/canBeFinal/FieldAssignedFromOtherClass/expected.xml b/java/java-tests/testData/inspection/canBeFinal/FieldAssignedFromOtherClass/expected.xml new file mode 100644 index 000000000000..e8f00e82629f --- /dev/null +++ b/java/java-tests/testData/inspection/canBeFinal/FieldAssignedFromOtherClass/expected.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/canBeFinal/FieldAssignedFromOtherClass/src/X.java b/java/java-tests/testData/inspection/canBeFinal/FieldAssignedFromOtherClass/src/X.java new file mode 100644 index 000000000000..fb413bd919c4 --- /dev/null +++ b/java/java-tests/testData/inspection/canBeFinal/FieldAssignedFromOtherClass/src/X.java @@ -0,0 +1,10 @@ +public final class X { + + private static int blabla; + + final class Other { + { + blabla = 2; + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/canBeFinal/FieldAssignedInClassInitializer/expected.xml b/java/java-tests/testData/inspection/canBeFinal/FieldAssignedInClassInitializer/expected.xml new file mode 100644 index 000000000000..e8f00e82629f --- /dev/null +++ b/java/java-tests/testData/inspection/canBeFinal/FieldAssignedInClassInitializer/expected.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/canBeFinal/FieldAssignedInClassInitializer/src/Test.java b/java/java-tests/testData/inspection/canBeFinal/FieldAssignedInClassInitializer/src/Test.java new file mode 100644 index 000000000000..8580bde1c5f3 --- /dev/null +++ b/java/java-tests/testData/inspection/canBeFinal/FieldAssignedInClassInitializer/src/Test.java @@ -0,0 +1,7 @@ +public final class Test { + + protected static String prefix = ""; + static { + prefix = "../"; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/CanBeFinalInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/CanBeFinalInspectionTest.java index f3a2ad157435..1b76fd73ae7d 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/CanBeFinalInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/CanBeFinalInspectionTest.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.java.codeInspection; @@ -41,6 +41,14 @@ public class CanBeFinalInspectionTest extends JavaInspectionTestCase { doTest(); } + public void testFieldAssignedInClassInitializer() { + doTest(); + } + + public void testFieldAssignedFromOtherClass() { + doTest(); + } + public void testsimpleClassInheritance() { doTest(); }