From 7cb8afb266fbada9792b9e04eeb9cef3ec10a3cc Mon Sep 17 00:00:00 2001
From: Oliver Burn
+ * 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. + *
+ * ** An example of how to configure the check is: *
@@ -43,12 +52,27 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes; * <property name="format" value="^[a-z](_?[a-zA-Z0-9]+)*$"/> * </module> * + * + *+ * An example of how to configure the check to allow method names + * to be equal to the residing class name is: + *
+ *+ * <module name="MethodName"> + * <property name="allowClassName" value="true"/> + * </module> + ** @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
MethodNameCheck 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;
}
}
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/naming/messages.properties b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/naming/messages.properties
index 061167c0e..3c4c30ac9 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/naming/messages.properties
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/naming/messages.properties
@@ -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.
\ No newline at end of file
diff --git a/src/testinputs/com/puppycrawl/tools/checkstyle/InputMethNameEqualClsName.java b/src/testinputs/com/puppycrawl/tools/checkstyle/InputMethNameEqualClsName.java
new file mode 100644
index 000000000..9c520c5e8
--- /dev/null
+++ b/src/testinputs/com/puppycrawl/tools/checkstyle/InputMethNameEqualClsName.java
@@ -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() {
+
+ }
+}
diff --git a/src/tests/com/puppycrawl/tools/checkstyle/checks/naming/MethodNameCheckTest.java b/src/tests/com/puppycrawl/tools/checkstyle/checks/naming/MethodNameCheckTest.java
index f5715ee74..46ac90881 100644
--- a/src/tests/com/puppycrawl/tools/checkstyle/checks/naming/MethodNameCheckTest.java
+++ b/src/tests/com/puppycrawl/tools/checkstyle/checks/naming/MethodNameCheckTest.java
@@ -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);
+ }
}
diff --git a/src/xdocs/config_naming.xml b/src/xdocs/config_naming.xml
index ffd04c66c..ba0a44037 100755
--- a/src/xdocs/config_naming.xml
+++ b/src/xdocs/config_naming.xml
@@ -18,17 +18,17 @@
href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html">
regular expression for valid identifiers. This is an example of a
configuration of the MemberName module to
- ensure that member identifiers begin with
+ ensure that member identifiers begin with
'm', followed
by an upper case letter, and then letters and digits:
-
+
All naming modules belong to package com.puppycrawl.tools.checkstyle.checks.naming and @@ -141,7 +141,7 @@ clause parameters begin with "e", followed by letters and digits:
- +- Module MemberName also has the following - properties: + The modules ConstantName, MemberName, StaticVariableName and TypeName also have the following properties:
- +| name | @@ -207,6 +209,38 @@true |
|---|
+ Module MethodName also has the following + properties: +
+ +| name | +description | +type | +default value | +
|---|---|---|---|
| allowClassName | +
+ 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:
+
+class MyClass {
+ public void MyClass() {} //this is a method
+ public MyClass() {} //this is a constructor
+}
+
+ |
+ Boolean | +false | +