Skip to content

Commit

Permalink
Issue #13758: Add pattern array converter for auto bean
Browse files Browse the repository at this point in the history
  • Loading branch information
Lmh-java committed Apr 9, 2024
1 parent e30260d commit 5b49c08
Show file tree
Hide file tree
Showing 17 changed files with 129 additions and 42 deletions.
Expand Up @@ -645,21 +645,6 @@
</details>
</checkerFrameworkError>

<checkerFrameworkError unstable="false">
<fileName>src/main/java/com/puppycrawl/tools/checkstyle/checks/metrics/AbstractClassCouplingCheck.java</fileName>
<specifier>methodref.receiver.bound</specifier>
<message>Incompatible receiver type</message>
<lineContent>.forEach(excludeClassesRegexps::add);</lineContent>
<details>
found : @GuardedBy List&lt;@GuardedBy Pattern&gt;
required: @GuardSatisfied List&lt;@GuardedBy Pattern&gt;
Consequence: method
@GuardedBy List&lt;@GuardedBy Pattern&gt;
is not a valid method reference for method in @GuardedBy List&lt;@GuardedBy Pattern&gt;
@GuardedBy boolean add(@GuardSatisfied List&lt;@GuardedBy Pattern&gt; this, @GuardedBy Pattern p0)
</details>
</checkerFrameworkError>

<checkerFrameworkError unstable="false">
<fileName>src/main/java/com/puppycrawl/tools/checkstyle/checks/naming/AccessModifierOption.java</fileName>
<specifier>method.guarantee.violated</specifier>
Expand Down
2 changes: 2 additions & 0 deletions config/linkcheck-suppressions.txt
Expand Up @@ -35,6 +35,7 @@
<a href="AbstractNode.html#getDeclaredNamespaces(net.sf.saxon.om.NamespaceBinding%5B%5D)">AbstractNode.html#getDeclaredNamespaces(net.sf.saxon.om.NamespaceBinding%5B%5D)</a>: doesn't exist.
<a href="apidocs/com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.OutputStreamOptions.html#%3Cinit%3E()">#%3Cinit%3E()</a>: doesn't exist.
<a href="apidocs/com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.PatternConverter.html#%3Cinit%3E()">#%3Cinit%3E()</a>: doesn't exist.
<a href="apidocs/com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.PatternArrayConverter.html#%3Cinit%3E()">#%3Cinit%3E()</a>: doesn't exist.
<a href="apidocs/com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.RelaxedAccessModifierArrayConverter.html#%3Cinit%3E()">#%3Cinit%3E()</a>: doesn't exist.
<a href="apidocs/com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.RelaxedStringArrayConverter.html#%3Cinit%3E()">#%3Cinit%3E()</a>: doesn't exist.
<a href="apidocs/com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.ScopeConverter.html#%3Cinit%3E()">#%3Cinit%3E()</a>: doesn't exist.
Expand Down Expand Up @@ -801,6 +802,7 @@
<a href="apidocs/com/puppycrawl/tools/checkstyle/xpath/iterators/ReverseListIterator.html#%3Cinit%3E(java.util.Collection)">#%3Cinit%3E(java.util.Collection)</a>: doesn't exist.
<a href="apidocs/com/puppycrawl/tools/checkstyle/site/XdocsTemplateSink.CustomPrintWriter.html#%3Cinit%3E(java.io.Writer)">#%3Cinit%3E(java.io.Writer)</a>: doesn't exist.
<a href="com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.OutputStreamOptions.html#%3Cinit%3E()">com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.OutputStreamOptions.html#%3Cinit%3E()</a>: doesn't exist.
<a href="com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.PatternArrayConverter.html#%3Cinit%3E()">com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.PatternArrayConverter.html#%3Cinit%3E()</a>: doesn't exist.
<a href="com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.PatternConverter.html#%3Cinit%3E()">com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.PatternConverter.html#%3Cinit%3E()</a>: doesn't exist.
<a href="com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.RelaxedAccessModifierArrayConverter.html#%3Cinit%3E()">com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.RelaxedAccessModifierArrayConverter.html#%3Cinit%3E()</a>: doesn't exist.
<a href="com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.RelaxedStringArrayConverter.html#%3Cinit%3E()">com/puppycrawl/tools/checkstyle/AbstractAutomaticBean.RelaxedStringArrayConverter.html#%3Cinit%3E()</a>: doesn't exist.
Expand Down
18 changes: 18 additions & 0 deletions config/pitest-suppressions/pitest-imports-suppressions.xml
@@ -1,5 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<suppressedMutations>
<mutation unstable="false">
<sourceFile>ImportOrderCheck.java</sourceFile>
<mutatedClass>com.puppycrawl.tools.checkstyle.checks.imports.ImportOrderCheck</mutatedClass>
<mutatedMethod>setGroups</mutatedMethod>
<mutator>org.pitest.mutationtest.engine.gregor.mutators.experimental.ArgumentPropagationMutator</mutator>
<description>replaced call to java/util/Arrays::copyOf with argument</description>
<lineContent>groups = Arrays.copyOf(packageGroups, packageGroups.length);</lineContent>
</mutation>

