diff --git a/config/checkstyle-checks.xml b/config/checkstyle-checks.xml index 8c6fceefe4a..9662427f36d 100644 --- a/config/checkstyle-checks.xml +++ b/config/checkstyle-checks.xml @@ -539,6 +539,7 @@ + diff --git a/config/checkstyle-non-main-files-suppressions.xml b/config/checkstyle-non-main-files-suppressions.xml index 619da4641e0..9e1d51740fb 100644 --- a/config/checkstyle-non-main-files-suppressions.xml +++ b/config/checkstyle-non-main-files-suppressions.xml @@ -234,6 +234,8 @@ files="src[\\/]xdocs[\\/]checks[\\/]coding[\\/]nofinalizer.xml.template"/> + #%3Cinit%3E(): doesn't exist. #%3Cinit%3E(): doesn't exist. #%3Cinit%3E(): doesn't exist. +#%3Cinit%3E(): doesn't exist. #%3Cinit%3E(): doesn't exist. #%3Cinit%3E(): doesn't exist. #%3Cinit%3E(): doesn't exist. @@ -949,6 +950,7 @@ com/puppycrawl/tools/checkstyle/checks/coding/AvoidDoubleBraceInitializationCheck.html#%3Cinit%3E(): doesn't exist. com/puppycrawl/tools/checkstyle/checks/coding/AvoidInlineConditionalsCheck.html#%3Cinit%3E(): doesn't exist. com/puppycrawl/tools/checkstyle/checks/coding/AvoidNoArgumentSuperConstructorCallCheck.html#%3Cinit%3E(): doesn't exist. +com/puppycrawl/tools/checkstyle/checks/coding/ConstructorsDeclarationGroupingCheck.html#%3Cinit%3E(): doesn't exist. com/puppycrawl/tools/checkstyle/checks/coding/CovariantEqualsCheck.html#%3Cinit%3E(): doesn't exist. com/puppycrawl/tools/checkstyle/checks/coding/DeclarationOrderCheck.ScopeState.html#%3Cinit%3E(): doesn't exist. com/puppycrawl/tools/checkstyle/checks/coding/DeclarationOrderCheck.html#%3Cinit%3E(): doesn't exist. diff --git a/pom.xml b/pom.xml index 705521d8690..c2c7c066686 100644 --- a/pom.xml +++ b/pom.xml @@ -3264,6 +3264,7 @@ com.puppycrawl.tools.checkstyle.checks.coding.AvoidDoubleBraceInitializationCheck* com.puppycrawl.tools.checkstyle.checks.coding.AvoidInlineConditionalsCheck* com.puppycrawl.tools.checkstyle.checks.coding.AvoidNoArgumentSuperConstructorCallCheck* + com.puppycrawl.tools.checkstyle.checks.coding.ConstructorsDeclarationGroupingCheck* com.puppycrawl.tools.checkstyle.checks.coding.CovariantEqualsCheck* com.puppycrawl.tools.checkstyle.checks.coding.DeclarationOrderCheck* com.puppycrawl.tools.checkstyle.checks.coding.DefaultComesLastCheck* @@ -3288,6 +3289,7 @@ com.puppycrawl.tools.checkstyle.checks.coding.AvoidDoubleBraceInitializationCheckTest com.puppycrawl.tools.checkstyle.checks.coding.AvoidInlineConditionalsCheckTest com.puppycrawl.tools.checkstyle.checks.coding.AvoidNoArgumentSuperConstructorCallCheckTest + com.puppycrawl.tools.checkstyle.checks.coding.ConstructorsDeclarationGroupingCheckTest com.puppycrawl.tools.checkstyle.checks.coding.CovariantEqualsCheckTest com.puppycrawl.tools.checkstyle.checks.coding.DeclarationOrderCheckTest com.puppycrawl.tools.checkstyle.checks.coding.DefaultComesLastCheckTest diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionConstructorsDeclarationGroupingTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionConstructorsDeclarationGroupingTest.java new file mode 100644 index 00000000000..ae7dbcbd405 --- /dev/null +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionConstructorsDeclarationGroupingTest.java @@ -0,0 +1,105 @@ +/////////////////////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code and other text files for adherence to a set of rules. +// Copyright (C) 2001-2024 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 org.checkstyle.suppressionxpathfilter; + +import java.io.File; +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import com.puppycrawl.tools.checkstyle.DefaultConfiguration; +import com.puppycrawl.tools.checkstyle.checks.coding.ConstructorsDeclarationGroupingCheck; + +public class XpathRegressionConstructorsDeclarationGroupingTest extends AbstractXpathTestSupport { + + private final Class clazz = + ConstructorsDeclarationGroupingCheck.class; + + @Override + protected String getCheckName() { + return clazz.getSimpleName(); + } + + @Test + public void testOne() throws Exception { + final File fileToProcess = new File( + getPath("InputXpathConstructorsDeclarationGroupingOne.java")); + + final DefaultConfiguration moduleConfig = createModuleConfig(clazz); + + final String[] expectedViolation = { + "10:5: " + getCheckMessage(clazz, + ConstructorsDeclarationGroupingCheck.MSG_KEY, 6), + }; + + final List expectedXpathQueries = Arrays.asList( + "/COMPILATION_UNIT/CLASS_DEF[./IDENT" + + "[@text='InputXpathConstructorsDeclarationGroupingOne']]" + + "/OBJBLOCK/CTOR_DEF[./IDENT" + + "[@text='InputXpathConstructorsDeclarationGroupingOne']]", + "/COMPILATION_UNIT/CLASS_DEF[./IDENT" + + "[@text='InputXpathConstructorsDeclarationGroupingOne']]" + + "/OBJBLOCK/CTOR_DEF[./IDENT" + + "[@text='InputXpathConstructorsDeclarationGroupingOne']]" + + "/MODIFIERS", + "/COMPILATION_UNIT/CLASS_DEF[./IDENT" + + "[@text='InputXpathConstructorsDeclarationGroupingOne']]" + + "/OBJBLOCK/CTOR_DEF/IDENT" + + "[@text='InputXpathConstructorsDeclarationGroupingOne']" + + ); + + runVerifications(moduleConfig, fileToProcess, expectedViolation, expectedXpathQueries); + } + + @Test + public void testTwo() throws Exception { + final File fileToProcess = new File( + getPath("InputXpathConstructorsDeclarationGroupingTwo.java")); + + final DefaultConfiguration moduleConfig = createModuleConfig(clazz); + + final String[] expectedViolation = { + "12:5: " + getCheckMessage(clazz, + ConstructorsDeclarationGroupingCheck.MSG_KEY, 8), + }; + + final List expectedXpathQueries = Arrays.asList( + "/COMPILATION_UNIT/ENUM_DEF[./IDENT" + + "[@text='InputXpathConstructorsDeclarationGroupingTwo']]" + + "/OBJBLOCK/CTOR_DEF" + + "[./IDENT[@text='InputXpathConstructorsDeclarationGroupingTwo']]", + + "/COMPILATION_UNIT/ENUM_DEF[./IDENT" + + "[@text='InputXpathConstructorsDeclarationGroupingTwo']]" + + "/OBJBLOCK/CTOR_DEF" + + "[./IDENT[@text='InputXpathConstructorsDeclarationGroupingTwo']]" + + "/MODIFIERS", + + "/COMPILATION_UNIT/ENUM_DEF[./IDENT" + + "[@text='InputXpathConstructorsDeclarationGroupingTwo']]" + + "/OBJBLOCK/CTOR_DEF/IDENT" + + "[@text='InputXpathConstructorsDeclarationGroupingTwo']" + ); + + runVerifications(moduleConfig, fileToProcess, expectedViolation, expectedXpathQueries); + } +} diff --git a/src/it/resources/org/checkstyle/suppressionxpathfilter/constructorsdeclarationgrouping/InputXpathConstructorsDeclarationGroupingOne.java b/src/it/resources/org/checkstyle/suppressionxpathfilter/constructorsdeclarationgrouping/InputXpathConstructorsDeclarationGroupingOne.java new file mode 100644 index 00000000000..df61195b996 --- /dev/null +++ b/src/it/resources/org/checkstyle/suppressionxpathfilter/constructorsdeclarationgrouping/InputXpathConstructorsDeclarationGroupingOne.java @@ -0,0 +1,11 @@ +package org.checkstyle.suppressionxpathfilter.constructorsdeclarationgrouping; + +public class InputXpathConstructorsDeclarationGroupingOne { + InputXpathConstructorsDeclarationGroupingOne() {} + + InputXpathConstructorsDeclarationGroupingOne(int a) {} + + int x; + + InputXpathConstructorsDeclarationGroupingOne(String str) {} // warn +} diff --git a/src/it/resources/org/checkstyle/suppressionxpathfilter/constructorsdeclarationgrouping/InputXpathConstructorsDeclarationGroupingTwo.java b/src/it/resources/org/checkstyle/suppressionxpathfilter/constructorsdeclarationgrouping/InputXpathConstructorsDeclarationGroupingTwo.java new file mode 100644 index 00000000000..99e2f642030 --- /dev/null +++ b/src/it/resources/org/checkstyle/suppressionxpathfilter/constructorsdeclarationgrouping/InputXpathConstructorsDeclarationGroupingTwo.java @@ -0,0 +1,13 @@ +package org.checkstyle.suppressionxpathfilter.constructorsdeclarationgrouping; + +public enum InputXpathConstructorsDeclarationGroupingTwo { + ONE; + + InputXpathConstructorsDeclarationGroupingTwo() {} + + InputXpathConstructorsDeclarationGroupingTwo(String str) {} + + int f; + + InputXpathConstructorsDeclarationGroupingTwo(int x) {} // warn +} diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/PackageObjectFactory.java b/src/main/java/com/puppycrawl/tools/checkstyle/PackageObjectFactory.java index f859c5ed2f6..1fe47ca5b53 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/PackageObjectFactory.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/PackageObjectFactory.java @@ -557,6 +557,8 @@ private static void fillChecksFromCodingPackage() { BASE_PACKAGE + ".checks.coding.OneStatementPerLineCheck"); NAME_TO_FULL_MODULE_NAME.put("OverloadMethodsDeclarationOrderCheck", BASE_PACKAGE + ".checks.coding.OverloadMethodsDeclarationOrderCheck"); + NAME_TO_FULL_MODULE_NAME.put("ConstructorsDeclarationGroupingCheck", + BASE_PACKAGE + ".checks.coding.ConstructorsDeclarationGroupingCheck"); NAME_TO_FULL_MODULE_NAME.put("PackageDeclarationCheck", BASE_PACKAGE + ".checks.coding.PackageDeclarationCheck"); NAME_TO_FULL_MODULE_NAME.put("ParameterAssignmentCheck", diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/ConstructorsDeclarationGroupingCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/ConstructorsDeclarationGroupingCheck.java new file mode 100644 index 00000000000..6afcdc8d9c6 --- /dev/null +++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/ConstructorsDeclarationGroupingCheck.java @@ -0,0 +1,109 @@ +/////////////////////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code and other text files for adherence to a set of rules. +// Copyright (C) 2001-2024 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 java.util.HashMap; +import java.util.Map; + +import com.puppycrawl.tools.checkstyle.FileStatefulCheck; +import com.puppycrawl.tools.checkstyle.api.AbstractCheck; +import com.puppycrawl.tools.checkstyle.api.DetailAST; +import com.puppycrawl.tools.checkstyle.api.TokenTypes; + +/** + *

