Skip to content

Commit

Permalink
Issue checkstyle#14726: new check: ConstructorsDeclarationGroupingCheck
Browse files Browse the repository at this point in the history
  • Loading branch information
Zopsss committed Apr 1, 2024
1 parent d55b3f9 commit d697fc5
Show file tree
Hide file tree
Showing 20 changed files with 489 additions and 3 deletions.
1 change: 1 addition & 0 deletions config/checkstyle-checks.xml
Expand Up @@ -539,6 +539,7 @@
<module name="NoFinalizer"/>
<module name="OneStatementPerLine"/>
<module name="OverloadMethodsDeclarationOrder"/>
<module name="ConstructorsDeclarationGrouping"/>
<module name="PackageDeclaration"/>
<module name="ParameterAssignment"/>
<module name="RequireThis"/>
Expand Down
1 change: 1 addition & 0 deletions config/jsoref-spellchecker/whitelist.words
Expand Up @@ -984,6 +984,7 @@ outertypenumber
outter
ove
overloadmethodsdeclarationorder
constructorsdeclarationgrouping
overloadsplit
overridable
OVERRIDERS
Expand Down
@@ -0,0 +1,52 @@
package org.checkstyle.suppressionxpathfilter;

import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
import com.puppycrawl.tools.checkstyle.checks.coding.ConstructorsDeclarationGroupingCheck;
import com.puppycrawl.tools.checkstyle.checks.coding.OverloadMethodsDeclarationOrderCheck;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.util.Arrays;
import java.util.List;

public class XpathRegressionConstructorsDeclarationGroupingTest extends AbstractXpathTestSupport{

private final Class<ConstructorsDeclarationGroupingCheck> clazz =
ConstructorsDeclarationGroupingCheck.class;
@Override
protected String getCheckName() {
return clazz.getSimpleName();
}

@Test
public void testOne() throws Exception {
final File fileToProcess = new File(
getPath("SuppressionXpathRegressionConstructorsDeclarationGrouping1.java"));

final DefaultConfiguration moduleConfig = createModuleConfig(clazz);

final String[] expectedViolation = {
"10:5: " + getCheckMessage(clazz,
ConstructorsDeclarationGroupingCheck.MSG_KEY),
};

final List<String> expectedXpathQueries = Arrays.asList(
"/COMPILATION_UNIT/CLASS_DEF[./IDENT"
+ "[@text='SuppressionXpathRegressionConstructorsDeclarationGrouping1']]"
+ "/OBJBLOCK/CTOR_DEF[./IDENT"
+ "[@text='SuppressionXpathRegressionConstructorsDeclarationGrouping1']]",
"/COMPILATION_UNIT/CLASS_DEF[./IDENT"
+ "[@text='SuppressionXpathRegressionConstructorsDeclarationGrouping1']]"
+ "/OBJBLOCK/CTOR_DEF[./IDENT"
+ "[@text='SuppressionXpathRegressionConstructorsDeclarationGrouping1']]"
+ "/MODIFIERS",
"/COMPILATION_UNIT/CLASS_DEF[./IDENT"
+ "[@text='SuppressionXpathRegressionConstructorsDeclarationGrouping1']]"
+ "/OBJBLOCK/CTOR_DEF/IDENT"
+ "[@text='SuppressionXpathRegressionConstructorsDeclarationGrouping1']"

);

runVerifications(moduleConfig, fileToProcess, expectedViolation, expectedXpathQueries);
}
}
@@ -0,0 +1,11 @@
package org.checkstyle.suppressionxpathfilter.constructorsdeclarationgrouping;

public class SuppressionXpathRegressionConstructorsDeclarationGrouping1 {
SuppressionXpathRegressionConstructorsDeclarationGrouping1() {}

SuppressionXpathRegressionConstructorsDeclarationGrouping1(int a) {}

int x;

SuppressionXpathRegressionConstructorsDeclarationGrouping1(String str) {} // warn
}
Expand Up @@ -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",
Expand Down
@@ -0,0 +1,107 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// 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 com.puppycrawl.tools.checkstyle.FileStatefulCheck;
import com.puppycrawl.tools.checkstyle.GlobalStatefulCheck;
import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;

import java.util.Objects;

/**
* <p>
* Checks that overloaded constructors are grouped together.
* If there is anything between overloaded constructors ( obviously, expect comments )
* then this check will give an error.
* </p>
* <p>
* Parent is {@code com.puppycrawl.tools.checkstyle.TreeWalker}
* </p>
* <p>
* Violation Message Keys:
* </p>
* <ul>
* <li>
* {@code constructors.declaration.grouping}
* </li>
* </ul>
*
* @since 10.15.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 if the constructor has occurred before. */
private boolean isCtorOccurred;

/** Specifies the previous IDENT name. */
private String previousIdent;

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

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

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