<mutation unstable="false">
<sourceFile>ImportOrderCheck.java</sourceFile>
<mutatedClass>com.puppycrawl.tools.checkstyle.checks.imports.ImportOrderCheck</mutatedClass>
<mutatedMethod>setStaticGroups</mutatedMethod>
<mutator>org.pitest.mutationtest.engine.gregor.mutators.experimental.ArgumentPropagationMutator</mutator>
<description>replaced call to java/util/Arrays::copyOf with argument</description>
<lineContent>staticGroups = Arrays.copyOf(packageGroups, packageGroups.length);</lineContent>
</mutation>

<mutation unstable="false">
<sourceFile>PkgImportControl.java</sourceFile>
<mutatedClass>com.puppycrawl.tools.checkstyle.checks.imports.PkgImportControl</mutatedClass>
Expand Down
3 changes: 2 additions & 1 deletion config/pmd.xml
Expand Up @@ -316,7 +316,8 @@
<!-- Main has an annotated field for each command line option. This is by design. -->
<property name="violationSuppressXPath"
value="//ClassOrInterfaceDeclaration[@SimpleName='Checker']
| //ClassOrInterfaceDeclaration[@SimpleName='Main']"/>
| //ClassOrInterfaceDeclaration[@SimpleName='Main']
| //ClassOrInterfaceDeclaration[@SimpleName='ImportOrderCheck']"/>
</properties>
</rule>
<rule ref="category/java/design.xml/TooManyMethods">
Expand Down
Expand Up @@ -84,6 +84,9 @@ public enum OutputStreamOptions {
/** Comma separator for StringTokenizer. */
private static final String COMMA_SEPARATOR = ",";

/** Separator that splits multiple regex expression in a string. */
private static final String REGEX_SEPARATOR = COMMA_SEPARATOR;

/** The configuration of this bean. */
private Configuration configuration;

Expand Down Expand Up @@ -170,6 +173,7 @@ private static void registerIntegralTypes(ConvertUtilsBean cub) {
*/
private static void registerCustomTypes(ConvertUtilsBean cub) {
cub.register(new PatternConverter(), Pattern.class);
cub.register(new PatternArrayConverter(), Pattern[].class);
cub.register(new SeverityLevelConverter(), SeverityLevel.class);
cub.register(new ScopeConverter(), Scope.class);
cub.register(new UriConverter(), URI.class);
Expand Down Expand Up @@ -313,6 +317,22 @@ public Object convert(Class type, Object value) {

}

/** A converter that converts a string array to a pattern. */
private static final class PatternArrayConverter implements Converter {

@SuppressWarnings("unchecked")
@Override
public Object convert(Class type, Object value) {
final String plainString = value.toString();
final String[] patternStrings = plainString.split(REGEX_SEPARATOR);
final Pattern[] patterns = new Pattern[patternStrings.length];
for (int index = 0; index < patternStrings.length; index++) {
patterns[index] = CommonUtil.createPattern(patternStrings[index]);
}
return patterns;
}
}

/** A converter that converts strings to severity level. */
private static final class SeverityLevelConverter implements Converter {

Expand Down
Expand Up @@ -19,6 +19,7 @@

package com.puppycrawl.tools.checkstyle.checks.imports;

import java.util.Arrays;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand All @@ -28,6 +29,7 @@
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.FullIdent;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import com.puppycrawl.tools.checkstyle.utils.CommonUtil;

/**
* <p>
Expand Down Expand Up @@ -74,7 +76,7 @@
* (e.g. {@code /regexp/}). All type imports, which does not match any group, falls into an
* additional group, located at the end.
* Thus, the empty list of type groups (the default value) means one group for all type imports.
* Type is {@code java.util.regex.Pattern[]}.
* Type is {@code java.lang.String[]}.
* Default value is {@code ""}.
* </li>
* <li>
Expand Down Expand Up @@ -118,7 +120,7 @@
* an additional group, located at the end. Thus, the empty list of static groups (the default
* value) means one group for all static imports. This property has effect only when the property
* {@code option} is set to {@code top} or {@code bottom}.
* Type is {@code java.util.regex.Pattern[]}.
* Type is {@code java.lang.String[]}.
* Default value is {@code ""}.
* </li>
* <li>
Expand Down Expand Up @@ -186,7 +188,7 @@ public class ImportOrderCheck
* located at the end. Thus, the empty list of type groups (the default value) means one group
* for all type imports.
*/
private Pattern[] groups = EMPTY_PATTERN_ARRAY;
private String[] groups = CommonUtil.EMPTY_STRING_ARRAY;

/**
* Specify list of <b>static</b> import groups. Every group identified either by a common prefix
Expand All @@ -196,7 +198,7 @@ public class ImportOrderCheck
* static imports. This property has effect only when the property {@code option} is set to
* {@code top} or {@code bottom}.
*/
private Pattern[] staticGroups = EMPTY_PATTERN_ARRAY;
private String[] staticGroups = CommonUtil.EMPTY_STRING_ARRAY;

/**
* Control whether type import groups should be separated by, at least, one blank
Expand Down Expand Up @@ -262,6 +264,16 @@ public class ImportOrderCheck
*/
private ImportOrderOption option = ImportOrderOption.UNDER;

/**
* Complied array of patterns for property {@code groups}.
*/
private Pattern[] groupsReg = EMPTY_PATTERN_ARRAY;

/**
* Complied array of patterns for property {@code staticGroups}.
*/
private Pattern[] staticGroupsReg = EMPTY_PATTERN_ARRAY;

/**
* Setter to specify policy on the relative order between type imports and static imports.
*
Expand All @@ -284,7 +296,8 @@ public void setOption(String optionStr) {
* @since 3.2
*/
public void setGroups(String... packageGroups) {
groups = compilePatterns(packageGroups);
groups = Arrays.copyOf(packageGroups, packageGroups.length);
groupsReg = compilePatterns(packageGroups);
}

/**
Expand All @@ -299,7 +312,8 @@ public void setGroups(String... packageGroups) {
* @since 8.12
*/
public void setStaticGroups(String... packageGroups) {
staticGroups = compilePatterns(packageGroups);
staticGroups = Arrays.copyOf(packageGroups, packageGroups.length);
staticGroupsReg = compilePatterns(packageGroups);
}

/**
Expand Down Expand Up @@ -662,10 +676,10 @@ private static String getImportContainer(String qualifiedImportName) {
private int getGroupNumber(boolean isStatic, String name) {
final Pattern[] patterns;
if (isStatic) {
patterns = staticGroups;
patterns = staticGroupsReg;
}
else {
patterns = groups;
patterns = groupsReg;
}

int number = getGroupNumber(patterns, name);
Expand Down
Expand Up @@ -118,7 +118,6 @@ public abstract class AbstractClassCouplingCheck extends AbstractCheck {
*/
protected AbstractClassCouplingCheck(int defaultMax) {
max = defaultMax;
excludeClassesRegexps.add(CommonUtil.createPattern("^$"));
}

/**
Expand Down Expand Up @@ -156,10 +155,8 @@ public final void setExcludedClasses(String... excludedClasses) {
*
* @param from array representing regular expressions of classes to ignore.
*/
public void setExcludeClassesRegexps(String... from) {
Arrays.stream(from)
.map(CommonUtil::createPattern)
.forEach(excludeClassesRegexps::add);
public void setExcludeClassesRegexps(Pattern... from) {
excludeClassesRegexps.addAll(Arrays.asList(from));
}

/**
Expand Down
Expand Up @@ -83,7 +83,7 @@
* Property {@code excludeClassesRegexps} - Specify user-configured regular
* expressions to ignore classes.
* Type is {@code java.util.regex.Pattern[]}.
* Default value is {@code ^$}.
* Default value is {@code ""}.
* </li>
* <li>
* Property {@code excludedClasses} - Specify user-configured class names to ignore.
Expand Down
Expand Up @@ -50,7 +50,7 @@
* Property {@code excludeClassesRegexps} - Specify user-configured regular
* expressions to ignore classes.
* Type is {@code java.util.regex.Pattern[]}.
* Default value is {@code ^$}.
* Default value is {@code ""}.
* </li>
* <li>
* Property {@code excludedClasses} - Specify user-configured class names to ignore.
Expand Down
Expand Up @@ -40,7 +40,7 @@
&lt;a href="https://en.wikipedia.org/wiki/ASCII#Order"&gt;ASCII sort order&lt;/a&gt;.
It affects both type imports and static imports.</description>
</property>
<property default-value="" name="groups" type="java.util.regex.Pattern[]">
<property default-value="" name="groups" type="java.lang.String[]">
<description>Specify list of &lt;b&gt;type import&lt;/b&gt; groups. Every group identified
either by a common prefix string, or by a regular expression enclosed in forward slashes
(e.g. {@code /regexp/}). All type imports, which does not match any group, falls into an
Expand Down Expand Up @@ -75,9 +75,7 @@
<description>Control whether
&lt;b&gt;static imports&lt;/b&gt; located at &lt;b&gt;top&lt;/b&gt; or &lt;b&gt;bottom&lt;/b&gt; are sorted within the group.</description>
</property>
<property default-value=""
name="staticGroups"
type="java.util.regex.Pattern[]">
<property default-value="" name="staticGroups" type="java.lang.String[]">
<description>Specify list of &lt;b&gt;static&lt;/b&gt; import groups. Every group
identified either by a common prefix string, or by a regular expression enclosed in forward
slashes (e.g. {@code /regexp/}). All static imports, which does not match any group, fall into
Expand Down
Expand Up @@ -61,7 +61,7 @@
&lt;/li&gt;
&lt;/ol&gt;</description>
<properties>
<property default-value="^$"
<property default-value=""
name="excludeClassesRegexps"
type="java.util.regex.Pattern[]">
<description>Specify user-configured regular
Expand Down
Expand Up @@ -28,7 +28,7 @@
&lt;/li&gt;
&lt;/ol&gt;</description>
<properties>
<property default-value="^$"
<property default-value=""
name="excludeClassesRegexps"
type="java.util.regex.Pattern[]">
<description>Specify user-configured regular
Expand Down
Expand Up @@ -23,7 +23,9 @@

import java.net.URI;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.apache.commons.beanutils.ConversionException;
import org.apache.commons.beanutils.ConvertUtilsBean;
Expand Down Expand Up @@ -278,6 +280,46 @@ public void testBeanConvertersUri3() {
}
}

@Test
public void testBeanConverterPatternArray1() throws Exception {
final ConverterBean bean = new ConverterBean();
final DefaultConfiguration config = new DefaultConfiguration("bean");
final String patternString = "^a*$,^b*$, ^c*$";
final List<String> expectedPatternString = Arrays.asList("^a*$", "^b*$", " ^c*$");
config.addProperty("patterns", patternString);
bean.configure(config);

assertWithMessage("invalid result")
.that(bean.patterns)
.hasLength(3);
assertWithMessage("invalid result")
.that(expectedPatternString)
.containsExactlyElementsIn(
Arrays.stream(bean.patterns)
.map(Pattern::pattern)
.collect(Collectors.toUnmodifiableList()));
}

@Test
public void testBeanConverterPatternArray2() throws Exception {
final ConverterBean bean = new ConverterBean();
final DefaultConfiguration config = new DefaultConfiguration("bean");
final String patternString = "^a*$";
final List<String> expectedPatternString = List.of("^a*$");
config.addProperty("patterns", patternString);
bean.configure(config);

assertWithMessage("invalid result")
.that(bean.patterns)
.hasLength(1);
assertWithMessage("invalid result")
.that(expectedPatternString)
.containsExactlyElementsIn(
Arrays.stream(bean.patterns)
.map(Pattern::pattern)
.collect(Collectors.toUnmodifiableList()));
}

private static final class ConvertUtilsBeanStub extends ConvertUtilsBean {

private int registerCount;
Expand Down Expand Up @@ -338,6 +380,7 @@ public static class ConverterBean extends AbstractAutomaticBean {
private Scope scope;
private URI uri;
private AccessModifierOption[] accessModifiers;
private Pattern[] patterns;

/**
* Setter for strings.
Expand Down Expand Up @@ -394,6 +437,15 @@ public void setAccessModifiers(AccessModifierOption... accessModifiers) {
accessModifiers.length);
}

/**
* Setter for patterns.
*
* @param patterns patterns
*/
public void setPatterns(Pattern... patterns) {
this.patterns = Arrays.copyOf(patterns, patterns.length);
}

@Override
protected void finishLocalSetup() {
// no code
Expand Down
4 changes: 2 additions & 2 deletions src/xdocs/checks/imports/importorder.xml
Expand Up @@ -53,7 +53,7 @@
<tr>
<td>groups</td>
<td>Specify list of <b>type import</b> groups. Every group identified either by a common prefix string, or by a regular expression enclosed in forward slashes (e.g. <code>/regexp/</code>). All type imports, which does not match any group, falls into an additional group, located at the end. Thus, the empty list of type groups (the default value) means one group for all type imports.</td>
<td><a href="../../property_types.html#Pattern.5B.5D">Pattern[]</a></td>
<td><a href="../../property_types.html#String.5B.5D">String[]</a></td>
<td><code>{}</code></td>
<td>3.2</td>
</tr>
Expand Down Expand Up @@ -95,7 +95,7 @@
<tr>
<td>staticGroups</td>
<td>Specify list of <b>static</b> import groups. Every group identified either by a common prefix string, or by a regular expression enclosed in forward slashes (e.g. <code>/regexp/</code>). All static imports, which does not match any group, fall into an additional group, located at the end. Thus, the empty list of static groups (the default value) means one group for all static imports. This property has effect only when the property <code>option</code> is set to <code>top</code> or <code>bottom</code>.</td>
<td><a href="../../property_types.html#Pattern.5B.5D">Pattern[]</a></td>
<td><a href="../../property_types.html#String.5B.5D">String[]</a></td>
<td><code>{}</code></td>
<td>8.12</td>
</tr>
Expand Down
2 changes: 1 addition & 1 deletion src/xdocs/checks/metrics/classdataabstractioncoupling.xml
Expand Up @@ -83,7 +83,7 @@
<td>excludeClassesRegexps</td>
<td>Specify user-configured regular expressions to ignore classes.</td>
<td><a href="../../property_types.html#Pattern.5B.5D">Pattern[]</a></td>
<td><code>^$</code></td>
<td><code>{}</code></td>
<td>7.7</td>
</tr>
<tr>
Expand Down

0 comments on commit 5b49c08

Please sign in to comment.