Skip to content

Commit

Permalink
fix for FinalLocalVariableCheck - FOR_EACH_CLAUSE variable is not rep…
Browse files Browse the repository at this point in the history
…orted. issue checkstyle#20
  • Loading branch information
Bhavik3 committed Mar 3, 2015
1 parent 62a9d14 commit 6a9deb2
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,32 @@
* <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
Expand All @@ -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()
{
Expand Down Expand Up @@ -116,7 +154,7 @@ public void visitToken(DetailAST ast)
}
case TokenTypes.VARIABLE_DEF:
if ((ast.getParent().getType() != TokenTypes.OBJBLOCK)
&& (ast.getParent().getType() != TokenTypes.FOR_EACH_CLAUSE)
&& shouldCheckEnhancedForLoopVariable(ast)
&& isVariableInForInit(ast))
{
insertVariable(ast);
Expand Down Expand Up @@ -154,6 +192,17 @@ && isVariableInForInit(ast))
}
}

/**
* 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.:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

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;
Expand Down Expand Up @@ -96,4 +97,28 @@ public void testFalsePositive() throws Exception
};
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);
}
}
Original file line number Diff line number Diff line change
@@ -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) {
}

}

}
13 changes: 13 additions & 0 deletions src/xdocs/config_coding.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down

0 comments on commit 6a9deb2

Please sign in to comment.