fix for FinalLocalVariableCheck - FOR_EACH_CLAUSE variable is not reported. issue #20

This commit is contained in:
Bhavik Patel 2015-02-19 22:30:07 +05:30
parent cf3c535a33
commit 93a33df5bd
4 changed files with 135 additions and 1 deletions

View File

@ -39,6 +39,32 @@ import java.util.Map;
* <property name="token" value="VARIABLE_DEF"/>
* </module>
* </pre>
* <p>
* By default, this Check skip final validation on
* <a href = "http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.14.2">
* Enhanced For-Loop</a>
* </p>
* <p>
* Option 'validateEnhancedForLoopVariable' could be used to make Check to validate even variable
* from Enhanced For Loop.
* </p>
* <p>
* An example of how to configure the check so that it also validates enhanced For Loop Variable is:
* </p>
* <pre>
* &lt;module name="FinalLocalVariable"&gt;
* &lt;property name="token" value="VARIABLE_DEF"/&gt;
* &lt;property name="validateEnhancedForLoopVariable" value="true"/&gt;
* &lt;/module&gt;
* </pre>
* <p>Example:</p>
* <p>
* <code>
* for (int number : myNumbers) { // violation
* System.out.println(number);
* }
* </code>
* </p>
* @author k_gibbs, r_auckenthaler
*/
public class FinalLocalVariableCheck extends Check
@ -54,6 +80,18 @@ public class FinalLocalVariableCheck extends Check
private final FastStack<Map<String, DetailAST>> scopeStack =
FastStack.newInstance();
/** Controls whether to check enhanced for-loop variable. */
private boolean validateEnhancedForLoopVariable;
/**
* Whether to check enhanced for-loop variable or not.
* @param validateEnhancedForLoopVariable whether to check for-loop variable
*/
public final void setValidateEnhancedForLoopVariable(boolean validateEnhancedForLoopVariable)
{
this.validateEnhancedForLoopVariable = validateEnhancedForLoopVariable;
}
@Override
public int[] getDefaultTokens()
{
@ -116,7 +154,7 @@ public class FinalLocalVariableCheck extends Check
}
case TokenTypes.VARIABLE_DEF:
if ((ast.getParent().getType() != TokenTypes.OBJBLOCK)
&& (ast.getParent().getType() != TokenTypes.FOR_EACH_CLAUSE)
&& shouldCheckEnhancedForLoopVariable(ast)
&& isVariableInForInit(ast))
{
insertVariable(ast);
@ -154,6 +192,17 @@ public class FinalLocalVariableCheck extends Check
}
}
/**
* Determines whether enhanced for-loop variable should be checked or not.
* @param ast The ast to compare.
* @return true if enhanced for-loop variable should be checked.
*/
private boolean shouldCheckEnhancedForLoopVariable(DetailAST ast)
{
return validateEnhancedForLoopVariable
|| ast.getParent().getType() != TokenTypes.FOR_EACH_CLAUSE;
}
/**
* Checks if current variable is defined in
* {@link TokenTypes#FOR_INIT for-loop init}, e.g.:

View File

@ -20,6 +20,7 @@ package com.puppycrawl.tools.checkstyle.checks.coding;
import com.puppycrawl.tools.checkstyle.BaseCheckTestSupport;
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
import org.junit.Test;
import static com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck.MSG_KEY;
@ -96,4 +97,28 @@ public class FinalLocalVariableCheckTest
};
verify(checkConfig, getPath("coding/InputFinalLocalVariableCheckFalsePositive.java"), expected);
}
@Test
public void testEnhancedForLoopVariableTrue() throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(FinalLocalVariableCheck.class);
checkConfig.addAttribute("tokens", "VARIABLE_DEF, PARAMETER_DEF");
checkConfig.addAttribute("validateEnhancedForLoopVariable", "true");
final String[] expected = {
"8:20: " + "Variable 'a' should be declared final.",
"15:13: " + "Variable 'x' should be declared final.",
};
verify(checkConfig, getPath("coding/InputFinalLocalVariableEnhancedForLoopVariable.java"), expected);
}
@Test
public void testEnhancedForLoopVariableFalse() throws Exception
{
final DefaultConfiguration checkConfig =
createCheckConfig(FinalLocalVariableCheck.class);
checkConfig.addAttribute("tokens", "VARIABLE_DEF, PARAMETER_DEF");
final String[] expected = {
"15:13: " + "Variable 'x' should be declared final.",
};
verify(checkConfig, getPath("coding/InputFinalLocalVariableEnhancedForLoopVariable.java"), expected);
}
}

View File

@ -0,0 +1,21 @@
package com.puppycrawl.tools.checkstyle.coding;
public class InputFinalLocalVariableEnhancedForLoopVariable {
public void method1()
{
final java.util.List<Object> list = new java.util.ArrayList<>();
for(Object a : list){
}
}
public void method2()
{
final int[] squares = {0, 1, 4, 9, 16, 25};
int x;
for (final int i : squares) {
}
}
}

View File

@ -344,6 +344,19 @@ number.equals(i + j);
href="apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#VARIABLE_DEF">VARIABLE_DEF</a>
</td>
</tr>
<tr>
<td>validateEnhancedForLoopVariable</td>
<td>Controls whether to check <a href = "http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.14.2">enhanced for-loop</a> variable.</td>
<td>
<a
href="property_types.html#boolean">Boolean</a>,
</td>
<td>
<code>
false
</code>
</td>
</tr>
</table>
</subsection>
@ -364,6 +377,32 @@ number.equals(i + j);
&lt;property name=&quot;tokens&quot; value=&quot;VARIABLE_DEF,PARAMETER_DEF&quot;/&gt;
&lt;/module&gt;
</source>
<p>
By default, this Check skip final validation on
<a href = "http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.14.2">
Enhanced For-Loop</a>.
</p>
<p>
Option 'validateEnhancedForLoopVariable' could be used to make Check to validate even variable
from Enhanced For Loop.
</p>
<p>
An example of how to configure the check so that it also validates enhanced For Loop Variable is:
</p>
<source>
&lt;module name="FinalLocalVariable"&gt;
&lt;property name="token" value="VARIABLE_DEF"/&gt;
&lt;property name="validateEnhancedForLoopVariable" value="true"/&gt;
&lt;/module&gt;
</source>
<p>Example:</p>
<p>
<source>
for (int number : myNumbers) { // violation
System.out.println(number);
}
</source>
</p>
</subsection>
<subsection name="Package">