Skip to content

Commit

Permalink
Issue checkstyle#6773: Add UnnecessarySemicolonInEnumerationCheck
Browse files Browse the repository at this point in the history
  • Loading branch information
strkkk committed May 30, 2019
1 parent e3cd671 commit 1ece92f
Show file tree
Hide file tree
Showing 17 changed files with 399 additions and 1 deletion.
1 change: 1 addition & 0 deletions .ci/jsoref-spellchecker/whitelist.words
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,7 @@ uniqueproperties
Unitless
unlzma
unnecessaryparentheses
unnecessarysemicoloninenumeration
Unproxyable
unregister
unsubscribe
Expand Down
1 change: 1 addition & 0 deletions config/checkstyle_checks.xml
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@
<module name="SuperClone"/>
<module name="SuperFinalize"/>
<module name="UnnecessaryParentheses"/>
<module name="UnnecessarySemicolonInEnumeration"/>
<module name="VariableDeclarationUsageDistance"/>

<!-- Filters-->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,8 @@ private static void fillChecksFromCodingPackage() {
BASE_PACKAGE + ".checks.coding.SuperFinalizeCheck");
NAME_TO_FULL_MODULE_NAME.put("UnnecessaryParenthesesCheck",
BASE_PACKAGE + ".checks.coding.UnnecessaryParenthesesCheck");
NAME_TO_FULL_MODULE_NAME.put("UnnecessarySemicolonInEnumerationCheck",
BASE_PACKAGE + ".checks.coding.UnnecessarySemicolonInEnumerationCheck");
NAME_TO_FULL_MODULE_NAME.put("VariableDeclarationUsageDistanceCheck",
BASE_PACKAGE + ".checks.coding.VariableDeclarationUsageDistanceCheck");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2019 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.coding;

import com.puppycrawl.tools.checkstyle.StatelessCheck;
import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;