@Override
public void visitToken(DetailAST ast) {
final DetailAST previousSibling = ast.getPreviousSibling();

if (previousSibling != null) {
final DetailAST parent = ast.getParent().getParent();
final String ident = parent.findFirstToken(TokenTypes.IDENT).getText();

if (!Objects.equals(ident, previousIdent)) {
isCtorOccurred = false;
previousIdent = ident;
}

final int siblingType = previousSibling.getType();

if (siblingType != TokenTypes.CTOR_DEF && !isCtorOccurred) {
isCtorOccurred = true;
}
else if (siblingType != TokenTypes.CTOR_DEF) {
log(ast, MSG_KEY);
}
}

}
}
Expand Up @@ -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
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.
Expand Down
Expand Up @@ -3,6 +3,7 @@ assignment.inner.avoid=应避免在子表达式中赋值。
avoid.clone.method=避免重写 clone 方法。
avoid.double.brace.init=避免双括号初始化。
avoid.finalizer.method=避免重写finalize方法。
constructors.declaration.grouping=????????????????
covariant.equals=重写''equals()''方法时,必须确保重写了''equals(java.lang.Object)''方法。
declaration.order.access=属性访问器定义顺序错误。
declaration.order.constructor=构造器定义顺序错误。
Expand Down
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<checkstyle-metadata>
<module>
<check fully-qualified-name="com.puppycrawl.tools.checkstyle.checks.coding.ConstructorsDeclarationGroupingCheck"
name="ConstructorsDeclarationGrouping"
parent="com.puppycrawl.tools.checkstyle.TreeWalker">
<description>&lt;p&gt;
Checks that overloaded constructors are grouped together.
If there is anything between overloaded constructors ( obviously, expect comments )
then this check will give an error.
&lt;/p&gt;</description>
<message-keys>
<message-key key="constructors.declaration.grouping"/>
</message-keys>
</check>
</module>
</checkstyle-metadata>
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<checkstyle-metadata>
<module>
<check fully-qualified-name="com.puppycrawl.tools.checkstyle.checks.coding.ConstructorsDeclarationGroupingCheck"
name="ConstructorsDeclarationGrouping"
parent="com.puppycrawl.tools.checkstyle.TreeWalker">
<description>&lt;p&gt;
Checks that overloaded constructors are grouped together.
If there is anything between overloaded constructors ( obviously, expect comments )
then this check will give an error.
&lt;/p&gt;</description>
<message-keys>
<message-key key="constructors.declaration.grouping"/>
</message-keys>
</check>
</module>
</checkstyle-metadata>
2 changes: 2 additions & 0 deletions src/site/site.xml
Expand Up @@ -149,6 +149,8 @@
<item name="OneStatementPerLine" href="checks/coding/onestatementperline.html"/>
<item name="OverloadMethodsDeclarationOrder"
href="checks/coding/overloadmethodsdeclarationorder.html"/>
<item name="ConstructorsDeclarationGrouping"
href="checks/coding/constructorsdeclarationgrouping.html"/>
<item name="PackageDeclaration" href="checks/coding/packagedeclaration.html"/>
<item name="ParameterAssignment" href="checks/coding/parameterassignment.html"/>
<item name="RequireThis" href="checks/coding/requirethis.html"/>
Expand Down
@@ -0,0 +1,25 @@
package com.puppycrawl.tools.checkstyle.checks.coding;

import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
import org.junit.jupiter.api.Test;

import static com.puppycrawl.tools.checkstyle.checks.coding.ConstructorsDeclarationGroupingCheck.MSG_KEY;

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),
"27:5: " + getCheckMessage(MSG_KEY),
"40:9: " + getCheckMessage(MSG_KEY),
"51:13: " + getCheckMessage(MSG_KEY),
};
verifyWithInlineConfigParser(
getPath("InputConstructorsDeclarationGrouping.java"), expected);
}
}
Expand Up @@ -200,6 +200,7 @@ public class XpathRegressionTest extends AbstractModuleTestSupport {
"OuterTypeFilename",
"OuterTypeNumber",
"OverloadMethodsDeclarationOrder",
"ConstructorsDeclarationGrouping",
"PackageName",
"ParameterAssignment",
"ParameterName",
Expand Down
Expand Up @@ -40,20 +40,20 @@ protected String getPackageLocation() {

@Test
public void test() {
assertThat(XmlMetaReader.readAllModulesIncludingThirdPartyIfAny()).hasSize(200);
assertThat(XmlMetaReader.readAllModulesIncludingThirdPartyIfAny()).hasSize(202);
}

@Test
public void testDuplicatePackage() {
assertThat(XmlMetaReader
.readAllModulesIncludingThirdPartyIfAny("com.puppycrawl.tools.checkstyle.meta"))
.hasSize(200);
.hasSize(202);
}

@Test
public void testBadPackage() {
assertThat(XmlMetaReader.readAllModulesIncludingThirdPartyIfAny("DOES.NOT.EXIST"))
.hasSize(200);
.hasSize(202);
}

@Test
Expand Down
@@ -0,0 +1,55 @@
/*
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 Yo {
int x;

Yo(){}

Yo(int x) {}

String neko;

Yo(String g) {} // violation
}

}
}
@@ -0,0 +1,25 @@
/*xml
<module name="Checker">
<module name="TreeWalker">
<module name="ConstructorsDeclarationGrouping"/>
</module>
</module>
*/

package com.puppycrawl.tools.checkstyle.checks.coding.constructorsdeclarationgrouping;

// xdoc section -- start
public class Example1 {
int x;

void foo() {}

Example1() {}

Example1(int a){}

void foo2() {}

Example1(String str) {} // violation
}
// xdoc section -- end

0 comments on commit d697fc5

Please sign in to comment.