diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/modifier/RedundantModifierCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/modifier/RedundantModifierCheck.java index f513f8b57..af06aa17e 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/modifier/RedundantModifierCheck.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/modifier/RedundantModifierCheck.java @@ -31,7 +31,8 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes; /** * Checks for redundant modifiers in interface and annotation definitions. * Checks for non public class constructor and enum constructor redundant modifier. - * Also checks for redundant final modifiers on methods of final classes + * Checks for redundant final modifiers on methods of final classes. + * Checks for redundant static modifiers on nested enums. * *

Examples:

* @@ -74,6 +75,7 @@ import com.puppycrawl.tools.checkstyle.api.TokenTypes; * * @author lkuehne * @author liscju + * @author Vladislav Lisetskiy */ public class RedundantModifierCheck extends Check { @@ -128,6 +130,9 @@ public class RedundantModifierCheck checkClassConstructorModifiers(ast); } } + else if (ast.getType() == TokenTypes.ENUM_DEF) { + checkEnumDef(ast); + } else if (isInterfaceOrAnnotationMember(ast)) { processInterfaceOrAnnotation(ast); } @@ -167,6 +172,24 @@ public class RedundantModifierCheck } } + /** + * Checks whether enum has proper modifiers. + * @param ast enum definition. + */ + private void checkEnumDef(DetailAST ast) { + if (isInterfaceOrAnnotationMember(ast)) { + processInterfaceOrAnnotation(ast); + } + else if (ast.getParent() != null) { + final DetailAST modifiers = ast.findFirstToken(TokenTypes.MODIFIERS); + final DetailAST staticModifier = modifiers.findFirstToken(TokenTypes.LITERAL_STATIC); + if (staticModifier != null) { + log(staticModifier.getLineNo(), staticModifier.getColumnNo(), + MSG_KEY, staticModifier.getText()); + } + } + } + /** * Do validation of interface of annotation. * @param ast token AST diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/modifier/RedundantModifierTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/modifier/RedundantModifierTest.java index b81449284..00031f38e 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/modifier/RedundantModifierTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/modifier/RedundantModifierTest.java @@ -137,4 +137,17 @@ public class RedundantModifierTest int[] expected = ArrayUtils.EMPTY_INT_ARRAY; Assert.assertArrayEquals(expected, actual); } + + @Test + public void testNestedStaticEnum() throws Exception { + final DefaultConfiguration checkConfig = + createCheckConfig(RedundantModifierCheck.class); + final String[] expected = { + "4:5: " + getCheckMessage(MSG_KEY, "static"), + "8:9: " + getCheckMessage(MSG_KEY, "static"), + "12:9: " + getCheckMessage(MSG_KEY, "static"), + }; + verify(checkConfig, getPath("InputRedundantStatic" + + "ModifierInNestedEnum.java"), expected); + } } diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/InputRedundantStaticModifierInNestedEnum.java b/src/test/resources/com/puppycrawl/tools/checkstyle/InputRedundantStaticModifierInNestedEnum.java new file mode 100644 index 000000000..7ef65f78d --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/InputRedundantStaticModifierInNestedEnum.java @@ -0,0 +1,14 @@ +package com.puppycrawl.tools.checkstyle; + +public class InputRedundantStaticModifierInNestedEnum { + static enum NestedEnumWithRedundantStatic {} // violation + + enum CorrectNestedEnum { + VAL; + static enum NestedEnumWithRedundantStatic {} // violation + } + + interface NestedInterface { + static enum NestedEnumWithRedundantStatic {} // violation + } +} diff --git a/src/xdocs/config_modifier.xml b/src/xdocs/config_modifier.xml index 0fd4c4ba1..9327043d7 100644 --- a/src/xdocs/config_modifier.xml +++ b/src/xdocs/config_modifier.xml @@ -98,13 +98,17 @@ Checks for redundant modifiers in:

    -
  1. interface and annotation definitions,
  2. -
  3. the final modifier on methods of final classes, and
  4. +
  5. Interface and annotation definitions.
  6. +
  7. Final modifier on methods of final classes.
  8. - inner interface declarations that are declared + Inner interface declarations that are declared + as static. +
  9. +
  10. Class constructors.
  11. +
  12. + Nested enum definitions that are declared as static.
  13. -
  14. class constructors

Rationale: The Java Language Specification strongly @@ -134,6 +138,10 @@ modifier on the method of a final class is redundant.

+

+ Nested enum types are always static by default. +

+

Public modifier for constructors in non-public non-protected classes is always obsolete: