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();
}