field can be local: treat non-primitive fields as read/write (IDEA-52901)

This commit is contained in:
anna
2010-03-15 19:45:03 +03:00
parent 79b3974643
commit 0dbd16d7ef
6 changed files with 37 additions and 3 deletions
@@ -15,9 +15,9 @@
*/
package com.intellij.codeInspection.varScopeCanBeNarrowed;
import com.intellij.codeInsight.CodeInsightUtil;
import com.intellij.codeInsight.daemon.GroupNames;
import com.intellij.codeInsight.daemon.ImplicitUsageProvider;
import com.intellij.codeInsight.CodeInsightUtil;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
@@ -29,6 +29,7 @@ import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
@@ -153,13 +154,13 @@ public class FieldCanBeLocalInspection extends BaseLocalInspectionTool {
}
}
}
final Collection<PsiVariable> writtenVariables = ControlFlowUtil.getWrittenVariables(controlFlow, 0, controlFlow.getSize(), false);
final Ref<Collection<PsiVariable>> writtenVariables = new Ref<Collection<PsiVariable>>();
final List<PsiReferenceExpression> readBeforeWrites = ControlFlowUtil.getReadBeforeWrite(controlFlow);
for (final PsiReferenceExpression readBeforeWrite : readBeforeWrites) {
final PsiElement resolved = readBeforeWrite.resolve();
if (resolved instanceof PsiField) {
final PsiField field = (PsiField)resolved;
if (writtenVariables.contains(field)){
if (!(field.getType() instanceof PsiPrimitiveType) || getWrittenVariables(controlFlow, writtenVariables).contains(field)){
PsiElement parent = body.getParent();
if (!(parent instanceof PsiMethod) ||
!((PsiMethod)parent).isConstructor() ||
@@ -177,6 +178,13 @@ public class FieldCanBeLocalInspection extends BaseLocalInspectionTool {
}
}
private static Collection<PsiVariable> getWrittenVariables(ControlFlow controlFlow, Ref<Collection<PsiVariable>> writtenVariables) {
if (writtenVariables.get() == null) {
writtenVariables.set(ControlFlowUtil.getWrittenVariables(controlFlow, 0, controlFlow.getSize(), false));
}
return writtenVariables.get();
}
private static void removeFieldsReferencedFromInitializers(final PsiClass aClass, final Set<PsiField> candidates) {
aClass.accept(new JavaRecursiveElementWalkingVisitor() {
@Override public void visitMethod(PsiMethod method) {
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems/>
@@ -0,0 +1,11 @@
import java.util.*;
public class Outer {
private Map<String, String> value = new HashMap<String, String>();
public class Inner {
public Inner(String s) {
if (!value.containsKey(s)) value.put(s, "");
}
}
}
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
</problems>
@@ -0,0 +1,8 @@
import java.util.*;
public class Test {
private final Map<String, String> myModuleToOutput = new HashMap<String, String>();
void foo() {
if (myModuleToOutput.containsKey(null)) myModuleToOutput.put("", "");
}
}
@@ -26,4 +26,6 @@ public class FieldCanBeLocalTest extends InspectionTestCase {
public void testStaticAccess() throws Exception { doTest(); }
public void testInnerClassConstructor() throws Exception { doTest(); }
public void testLocalVar2InnerClass() throws Exception { doTest(); }
public void testStateField() throws Exception { doTest(); }
public void testLocalStateVar2InnerClass() throws Exception { doTest(); }
}