/**
* <p>
* Checks if unnecessary semicolon is in enum definitions.
* Semicolon is not needed if enum body contains only enum constants.
* </p>
* <p>
* To configure the check:
* </p>
* <pre>
* &lt;module name=&quot;UnnecessarySemicolonInEnumeration&quot;/&gt;
* </pre>
* <p>
* Example of violations
* </p>
* <pre>
* enum One {
* A,B; // violation
* }
* enum Two {
* A,B,; // violation
* }
* enum Three {
* A,B(); // violation
* }
* enum Four {
* A,B{}; // violation
* }
* enum Five {
* A,
* B
* ; // violation
* }
* </pre>
* <p>
* Example of good cases
* </p>
* <pre>
* enum Normal {
* A,
* B,
* ; // required ";", no violation
* Normal(){}
* }
* enum NoSemicolon {
* A, B // only enum constants, no semicolon required
* }
* </pre>
*
* @since 8.22
*/
@StatelessCheck
public final class UnnecessarySemicolonInEnumerationCheck extends AbstractCheck {

/**
* A key is pointing to the warning message text in "messages.properties"
* file.
*/
public static final String MSG_SEMI = "unnecessary.semicolon";

@Override
public int[] getDefaultTokens() {
return getRequiredTokens();
}

@Override
public int[] getAcceptableTokens() {
return getRequiredTokens();
}

@Override
public int[] getRequiredTokens() {
return new int[] {
TokenTypes.ENUM_DEF,
};
}

@Override
public void visitToken(DetailAST ast) {
final DetailAST enumBlock = ast.findFirstToken(TokenTypes.OBJBLOCK);
final DetailAST semicolon = enumBlock.findFirstToken(TokenTypes.SEMI);
if (semicolon != null && isEndOfEnumerationAfter(semicolon)) {
log(semicolon, MSG_SEMI);
}
}

/**
* Checks if enum body has no code elements after enum constants semicolon.
* @param ast semicolon in enum constants definition end
* @return true if there is no code elements, false otherwise.
*/
private static boolean isEndOfEnumerationAfter(DetailAST ast) {
return ast.getNextSibling().getType() == TokenTypes.RCURLY;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ unnecessary.paren.lambda=Unnecessary parentheses around lambda value.
unnecessary.paren.literal=Unnecessary parentheses around literal ''{0}''.
unnecessary.paren.return=Unnecessary parentheses around return value.
unnecessary.paren.string=Unnecessary parentheses around string {0}.
unnecessary.semicolon=Unnecessary semicolon.
variable.declaration.usage.distance=Distance between variable ''{0}'' declaration and its first usage is {1}, but allowed {2}.
variable.declaration.usage.distance.extend=Distance between variable ''{0}'' declaration and its first usage is {1}, but allowed {2}. Consider making that variable final if you still need to store its value in advance (before method calls that might have side effects on the original value).
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ unnecessary.paren.lambda=Überflüssige Klammern um Lambdawert.
unnecessary.paren.literal=Überflüssige Klammern um das Literal ''{0}''.
unnecessary.paren.return=Überflüssige Klammern um den Rückgabewert.
unnecessary.paren.string=Überflüssige Klammern um den String ''{0}''.
unnecessary.semicolon=Unnötiges Semikolon.
variable.declaration.usage.distance=Der Abstand zwischen der Deklaration der Variablen ''{0}'' und ihrer ersten Verwendung beträgt {1} (Obergrenze ist {2}).
variable.declaration.usage.distance.extend=Der Abstand zwischen der Deklaration der Variable ''{0}'' und ihrer ersten Verwendung beträgt {1} (Obergrenze ist {2}). \
Erwägen Sie, diese Variable final zu machen, wenn Sie den Wert schon vorher speichern müssen (vor Methodenaufrufen mit Nebenwirkungen auf den ursprünglichen Wert).
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ unnecessary.paren.lambda=Paréntesis innecesarios alrededor del valor lambda.
unnecessary.paren.literal=Paréntesis innecesarios alrededor del literal ''{0}''.
unnecessary.paren.return=Paréntesis innecesarios alrededor del valor de retorno.
unnecessary.paren.string=Paréntesis innecesarios alrededor de la cadena {0}.
unnecessary.semicolon=Punto y coma innecesario.
variable.declaration.usage.distance=Distancia entre la variable ''{0}'' declaración y su primer uso es {1} pero permitió {2}
variable.declaration.usage.distance.extend=Distancia entre la variable ''{0}'' declaración y su primer uso es {1} pero permitió {2} Considere la posibilidad de hacer esa variable como final si usted todavía tiene que almacenar su valor con antelación (antes llamadas a métodos que puedan hacer efecto secundario en el valor original).
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ unnecessary.paren.ident=Tarpeettomia sulkuja noin tunniste ''{0}''.
unnecessary.paren.lambda=Tarpeettomat sulkeet lambda-arvon ympärillä.
unnecessary.paren.literal=Tarpeettomia sulkuja noin kirjaimellisesti ''{0}''.
unnecessary.paren.return=Tarpeettomia sulkuja noin paluuarvo.
unnecessary.paren.string=Tarpeettomia sulkuja noin merkkijono {0} .
unnecessary.paren.string=Tarpeettomia sulkuja noin merkkijono {0}.
unnecessary.semicolon=Tarpeeton puolipiste.
variable.declaration.usage.distance=Etäisyys muuttuja ''{0}'' ilmoituksen ja sen ensimmäinen käyttö on {1} , mutta sallittu {2} .
variable.declaration.usage.distance.extend=Etäisyys muuttuja ''{0}'' ilmoituksen ja sen ensimmäinen käyttö on {1} , mutta sallittu {2} . Harkitse tehdä, että muuttujan lopullinen jos tarvitset silti säilyttää sen arvo etukäteen (ennen metodikutsuja että voisi tehdä sivuvaikutus alkuperäinen arvo).
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ unnecessary.paren.lambda=Parenthèses inutiles autour de la valeur lambda.
unnecessary.paren.literal=Parenthèses inutiles autour de la chaîne littérale ''{0}''.
unnecessary.paren.return=Parenthèses inutiles autour de la valeur de retour.
unnecessary.paren.string=Parenthèses inutiles autour de la chaîne {0}.
unnecessary.semicolon=Point-virgule inutile.
variable.declaration.usage.distance=La distance entre la déclaration de la variable ''{0}'' et sa première utilisation est de {1}, alors que le maximum autorisé est de {2}.
variable.declaration.usage.distance.extend=La distance entre la déclaration de la variable ''{0}'' et sa première utilisation est de {1}, alors que le maximum autorisé est de {2}. Envisagez de rendre cette variable finale si vous avez encore besoin de stocker sa valeur à l''avance (avant les appels de méthode qui pourrait avoir des effets secondaires sur la valeur d''origine).
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ unnecessary.paren.lambda=ラムダ値の周りの不必要なカッコ。
unnecessary.paren.literal=リテラル ''{0}'' の前後に不要な括弧があります。
unnecessary.paren.return=戻り値の前後に不要な括弧があります。
unnecessary.paren.string=文字列 {0} の前後に不要な括弧があります。
unnecessary.semicolon=不要なセミコロン。
variable.declaration.usage.distance=変数 ''{0}'' の宣言と、その変数の使用開始位置までの距離が {1} です。許可された距離 は {2} です。
variable.declaration.usage.distance.extend=変数 ''{0}'' の宣言と、その変数の使用開始位置までの距離が {1} です。許可された距離 は {2} です。 もし、事前(元の値への副作用をともなうメソッド呼び出しの前)に、その値を格納する必要があるのであれば、その変数をfinalとすることを検討してください。
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ unnecessary.paren.lambda=Parênteses desnecessários em torno do valor lambda.
unnecessary.paren.literal=Parênteses desnecessários em torno do literal ''{0}''.
unnecessary.paren.return=Parênteses desnecessários em torno do valor de retorno.
unnecessary.paren.string=Parênteses desnecessários em torno da cadeia {0}.
unnecessary.semicolon=Semicolon desnecessário.
variable.declaration.usage.distance=A distância entre a declaração da variável ''{0}'' e o seu primeiro uso é {1}. O máximo permitido é {2}.
variable.declaration.usage.distance.extend=A distância entre a declaração da variável ''{0}'' e o seu primeiro uso é {1}. O máximo permitido é {2}. Considere tornar essa variável final se você ainda precisa armazenar o seu valor com antecedência (antes que chamadas de métodos que possam causar efeitos colaterais sobre o seu valor original).
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,6 @@ unnecessary.paren.lambda=Lamba değeri etrafında gereksiz parantezler var.
unnecessary.paren.literal=''{0}'' etrafında gereksiz parantez mevcut.
unnecessary.paren.return=Geri dönüş değeri etrafında gereksiz parantez mevcut.
unnecessary.paren.string=''{0}'' etrafında gereksiz parantez mevcut.
unnecessary.semicolon=Gereksiz noktalı virgül.
variable.declaration.usage.distance=Değişken arasındaki mesafe ''{0}'' beyanı ve ilk kullanım olduğu {1} ancak izin verilen {2}
variable.declaration.usage.distance.extend=Değişken arasındaki mesafe ''{0}'' beyanı ve ilk kullanım olduğu {1} ancak izin verilen {2} Hala (Orijinal değerine yan etkisi yapabilir yöntem çağrıları öncesi) peşin değerini saklamak gerekiyorsa son olarak bu değişken yapmak düşünün.
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ unnecessary.paren.lambda=lambda 值周围不必要的小括号。
unnecessary.paren.literal=字符串 ''{0}'' 周围不必要的小括号。
unnecessary.paren.return=return 值周围不必要的小括号。
unnecessary.paren.string=字符串 {0} 周围不必要的小括号。
unnecessary.semicolon=不必要的分号。
variable.declaration.usage.distance=变量''{0}''声明及第一次使用距离{1}行(最多:{2} 行)。
variable.declaration.usage.distance.extend=变量''{0}''声明及第一次使用距离{1}行(最多:{2} 行)。若需要存储该变量的值,请将其声明为final的(方法调用前声明以避免副作用影响原值)。
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2019 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.coding;

import static com.puppycrawl.tools.checkstyle.checks.coding.UnnecessarySemicolonInEnumerationCheck.MSG_SEMI;

import org.junit.Assert;
import org.junit.Test;

import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;

/**
* Test fixture for the UnnecessarySemicolonInEnumerationCheck.
*
*/
public class UnnecessarySemicolonInEnumerationCheckTest extends AbstractModuleTestSupport {

@Override
protected String getPackageLocation() {
return "com/puppycrawl/tools/checkstyle/checks/coding/"
+ "unnecessarysemicoloninenumeration";
}

@Test
public void testDefault() throws Exception {
final DefaultConfiguration checkConfig =
createModuleConfig(UnnecessarySemicolonInEnumerationCheck.class);

final String[] expected = {
"24:12: " + getCheckMessage(MSG_SEMI),
"27:13: " + getCheckMessage(MSG_SEMI),
"30:14: " + getCheckMessage(MSG_SEMI),
"33:14: " + getCheckMessage(MSG_SEMI),
"36:54: " + getCheckMessage(MSG_SEMI),
"39:15: " + getCheckMessage(MSG_SEMI),
"42:56: " + getCheckMessage(MSG_SEMI),
"46:9: " + getCheckMessage(MSG_SEMI),
"51:33: " + getCheckMessage(MSG_SEMI),
"55:9: " + getCheckMessage(MSG_SEMI),
};

verify(checkConfig, getPath("InputUnnecessarySemicolonInEnumeration.java"), expected);
}

@Test
public void testTokensNotNull() {
final UnnecessarySemicolonInEnumerationCheck check =
new UnnecessarySemicolonInEnumerationCheck();
final int[] expected = {
TokenTypes.ENUM_DEF,
};
Assert.assertArrayEquals("Acceptable required tokens are invalid",
expected, check.getAcceptableTokens());
Assert.assertArrayEquals("Default required tokens are invalid",
expected, check.getDefaultTokens());
Assert.assertArrayEquals("Required required tokens are invalid",
expected, check.getRequiredTokens());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package com.puppycrawl.tools.checkstyle.checks.coding.unnecessarysemicoloninenumeration;

public class InputUnnecessarySemicolonInEnumeration{

enum Nothing {
A,B
}
enum Comma {
A,B,
}
enum Paren {
A,B()
}
enum Block {
A,B{}
}
enum ParenAndBlock {
A,B(){ public String toString() { return "";}}
}
enum ParenAndBlockAndComma {
A,B(){ public String toString() { return "";}},
}
enum Semicolon {
A,B; // violation
}
enum CommaAndSemicolon {
A,B,; // violation
}
enum BlockAndSemicolon {
A,B{}; // violation
}
enum ParensAndSemicolon {
A,B(); // violation
}
enum BlockAndCommaAndSemicolon {
A,B{ public String toString() { return "";}},; // violation
}
enum ParensAndCommaAndSemicolon {
A,B(),; // violation
}
enum All {
A,B(){ public String toString() { return "";}},; // violation
}
enum SemicolonNextLine {
A,B
; // violation
}
enum NestedEnum {
A, B, C;
enum Nested {
First, Second, Third; // violation
}
}
enum NoEnums {
; // violation
}
enum NoEnums2 {
;
{}
}
enum EmptyEnum {
}
enum Normal {
A,B;
void m(){}
}
enum CommaNormal {
A,B,;
{}
}
enum ParenNormal {
A,B();
static {}
}
enum SemiNextLine {
A,
B
;
SemiNextLine(){}
}
enum BlockNormal {
A,B{ public String toString() { return "";}};
BlockNormal(){}
}
enum ParenAndBlockNormal {
A,B(){ public String toString() { return "";}};
int a = 10;
}
enum ParenAndBlockAndCommaNormal {
A,B(){ public String toString() { return "";}},;
interface a {}
}
}
4 changes: 4 additions & 0 deletions src/xdocs/checks.xml
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,10 @@
<td>
Checks if unnecessary parentheses are used in a statement or expression.</td>
</tr>
<tr>
<td><a href="config_coding.html#UnnecessarySemicolonInEnumeration">UnnecessarySemicolonInEnumeration</a></td>
<td>Checks if unnecessary semicolon is in enum definitions.</td>
</tr>
<tr>
<td><a href="config_imports.html#UnusedImports">UnusedImports</a></td>
<td>
Expand Down
Loading

0 comments on commit 1ece92f

Please sign in to comment.