+ * Checks that all constructors are grouped together. + * If there is anything between overloaded constructors ( expect comments ) + * then this check will give an error. + *

+ *

+ * Parent is {@code com.puppycrawl.tools.checkstyle.TreeWalker} + *

+ *

+ * Violation Message Keys: + *

+ *
    + *
  • + * {@code constructors.declaration.grouping} + *
  • + *
+ * + * @since 10.16.0 + */ + +@FileStatefulCheck +public class ConstructorsDeclarationGroupingCheck extends AbstractCheck { + + /** + * A key is pointing to the warning message text in "messages.properties" + * file. + */ + public static final String MSG_KEY = "constructors.declaration.grouping"; + + /** + * Specifies different Object Blocks scope. + */ + private final Map allObjBlocks = new HashMap<>(); + + @Override + public int[] getDefaultTokens() { + return getRequiredTokens(); + } + + @Override + public int[] getAcceptableTokens() { + return getRequiredTokens(); + } + + @Override + public int[] getRequiredTokens() { + return new int[] { + TokenTypes.CTOR_DEF, + TokenTypes.COMPACT_CTOR_DEF, + }; + } + + @Override + public void beginTree(DetailAST rootAst) { + allObjBlocks.clear(); + } + + @Override + public void visitToken(DetailAST ast) { + final DetailAST currObjBlock = ast.getParent(); + final Integer previousCtorLineNo = allObjBlocks.get(currObjBlock); + + if (previousCtorLineNo != null) { + final DetailAST previousSibling = ast.getPreviousSibling(); + final int siblingType = previousSibling.getType(); + final boolean isCtor = siblingType == TokenTypes.CTOR_DEF; + final boolean isCompactCtor = siblingType == TokenTypes.COMPACT_CTOR_DEF; + + if (!isCtor && !isCompactCtor) { + log(ast, MSG_KEY, previousCtorLineNo); + } + + allObjBlocks.put(currObjBlock, ast.getLineNo()); + } + else { + allObjBlocks.put(currObjBlock, ast.getLineNo()); + } + } +} diff --git a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages.properties b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages.properties index 31019fcee70..deaf6b64512 100644 --- a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages.properties +++ b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages.properties @@ -3,6 +3,7 @@ assignment.inner.avoid=Inner assignments should be avoided. avoid.clone.method=Avoid using clone method. avoid.double.brace.init=Avoid double brace initialization. avoid.finalizer.method=Avoid using finalizer method. +constructors.declaration.grouping=All overloaded constructors should be grouped together. Previous constructor was at line number ''{0}''. covariant.equals=covariant equals without overriding equals(java.lang.Object). declaration.order.access=Variable access definition in wrong order. declaration.order.constructor=Constructor definition in wrong order. diff --git a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_de.properties b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_de.properties index 2d4f885d8e0..d049f5e5994 100644 --- a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_de.properties +++ b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_de.properties @@ -3,6 +3,7 @@ assignment.inner.avoid=Innere Zuweisungen sollten vermieden werden. avoid.clone.method=Die Methode clone() sollte vermieden werden. avoid.double.brace.init=Vermeiden Sie doppelte geschweifte Klammern. avoid.finalizer.method=Die Methode finalize() sollte vermieden werden. +constructors.declaration.grouping=Alle überladenen Konstruktoren sollten gruppiert werden. Der vorherige Konstruktor befand sich in der Zeilennummer „{0}“. covariant.equals=Kovariante Definition von equals(), ohne equals(java.lang.Object) zu überschreiben. declaration.order.access=Fehlerhafte Deklarationsreihenfolge für diesen Scope. declaration.order.constructor=Der Konstruktor steht an der falschen Stelle. diff --git a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_es.properties b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_es.properties index c9bcff58460..92e8c74ffa9 100644 --- a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_es.properties +++ b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_es.properties @@ -3,6 +3,7 @@ assignment.inner.avoid=Deben evitarse las asignaciones internas. avoid.clone.method=Evite el uso de método clone. avoid.double.brace.init=Evite la inicialización de llaves dobles. avoid.finalizer.method=Evite el uso de método de finalizador. +constructors.declaration.grouping=Todos los constructores sobrecargados deben agruparse. El constructor anterior estaba en la línea número ''{0}''. covariant.equals=equals covariante sin sobrescribir equals(java.lang.Object). declaration.order.access=Definición de acceso a variable en orden incorrecto. declaration.order.constructor=Definición de constructor en orden incorrecto. diff --git a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_fi.properties b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_fi.properties index 8011d41b235..b34b429ce7f 100644 --- a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_fi.properties +++ b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_fi.properties @@ -3,6 +3,7 @@ assignment.inner.avoid=Älä käytä sisäkkäisiä sijoituksia. avoid.clone.method=Vältä klooni menetelmää. avoid.double.brace.init=Vältä kaksinkertaista ahdintuen alustamista. avoid.finalizer.method=Vältä Finalizer menetelmää. +constructors.declaration.grouping=Kaikki ylikuormitetut rakentajat tulee ryhmitellä yhteen. Edellinen rakentaja oli rivillä ''{0}''. covariant.equals=covariant vastaa ilman painavaa tasavertaisten (java.lang.Object). declaration.order.access=Muuttuja pääsy määritelmä väärässä järjestyksessä. declaration.order.constructor=Rakentaja määritelmä väärässä järjestyksessä. diff --git a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_fr.properties b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_fr.properties index 30ea96c8b53..4831085be29 100644 --- a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_fr.properties +++ b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_fr.properties @@ -3,6 +3,7 @@ assignment.inner.avoid=Évitez d''affecter une valeur à une variable au sein d' avoid.clone.method=Évitez d''utiliser la méthode de clonage. avoid.double.brace.init=Évitez l''initialisation à double accolade. avoid.finalizer.method=Évitez d''utiliser la méthode de finalisation. +constructors.declaration.grouping=Tous les constructeurs surchargés doivent être regroupés. Le constructeur précédent se trouvait au numéro de ligne « {0} ». covariant.equals=Votre méthode equals compare uniquement les objets de votre classe. N''oubliez pas de surcharger la méthode equals(java.lang.Object). declaration.order.access=La définition des variables n''est pas triée suivant leur portée. declaration.order.constructor=La définition des constructeurs n''apparaît pas dans le bon ordre. diff --git a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_ja.properties b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_ja.properties index 9e9254045e6..9fc746de2f6 100644 --- a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_ja.properties +++ b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_ja.properties @@ -3,6 +3,7 @@ assignment.inner.avoid=式内部での代入は避けるべきです。 avoid.clone.method=cloneメソッドを使用しないでください。 avoid.double.brace.init=二重中括弧を使った初期化は使用しないでください。 avoid.finalizer.method=ファイナライザメソッドを使用しないでください。 +constructors.declaration.grouping=オーバーロードされたコンストラクターはすべてグループ化する必要があります。前のコンストラクターは行番号 ''{0}'' にありました。 covariant.equals=equals(java.lang.Object) をオーバーライドせずに共変 な equals を定義しています。 declaration.order.access=変数アクセスの定義順序が間違っています。 declaration.order.constructor=コンストラクタの定義順序が間違っています。 diff --git a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_pt.properties b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_pt.properties index 6f8b2df64ce..a381c48b350 100644 --- a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_pt.properties +++ b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_pt.properties @@ -3,6 +3,7 @@ assignment.inner.avoid=Atribuições aninhadas devem ser evitadas. avoid.clone.method=Evite o uso do método ''clone()''. avoid.double.brace.init=Evite a inicialização entre chaves. avoid.finalizer.method=Evite o uso do método ''finalize()''. +constructors.declaration.grouping=Todos os construtores sobrecarregados devem ser agrupados. O construtor anterior estava no número de linha ''{0}''. covariant.equals="equals" covariante sem sobrescrever ''equals(java.lang.Object)''. declaration.order.access=Definição de acesso a variável em ordem errada. declaration.order.constructor=Definição de construtor em ordem errada. diff --git a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_ru.properties b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_ru.properties index dd9c2e64217..9d729c37720 100644 --- a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_ru.properties +++ b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_ru.properties @@ -3,6 +3,7 @@ assignment.inner.avoid=Внутренние присвоения следует avoid.clone.method=Избегайте использования метода clone(). avoid.double.brace.init=Избегайте инициализации в двойных скобках. avoid.finalizer.method=Избегайте использования метода finalize(). +constructors.declaration.grouping=Все перегруженные конструкторы должны быть сгруппированы вместе. Предыдущий конструктор находился на строке с номером ''{0}''. covariant.equals=Ковариантный equals() без переопределения equals(java.lang.Object). declaration.order.access=Объявляйте переменные в порядке расширения доступа. declaration.order.constructor=Определение конструктора в неправильном порядке. diff --git a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_tr.properties b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_tr.properties index c522116dbd8..8ef9edf0b32 100644 --- a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_tr.properties +++ b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_tr.properties @@ -3,6 +3,7 @@ assignment.inner.avoid=Dahili atamalar kullanılmamalıdır. avoid.clone.method=''clone'' metodu kullanılmamalıdır. avoid.double.brace.init=Çift ayraç başlatmadan kaçının. avoid.finalizer.method=''finalize'' metodu kullanılmamalıdır. +constructors.declaration.grouping=Aşırı yüklenmiş tüm kurucular birlikte gruplandırılmalıdır. Önceki kurucu ''{0}'' satır numarasındaydı. covariant.equals=java.lang.Object sınıfının ''equals'' metodundan başka bir ''equals'' metodu tanımlanmış, java.lang.Object sınıfından gelen ''equals'' metodu da ezilmelidir (override). declaration.order.access=Değişken, erişim seviyesine göre yanlış sırada tanımlanmış. declaration.order.constructor=''constructor'' tanımı yanlış sırada yapılmış. diff --git a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_zh.properties b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_zh.properties index 2a80006f644..d3db4a94cd9 100644 --- a/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_zh.properties +++ b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_zh.properties @@ -3,6 +3,7 @@ assignment.inner.avoid=应避免在子表达式中赋值。 avoid.clone.method=避免重写 clone 方法。 avoid.double.brace.init=避免双括号初始化。 avoid.finalizer.method=避免重写finalize方法。 +constructors.declaration.grouping=所有重载的构造函数应该组合在一起。上一个构造函数位于行号“{0}”。 covariant.equals=重写''equals()''方法时,必须确保重写了''equals(java.lang.Object)''方法。 declaration.order.access=属性访问器定义顺序错误。 declaration.order.constructor=构造器定义顺序错误。 diff --git a/src/main/resources/com/puppycrawl/tools/checkstyle/meta/checks/coding/ConstructorsDeclarationGroupingCheck.xml b/src/main/resources/com/puppycrawl/tools/checkstyle/meta/checks/coding/ConstructorsDeclarationGroupingCheck.xml new file mode 100644 index 00000000000..a1b5240403c --- /dev/null +++ b/src/main/resources/com/puppycrawl/tools/checkstyle/meta/checks/coding/ConstructorsDeclarationGroupingCheck.xml @@ -0,0 +1,17 @@ + + + + + <p> + Checks that all constructors are grouped together. + If there is anything between overloaded constructors ( expect comments ) + then this check will give an error. + </p> + + + + + + diff --git a/src/site/site.xml b/src/site/site.xml index 5181f54f6b6..c9346167131 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -149,6 +149,8 @@ + diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/coding/ConstructorsDeclarationGroupingCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/coding/ConstructorsDeclarationGroupingCheckTest.java new file mode 100644 index 00000000000..058a74c1c50 --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/coding/ConstructorsDeclarationGroupingCheckTest.java @@ -0,0 +1,81 @@ +/////////////////////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code and other text files for adherence to a set of rules. +// Copyright (C) 2001-2024 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.google.common.truth.Truth.assertWithMessage; +import static com.puppycrawl.tools.checkstyle.checks.coding.ConstructorsDeclarationGroupingCheck.MSG_KEY; + +import org.junit.jupiter.api.Test; + +import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport; +import com.puppycrawl.tools.checkstyle.api.TokenTypes; + +public class ConstructorsDeclarationGroupingCheckTest extends AbstractModuleTestSupport { + @Override + protected String getPackageLocation() { + return "com/puppycrawl/tools/checkstyle/checks/coding/constructorsdeclarationgrouping"; + } + + @Test + public void testDefault() throws Exception { + final String[] expected = { + "23:5: " + getCheckMessage(MSG_KEY, 19), + "27:5: " + getCheckMessage(MSG_KEY, 23), + "40:9: " + getCheckMessage(MSG_KEY, 36), + "49:13: " + getCheckMessage(MSG_KEY, 43), + "52:9: " + getCheckMessage(MSG_KEY, 40), + "55:5: " + getCheckMessage(MSG_KEY, 27), + }; + verifyWithInlineConfigParser( + getPath("InputConstructorsDeclarationGrouping.java"), expected); + } + + @Test + public void testConstructorsDeclarationGroupingRecords() throws Exception { + + final String[] expected = { + "18:9: " + getCheckMessage(MSG_KEY, 12), + "34:9: " + getCheckMessage(MSG_KEY, 30), + }; + + verifyWithInlineConfigParser( + getNonCompilablePath("InputConstructorsDeclarationGroupingRecords.java"), + expected); + } + + @Test + public void testTokensNotNull() { + final ConstructorsDeclarationGroupingCheck check = + new ConstructorsDeclarationGroupingCheck(); + assertWithMessage("Acceptable tokens should be CTOR_DEF and COMPACT_CTOR_DEF") + .that(check.getAcceptableTokens()) + .isEqualTo(new int[] {TokenTypes.CTOR_DEF, TokenTypes.COMPACT_CTOR_DEF}); + assertWithMessage("Acceptable tokens should not be null") + .that(check.getAcceptableTokens()) + .isNotNull(); + assertWithMessage("Default tokens should not be null") + .that(check.getDefaultTokens()) + .isNotNull(); + assertWithMessage("Required tokens should not be null") + .that(check.getRequiredTokens()) + .isNotNull(); + } + +} diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/meta/XmlMetaReaderTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/meta/XmlMetaReaderTest.java index 867cb7f2991..f117d9c4d93 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/meta/XmlMetaReaderTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/meta/XmlMetaReaderTest.java @@ -40,20 +40,20 @@ protected String getPackageLocation() { @Test public void test() { - assertThat(XmlMetaReader.readAllModulesIncludingThirdPartyIfAny()).hasSize(200); + assertThat(XmlMetaReader.readAllModulesIncludingThirdPartyIfAny()).hasSize(201); } @Test public void testDuplicatePackage() { assertThat(XmlMetaReader .readAllModulesIncludingThirdPartyIfAny("com.puppycrawl.tools.checkstyle.meta")) - .hasSize(200); + .hasSize(201); } @Test public void testBadPackage() { assertThat(XmlMetaReader.readAllModulesIncludingThirdPartyIfAny("DOES.NOT.EXIST")) - .hasSize(200); + .hasSize(201); } @Test diff --git a/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/checks/coding/constructorsdeclarationgrouping/InputConstructorsDeclarationGroupingRecords.java b/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/checks/coding/constructorsdeclarationgrouping/InputConstructorsDeclarationGroupingRecords.java new file mode 100644 index 00000000000..eff55817be6 --- /dev/null +++ b/src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/checks/coding/constructorsdeclarationgrouping/InputConstructorsDeclarationGroupingRecords.java @@ -0,0 +1,36 @@ +/* +ConstructorsDeclarationGrouping + + +*/ + +//non-compiled with javac: Compilable with Java14 +package com.puppycrawl.tools.checkstyle.checks.coding.constructorsdeclarationgrouping; + +public class InputConstructorsDeclarationGroupingRecords { + public record MyRecord1(int x, int y) { + public MyRecord1(int a) { + this(a,a); + } + + void foo() {} + + public MyRecord1 {} // violation + + public MyRecord1(int x, int y, int z) { + this(x+y, z); + } + } + + class MyClass { + int x = 20; + + MyClass() {} + + MyClass(String s) {} + + String[] str; + + MyClass(int a) {} // violation + } +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/coding/constructorsdeclarationgrouping/InputConstructorsDeclarationGrouping.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/coding/constructorsdeclarationgrouping/InputConstructorsDeclarationGrouping.java new file mode 100644 index 00000000000..df8efb5ff72 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/coding/constructorsdeclarationgrouping/InputConstructorsDeclarationGrouping.java @@ -0,0 +1,66 @@ +/* +ConstructorsDeclarationGrouping + + +*/ + +package com.puppycrawl.tools.checkstyle.checks.coding.constructorsdeclarationgrouping; + +public class InputConstructorsDeclarationGrouping { + + int a; + + int b; + + void foo() {} + + InputConstructorsDeclarationGrouping() {} + + InputConstructorsDeclarationGrouping(String a) {} + + void foo2() {} + + InputConstructorsDeclarationGrouping(int a) {} // violation + + int abc; + + InputConstructorsDeclarationGrouping(double x) {} // violation + + private enum Testing { + + one; + + int x; + Testing() {} + + Testing(String f) {} + + String str; + + Testing(int x) {} // violation + + private abstract class Inner { + Inner() {} + + int x; + + String neko; + + Inner(String g) {} // violation + } + + Testing(double d) {} // violation + } + + InputConstructorsDeclarationGrouping(float x) {} // violation + + private class Inner { + Inner() {} + + Inner(String str) {} + + // Comments are allowed between overloaded constructors. + Inner(int x) {} + } + +} diff --git a/src/xdocs-examples/resources/com/puppycrawl/tools/checkstyle/checks/coding/constructorsdeclarationgrouping/Example1.java b/src/xdocs-examples/resources/com/puppycrawl/tools/checkstyle/checks/coding/constructorsdeclarationgrouping/Example1.java new file mode 100644 index 00000000000..0d141a6bcc5 --- /dev/null +++ b/src/xdocs-examples/resources/com/puppycrawl/tools/checkstyle/checks/coding/constructorsdeclarationgrouping/Example1.java @@ -0,0 +1,39 @@ +/*xml + + + + + +*/ + +package com.puppycrawl.tools.checkstyle.checks.coding.constructorsdeclarationgrouping; + +// xdoc section -- start +public class Example1 { + Example1() {} + + Example1(int a){} + + void foo2() {} + + Example1(String str) {} // violation + + Example1(double d) {} + + private enum ExampleEnum { + ONE, TWO, THREE; + + ExampleEnum() {} + + ExampleEnum(String str) {} + + final int x = 10; + + ExampleEnum(int age) {} // violation + + void foo() {} + } + + Example1(float f) {} // violation +} +// xdoc section -- end diff --git a/src/xdocs/checks.xml b/src/xdocs/checks.xml index 9dc8ce06ec2..a7546dd75cd 100644 --- a/src/xdocs/checks.xml +++ b/src/xdocs/checks.xml @@ -987,6 +987,14 @@ Checks that overloaded methods are grouped together. + + + + ConstructorsDeclarationGrouping + + + Checks that all constructors are grouped together. + diff --git a/src/xdocs/checks/coding/constructorsdeclarationgrouping.xml b/src/xdocs/checks/coding/constructorsdeclarationgrouping.xml new file mode 100644 index 00000000000..89a33299a91 --- /dev/null +++ b/src/xdocs/checks/coding/constructorsdeclarationgrouping.xml @@ -0,0 +1,97 @@ + + + + ConstructorsDeclarationGrouping + + +
+

