diff --git a/config/checker-framework-suppressions/checker-lock-tainting-suppressions.xml b/config/checker-framework-suppressions/checker-lock-tainting-suppressions.xml index 733391909f8..c4858c99a50 100644 --- a/config/checker-framework-suppressions/checker-lock-tainting-suppressions.xml +++ b/config/checker-framework-suppressions/checker-lock-tainting-suppressions.xml @@ -452,6 +452,36 @@ + + src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/ConstructorsDeclarationGroupingCheck.java + methodref.param + Incompatible parameter type for arg0 + .map(children::indexOf); +
+ found : @GuardSatisfied Object + required: @GuardedBy DetailAST + Consequence: method in @GuardedBy List<@GuardedBy DetailAST> + @GuardedBy int indexOf(@GuardSatisfied List<@GuardedBy DetailAST> this, @GuardSatisfied Object p0) + is not a valid method reference for method in @GuardedBy Function<@GuardedBy DetailAST, @GuardedBy Integer> + @GuardedBy Integer apply(@GuardedBy Function<@GuardedBy DetailAST, @GuardedBy Integer> this, @GuardedBy DetailAST p0) +
+
+ + + src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/ConstructorsDeclarationGroupingCheck.java + methodref.receiver.bound + Incompatible receiver type + .map(children::indexOf); +
+ found : @GuardedBy List<@GuardedBy DetailAST> + required: @GuardSatisfied List<@GuardedBy DetailAST> + Consequence: method + @GuardedBy List<@GuardedBy DetailAST> + is not a valid method reference for method in @GuardedBy List<@GuardedBy DetailAST> + @GuardedBy int indexOf(@GuardSatisfied List<@GuardedBy DetailAST> this, @GuardSatisfied Object p0) +
+
+ src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/ModifiedControlVariableCheck.java methodref.param diff --git a/src/it/resources-noncompilable/org/checkstyle/suppressionxpathfilter/constructorsdeclarationgrouping/InputXpathConstructorsDeclarationGroupingRecords.java b/src/it/resources-noncompilable/org/checkstyle/suppressionxpathfilter/constructorsdeclarationgrouping/InputXpathConstructorsDeclarationGroupingRecords.java index 818f7d880d0..bf12fe5fd82 100644 --- a/src/it/resources-noncompilable/org/checkstyle/suppressionxpathfilter/constructorsdeclarationgrouping/InputXpathConstructorsDeclarationGroupingRecords.java +++ b/src/it/resources-noncompilable/org/checkstyle/suppressionxpathfilter/constructorsdeclarationgrouping/InputXpathConstructorsDeclarationGroupingRecords.java @@ -12,9 +12,5 @@ public MyRecord(int a) { void foo() {} public MyRecord {} // warn - - public MyRecord(int x, int y, int z) { - this(x+y, z); - } } } 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 index 92cf5f007e4..d02cae33394 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/ConstructorsDeclarationGroupingCheck.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/coding/ConstructorsDeclarationGroupingCheck.java @@ -19,10 +19,12 @@ package com.puppycrawl.tools.checkstyle.checks.coding; -import java.util.HashMap; -import java.util.Map; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; -import com.puppycrawl.tools.checkstyle.FileStatefulCheck; +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; @@ -30,9 +32,10 @@ /** *

* Checks that all constructors are grouped together. - * If there is any code between the constructors - * then this check will give an error. - * Comments between constructors are ignored. + * If there is any non-constructor code separating constructors, + * this check identifies and logs a violation for those ungrouped constructors. + * The violation message will specify the line number of the last grouped constructor. + * Comments between constructors are allowed. *

*

* Parent is {@code com.puppycrawl.tools.checkstyle.TreeWalker} @@ -46,10 +49,10 @@ * * * - * @since 10.16.0 + * @since 10.17.0 */ -@FileStatefulCheck +@StatelessCheck public class ConstructorsDeclarationGroupingCheck extends AbstractCheck { /** @@ -58,11 +61,6 @@ public class ConstructorsDeclarationGroupingCheck extends AbstractCheck { */ 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(); @@ -76,35 +74,82 @@ public int[] getAcceptableTokens() { @Override public int[] getRequiredTokens() { return new int[] { - TokenTypes.CTOR_DEF, - TokenTypes.COMPACT_CTOR_DEF, + TokenTypes.CLASS_DEF, + TokenTypes.ENUM_DEF, + TokenTypes.RECORD_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); + // list of all child ASTs + final List children = getChildList(ast); + + // find first constructor + final DetailAST firstConstructor = children.stream() + .filter(ConstructorsDeclarationGroupingCheck::isConstructor) + .findFirst() + .orElse(null); + + if (firstConstructor != null) { + + // get all children AST after the first constructor + final List childrenAfterFirstConstructor = + children.subList(children.indexOf(firstConstructor), children.size()); + + // find the first index of non-constructor AST after the first constructor, if present + final Optional indexOfFirstNonConstructor = childrenAfterFirstConstructor + .stream() + .filter(currAst -> !isConstructor(currAst)) + .findFirst() + .map(children::indexOf); - 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; + // list of all children after first non-constructor AST + final List childrenAfterFirstNonConstructor = indexOfFirstNonConstructor + .map(index -> children.subList(index, children.size())) + .orElseGet(ArrayList::new); - if (!isCtor && !isCompactCtor) { - log(ast, MSG_KEY, previousCtorLineNo); - } + // create a list of all constructors that are not grouped to log + final List constructorsToLog = childrenAfterFirstNonConstructor.stream() + .filter(ConstructorsDeclarationGroupingCheck::isConstructor) + .collect(Collectors.toUnmodifiableList()); - allObjBlocks.put(currObjBlock, ast.getLineNo()); + // find the last grouped constructor + final DetailAST lastGroupedConstructor = childrenAfterFirstConstructor.stream() + .takeWhile(ConstructorsDeclarationGroupingCheck::isConstructor) + .reduce((first, second) -> second) + .orElse(firstConstructor); + + // log all constructors that are not grouped + constructorsToLog + .forEach(ctor -> log(ctor, MSG_KEY, lastGroupedConstructor.getLineNo())); } - else { - allObjBlocks.put(currObjBlock, ast.getLineNo()); + } + + /** + * Get a list of all children of the given AST. + * + * @param ast the AST to get children of + * @return a list of all children of the given AST + */ + private static List getChildList(DetailAST ast) { + final List children = new ArrayList<>(); + DetailAST child = ast.findFirstToken(TokenTypes.OBJBLOCK).getFirstChild(); + while (child != null) { + children.add(child); + child = child.getNextSibling(); } + return children; + } + + /** + * Check if the given AST is a constructor. + * + * @param ast the AST to check + * @return true if the given AST is a constructor, false otherwise + */ + private static boolean isConstructor(DetailAST ast) { + return ast.getType() == TokenTypes.CTOR_DEF + || ast.getType() == TokenTypes.COMPACT_CTOR_DEF; } } 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 9944f687eaa..6313230da97 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,7 +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 constructors should be grouped together. Previous constructor was at line number ''{0}''. +constructors.declaration.grouping=Constructors should be grouped together. The last grouped constructor is declared at line ''{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_fi.properties b/src/main/resources/com/puppycrawl/tools/checkstyle/checks/coding/messages_fi.properties index 5ac6bec22de..0f443585f2d 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,7 +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 rakentajat tulee ryhmitellä yhteen. Edellinen rakentaja oli rivillä ''{0}''. +constructors.declaration.grouping=Rakentajat tulee ryhmitellä yhteen. Viimeinen ryhmitelty rakentaja ilmoitetaan 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 b67ce2cbcb1..3b57ed57e2e 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,7 +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 doivent être regroupés. Le constructeur précédent se trouvait au numéro de ligne ''{0}''. +constructors.declaration.grouping=Les constructeurs doivent être regroupés. Le dernier constructeur groupé est déclaré à la 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 11e5ecbbab5..9ad64032485 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,7 +3,7 @@ assignment.inner.avoid=式内部での代入は避けるべきです。 avoid.clone.method=cloneメソッドを使用しないでください。 avoid.double.brace.init=二重中括弧を使った初期化は使用しないでください。 avoid.finalizer.method=ファイナライザメソッドを使用しないでください。 -constructors.declaration.grouping=すべてのコンストラクターはグループ化する必要があります。前のコンストラクターは行番号 ''{0}'' にありました。 +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 49f5ec71b56..c8b0cabe7c3 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,7 +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 devem ser agrupados. O construtor anterior estava no número de linha ''{0}''. +constructors.declaration.grouping=Os construtores devem ser agrupados. O último construtor agrupado é declarado na 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 0fb299843bb..2032e01713c 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,7 +3,7 @@ assignment.inner.avoid=Внутренние присвоения следует avoid.clone.method=Избегайте использования метода clone(). avoid.double.brace.init=Избегайте инициализации в двойных скобках. avoid.finalizer.method=Избегайте использования метода finalize(). -constructors.declaration.grouping=Все конструкторы должны быть сгруппированы вместе. Предыдущий конструктор находился на строке с номером ''{0}''. +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 a16b83dc898..4d672388712 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,7 +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=Tüm kurucular birlikte gruplandırılmalıdır. Önceki kurucu ''{0}'' satır numarasındaydı. +constructors.declaration.grouping=Yapıcılar birlikte gruplandırılmalıdır. Gruplandırılan son kurucu ''{0}'' satırında bildirildi. 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 d546d9db9dd..16a9fda6d41 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,7 +3,7 @@ assignment.inner.avoid=应避免在子表达式中赋值。 avoid.clone.method=避免重写 clone 方法。 avoid.double.brace.init=避免双括号初始化。 avoid.finalizer.method=避免重写finalize方法。 -constructors.declaration.grouping=所有构造函数应该组合在一起。先前的构造函数位于行号''{0}'' +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 index 4cd256e79bb..2ba5c9f084d 100644 --- 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 @@ -6,9 +6,10 @@ parent="com.puppycrawl.tools.checkstyle.TreeWalker"> <p> Checks that all constructors are grouped together. - If there is any code between the constructors - then this check will give an error. - Comments between constructors are ignored. + If there is any non-constructor code separating constructors, + this check identifies and logs a violation for those ungrouped constructors. + The violation message will specify the line number of the last grouped constructor. + Comments between constructors are allowed. </p> 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 index 2b55af8b1bb..e162bff9c07 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/coding/ConstructorsDeclarationGroupingCheckTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/coding/ConstructorsDeclarationGroupingCheckTest.java @@ -22,17 +22,9 @@ import static com.google.common.truth.Truth.assertWithMessage; import static com.puppycrawl.tools.checkstyle.checks.coding.ConstructorsDeclarationGroupingCheck.MSG_KEY; -import java.io.File; -import java.util.Map; -import java.util.Optional; - import org.junit.jupiter.api.Test; import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport; -import com.puppycrawl.tools.checkstyle.JavaParser; -import com.puppycrawl.tools.checkstyle.api.DetailAST; -import com.puppycrawl.tools.checkstyle.api.TokenTypes; -import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil; public class ConstructorsDeclarationGroupingCheckTest extends AbstractModuleTestSupport { @Override @@ -44,11 +36,16 @@ protected String getPackageLocation() { public void testDefault() throws Exception { final String[] expected = { "23:5: " + getCheckMessage(MSG_KEY, 19), - "27:5: " + getCheckMessage(MSG_KEY, 23), - "41:9: " + getCheckMessage(MSG_KEY, 37), - "50:13: " + getCheckMessage(MSG_KEY, 44), - "53:9: " + getCheckMessage(MSG_KEY, 41), - "56:5: " + getCheckMessage(MSG_KEY, 27), + "27:5: " + getCheckMessage(MSG_KEY, 19), + "43:9: " + getCheckMessage(MSG_KEY, 37), + "52:13: " + getCheckMessage(MSG_KEY, 46), + "55:9: " + getCheckMessage(MSG_KEY, 37), + "58:5: " + getCheckMessage(MSG_KEY, 19), + "60:5: " + getCheckMessage(MSG_KEY, 19), + "78:7: " + getCheckMessage(MSG_KEY, 74), + "82:7: " + getCheckMessage(MSG_KEY, 74), + "84:7: " + getCheckMessage(MSG_KEY, 74), + "87:5: " + getCheckMessage(MSG_KEY, 19), }; verifyWithInlineConfigParser( getPath("InputConstructorsDeclarationGrouping.java"), expected); @@ -58,8 +55,10 @@ public void testDefault() throws Exception { public void testConstructorsDeclarationGroupingRecords() throws Exception { final String[] expected = { - "18:9: " + getCheckMessage(MSG_KEY, 12), - "34:9: " + getCheckMessage(MSG_KEY, 30), + "20:9: " + getCheckMessage(MSG_KEY, 12), + "22:9: " + getCheckMessage(MSG_KEY, 12), + "26:9: " + getCheckMessage(MSG_KEY, 12), + "42:9: " + getCheckMessage(MSG_KEY, 36), }; verifyWithInlineConfigParser( @@ -82,32 +81,4 @@ public void testTokensNotNull() { .isNotNull(); } - /** - * We cannot reproduce situation when visitToken is called and leaveToken is not. - * So, we have to use reflection to be sure that even in such situation - * state of the field will be cleared. - * - * @throws Exception when code tested throws exception - */ - @Test - @SuppressWarnings("unchecked") - public void testClearState() throws Exception { - final ConstructorsDeclarationGroupingCheck check = - new ConstructorsDeclarationGroupingCheck(); - final Optional ctorDef = TestUtil.findTokenInAstByPredicate( - JavaParser.parseFile(new File(getNonCompilablePath( - "InputConstructorsDeclarationGroupingRecords.java")), - JavaParser.Options.WITHOUT_COMMENTS), - ast -> ast.getType() == TokenTypes.CTOR_DEF); - - assertWithMessage("Ast should contain CTOR_DEF") - .that(ctorDef.isPresent()) - .isTrue(); - assertWithMessage("State is not cleared on beginTree") - .that(TestUtil.isStatefulFieldClearedDuringBeginTree(check, ctorDef.get(), - "allObjBlocks", - allObjBlocks -> ((Map) allObjBlocks).isEmpty())) - .isTrue(); - } - } 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 index eff55817be6..a50875a62cf 100644 --- 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 @@ -15,9 +15,15 @@ public MyRecord1(int a) { void foo() {} + void foo2() {} + public MyRecord1 {} // violation - public MyRecord1(int x, int y, int z) { + public MyRecord1(int a, int b, int c, int d) { // violation + this(a+b, c+d); + } + + public MyRecord1(int x, int y, int z) { // violation this(x+y, z); } } @@ -31,6 +37,40 @@ class MyClass { String[] str; + String[] str2; + MyClass(int a) {} // violation } + + public record MyRecord2(double d) { + public MyRecord2(double a, double b, double c) { + this(a+b+c); + } + + public MyRecord2 {} + + public MyRecord2(double a, double b) { + this(a+b); + } + } + + public record MyRecord3(float f) { + public MyRecord3(float a, float b, float c) { + this(a+b+c); + } + } + + public record MyRecord4(String str) { + public MyRecord4 {} + } + + public record MyRecord5(long l) { + void test() {} + + void test2() {} + + void test3() {} + } + + public record MyRecord6(String str, int x) {} } 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 index f567fbc207f..758c71a79c5 100644 --- 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 @@ -26,19 +26,21 @@ void foo2() {} InputConstructorsDeclarationGrouping(double x) {} // violation - private enum Testing { + private enum InnerEnum1 { one; int x; - Testing() {} + InnerEnum1() {} - Testing(String f) {} + InnerEnum1(String f) {} String str; - Testing(int x) {} // violation + String str2; + + InnerEnum1(int x) {} // violation private abstract class Inner { Inner() {} @@ -50,11 +52,13 @@ private abstract class Inner { Inner(String g) {} // violation } - Testing(double d) {} // violation + InnerEnum1(double d) {} // violation } InputConstructorsDeclarationGrouping(float x) {} // violation + InputConstructorsDeclarationGrouping(long l) {} // violation + private class Inner { Inner() {} @@ -64,4 +68,52 @@ private class Inner { Inner(int x) {} } + private class Inner2 { + Inner2() {} + + Inner2(String str) {} + + int x; + + Inner2(int x) {} // violation + + String xx; + + Inner2(double d) {} // violation + + Inner2(float f) {} // violation + } + + InputConstructorsDeclarationGrouping(long l, double d) {} // violation + + InputConstructorsDeclarationGrouping annoynmous = new InputConstructorsDeclarationGrouping() { + int x; + void test() {} + void test2() {} + }; + + private enum InnerEnum2 { + ONE,TWO,THREE; + void test() {} + void test2() {} + void test3() {} + } + + private enum InnerEnum3 { + InnerEnum3() {} + } + + private enum InnerEnum4 {} + + private class Inner3 { + void test() {} + void test2() {} + void test3() {} + } + + private class Inner4 { + Inner4() {} + } + + private class Inner5 {} } 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 index f9033c2fd1a..c9d43ffae3e 100644 --- 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 @@ -10,6 +10,7 @@ // xdoc section -- start public class Example1 { + int x; Example1() {} @@ -24,6 +25,7 @@ public class Example1 { void foo() {} private enum ExampleEnum { + ONE, TWO, THREE; ExampleEnum() {} diff --git a/src/xdocs-examples/resources/com/puppycrawl/tools/checkstyle/checks/coding/constructorsdeclarationgrouping/Example2.java b/src/xdocs-examples/resources/com/puppycrawl/tools/checkstyle/checks/coding/constructorsdeclarationgrouping/Example2.java index c6b4e402e4c..bd3c517e134 100644 --- a/src/xdocs-examples/resources/com/puppycrawl/tools/checkstyle/checks/coding/constructorsdeclarationgrouping/Example2.java +++ b/src/xdocs-examples/resources/com/puppycrawl/tools/checkstyle/checks/coding/constructorsdeclarationgrouping/Example2.java @@ -21,9 +21,10 @@ void foo() {} Example2(int x) {} // violation - Example2(String s, int x) {} + Example2(String s, int x) {} // violation private enum ExampleEnum { + ONE, TWO, THREE; ExampleEnum() {} diff --git a/src/xdocs/checks/coding/constructorsdeclarationgrouping.xml b/src/xdocs/checks/coding/constructorsdeclarationgrouping.xml index 6f33d5b399b..d92da9d92d5 100644 --- a/src/xdocs/checks/coding/constructorsdeclarationgrouping.xml +++ b/src/xdocs/checks/coding/constructorsdeclarationgrouping.xml @@ -7,13 +7,15 @@

-

Since Checkstyle 10.16.0

+

Since Checkstyle 10.17.0

Checks that all constructors are grouped together. - If there is any code between the constructors - then this check will give an error. - Comments between constructors are ignored. + If there is any non-constructor code separating constructors, + this check identifies and logs a violation for those ungrouped constructors. + The violation message will specify the line number + of the last grouped constructor. + Comments between constructors are allowed.

@@ -29,6 +31,7 @@

Example of correct grouping of constructors:

public class Example1 { + int x; Example1() {} @@ -43,6 +46,7 @@ public class Example1 { void foo() {} private enum ExampleEnum { + ONE, TWO, THREE; ExampleEnum() {} @@ -71,9 +75,10 @@ public class Example2 { Example2(int x) {} // violation - Example2(String s, int x) {} + Example2(String s, int x) {} // violation private enum ExampleEnum { + ONE, TWO, THREE; ExampleEnum() {} diff --git a/src/xdocs/checks/coding/constructorsdeclarationgrouping.xml.template b/src/xdocs/checks/coding/constructorsdeclarationgrouping.xml.template index 90de2bbf3ba..d4e131048bf 100644 --- a/src/xdocs/checks/coding/constructorsdeclarationgrouping.xml.template +++ b/src/xdocs/checks/coding/constructorsdeclarationgrouping.xml.template @@ -7,13 +7,15 @@
-

Since Checkstyle 10.16.0

+

Since Checkstyle 10.17.0

Checks that all constructors are grouped together. - If there is any code between the constructors - then this check will give an error. - Comments between constructors are ignored. + If there is any non-constructor code separating constructors, + this check identifies and logs a violation for those ungrouped constructors. + The violation message will specify the line number + of the last grouped constructor. + Comments between constructors are allowed.