Enhanced the MethodName check to detect when a method name is the same as the residing class name. Thanks to Travis Schneeberger for providing patch #1892364.
This commit is contained in:
parent
b81ed9788d
commit
7cb8afb266
|
|
@ -18,6 +18,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
package com.puppycrawl.tools.checkstyle.checks.naming;
|
||||
|
||||
import com.puppycrawl.tools.checkstyle.api.DetailAST;
|
||||
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
|
||||
|
||||
/**
|
||||
|
|
@ -28,6 +29,14 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes;
|
|||
* and defaults to
|
||||
* <strong>^[a-z][a-zA-Z0-9]*$</strong>.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Also, checks if a method name has the same name as the residing class.
|
||||
* The default is false (it is not allowed). It is legal in Java to have
|
||||
* method with the same name as a class. As long as a return type is specified
|
||||
* it is a method and not a constructor which it could be easily confused as.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* An example of how to configure the check is:
|
||||
* </p>
|
||||
|
|
@ -43,12 +52,27 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes;
|
|||
* <property name="format" value="^[a-z](_?[a-zA-Z0-9]+)*$"/>
|
||||
* </module>
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* An example of how to configure the check to allow method names
|
||||
* to be equal to the residing class name is:
|
||||
* </p>
|
||||
* <pre>
|
||||
* <module name="MethodName">
|
||||
* <property name="allowClassName" value="true"/>
|
||||
* </module>
|
||||
* </pre>
|
||||
* @author Oliver Burn
|
||||
* @version 1.0
|
||||
* @author Travis Schneeberger
|
||||
* @version 1.1
|
||||
*/
|
||||
public class MethodNameCheck
|
||||
extends AbstractAccessControlNameCheck
|
||||
public class MethodNameCheck extends AbstractNameCheck
|
||||
{
|
||||
/**
|
||||
* for allowing method name to be the same as the class name.
|
||||
*/
|
||||
private boolean mAllowClassName;
|
||||
|
||||
/** Creates a new <code>MethodNameCheck</code> instance. */
|
||||
public MethodNameCheck()
|
||||
{
|
||||
|
|
@ -58,6 +82,35 @@ public class MethodNameCheck
|
|||
@Override
|
||||
public int[] getDefaultTokens()
|
||||
{
|
||||
return new int[] {TokenTypes.METHOD_DEF};
|
||||
return new int[] {TokenTypes.METHOD_DEF, };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitToken(DetailAST aAst)
|
||||
{
|
||||
super.visitToken(aAst); // Will check the name against the format.
|
||||
|
||||
if (!mAllowClassName) {
|
||||
final DetailAST method =
|
||||
aAst.findFirstToken(TokenTypes.IDENT);
|
||||
//in all cases this will be the classDef type except anon inner
|
||||
//with anon inner classes this will be the Literal_New keyword
|
||||
final DetailAST classDefOrNew = aAst.getParent().getParent();
|
||||
final DetailAST classIdent =
|
||||
classDefOrNew.findFirstToken(TokenTypes.IDENT);
|
||||
if (method.getText().equals(classIdent.getText())) {
|
||||
log(method.getLineNo(), method.getColumnNo(),
|
||||
"method.name.equals.class.name", method.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the property for allowing a method to be the same name as a class.
|
||||
* @param aAllowClassName true to allow false to disallow
|
||||
*/
|
||||
public void setAllowClassName(boolean aAllowClassName)
|
||||
{
|
||||
mAllowClassName = aAllowClassName;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
name.invalidPattern=Name ''{0}'' must match pattern ''{1}''.
|
||||
illegal.abstract.class.name=Name ''{0}'' must match pattern ''{1}''.
|
||||
method.name.equals.class.name=Method Name ''{0}'' must not equal the enclosing class name.
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.puppycrawl.tools.checkstyle;
|
||||
|
||||
/**
|
||||
* Test input for MethodNameCheck specifically
|
||||
* whether the method name equals the class name.
|
||||
*
|
||||
* @author Travis Schneeberger
|
||||
*/
|
||||
public class InputMethNameEqualClsName {
|
||||
|
||||
//illegal name
|
||||
public int InputMethNameEqualClsName() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
class Inner {
|
||||
//illegal name
|
||||
public int Inner() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//OK name - name of the outter class's ctor
|
||||
public int InputMethNameEqualClsName() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void anotherMethod() {
|
||||
new InputMethNameEqualClsName() {
|
||||
|
||||
//illegal name
|
||||
public int InputMethNameEqualClsName() {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
interface SweetInterface {
|
||||
|
||||
//illegal name
|
||||
int SweetInterface();
|
||||
}
|
||||
|
||||
class Outter {
|
||||
|
||||
//illegal name
|
||||
public void Outter() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -18,4 +18,46 @@ public class MethodNameCheckTest
|
|||
};
|
||||
verify(checkConfig, getPath("InputSimple.java"), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodEqClass() throws Exception
|
||||
{
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(MethodNameCheck.class);
|
||||
|
||||
final String[] expected = {
|
||||
"12:16: Method Name 'InputMethNameEqualClsName' must not equal the enclosing class name.",
|
||||
"12:16: Name 'InputMethNameEqualClsName' must match pattern '^[a-z][a-zA-Z0-9]*$'.",
|
||||
"18:20: Method Name 'Inner' must not equal the enclosing class name.",
|
||||
"18:20: Name 'Inner' must match pattern '^[a-z][a-zA-Z0-9]*$'.",
|
||||
"23:20: Name 'InputMethNameEqualClsName' must match pattern '^[a-z][a-zA-Z0-9]*$'.",
|
||||
"32:24: Method Name 'InputMethNameEqualClsName' must not equal the enclosing class name.",
|
||||
"32:24: Name 'InputMethNameEqualClsName' must match pattern '^[a-z][a-zA-Z0-9]*$'.",
|
||||
"42:9: Method Name 'SweetInterface' must not equal the enclosing class name.",
|
||||
"42:9: Name 'SweetInterface' must match pattern '^[a-z][a-zA-Z0-9]*$'.",
|
||||
"48:17: Method Name 'Outter' must not equal the enclosing class name.",
|
||||
"48:17: Name 'Outter' must match pattern '^[a-z][a-zA-Z0-9]*$'.",
|
||||
};
|
||||
|
||||
verify(checkConfig, getPath("InputMethNameEqualClsName.java"), expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMethodEqClassAllow() throws Exception
|
||||
{
|
||||
final DefaultConfiguration checkConfig =
|
||||
createCheckConfig(MethodNameCheck.class);
|
||||
checkConfig.addAttribute("allowClassName", "true"); //allow method names and class names to equal
|
||||
|
||||
final String[] expected = {
|
||||
"12:16: Name 'InputMethNameEqualClsName' must match pattern '^[a-z][a-zA-Z0-9]*$'.",
|
||||
"18:20: Name 'Inner' must match pattern '^[a-z][a-zA-Z0-9]*$'.",
|
||||
"23:20: Name 'InputMethNameEqualClsName' must match pattern '^[a-z][a-zA-Z0-9]*$'.",
|
||||
"32:24: Name 'InputMethNameEqualClsName' must match pattern '^[a-z][a-zA-Z0-9]*$'.",
|
||||
"42:9: Name 'SweetInterface' must match pattern '^[a-z][a-zA-Z0-9]*$'.",
|
||||
"48:17: Name 'Outter' must match pattern '^[a-z][a-zA-Z0-9]*$'.",
|
||||
};
|
||||
|
||||
verify(checkConfig, getPath("InputMethNameEqualClsName.java"), expected);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,17 +18,17 @@
|
|||
href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html">
|
||||
regular expression</a> for valid identifiers. This is an example of a
|
||||
configuration of the <span class="code">MemberName</span> module to
|
||||
ensure that member identifiers begin with
|
||||
ensure that member identifiers begin with
|
||||
<span class="code">'m'</span>, followed
|
||||
by an upper case letter, and then letters and digits:
|
||||
</p>
|
||||
|
||||
|
||||
<source>
|
||||
<module name="MemberName">
|
||||
<property name="format" value="^m[A-Z][a-zA-Z0-9]*$"/>
|
||||
</module>
|
||||
</source>
|
||||
|
||||
|
||||
<p>
|
||||
All naming modules belong to package <span
|
||||
class="code">com.puppycrawl.tools.checkstyle.checks.naming</span> and
|
||||
|
|
@ -141,7 +141,7 @@
|
|||
clause parameters begin with <span class="code">"e"</span>, followed
|
||||
by letters and digits:
|
||||
</p>
|
||||
|
||||
|
||||
<source>
|
||||
<module name="LocalVariableName">
|
||||
<property name="format" value="^e[a-zA-Z0-9]*$"/>
|
||||
|
|
@ -169,10 +169,12 @@
|
|||
</source>
|
||||
|
||||
<p>
|
||||
Module <span class="code">MemberName</span> also has the following
|
||||
properties:
|
||||
The modules <span class="code">ConstantName</span>, <span
|
||||
class="code">MemberName</span>, <span
|
||||
class="code">StaticVariableName</span> and <span
|
||||
class="code">TypeName</span> also have the following properties:
|
||||
</p>
|
||||
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>name</th>
|
||||
|
|
@ -207,6 +209,38 @@
|
|||
<td><span class="default">true</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
Module <span class="code">MethodName</span> also has the following
|
||||
properties:
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>name</th>
|
||||
<th>description</th>
|
||||
<th>type</th>
|
||||
<th>default value</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>allowClassName</td>
|
||||
<td>
|
||||
Controls whether to allow a method name to have the same
|
||||
name as the residing class name. This is not to be confused
|
||||
with a constructor. An easy mistake is to place a return
|
||||
type on a constructor declaration which turns it into a
|
||||
method. For example:
|
||||
<pre>
|
||||
class MyClass {
|
||||
public void MyClass() {} //this is a method
|
||||
public MyClass() {} //this is a constructor
|
||||
}
|
||||
</pre>
|
||||
</td>
|
||||
<td><a href="property_types.html#boolean">Boolean</a></td>
|
||||
<td><span class="default">false</span></td>
|
||||
</tr>
|
||||
</table>
|
||||
</section>
|
||||
</body>
|
||||
</document>
|
||||
|
|
|
|||
|
|
@ -65,6 +65,12 @@
|
|||
for ensuring there are no static import statements. Thanks to
|
||||
Travis Schneeberger for providing patch #1940611.
|
||||
</li>
|
||||
<li>
|
||||
Enhanced the <a href="config_naming.html">MethodName</a> check
|
||||
to detect when a method name is the same as the residing class
|
||||
name. Thanks to Travis Schneeberger for providing patch
|
||||
#1892364.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>Fixed Bugs:</p>
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@
|
|||
|
||||
<div class="csBottomBar">
|
||||
<div class="csBottomBarContents">
|
||||
Copyright © 2001-2007, Oliver Burn
|
||||
Copyright © 2001-2008, Oliver Burn
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
|||
Loading…
Reference in New Issue