Since Checkstyle 10.16.0

+ +

+ Checks that all constructors are grouped together. + If there is anything between overloaded constructors ( expect comments ) + then this check will give an error. +

+
+ + +

To configure the check:

+ +<module name="Checker"> + <module name="TreeWalker"> + <module name="ConstructorsDeclarationGrouping"/> + </module> +</module> + +

Example:

+ +public class Example1 { + Example1() {} + + Example1(int a){} + + void foo2() {} + + Example1(String str) {} // violation + + Example1(double d) {} + + private enum ExampleEnum { + ONE, TWO, THREE; + + ExampleEnum() {} + + ExampleEnum(String str) {} + + final int x = 10; + + ExampleEnum(int age) {} // violation + + void foo() {} + } + + Example1(float f) {} // violation +} + +
+ + +
+ + + + +

+ All messages can be customized if the default message doesn't suit you. + Please see the documentation + to learn how to. +

+
+ + +

+ com.puppycrawl.tools.checkstyle.checks.coding +

+
+ + +

+ TreeWalker +

+
+
+ + diff --git a/src/xdocs/checks/coding/constructorsdeclarationgrouping.xml.template b/src/xdocs/checks/coding/constructorsdeclarationgrouping.xml.template new file mode 100644 index 00000000000..87aa9bc06df --- /dev/null +++ b/src/xdocs/checks/coding/constructorsdeclarationgrouping.xml.template @@ -0,0 +1,67 @@ + + + + ConstructorsDeclarationGrouping + + +
+

Since Checkstyle 10.16.0

+ +

+ Checks that all constructors are grouped together. + If there is anything between overloaded constructors ( expect comments ) + then this check will give an error. +

+
+ + +

To configure the check:

+ + + + +

Example:

+ + + + +
+ + + + + + + + + +

+ All messages can be customized if the default message doesn't suit you. + Please see the documentation + to learn how to. +

+
+ + +

+ com.puppycrawl.tools.checkstyle.checks.coding +

+
+ + + + + + +
+ +
diff --git a/src/xdocs/checks/coding/index.xml b/src/xdocs/checks/coding/index.xml index 612dee1c918..8983ba88b35 100644 --- a/src/xdocs/checks/coding/index.xml +++ b/src/xdocs/checks/coding/index.xml @@ -395,6 +395,16 @@ Checks that overloaded methods are grouped together. + + + + ConstructorsDeclarationGrouping + + + + Checks that all constructors are grouped together. + +