diff --git a/eclipsecs-sevntu-plugin/src/com/github/sevntu/checkstyle/checks/coding/checkstyle-metadata.properties b/eclipsecs-sevntu-plugin/src/com/github/sevntu/checkstyle/checks/coding/checkstyle-metadata.properties index b7859c2c4a..b08ae76fa3 100755 --- a/eclipsecs-sevntu-plugin/src/com/github/sevntu/checkstyle/checks/coding/checkstyle-metadata.properties +++ b/eclipsecs-sevntu-plugin/src/com/github/sevntu/checkstyle/checks/coding/checkstyle-metadata.properties @@ -43,6 +43,9 @@ EmptyPublicCtorInClassCheck.desc =
This Check looks for useless empty public EmptyPublicCtorInClassCheck.classAnnotationNames = Regex which matches names of class annotations which require class to have public no-argument ctor. Default value is "javax\\.persistence\\.Entity". EmptyPublicCtorInClassCheck.ctorAnnotationNames = Regex which matches names of ctor annotations which make empty public ctor essential. Default value is "com\\.google\\.inject\\.Inject". +EnumTrailingComma.name = Enum Trailing Comma +EnumTrailingComma.desc =
The check demands a comma at the end if neither left nor right curly braces are on the same line as the last element of the enum.
+ FinalizeImplementationCheck.name = Finalize Implementation FinalizeImplementationCheck.desc =This Check detects 3 most common cases of incorrect finalize() method implementation:
protected void finalize() { }
protected void finalize() { doSomething(); }protected void finalize() { super.finalize(); }public void finalize() { try { doSomething(); } finally { super.finalize() } }+ * Checks that enums contains a trailing comma. + *
+ *
+ * enum MovieType {
+ * GOOD,
+ * BAD,
+ * UGLY,
+ * ;
+ * }
+ *
+ * + * The check demands a comma at the end if neither left nor right curly braces are on the same line + * as the last element of the enum. + *
+ *
+ * enum MovieType {GOOD, BAD, UGLY;}
+ * enum MovieType {GOOD, BAD, UGLY
+ * ;}
+ * enum MovieType {GOOD, BAD,
+ * UGLY;}
+ * enum MovieType {GOOD, BAD,
+ * UGLY; // Violation
+ * }
+ *
+ * + * Putting this comma in makes it easier to change the order of the elements or add new elements + * at the end. Main benefit of a trailing comma is that when you add new entry to an enum, no + * surrounding lines are changed. + *
+ *
+ * enum MovieType {
+ * GOOD,
+ * BAD, //OK
+ * }
+ *
+ * enum MovieType {
+ * GOOD,
+ * BAD,
+ * UGLY, // Just this line added, no other changes
+ * }
+ *
+ * + * If closing brace is on the same line as trailing comma, this benefit is gone (as the check does + * not demand a certain location of curly braces the following two cases will not produce a + * violation): + *
+ *
+ * enum MovieType {GOOD,
+ * BAD,} // Trailing comma not needed, line needs to be modified anyway
+ *
+ * enum MovieType {GOOD,
+ * BAD, // Modified line
+ * UGLY,} // Added line
+ *
+ *
+ * @author Yasser Aziza
+ */
+public class EnumTrailingComma extends AbstractCheck {
+
+ /**
+ * Warning message key pointing to the warning message text in "messages.properties" file.
+ */
+ public static final String MSG_KEY = "enum.trailing.comma";
+
+ @Override
+ public int[] getDefaultTokens() {
+ return new int[] {
+ TokenTypes.ENUM_CONSTANT_DEF,
+ };
+ }
+
+ @Override
+ public int[] getAcceptableTokens() {
+ return getDefaultTokens();
+ }
+
+ @Override
+ public int[] getRequiredTokens() {
+ return getDefaultTokens();
+ }
+
+ @Override
+ public void visitToken(DetailAST ast) {
+ final DetailAST nextSibling = ast.getNextSibling();
+
+ if (TokenTypes.COMMA != nextSibling.getType() && isSeparateLine(ast)) {
+ log(ast, MSG_KEY);
+ }
+ }
+
+ /**
+ * Checks if the given {@link TokenTypes#ENUM_CONSTANT_DEF} element is in the same line with
+ * the {@link TokenTypes#LCURLY} or {@link TokenTypes#RCURLY}.
+ *
+ * @param ast the enum node
+ * @return {@code true} if the element is on the same line with {@link TokenTypes#LCURLY} or
+ * {@link TokenTypes#RCURLY}, {@code false} otherwise.
+ */
+ private static boolean isSeparateLine(DetailAST ast) {
+ final DetailAST objBlock = ast.getParent();
+ final DetailAST leftCurly = objBlock.findFirstToken(TokenTypes.LCURLY);
+ final DetailAST rightCurly = objBlock.findFirstToken(TokenTypes.RCURLY);
+
+ return !areOnSameLine(leftCurly, ast)
+ && !areOnSameLine(ast, rightCurly);
+ }
+
+ /**
+ * Determines if two ASTs are on the same line.
+ *
+ * @param ast1 the first AST
+ * @param ast2 the second AST
+ *
+ * @return true if they are on the same line.
+ */
+ private static boolean areOnSameLine(DetailAST ast1, DetailAST ast2) {
+ return ast1.getLineNo() == ast2.getLineNo();
+ }
+
+}
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/Jsr305AnnotationsCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/Jsr305AnnotationsCheck.java
index a9d87c2213..dab95036c3 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/Jsr305AnnotationsCheck.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/Jsr305AnnotationsCheck.java
@@ -293,7 +293,8 @@ private enum NullnessAnnotation {
PARAMETERS_ARE_NULLABLE_BY_DEFAULT("ParametersAreNullableByDefault", PKG_JAVAX_ANNOTATION),
/** ReturnValuesAreNonnullByDefault. */
RETURN_VALUES_ARE_NONNULL_BY_DEFAULT("ReturnValuesAreNonnullByDefault",
- "edu.umd.cs.findbugs.annotations");
+ "edu.umd.cs.findbugs.annotations"),
+ ;
/** The annotation's name. */
private final String annotationName;
diff --git a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/NumericLiteralNeedsUnderscoreCheck.java b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/NumericLiteralNeedsUnderscoreCheck.java
index f0b8132391..8c8d258417 100644
--- a/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/NumericLiteralNeedsUnderscoreCheck.java
+++ b/sevntu-checks/src/main/java/com/github/sevntu/checkstyle/checks/coding/NumericLiteralNeedsUnderscoreCheck.java
@@ -167,7 +167,7 @@ protected enum NumericType {
/**
* Denotes a binary literal. For example, 0b0011
*/
- BINARY
+ BINARY,
}
diff --git a/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/coding/messages.properties b/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/coding/messages.properties
index 465f6cf02c..f170cb5364 100644
--- a/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/coding/messages.properties
+++ b/sevntu-checks/src/main/resources/com/github/sevntu/checkstyle/checks/coding/messages.properties
@@ -14,6 +14,7 @@ custom.declaration.order.method=Method definition in wrong order. Expected ''{0}
diamond.operator.for.variable.definition=Diamond operator expected.
either.log.or.throw=Either log or throw exception.
empty.public.ctor=This empty public constructor is useless.
+enum.trailing.comma=Enum should contain trailing comma.
finalize.implementation.missed.super.finalize=You have to call super.finalize() right after finally opening brace.
finalize.implementation.missed.try.finally=finalize() method should contain try-finally block with super.finalize() call inside finally block.
finalize.implementation.public=finalize() method should have a "protected" visibility.
diff --git a/sevntu-checks/src/test/java/com/github/sevntu/checkstyle/checks/coding/EnumTrailingCommaTest.java b/sevntu-checks/src/test/java/com/github/sevntu/checkstyle/checks/coding/EnumTrailingCommaTest.java
new file mode 100644
index 0000000000..3b3819243c
--- /dev/null
+++ b/sevntu-checks/src/test/java/com/github/sevntu/checkstyle/checks/coding/EnumTrailingCommaTest.java
@@ -0,0 +1,58 @@
+////////////////////////////////////////////////////////////////////////////////
+// checkstyle: Checks Java source code for adherence to a set of rules.
+// Copyright (C) 2001-2020 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.github.sevntu.checkstyle.checks.coding;
+
+import static com.github.sevntu.checkstyle.checks.coding.EnumTrailingComma.MSG_KEY;
+
+import org.junit.Test;
+
+import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
+import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
+
+/**
+ * @author Yasser Aziza
+ */
+public class EnumTrailingCommaTest extends AbstractModuleTestSupport {
+
+ /**
+ * An error message for current check.
+ */
+ private final String warningMessage = getCheckMessage(MSG_KEY);
+
+ @Override
+ protected String getPackageLocation() {
+ return "com/github/sevntu/checkstyle/checks/coding";
+ }
+
+ @Test
+ public void testDefault() throws Exception {
+ final DefaultConfiguration checkConfig = createModuleConfig(EnumTrailingComma.class);
+
+ final String[] expected = {
+ "14:9: " + warningMessage,
+ "19:9: " + warningMessage,
+ "27:9: " + warningMessage,
+ "39:9: " + warningMessage,
+ };
+
+ verify(checkConfig, getPath("InputEnumTrailingCommaCheck.java"), expected);
+ }
+
+}
diff --git a/sevntu-checks/src/test/resources/com/github/sevntu/checkstyle/checks/coding/InputEnumTrailingCommaCheck.java b/sevntu-checks/src/test/resources/com/github/sevntu/checkstyle/checks/coding/InputEnumTrailingCommaCheck.java
new file mode 100644
index 0000000000..218c455acb
--- /dev/null
+++ b/sevntu-checks/src/test/resources/com/github/sevntu/checkstyle/checks/coding/InputEnumTrailingCommaCheck.java
@@ -0,0 +1,61 @@
+package com.github.sevntu.checkstyle.checks.coding;
+
+public class InputEnumTrailingCommaCheck {
+
+ enum MovieType {
+ GOOD,
+ BAD,
+ UGLY,
+ ;
+ }
+
+ enum Gender {
+ FEMALE,
+ MALE // Violation
+ }
+
+ enum Language {
+ ENGLISH,
+ GERMAN // Violation
+ ;
+ }
+
+ // Violation
+ enum ErrorMessage {
+ USER_DOES_NOT_EXIST,
+ INVALID_USER_PASS,
+ EVERYTHING_ELSE; // Violation
+ }
+
+ enum BinType {ZERO, ONE
+ ;}
+
+ enum SameLine {FIRST, SECOND, THIRD;}
+
+ enum LineBreak {FIRST, SECOND,
+ THIRD;}
+
+ enum LastLineBreak {FIRST, SECOND,
+ THIRD; // Violation
+ }
+
+ enum LastBreakSemicolon {FIRST, SECOND, THIRD
+ ;
+ }
+
+ enum RgbColor {
+ RED,
+ GREEN,
+ BLUE
+ ,
+ }
+
+ enum OperatingSystem {
+ LINUX,
+ MAC
+ ,}
+
+ enum EMPTY {E
+ }
+
+}
diff --git a/sevntu-checkstyle-sonar-plugin/src/main/resources/com/github/sevntu/checkstyle/sonar/checkstyle-extensions.xml b/sevntu-checkstyle-sonar-plugin/src/main/resources/com/github/sevntu/checkstyle/sonar/checkstyle-extensions.xml
index 53ef2ae7dd..abd44d045a 100644
--- a/sevntu-checkstyle-sonar-plugin/src/main/resources/com/github/sevntu/checkstyle/sonar/checkstyle-extensions.xml
+++ b/sevntu-checkstyle-sonar-plugin/src/main/resources/com/github/sevntu/checkstyle/sonar/checkstyle-extensions.xml
@@ -346,6 +346,14 @@
+