can be final: don't suggest final modifiers for implicitly write fields (IDEA-148069)

This commit is contained in:
Anna Kozlova
2016-07-08 10:46:34 +02:00
parent 26b66bb2fc
commit 6ee2ce046e
6 changed files with 53 additions and 2 deletions
@@ -89,6 +89,12 @@ class CanBeFinalAnnotator extends RefGraphAnnotatorEx {
}
}
}
else if (refElement instanceof RefField) {
final PsiElement element = refElement.getElement();
if (element != null && RefUtil.isImplicitWrite(element)) {
((RefElementImpl)refElement).setFlag(false, CAN_BE_FINAL_MASK);
}
}
}
@@ -121,7 +121,7 @@ public class RefFieldImpl extends RefJavaElementImpl implements RefField {
refUtil.addReferences(psiField, this, psiField);
}
if (psiField.getInitializer() != null || psiField instanceof PsiEnumConstant || RefUtil.isWriteImplicitly(psiField)) {
if (psiField.getInitializer() != null || psiField instanceof PsiEnumConstant || RefUtil.isImplicitWrite(psiField)) {
if (!checkFlag(USED_FOR_WRITING_MASK)) {
setFlag(true, ASSIGNED_ONLY_IN_INITIALIZER_MASK);
setFlag(true, USED_FOR_WRITING_MASK);
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
<problem>
<file>Test.java</file>
<line>3</line>
<description>Declaration can have final modifier</description>
</problem>
</problems>
@@ -0,0 +1,9 @@
final class G {
private Object implicitWrite;
private Object foo;
void fooBar() {
System.out.println(implicitWrite);
System.out.println(foo);
}
}
@@ -9,8 +9,14 @@
package com.intellij.codeInspection;
import com.intellij.JavaTestUtil;
import com.intellij.codeInsight.daemon.ImplicitUsageProvider;
import com.intellij.codeInspection.canBeFinal.CanBeFinalInspection;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiNamedElement;
import com.intellij.testFramework.InspectionTestCase;
import com.intellij.testFramework.PlatformTestUtil;
public class CanBeFinalTest extends InspectionTestCase {
@Override
@@ -120,4 +126,25 @@ public class CanBeFinalTest extends InspectionTestCase {
doTest(tool);
}
public void testfieldImplicitWrite() throws Exception {
PlatformTestUtil.registerExtension(ImplicitUsageProvider.EP_NAME, new ImplicitUsageProvider() {
@Override
public boolean isImplicitUsage(PsiElement element) {
return isImplicitWrite(element);
}
@Override
public boolean isImplicitRead(PsiElement element) {
return false;
}
@Override
public boolean isImplicitWrite(PsiElement element) {
return element instanceof PsiField && "implicitWrite".equals(((PsiNamedElement)element).getName());
}
}, myTestRootDisposable);
doTest();
}
}
@@ -58,7 +58,7 @@ public class RefUtil {
return false;
}
public static boolean isWriteImplicitly(PsiElement element) {
public static boolean isImplicitWrite(PsiElement element) {
final ImplicitUsageProvider[] implicitUsageProviders = Extensions.getExtensions(ImplicitUsageProvider.EP_NAME);
for (ImplicitUsageProvider provider : implicitUsageProviders) {
if (provider.isImplicitWrite(element)) return true;