Corrected bug 747530, inner class fields interpreted as local variables.
Incorporated catch parameters as local variables.
This commit is contained in:
parent
c1bc1ef555
commit
4981978ee2
|
|
@ -58,7 +58,8 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td><span class="code">LocalVariableName</span></td>
|
||||
<td>local, non-<span class="code">final</span> variables</td>
|
||||
<td>local, non-<span class="code">final</span> variables, including
|
||||
<span class="code">catch</span> parameters</td>
|
||||
<td><span class="default">^[a-z][a-zA-Z0-9]*$</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -110,6 +111,22 @@
|
|||
</module>
|
||||
</pre>
|
||||
</li>
|
||||
<li>
|
||||
Module <span class="code">LocalVariableName</span> also has property <span class="code">tokens</span>
|
||||
which can be used to control whether the check applies to variable declarations or
|
||||
<span class="code">catch</span> clause parameters through
|
||||
tokens
|
||||
<span class="code">VARIABLE_DEF</span> and <span class="code">PARAMETER_DEF</span>.
|
||||
For example, the following configuration element ensures that
|
||||
<span class="code">catch</span> clause parameters begin with <span class="code">"e"</span>,
|
||||
followed by letters and digits:
|
||||
<pre class="body">
|
||||
<module name="LocalVariableName">
|
||||
<property name="format" value="^e[a-zA-Z0-9]*$"/>
|
||||
<property name="tokens" value="PARAMETER_DEF"/>
|
||||
</module>
|
||||
</pre>
|
||||
</li>
|
||||
<li>
|
||||
Module <span class="code">TypeName</span> also has property <span class="code">tokens</span>
|
||||
which can be used to control whether the check applies to classes or interfaces through
|
||||
|
|
|
|||
|
|
@ -90,6 +90,8 @@
|
|||
|
||||
<li class="body">EmptyBlock does not accept stmt option (bug 747400)</li>
|
||||
|
||||
<li class="body">Inner class fields interpreted as local variables (bug 747530)</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -178,4 +178,32 @@ public final class ScopeUtils
|
|||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a node is a local variable definition,
|
||||
* i.e. is declared in a code block, a for initializer, or a
|
||||
* catch parameter.
|
||||
* @param aAST the node to check.
|
||||
* @return whether aAST is a local variable definition.
|
||||
*/
|
||||
public static boolean isLocalVariableDef(DetailAST aAST)
|
||||
{
|
||||
// variable declaration?
|
||||
if (aAST.getType() == TokenTypes.VARIABLE_DEF) {
|
||||
final DetailAST parent = aAST.getParent();
|
||||
if (parent != null) {
|
||||
final int type = parent.getType();
|
||||
return (type == TokenTypes.SLIST)
|
||||
|| (type == TokenTypes.FOR_INIT);
|
||||
}
|
||||
}
|
||||
// catch parameter?
|
||||
else if (aAST.getType() == TokenTypes.PARAMETER_DEF) {
|
||||
final DetailAST parent = aAST.getParent();
|
||||
if (parent != null) {
|
||||
return (parent.getType() == TokenTypes.LITERAL_CATCH);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,7 +134,9 @@ public class HiddenFieldCheck
|
|||
private void processVariable(DetailAST aAST)
|
||||
{
|
||||
if (!ScopeUtils.inInterfaceBlock(aAST)) {
|
||||
if (ScopeUtils.inCodeBlock(aAST)) {
|
||||
if (ScopeUtils.isLocalVariableDef(aAST)
|
||||
|| (aAST.getType() == TokenTypes.PARAMETER_DEF))
|
||||
{
|
||||
//local variable or parameter. Does it shadow a field?
|
||||
final DetailAST nameAST = aAST.findFirstToken(TokenTypes.IDENT);
|
||||
final String name = nameAST.getText();
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ public class LocalFinalVariableNameCheck
|
|||
aAST.findFirstToken(TokenTypes.MODIFIERS);
|
||||
final boolean isFinal = (modifiersAST != null)
|
||||
&& modifiersAST.branchContains(TokenTypes.FINAL);
|
||||
|
||||
return (isFinal && ScopeUtils.inCodeBlock(aAST));
|
||||
return (isFinal && ScopeUtils.isLocalVariableDef(aAST));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes;
|
|||
/**
|
||||
* <p>
|
||||
* Checks that local, non-final variable names conform to a format specified
|
||||
* by the format property. The format is a
|
||||
* by the format property. A catch parameter is considered to be
|
||||
* a local variable. The format is a
|
||||
* <a href="http://jakarta.apache.org/regexp/apidocs/org/apache/regexp/RE.html">
|
||||
* regular expression</a>
|
||||
* and defaults to
|
||||
|
|
@ -61,7 +62,10 @@ public class LocalVariableNameCheck
|
|||
/** @see com.puppycrawl.tools.checkstyle.api.Check */
|
||||
public int[] getDefaultTokens()
|
||||
{
|
||||
return new int[] {TokenTypes.VARIABLE_DEF};
|
||||
return new int[] {
|
||||
TokenTypes.VARIABLE_DEF,
|
||||
TokenTypes.PARAMETER_DEF,
|
||||
};
|
||||
}
|
||||
|
||||
/** @see com.puppycrawl.tools.checkstyle.checks.AbstractNameCheck */
|
||||
|
|
@ -71,7 +75,6 @@ public class LocalVariableNameCheck
|
|||
aAST.findFirstToken(TokenTypes.MODIFIERS);
|
||||
final boolean isFinal = (modifiersAST != null)
|
||||
&& modifiersAST.branchContains(TokenTypes.FINAL);
|
||||
|
||||
return (!isFinal && ScopeUtils.inCodeBlock(aAST));
|
||||
return (!isFinal && ScopeUtils.isLocalVariableDef(aAST));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,6 +73,6 @@ public class MemberNameCheck
|
|||
&& modifiersAST.branchContains(TokenTypes.LITERAL_STATIC);
|
||||
|
||||
return (!isStatic && !ScopeUtils.inInterfaceBlock(aAST)
|
||||
&& !ScopeUtils.inCodeBlock(aAST));
|
||||
&& !ScopeUtils.isLocalVariableDef(aAST));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,4 +41,19 @@ class InputInner
|
|||
protected static Object sWeird = new Object();
|
||||
/** demonstrate bug in handling static final **/
|
||||
static Object sWeird2 = new Object();
|
||||
|
||||
/** demonstrate bug in local final variable */
|
||||
public interface Inter
|
||||
{
|
||||
}
|
||||
|
||||
public static void main()
|
||||
{
|
||||
Inter m = new Inter()
|
||||
{
|
||||
private static final int CDS = 1;
|
||||
|
||||
private int ABC;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,5 +28,14 @@ public class LocalFinalVariableNameCheckTest
|
|||
};
|
||||
verify(checkConfig, getPath("InputSimple.java"), expected);
|
||||
}
|
||||
|
||||
public void testInnerClass()
|
||||
throws Exception
|
||||
{
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(LocalFinalVariableNameCheck.class);
|
||||
final String[] expected = {};
|
||||
verify(checkConfig, getPath("InputInner.java"), expected);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,5 +18,27 @@ public class LocalVariableNameCheckTest
|
|||
};
|
||||
verify(checkConfig, getPath("InputSimple.java"), expected);
|
||||
}
|
||||
|
||||
public void testInnerClass()
|
||||
throws Exception
|
||||
{
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(LocalVariableNameCheck.class);
|
||||
final String[] expected = {};
|
||||
verify(checkConfig, getPath("InputInner.java"), expected);
|
||||
}
|
||||
|
||||
public void testCatchParameter()
|
||||
throws Exception
|
||||
{
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(LocalVariableNameCheck.class);
|
||||
checkConfig.addAttribute("tokens", "PARAMETER_DEF");
|
||||
checkConfig.addAttribute("format", "^e$");
|
||||
final String[] expected = {
|
||||
"74:24: Name 'ex' must match pattern '^e$'.",
|
||||
};
|
||||
verify(checkConfig, getPath("InputEmptyStatement.java"), expected);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,5 +17,16 @@ public class MemberNameCheckTest
|
|||
};
|
||||
verify(checkConfig, getPath("InputSimple.java"), expected);
|
||||
}
|
||||
|
||||
public void testInnerClass()
|
||||
throws Exception
|
||||
{
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(MemberNameCheck.class);
|
||||
final String[] expected = {
|
||||
"56:25: Name 'ABC' must match pattern '^[a-z][a-zA-Z0-9]*$'.",
|
||||
};
|
||||
verify(checkConfig, getPath("InputInner.java"), expected);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue