From d67d10e9f2b480f7f56fe7cda2a908cd5fe770c7 Mon Sep 17 00:00:00 2001 From: Michal Kordas Date: Tue, 17 Nov 2015 23:38:59 +0100 Subject: [PATCH] Issue #2616: Add CatchParameterName check for catch blocks parameters --- config/checkstyle_checks.xml | 3 + .../CatchParameterNameTest.java | 55 ++++++++++ .../InputCatchParameterName.java | 53 +++++++++ .../naming/CatchParameterNameCheck.java | 91 ++++++++++++++++ src/main/resources/google_checks.xml | 5 + .../naming/CatchParameterNameCheckTest.java | 102 ++++++++++++++++++ .../naming/InputCatchParameterName.java | 50 +++++++++ src/xdocs/checks.xml | 4 + src/xdocs/config_naming.xml | 84 +++++++++++++++ src/xdocs/google_style.xml | 12 +++ 10 files changed, 459 insertions(+) create mode 100644 src/it/java/com/google/checkstyle/test/chapter5naming/rule51identifiernames/CatchParameterNameTest.java create mode 100644 src/it/resources/com/google/checkstyle/test/chapter5naming/rule51identifiernames/InputCatchParameterName.java create mode 100644 src/main/java/com/puppycrawl/tools/checkstyle/checks/naming/CatchParameterNameCheck.java create mode 100644 src/test/java/com/puppycrawl/tools/checkstyle/checks/naming/CatchParameterNameCheckTest.java create mode 100644 src/test/resources/com/puppycrawl/tools/checkstyle/checks/naming/InputCatchParameterName.java diff --git a/config/checkstyle_checks.xml b/config/checkstyle_checks.xml index 672bca6c3..fb2740935 100644 --- a/config/checkstyle_checks.xml +++ b/config/checkstyle_checks.xml @@ -338,6 +338,9 @@ + + + diff --git a/src/it/java/com/google/checkstyle/test/chapter5naming/rule51identifiernames/CatchParameterNameTest.java b/src/it/java/com/google/checkstyle/test/chapter5naming/rule51identifiernames/CatchParameterNameTest.java new file mode 100644 index 000000000..2ec269174 --- /dev/null +++ b/src/it/java/com/google/checkstyle/test/chapter5naming/rule51identifiernames/CatchParameterNameTest.java @@ -0,0 +1,55 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2015 the original author or authors. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//////////////////////////////////////////////////////////////////////////////// + +package com.google.checkstyle.test.chapter5naming.rule51identifiernames; + +import java.io.File; +import java.io.IOException; + +import org.junit.Test; + +import com.google.checkstyle.test.base.BaseCheckTestSupport; +import com.puppycrawl.tools.checkstyle.api.Configuration; + +public class CatchParameterNameTest extends BaseCheckTestSupport { + @Override + protected String getPath(String fileName) throws IOException { + return super.getPath("chapter5naming" + File.separator + "rule51identifiernames" + + File.separator + fileName); + } + + @Test + public void catchParameterNameTest() throws Exception { + final Configuration checkConfig = getCheckConfig("CatchParameterName"); + final String msgKey = "name.invalidPattern"; + final String format = "^[a-z][a-z0-9][a-zA-Z0-9]*$"; + + final String[] expected = { + "6:28: " + getCheckMessage(checkConfig.getMessages(), msgKey, "e", format), + "24:28: " + getCheckMessage(checkConfig.getMessages(), msgKey, "t", format), + "47:28: " + getCheckMessage(checkConfig.getMessages(), msgKey, "iException", format), + "50:28: " + getCheckMessage(checkConfig.getMessages(), msgKey, "x", format), + }; + + final String filePath = getPath("InputCatchParameterName.java"); + + final Integer[] warnList = getLinesWithWarn(filePath); + verify(checkConfig, filePath, expected, warnList); + } +} diff --git a/src/it/resources/com/google/checkstyle/test/chapter5naming/rule51identifiernames/InputCatchParameterName.java b/src/it/resources/com/google/checkstyle/test/chapter5naming/rule51identifiernames/InputCatchParameterName.java new file mode 100644 index 000000000..acb175a8e --- /dev/null +++ b/src/it/resources/com/google/checkstyle/test/chapter5naming/rule51identifiernames/InputCatchParameterName.java @@ -0,0 +1,53 @@ +package com.google.checkstyle.test.chapter5naming.rule51identifiernames; + +public class InputCatchParameterName { + { + try { + } catch (Exception e) { // warn + } + try { + } catch (Exception ex) { // ok + } + try { + } catch (Error | Exception err) { // ok + } + try { + } catch (Exception exception) { // ok + } + try { + } catch (Exception exception1) { // ok + } + try { + } catch (Exception noWorries) { // ok + } + try { + } catch (Throwable t) { // warn + } + try { + throw new InterruptedException("interruptedException"); + } catch (InterruptedException ie) { // ok + } + try { + } catch (Exception ok) { // ok + // appropriate to take no action here + } + try { + } catch (Exception e1) { // ok + try { + } catch (Exception e2) { // ok + } + } + try { + } catch (Throwable t1) { // ok + try { + } catch (Throwable t2) { // ok + } + } + try { + } catch (Exception iException) { // warn + } + try { + } catch (Exception x) { // warn + } + } +} diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/naming/CatchParameterNameCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/naming/CatchParameterNameCheck.java new file mode 100644 index 000000000..5a572b34a --- /dev/null +++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/naming/CatchParameterNameCheck.java @@ -0,0 +1,91 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2015 the original author or authors. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//////////////////////////////////////////////////////////////////////////////// + +package com.puppycrawl.tools.checkstyle.checks.naming; + +import com.puppycrawl.tools.checkstyle.api.DetailAST; +import com.puppycrawl.tools.checkstyle.api.TokenTypes; + +/** + *

