IDEA-115516 (Multiple warnings local foreach parameter can be final)

This commit is contained in:
Bas Leijdekkers
2013-10-28 15:17:57 +01:00
parent f214acc2b0
commit 2a1ebb5187
4 changed files with 49 additions and 32 deletions
@@ -33,9 +33,7 @@ import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.*;
import java.util.List;
/**
@@ -118,10 +116,10 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool {
int start = flow.getStartOffset(body);
int end = flow.getEndOffset(body);
final List<PsiVariable> writtenVariables = new ArrayList<PsiVariable>(ControlFlowUtil.getWrittenVariables(flow, start, end, false));
final Collection<PsiVariable> writtenVariables = ControlFlowUtil.getWrittenVariables(flow, start, end, false);
final List<ProblemDescriptor> problems = new ArrayList<ProblemDescriptor>();
final HashSet<PsiVariable> ssaVarsSet = new HashSet<PsiVariable>();
final HashSet<PsiVariable> result = new HashSet<PsiVariable>();
body.accept(new JavaRecursiveElementWalkingVisitor() {
@Override public void visitCodeBlock(PsiCodeBlock block) {
if (block.getParent() instanceof PsiLambdaExpression && block != body) {
@@ -142,7 +140,7 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool {
HashSet<PsiElement> declared = getDeclaredVariables(block);
for (PsiVariable psiVariable : ssa) {
if (declared.contains(psiVariable)) {
ssaVarsSet.add(psiVariable);
result.add(psiVariable);
}
}
}
@@ -150,13 +148,16 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool {
@Override public void visitForeachStatement(PsiForeachStatement statement) {
super.visitForeachStatement(statement);
final PsiParameter param = statement.getIterationParameter();
if (PsiTreeUtil.getParentOfType(param, PsiClass.class) != PsiTreeUtil.getParentOfType(body, PsiClass.class)) {
return;
}
final PsiStatement body = statement.getBody();
if (body == null) return;
int from = flow.getStartOffset(body);
int end = flow.getEndOffset(body);
if (!ControlFlowUtil.getWrittenVariables(flow, from, end, false).contains(param)) {
writtenVariables.remove(param);
ssaVarsSet.add(param);
result.add(param);
}
}
@@ -185,27 +186,15 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool {
}
});
final ArrayList<PsiVariable> result = new ArrayList<PsiVariable>(ssaVarsSet);
if (body.getParent() instanceof PsiMethod) {
PsiMethod method = (PsiMethod)body.getParent();
PsiParameter[] parameters = method.getParameterList().getParameters();
for (PsiParameter parameter : parameters) {
if (!result.contains(parameter)) result.add(parameter);
}
if (body.getParent() instanceof PsiMethod && isReportParameters()) {
final PsiMethod method = (PsiMethod)body.getParent();
Collections.addAll(result, method.getParameterList().getParameters());
}
PsiVariable[] psiVariables = result.toArray(new PsiVariable[result.size()]);
for (PsiVariable psiVariable : psiVariables) {
if (shouldBeIgnored(psiVariable)) {
result.remove(psiVariable);
}
if (psiVariable instanceof PsiLocalVariable) {
PsiDeclarationStatement decl = (PsiDeclarationStatement)psiVariable.getParent();
if (decl != null && decl.getParent() instanceof PsiForStatement) {
result.remove(psiVariable);
}
for (Iterator<PsiVariable> iterator = result.iterator(); iterator.hasNext(); ) {
final PsiVariable variable = iterator.next();
if (shouldBeIgnored(variable) || !variable.isPhysical()) {
iterator.remove();
}
}
@@ -216,12 +205,6 @@ public class LocalCanBeFinal extends BaseJavaBatchLocalInspectionTool {
}
if (result.isEmpty()) return null;
for (Iterator<PsiVariable> iterator = result.iterator(); iterator.hasNext();) {
final PsiVariable variable = iterator.next();
if (!variable.isPhysical()){
iterator.remove();
}
}
for (PsiVariable variable : result) {
final PsiIdentifier nameIdentifier = variable.getNameIdentifier();
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
<problem>
<file>NestedForeach.java</file>
<line>9</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Local variable or parameter can be final</problem_class>
<description>Variable &lt;code&gt;s&lt;/code&gt; can have &lt;code&gt;final&lt;/code&gt; modifier</description>
</problem>
</problems>
@@ -0,0 +1,19 @@
class NestedForeach {
void foo(final List<String> list) {
new Object() {
void one() {
new Object() {
void two() {
new Object() {
void three() {
for (String s : list) {
System.out.println(s);
}
}
};
}
};
}
};
}
}
@@ -129,4 +129,10 @@ public class LocalCanBeFinalTest extends InspectionTestCase {
myTool.REPORT_VARIABLES = false;
doTest();
}
public void testNestedForeach() throws Exception {
myTool.REPORT_VARIABLES = true;
myTool.REPORT_PARAMETERS = false;
doTest();
}
}