+ * Checks that {@code catch} parameter names conform to a format specified by the format property. + * The format is a {@link java.util.regex.Pattern regular expression} and defaults to + * ^(e|t|ex|[a-z][a-z][a-zA-Z]+)$. + *

+ *

+ * Default pattern has the following characteristic: + *

+ *
    + *
  • allows names beginning with two lowercase letters followed by at least one uppercase or + * lowercase letter
  • + *
  • allows {@code e} abbreviation (suitable for exceptions end errors)
  • + *
  • allows {@code ex} abbreviation (suitable for exceptions)
  • + *
  • allows {@code t} abbreviation (suitable for throwables)
  • + *
  • prohibits numbered abbreviations like {@code e1} or {@code t2}
  • + *
  • prohibits one letter prefixes like {@code pException}
  • + *
  • prohibits two letter abbreviations like {@code ie} or {@code ee}
  • + *
  • prohibits any other characters than letters
  • + *
+ *

+ * An example of how to configure the check is: + *

+ *
+ * <module name="CatchParameterName"/>
+ * 
+ *

+ * An example of how to configure the check for names that begin with a lower case letter, + * followed by any letters or digits is: + *

+ *
+ * <module name="CatchParameterName">
+ *    <property name="format" value="^[a-z][a-zA-Z0-9]+$"/>
+ * </module>
+ * 
+ * + * @author Michal Kordas + */ +public class CatchParameterNameCheck extends AbstractNameCheck { + + /** + * Creates a new {@code CatchParameterNameCheck} instance. + */ + public CatchParameterNameCheck() { + super("^(e|t|ex|[a-z][a-z][a-zA-Z]+)$"); + } + + @Override + public int[] getDefaultTokens() { + return getAcceptableTokens(); + } + + @Override + public int[] getAcceptableTokens() { + return new int[]{TokenTypes.PARAMETER_DEF}; + } + + @Override + public int[] getRequiredTokens() { + return getAcceptableTokens(); + } + + @Override + protected boolean mustCheckName(DetailAST ast) { + return ast.getParent().getType() == TokenTypes.LITERAL_CATCH; + } +} diff --git a/src/main/resources/google_checks.xml b/src/main/resources/google_checks.xml index 3f21853f9..4ddc8fc4c 100644 --- a/src/main/resources/google_checks.xml +++ b/src/main/resources/google_checks.xml @@ -112,6 +112,11 @@ + + + + diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/naming/CatchParameterNameCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/naming/CatchParameterNameCheckTest.java new file mode 100644 index 000000000..a04fc9e51 --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/naming/CatchParameterNameCheckTest.java @@ -0,0 +1,102 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2015 the original author or authors. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//////////////////////////////////////////////////////////////////////////////// + +package com.puppycrawl.tools.checkstyle.checks.naming; + +import static com.puppycrawl.tools.checkstyle.checks.naming.AbstractNameCheck.MSG_INVALID_PATTERN; +import static org.junit.Assert.assertArrayEquals; + +import java.io.File; +import java.io.IOException; + +import org.apache.commons.lang3.ArrayUtils; +import org.junit.Test; + +import com.puppycrawl.tools.checkstyle.BaseCheckTestSupport; +import com.puppycrawl.tools.checkstyle.DefaultConfiguration; +import com.puppycrawl.tools.checkstyle.api.Configuration; +import com.puppycrawl.tools.checkstyle.api.TokenTypes; + +public class CatchParameterNameCheckTest extends BaseCheckTestSupport { + @Override + protected String getPath(String filename) throws IOException { + return super.getPath("checks" + File.separator + "naming" + File.separator + filename); + } + + @Test + public void testTokens() { + final CatchParameterNameCheck catchParameterNameCheck = new CatchParameterNameCheck(); + final int[] expected = {TokenTypes.PARAMETER_DEF}; + + assertArrayEquals(expected, catchParameterNameCheck.getRequiredTokens()); + assertArrayEquals(expected, catchParameterNameCheck.getAcceptableTokens()); + } + + @Test + public void testDefaultConfigurationOnCorrectFile() throws Exception { + final Configuration checkConfig = createCheckConfig(CatchParameterNameCheck.class); + final String[] expected = ArrayUtils.EMPTY_STRING_ARRAY; + + verify(checkConfig, getPath("InputSimple.java"), expected); + } + + @Test + public void testDefaultConfigurationOnFileWithViolations() throws Exception { + final Configuration checkConfig = createCheckConfig(CatchParameterNameCheck.class); + final String defaultFormat = "^(e|t|ex|[a-z][a-z][a-zA-Z]+)$"; + + final String[] expected = { + "18:28: " + getCheckMessage(MSG_INVALID_PATTERN, "exception1", defaultFormat), + "28:39: " + getCheckMessage(MSG_INVALID_PATTERN, "ie", defaultFormat), + "31:28: " + getCheckMessage(MSG_INVALID_PATTERN, "iException", defaultFormat), + "34:28: " + getCheckMessage(MSG_INVALID_PATTERN, "ok", defaultFormat), + "38:28: " + getCheckMessage(MSG_INVALID_PATTERN, "e1", defaultFormat), + "40:32: " + getCheckMessage(MSG_INVALID_PATTERN, "e2", defaultFormat), + "44:28: " + getCheckMessage(MSG_INVALID_PATTERN, "t1", defaultFormat), + "46:32: " + getCheckMessage(MSG_INVALID_PATTERN, "t2", defaultFormat), + }; + + verify(checkConfig, getPath("InputCatchParameterName.java"), expected); + } + + @Test + public void testCustomFormatFromJavadoc() throws Exception { + final DefaultConfiguration checkConfig = createCheckConfig(CatchParameterNameCheck.class); + final String format = "^[a-z][a-zA-Z0-9]+$"; + checkConfig.addAttribute("format", format); + + final String[] expected = { + "6:28: " + getCheckMessage(MSG_INVALID_PATTERN, "e", format), + "24:28: " + getCheckMessage(MSG_INVALID_PATTERN, "t", format), + }; + + verify(checkConfig, getPath("InputCatchParameterName.java"), expected); + } + + @Test + public void testCustomFormatWithNoAnchors() throws Exception { + final DefaultConfiguration checkConfig = createCheckConfig(CatchParameterNameCheck.class); + final String format = "[a-z]"; + checkConfig.addAttribute("format", format); + + final String[] expected = ArrayUtils.EMPTY_STRING_ARRAY; + + verify(checkConfig, getPath("InputCatchParameterName.java"), expected); + } +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/naming/InputCatchParameterName.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/naming/InputCatchParameterName.java new file mode 100644 index 000000000..fecd4b491 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/naming/InputCatchParameterName.java @@ -0,0 +1,50 @@ +package com.puppycrawl.tools.checkstyle.checks.naming; + +public class InputCatchParameterName { + { + try { + } catch (Exception e) { + } + try { + } catch (Exception ex) { + } + try { + } catch (Error | Exception err) { + } + try { + } catch (Exception exception) { + } + try { + } catch (Exception exception1) { + } + try { + } catch (Exception noWorries) { + } + try { + } catch (Throwable t) { + } + try { + throw new InterruptedException("interruptedException"); + } catch (InterruptedException ie) { // violation with default config + } + try { + } catch (Exception iException) { // violation with default config + } + try { + } catch (Exception ok) { + // appropriate to take no action here + } + try { + } catch (Exception e1) { + try { + } catch (Exception e2) { + } + } + try { + } catch (Throwable t1) { + try { + } catch (Throwable t2) { + } + } + } +} diff --git a/src/xdocs/checks.xml b/src/xdocs/checks.xml index 92c530c3b..d4a287593 100644 --- a/src/xdocs/checks.xml +++ b/src/xdocs/checks.xml @@ -94,6 +94,10 @@ and ^) to a specified depth (default = 3). + + CatchParameterName + Checks that catch parameter names conform to a format specified by the format property. + ClassDataAbstractionCoupling This metric measures the number of instantiations of other classes within the given class. diff --git a/src/xdocs/config_naming.xml b/src/xdocs/config_naming.xml index 03867b6e0..334a09b4d 100644 --- a/src/xdocs/config_naming.xml +++ b/src/xdocs/config_naming.xml @@ -230,6 +230,90 @@ +
+ +

+ Checks that catch parameter names conform to a format specified by the format property. + Default pattern has the following characteristic: +

+
    +
  • allows names beginning with two lowercase letters followed by at least one uppercase + or lowercase letter
  • +
  • allows e abbreviation (suitable for exceptions end errors)
  • +
  • allows ex abbreviation (suitable for exceptions)
  • +
  • allows t abbreviation (suitable for throwables)
  • +
  • prohibits numbered abbreviations like e1 or t2
  • +
  • prohibits one letter prefixes like pException
  • +
  • prohibits two letter abbreviations like ie or ee
  • +
  • prohibits any other characters than letters
  • +
+
+ + + + + + + + + + + + + + + +
namedescriptiontypedefault value
formatSpecifies valid identifiers. + regular expression + + ^(e|t|ex|[a-z][a-z][a-zA-Z]+)$ +
+
+ + +

+ To configure the check: +

+ +<module name="CatchParameterName"/> + +

+ An example of how to configure the check for names that begin with + a lower case letter, followed by letters and digits is: +

+ +<module name="ParameterName"> + <property name="format" value="^[a-z][a-zA-Z0-9]+$"/> +</module> + +
+ + + + + + +

com.puppycrawl.tools.checkstyle.checks.naming

+
+ + +

+ TreeWalker +

+
+
+

Validates identifiers for class type parameters.

diff --git a/src/xdocs/google_style.xml b/src/xdocs/google_style.xml index 60244bfe6..519d0c6c4 100644 --- a/src/xdocs/google_style.xml +++ b/src/xdocs/google_style.xml @@ -1144,6 +1144,10 @@ src="images/ok_green.png" alt="" /> ParameterName +
+
+ + CatchParameterName test +
+ + config + +
+ + test +