Merge branch 'main' into java-unit-test-rules
This commit is contained in:
commit
f317e8bee5
@ -7819,6 +7819,33 @@
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "gudzpoz",
|
||||
"name": "gudzpoz",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/14026120?v=4",
|
||||
"profile": "https://kyo.iroiro.party/",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "phansys",
|
||||
"name": "Javier Spagnoletti",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1231441?v=4",
|
||||
"profile": "https://github.com/phansys",
|
||||
"contributions": [
|
||||
"bug"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Aryant-Tripathi",
|
||||
"name": "Aryant Tripathi",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/60316716?v=4",
|
||||
"profile": "https://github.com/Aryant-Tripathi",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
@ -6,7 +6,7 @@
|
||||
[![Build Status](https://github.com/pmd/pmd/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/pmd/pmd/actions)
|
||||
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/net.sourceforge.pmd/pmd/badge.svg)](https://maven-badges.herokuapp.com/maven-central/net.sourceforge.pmd/pmd)
|
||||
[![Reproducible Builds](https://img.shields.io/badge/Reproducible_Builds-ok-green?labelColor=blue)](https://github.com/jvm-repo-rebuild/reproducible-central/tree/master/content/net/sourceforge/pmd#readme)
|
||||
[![Coverage Status](https://coveralls.io/repos/github/pmd/pmd/badge.svg)](https://coveralls.io/github/pmd/pmd)
|
||||
[![Coverage Status](https://coveralls.io/repos/github/pmd/pmd/badge.svg?branch=main)](https://coveralls.io/github/pmd/pmd?branch=main)
|
||||
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/ea550046a02344ec850553476c4aa2ca)](https://app.codacy.com/organizations/gh/pmd/dashboard)
|
||||
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg)](code_of_conduct.md)
|
||||
[![Documentation (latest)](https://img.shields.io/badge/docs-latest-green)](https://docs.pmd-code.org/latest/)
|
||||
|
@ -11,10 +11,11 @@
|
||||
- root-node-name: name of the root node without prefix (eg "TopLevel"), will be made to implement RootNode
|
||||
|
||||
See AntlrGeneratedParserBase
|
||||
|
||||
-->
|
||||
<taskdef resource="net/sf/antcontrib/antcontrib.properties" />
|
||||
|
||||
<property name="target-package-dir" value="${antlr4.outputDirectory}/net/sourceforge/pmd/lang/${lang-id}/ast"/>
|
||||
<property name="stamp-file" value="${project.build.directory}/last-generated-timestamp" />
|
||||
|
||||
|
||||
<property name="lang-ast-package" value="net.sourceforge.pmd.lang.${lang-id}.ast" />
|
||||
@ -32,14 +33,100 @@
|
||||
<property name="base-visitor-file" value="${target-package-dir}/${base-visitor-name}.java"/>
|
||||
|
||||
<property name="listener-name" value="${lang-name}Listener"/>
|
||||
<property name="listener-file" value="${target-package-dir}/${visitor-name}.java"/>
|
||||
<property name="listener-file" value="${target-package-dir}/${listener-name}.java"/>
|
||||
|
||||
<property name="base-listener-name" value="${lang-name}BaseListener"/>
|
||||
<property name="base-listener-file" value="${target-package-dir}/${base-visitor-name}.java"/>
|
||||
<property name="base-listener-file" value="${target-package-dir}/${base-listener-name}.java"/>
|
||||
|
||||
<property name="node-itf-name" value="${lang-name}Node"/>
|
||||
<property name="base-class-name" value="Abstract${lang-name}Node"/>
|
||||
|
||||
<property name="lexer-name" value="${lang-name}Lexer"/>
|
||||
<property name="lexer-file" value="${target-package-dir}/${lexer-name}.java"/>
|
||||
|
||||
<target name="check-up-to-date"
|
||||
description="Checks the input files are up to date">
|
||||
|
||||
<uptodate property="processing-not-required" targetfile="${stamp-file}">
|
||||
<srcfiles dir="${target-package-dir}" includes="*.java" />
|
||||
<srcfiles file="${ant.file}" />
|
||||
</uptodate>
|
||||
<echo message="Up-to-date check: processing-not-required=${processing-not-required}" />
|
||||
</target>
|
||||
|
||||
<target name="update-stamp-file" unless="processing-not-required">
|
||||
<touch file="${stamp-file}" />
|
||||
</target>
|
||||
|
||||
<target name="annotate-classes" description="Adds the @Generated annotation to all classes"
|
||||
unless="processing-not-required">
|
||||
<if>
|
||||
<available file="${parser-file}"/>
|
||||
<then>
|
||||
<replace file="${parser-file}"
|
||||
token="public class ${parser-name}"
|
||||
value='@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool")${line.separator}
|
||||
public class ${parser-name}'/>
|
||||
|
||||
<!-- Parse tree classes for each element -->
|
||||
<replace file="${parser-file}"
|
||||
token="public static class "
|
||||
value='@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool")${line.separator}
|
||||
public static class '/>
|
||||
</then>
|
||||
</if>
|
||||
|
||||
<if>
|
||||
<available file="${visitor-file}"/>
|
||||
<then>
|
||||
<replace file="${visitor-file}"
|
||||
token="public interface ${visitor-name}"
|
||||
value='@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool")${line.separator}
|
||||
public interface ${visitor-name}'/>
|
||||
</then>
|
||||
</if>
|
||||
|
||||
<if>
|
||||
<available file="${base-visitor-file}"/>
|
||||
<then>
|
||||
<replace file="${base-visitor-file}"
|
||||
token="public class ${base-visitor-name}"
|
||||
value='@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool")${line.separator}
|
||||
public class ${base-visitor-name}'/>
|
||||
</then>
|
||||
</if>
|
||||
|
||||
<if>
|
||||
<available file="${listener-file}"/>
|
||||
<then>
|
||||
<replace file="${listener-file}"
|
||||
token="public interface ${listener-name}"
|
||||
value='@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool")${line.separator}
|
||||
public interface ${listener-name}'/>
|
||||
</then>
|
||||
</if>
|
||||
|
||||
<if>
|
||||
<available file="${base-listener-file}"/>
|
||||
<then>
|
||||
<replace file="${base-listener-file}"
|
||||
token="public class ${base-listener-name}"
|
||||
value='@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool")${line.separator}
|
||||
public class ${base-listener-name}'/>
|
||||
</then>
|
||||
</if>
|
||||
|
||||
<if>
|
||||
<available file="${lexer-file}"/>
|
||||
<then>
|
||||
<replace file="${lexer-file}"
|
||||
token="public class ${lexer-name}"
|
||||
value='@net.sourceforge.pmd.annotation.Generated("org.antlr.v4.Tool")${line.separator}
|
||||
public class ${lexer-name}'/>
|
||||
</then>
|
||||
</if>
|
||||
</target>
|
||||
|
||||
<condition property="rename-parser">
|
||||
<and>
|
||||
<not>
|
||||
@ -72,7 +159,9 @@
|
||||
tofile="${parser-file}"/>
|
||||
</target>
|
||||
|
||||
<target name="cpd-language" description="Adapt Antlr sources for CPD-only languages">
|
||||
<target name="cpd-language" depends="check-up-to-date, annotate-classes, cpd-language-processing, update-stamp-file"/>
|
||||
<target name="cpd-language-processing" description="Adapt Antlr sources for CPD-only languages"
|
||||
unless="processing-not-required">
|
||||
<!-- We only need the Lexer file. -->
|
||||
<delete file="${parser-file}"/>
|
||||
<delete>
|
||||
@ -83,7 +172,9 @@
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<target name="pmd-language" description="Adapt Antlr sources for PMD languages" depends="rename-parser">
|
||||
<target name="pmd-language" depends="check-up-to-date, annotate-classes, pmd-language-processing, update-stamp-file"/>
|
||||
<target name="pmd-language-processing" description="Adapt Antlr sources for PMD languages" depends="rename-parser"
|
||||
unless="processing-not-required">
|
||||
|
||||
<!-- Adapt parser. -->
|
||||
<replace file="${parser-file}">
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -21,27 +21,45 @@ This is a {{ site.pmd.release_type }} release.
|
||||
* {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} (Java Best Practices) now also considers JUnit 5 and TestNG tests.
|
||||
|
||||
#### Renamed Rules
|
||||
Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called
|
||||
after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG.
|
||||
|
||||
* {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseAfterAnnotation`.
|
||||
* {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseBeforeAnnotation`.
|
||||
* {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseTestAnnotation`.
|
||||
* {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} (Java Best Practices) has been renamed from `JUnitAssertionsShouldIncludeMessage`.
|
||||
* {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} (Java Best Practices) has been renamed from `JUnitTestContainsTooManyAsserts`.
|
||||
* {% rule java/bestpractices/UnitTestsShouldIncludeAssert %} (Java Best Practices) has been renamed from `JUnitTestsShouldIncludeAssert`.
|
||||
* Several rules for unit testing have been renamed to better reflect their actual scope. Lots of them were called
|
||||
after JUnit / JUnit 4, even when they applied to JUnit 5 and / or TestNG.
|
||||
* {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} (Java Best Practices) has been renamed from `JUnitAssertionsShouldIncludeMessage`.
|
||||
* {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} (Java Best Practices) has been renamed from `JUnitTestContainsTooManyAsserts`.
|
||||
* {% rule java/bestpractices/UnitTestShouldIncludeAssert %} (Java Best Practices) has been renamed from `JUnitTestsShouldIncludeAssert`.
|
||||
* {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseAfterAnnotation`.
|
||||
* {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseBeforeAnnotation`.
|
||||
* {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} (Java Best Practices) has been renamed from `JUnit4TestShouldUseTestAnnotation`.
|
||||
|
||||
The old rule names still work but are deprecated.
|
||||
|
||||
### 🐛 Fixed Issues
|
||||
* java
|
||||
* [#4532](https://github.com/pmd/pmd/issues/4532): \[java] Rule misnomer for JUnit* rules
|
||||
* [#5261](https://github.com/pmd/pmd/issues/5261): \[java] Record patterns with empty deconstructor lists lead to NPE
|
||||
* java-codestyle
|
||||
* [#5253](https://github.com/pmd/pmd/issues/5253): \[java] BooleanGetMethodName: False-negatives with `Boolean` wrapper
|
||||
* java-errorprone
|
||||
* [#5067](https://github.com/pmd/pmd/issues/5067): \[java] CloseResource: False positive for FileSystems.getDefault()
|
||||
|
||||
### 🚨 API Changes
|
||||
* java-bestpractices
|
||||
* The old rule name `JUnit4TestShouldUseAfterAnnotation` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestShouldUseAfterAnnotation %} instead.
|
||||
* The old rule name `JUnit4TestShouldUseBeforeAnnotation` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestShouldUseBeforeAnnotation %} instead.
|
||||
* The old rule name `JUnit4TestShouldUseTestAnnotation` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestShouldUseTestAnnotation %} instead.
|
||||
* The old rule name `JUnitAssertionsShouldIncludeMessage` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestAssertionsShouldIncludeMessage %} instead.
|
||||
* The old rule name `JUnitTestContainsTooManyAsserts` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestContainsTooManyAsserts %} instead.
|
||||
* The old rule name `JUnitTestsShouldIncludeAssert` has been deprecated. Use the new name {% rule java/bestpractices/UnitTestShouldIncludeAssert %} instead.
|
||||
|
||||
|
||||
### ✨ Merged pull requests
|
||||
* [#4965](https://github.com/pmd/pmd/pull/4965): \[java] Rename JUnit rules with overly restrictive names - [Juan Martín Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod)
|
||||
* [#5241](https://github.com/pmd/pmd/pull/5241): \Ignore javacc code in coverage report - [Juan Martín Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod)
|
||||
* [#4965](https://github.com/pmd/pmd/pull/4965): Fix #4532: \[java] Rename JUnit rules with overly restrictive names - [Juan Martín Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod)
|
||||
* [#5225](https://github.com/pmd/pmd/pull/5225): Fix #5067: \[java] CloseResource: False positive for FileSystems.getDefault() - [Lukas Gräf](https://github.com/lukasgraef) (@lukasgraef)
|
||||
* [#5241](https://github.com/pmd/pmd/pull/5241): Ignore javacc code in coverage report - [Juan Martín Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod)
|
||||
* [#5258](https://github.com/pmd/pmd/pull/5258): Ignore generated antlr classes in coverage reports - [Juan Martín Sotuyo Dodero](https://github.com/jsotuyod) (@jsotuyod)
|
||||
* [#5264](https://github.com/pmd/pmd/pull/5264): Fix #5261: \[java] Fix NPE with empty pattern list - [Clément Fournier](https://github.com/oowekyala) (@oowekyala)
|
||||
* [#5269](https://github.com/pmd/pmd/pull/5269): Fix #5253: \[java] Support Boolean wrapper class for BooleanGetMethodName rule - [Aryant Tripathi](https://github.com/Aryant-Tripathi) (@Aryant-Tripathi)
|
||||
* [#5275](https://github.com/pmd/pmd/pull/5275): Use plugin-classpath to simplify javacc-wrapper.xml - [Andreas Dangel](https://github.com/adangel) (@adangel)
|
||||
* [#5278](https://github.com/pmd/pmd/pull/5278): \[java] CouplingBetweenObjects: improve violation message - [Andreas Dangel](https://github.com/adangel) (@adangel)
|
||||
|
||||
{% endtocmaker %}
|
||||
|
||||
|
@ -25,9 +25,9 @@
|
||||
It also uses the following maven properties:
|
||||
|
||||
- javacc.outputDirectory: Directory in which to root the generated package tree
|
||||
- javacc.jar: JAR of JavaCC in the local maven repository
|
||||
- plugin-classpath: The classpath of maven-antrun-plugin with javacc.jar dependency
|
||||
Provided by maven via "<property name="plugin-classpath" refid="maven.plugin.classpath"/>"
|
||||
- some properties of project.build
|
||||
|
||||
-->
|
||||
|
||||
<condition property="lang-name-camelcase" value="${lang-name}">
|
||||
@ -40,8 +40,6 @@
|
||||
<property name="target-package-dir" value="${javacc.outputDirectory}/net/sourceforge/pmd/lang/${lang-id}/ast" />
|
||||
<property name="stamp-file" value="${project.build.directory}/last-generated-timestamp" />
|
||||
|
||||
<property name="javacc-home.path" value="${project.build.directory}/lib/javacc" />
|
||||
|
||||
<property name="lang-ast-package" value="net.sourceforge.pmd.lang.${lang-id}.ast" />
|
||||
<property name="ast-api-package" value="net.sourceforge.pmd.lang.ast" />
|
||||
<property name="ast-impl-package" value="${ast-api-package}.impl.javacc" />
|
||||
@ -84,7 +82,7 @@
|
||||
|
||||
<target name="alljavacc"
|
||||
description="Generates JavaCC sources and cleans them up"
|
||||
depends="checkUpToDate,init,jjtree,jjtree-ersatz,javacc,adapt-generated,default-visitor,cleanup" />
|
||||
depends="checkUpToDate,init,jjtree,jjtree-ersatz,javacc,adapt-generated,default-visitor" />
|
||||
|
||||
<target name="checkUpToDate"
|
||||
description="Checks the input files are up to date">
|
||||
@ -104,9 +102,6 @@
|
||||
|
||||
|
||||
<target name="init" unless="javaccBuildNotRequired" description="Initialize build">
|
||||
<mkdir dir="${javacc-home.path}" />
|
||||
<copy file="${javacc.jar}" tofile="${javacc-home.path}/javacc.jar" />
|
||||
|
||||
<mkdir dir="${javacc.outputDirectory}" />
|
||||
<touch file="${stamp-file}" />
|
||||
<delete dir="${target-package-dir}" />
|
||||
@ -117,11 +112,6 @@
|
||||
</condition>
|
||||
</target>
|
||||
|
||||
<target name="cleanup" unless="javaccBuildNotRequired">
|
||||
<delete dir="${javacc-home.path}" />
|
||||
</target>
|
||||
|
||||
|
||||
<target name="jjtree" unless="jjtreeBuildNotRequired" description="Runs JJTree">
|
||||
|
||||
<!--
|
||||
@ -130,7 +120,7 @@
|
||||
-->
|
||||
<java fork="true"
|
||||
classname="jjtree"
|
||||
classpath="${javacc-home.path}/javacc.jar">
|
||||
classpath="${plugin-classpath}">
|
||||
<sysproperty key="file.encoding" value="UTF-8" />
|
||||
<arg value="-OUTPUT_DIRECTORY:${target-package-dir}" />
|
||||
<arg value="-NODE_USES_PARSER:false" />
|
||||
@ -148,7 +138,7 @@
|
||||
<target name="javacc" depends="jjtree" unless="javaccBuildNotRequired">
|
||||
<java fork="true"
|
||||
classname="javacc"
|
||||
classpath="${javacc-home.path}/javacc.jar">
|
||||
classpath="${plugin-classpath}">
|
||||
<sysproperty key="file.encoding" value="UTF-8" />
|
||||
<arg value="-STATIC:false" />
|
||||
<arg value="-USER_CHAR_STREAM:true" />
|
||||
|
@ -11,7 +11,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
/**
|
||||
* Marks a class as generated code, and therefore to be ignored for code coverage purposes.
|
||||
*
|
||||
* @since 7.6.0
|
||||
* @since 7.7.0
|
||||
*/
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Documented
|
||||
|
@ -34,10 +34,10 @@
|
||||
<configuration>
|
||||
<target>
|
||||
<ant antfile="${javacc.ant.wrapper}" target="alljavacc">
|
||||
<property name="plugin-classpath" refid="maven.plugin.classpath"/>
|
||||
<property name="no-jjtree" value="true" /> <!-- This is a CPD module -->
|
||||
<property name="lang-name" value="Cpp" />
|
||||
<property name="lang-id" value="cpp" />
|
||||
<property name="javacc.jar" value="${javacc.jar}" />
|
||||
</ant>
|
||||
</target>
|
||||
</configuration>
|
||||
|
@ -1889,13 +1889,13 @@ void RecordPattern():
|
||||
(Annotation())* ReferenceType() RecordStructurePattern()
|
||||
}
|
||||
|
||||
void RecordStructurePattern() #void:
|
||||
void RecordStructurePattern() #PatternList:
|
||||
{}
|
||||
{
|
||||
"(" [ ComponentPatternList() ] ")"
|
||||
}
|
||||
|
||||
void ComponentPatternList() #PatternList :
|
||||
void ComponentPatternList() #void :
|
||||
{}
|
||||
{
|
||||
ComponentPattern() ( "," ComponentPattern() )*
|
||||
|
@ -105,7 +105,7 @@
|
||||
<configuration>
|
||||
<target>
|
||||
<ant antfile="${javacc.ant.wrapper}" target="alljavacc">
|
||||
<property name="javacc.jar" value="${javacc.jar}" />
|
||||
<property name="plugin-classpath" refid="maven.plugin.classpath"/>
|
||||
<property name="lang-name" value="Java" />
|
||||
<property name="lang-id" value="java" />
|
||||
</ant>
|
||||
|
@ -5,9 +5,9 @@
|
||||
package net.sourceforge.pmd.lang.java.rule.bestpractices;
|
||||
|
||||
/**
|
||||
* @deprecated The rule was renamed {@link UnitTestsShouldIncludeAssertRule}
|
||||
* @deprecated The rule was renamed {@link UnitTestShouldIncludeAssertRule}
|
||||
*/
|
||||
@Deprecated
|
||||
public class JUnitTestsShouldIncludeAssertRule extends UnitTestsShouldIncludeAssertRule {
|
||||
public class JUnitTestsShouldIncludeAssertRule extends UnitTestShouldIncludeAssertRule {
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import net.sourceforge.pmd.lang.java.rule.internal.TestFrameworksUtil;
|
||||
import net.sourceforge.pmd.properties.PropertyDescriptor;
|
||||
import net.sourceforge.pmd.properties.PropertyFactory;
|
||||
|
||||
public class UnitTestsShouldIncludeAssertRule extends AbstractJavaRulechainRule {
|
||||
public class UnitTestShouldIncludeAssertRule extends AbstractJavaRulechainRule {
|
||||
|
||||
private static final PropertyDescriptor<Set<String>> EXTRA_ASSERT_METHOD_NAMES =
|
||||
PropertyFactory.stringProperty("extraAssertMethodNames")
|
||||
@ -24,7 +24,7 @@ public class UnitTestsShouldIncludeAssertRule extends AbstractJavaRulechainRule
|
||||
.emptyDefaultValue()
|
||||
.build();
|
||||
|
||||
public UnitTestsShouldIncludeAssertRule() {
|
||||
public UnitTestShouldIncludeAssertRule() {
|
||||
super(ASTMethodDeclaration.class);
|
||||
definePropertyDescriptor(EXTRA_ASSERT_METHOD_NAMES);
|
||||
}
|
@ -52,9 +52,9 @@ public class CouplingBetweenObjectsRule extends AbstractJavaRule {
|
||||
public Object visit(ASTCompilationUnit cu, Object data) {
|
||||
super.visit(cu, data);
|
||||
|
||||
if (couplingCount > getProperty(THRESHOLD_DESCRIPTOR)) {
|
||||
asCtx(data).addViolation(cu,
|
||||
"A value of " + couplingCount + " may denote a high amount of coupling within the class");
|
||||
Integer threshold = getProperty(THRESHOLD_DESCRIPTOR);
|
||||
if (couplingCount > threshold) {
|
||||
asCtx(data).addViolation(cu, couplingCount, threshold);
|
||||
}
|
||||
|
||||
couplingCount = 0;
|
||||
|
@ -108,6 +108,7 @@ public class CloseResourceRule extends AbstractJavaRule {
|
||||
.desc("Detect if 'close' (or other closeTargets) is called outside of a finally-block").defaultValue(false).build();
|
||||
|
||||
private static final InvocationMatcher OBJECTS_NON_NULL = InvocationMatcher.parse("java.util.Objects#nonNull(_)");
|
||||
private static final InvocationMatcher FILESYSTEMS_GET_DEFAULT = InvocationMatcher.parse("java.nio.file.FileSystems#getDefault()");
|
||||
|
||||
private final Set<String> types = new HashSet<>();
|
||||
private final Set<String> simpleTypes = new HashSet<>();
|
||||
@ -204,6 +205,7 @@ public class CloseResourceRule extends AbstractJavaRule {
|
||||
.filter(this::isVariableNotSpecifiedInTryWithResource)
|
||||
.filter(var -> isResourceTypeOrSubtype(var) || isNodeInstanceOfResourceType(getTypeOfVariable(var)))
|
||||
.filterNot(var -> var.isAnnotationPresent("lombok.Cleanup"))
|
||||
.filterNot(this::isDefaultFileSystem)
|
||||
.toList();
|
||||
|
||||
for (ASTVariableId var : vars) {
|
||||
@ -499,6 +501,12 @@ public class CloseResourceRule extends AbstractJavaRule {
|
||||
return tryStatement == null || !isVariableSpecifiedInTryWithResource(varId, tryStatement);
|
||||
}
|
||||
|
||||
private boolean isDefaultFileSystem(ASTVariableId varId) {
|
||||
@Nullable
|
||||
ASTExpression initializer = varId.getInitializer();
|
||||
return FILESYSTEMS_GET_DEFAULT.matchesCall(initializer);
|
||||
}
|
||||
|
||||
private boolean isVariableSpecifiedInTryWithResource(ASTVariableId varId, ASTTryStatement tryWithResource) {
|
||||
// skip own resources - these are definitively closed
|
||||
if (tryWithResource.getResources().descendants(ASTVariableId.class).toList().contains(varId)) {
|
||||
|
@ -748,7 +748,7 @@ class MyTest { // not public, that's fine
|
||||
|
||||
<rule name="JUnitTestContainsTooManyAsserts" deprecated="true" ref="UnitTestContainsTooManyAsserts"/>
|
||||
|
||||
<rule name="JUnitTestsShouldIncludeAssert" deprecated="true" ref="UnitTestsShouldIncludeAssert" />
|
||||
<rule name="JUnitTestsShouldIncludeAssert" deprecated="true" ref="UnitTestShouldIncludeAssert" />
|
||||
|
||||
<rule name="JUnitUseExpected"
|
||||
language="java"
|
||||
@ -1239,6 +1239,8 @@ Unit assertions should include an informative message - i.e., use the three-argu
|
||||
`assertEquals()`, not the two-argument version.
|
||||
|
||||
This rule supports tests using JUnit (3, 4 and 5) and TestNG.
|
||||
|
||||
Note: This rule was named JUnitAssertionsShouldIncludeMessage before PMD 7.7.0.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<example>
|
||||
@ -1268,6 +1270,8 @@ public class Foo {
|
||||
Customize the maximum number of assertions used by this Rule to suit your needs.
|
||||
|
||||
This rule checks for JUnit (3, 4 and 5) and TestNG Tests.
|
||||
|
||||
Note: This rule was named JUnitTestContainsTooManyAsserts before PMD 7.7.0.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<example>
|
||||
@ -1292,6 +1296,36 @@ public class MyTestCase {
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
<rule name="UnitTestShouldIncludeAssert"
|
||||
language="java"
|
||||
since="2.0"
|
||||
message="This unit test should include assert() or fail()"
|
||||
class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnitTestShouldIncludeAssertRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unittestshouldincludeassert">
|
||||
<description>
|
||||
Unit tests should include at least one assertion. This makes the tests more robust, and using assert
|
||||
with messages provide the developer a clearer idea of what the test does.
|
||||
|
||||
This rule checks for JUnit (3, 4 and 5) and TestNG Tests.
|
||||
|
||||
Note: This rule was named JUnitTestsShouldIncludeAssert before PMD 7.7.0.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<example>
|
||||
<![CDATA[
|
||||
public class Foo {
|
||||
@Test
|
||||
public void testSomething() {
|
||||
Bar b = findBar();
|
||||
// This is better than having a NullPointerException
|
||||
// assertNotNull("bar not found", b);
|
||||
b.work();
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
<rule name="UnitTestShouldUseAfterAnnotation"
|
||||
language="java"
|
||||
since="4.0"
|
||||
@ -1309,6 +1343,8 @@ as long as you are following this convention to name the methods.
|
||||
all tests in the class, respectively.
|
||||
* TestNG provides the annotations `@AfterMethod` and `@AfterClass` to execute methods after each test or after
|
||||
tests in the class, respectively.
|
||||
|
||||
Note: This rule was named JUnit4TestShouldUseAfterAnnotation before PMD 7.7.0.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
@ -1366,6 +1402,8 @@ as long as you are following this convention to name the methods.
|
||||
tests in the class, respectively.
|
||||
* TestNG provides the annotations `@BeforeMethod` and `@BeforeClass` to execute methods before each test or before
|
||||
tests in the class, respectively.
|
||||
|
||||
Note: This rule was named JUnit4TestShouldUseBeforeAnnotation before PMD 7.7.0.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
@ -1418,6 +1456,8 @@ public class MyTest2 {
|
||||
In JUnit 4, only methods annotated with the `@Test` annotation are executed.
|
||||
In JUnit 5, one of the following annotations should be used for tests: `@Test`, `@RepeatedTest`, `@TestFactory`, `@TestTemplate` or `@ParameterizedTest`.
|
||||
In TestNG, only methods annotated with the `@Test` annotation are executed.
|
||||
|
||||
Note: This rule was named JUnit4TestShouldUseTestAnnotation before PMD 7.7.0.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
@ -1461,34 +1501,6 @@ public class MyTest {
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
<rule name="UnitTestsShouldIncludeAssert"
|
||||
language="java"
|
||||
since="2.0"
|
||||
message="Unit tests should include assert() or fail()"
|
||||
class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnitTestsShouldIncludeAssertRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unittestsshouldincludeassert">
|
||||
<description>
|
||||
Unit tests should include at least one assertion. This makes the tests more robust, and using assert
|
||||
with messages provide the developer a clearer idea of what the test does.
|
||||
|
||||
This rule checks for JUnit (3, 4 and 5) and TestNG Tests.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<example>
|
||||
<![CDATA[
|
||||
public class Foo {
|
||||
@Test
|
||||
public void testSomething() {
|
||||
Bar b = findBar();
|
||||
// This is better than having a NullPointerException
|
||||
// assertNotNull("bar not found", b);
|
||||
b.work();
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
<rule name="UnnecessaryVarargsArrayCreation"
|
||||
language="java"
|
||||
since="7.1.0"
|
||||
|
@ -172,32 +172,33 @@ public class SomeJNIClass {
|
||||
<rule name="BooleanGetMethodName"
|
||||
language="java"
|
||||
since="4.0"
|
||||
message="A 'getX()' method which returns a boolean should be named 'isX()'"
|
||||
message="A 'getX()' method which returns a boolean or Boolean should be named 'isX()'"
|
||||
class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#booleangetmethodname">
|
||||
<description>
|
||||
Methods that return boolean results should be named as predicate statements to denote this.
|
||||
I.e, 'isReady()', 'hasValues()', 'canCommit()', 'willFail()', etc. Avoid the use of the 'get'
|
||||
prefix for these methods.
|
||||
Methods that return boolean or Boolean results should be named as predicate statements to denote this.
|
||||
I.e., 'isReady()', 'hasValues()', 'canCommit()', 'willFail()', etc. Avoid the use of the 'get' prefix for these methods.
|
||||
</description>
|
||||
<priority>4</priority>
|
||||
<properties>
|
||||
<property name="xpath">
|
||||
<value>
|
||||
<![CDATA[
|
||||
<![CDATA[
|
||||
//MethodDeclaration
|
||||
[starts-with(@Name, 'get')]
|
||||
[@Arity = 0 or $checkParameterizedMethods = true()]
|
||||
[ PrimitiveType[@Kind = 'boolean'] and @Overridden = false() ]
|
||||
[ (PrimitiveType[@Kind = 'boolean'] or ClassType[pmd-java:typeIs('java.lang.Boolean')]) and @Overridden = false() ]
|
||||
]]>
|
||||
</value>
|
||||
</property>
|
||||
<property name="checkParameterizedMethods" type="Boolean" description="Check parameterized methods" value="false"/>
|
||||
</properties>
|
||||
<example>
|
||||
<![CDATA[
|
||||
<![CDATA[
|
||||
public boolean getFoo(); // bad
|
||||
public Boolean getFoo(); // bad
|
||||
public boolean isFoo(); // ok
|
||||
public Boolean isFoo(); // ok
|
||||
public boolean getFoo(boolean bar); // ok, unless checkParameterizedMethods=true
|
||||
]]>
|
||||
</example>
|
||||
|
@ -377,7 +377,7 @@ class Foo {
|
||||
<rule name="CouplingBetweenObjects"
|
||||
language="java"
|
||||
since="1.04"
|
||||
message="High amount of different objects as members denotes a high coupling"
|
||||
message="A value of {0} may denote a high amount of coupling within the class (threshold: {1})"
|
||||
class="net.sourceforge.pmd.lang.java.rule.design.CouplingBetweenObjectsRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#couplingbetweenobjects">
|
||||
<description>
|
||||
|
@ -24,13 +24,7 @@
|
||||
<!-- <rule ref="category/java/bestpractices.xml/ForLoopVariableCount" /> -->
|
||||
<rule ref="category/java/bestpractices.xml/GuardLogStatement"/>
|
||||
<!-- <rule ref="category/java/bestpractices.xml/JUnit4SuitesShouldUseSuiteAnnotation" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/JUnit4TestShouldUseAfterAnnotation" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/JUnit4TestShouldUseBeforeAnnotation" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/JUnit4TestShouldUseTestAnnotation" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/JUnit5TestShouldBePackagePrivate" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/JUnitAssertionsShouldIncludeMessage" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/JUnitTestContainsTooManyAsserts" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/JUnitTestsShouldIncludeAssert" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/JUnitUseExpected" /> -->
|
||||
<rule ref="category/java/bestpractices.xml/LiteralsFirstInComparisons" />
|
||||
<rule ref="category/java/bestpractices.xml/LooseCoupling"/>
|
||||
@ -45,6 +39,12 @@
|
||||
<rule ref="category/java/bestpractices.xml/SimplifiableTestAssertion"/>
|
||||
<rule ref="category/java/bestpractices.xml/SwitchStmtsShouldHaveDefault"/>
|
||||
<!-- <rule ref="category/java/bestpractices.xml/SystemPrintln" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/UnitTestAssertionsShouldIncludeMessage" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/UnitTestContainsTooManyAsserts" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/UnitTestShouldIncludeAssert" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/UnitTestShouldUseAfterAnnotation" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/UnitTestShouldUseBeforeAnnotation" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/UnitTestShouldUseTestAnnotation" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/UnnecessaryVarargsArrayCreation" /> -->
|
||||
<!-- <rule ref="category/java/bestpractices.xml/UnusedAssignment"/> -->
|
||||
<rule ref="category/java/bestpractices.xml/UnusedFormalParameter"/>
|
||||
|
@ -6,6 +6,6 @@ package net.sourceforge.pmd.lang.java.rule.bestpractices;
|
||||
|
||||
import net.sourceforge.pmd.test.PmdRuleTst;
|
||||
|
||||
class UnitTestsShouldIncludeAssertTest extends PmdRuleTst {
|
||||
class UnitTestShouldIncludeAssertTest extends PmdRuleTst {
|
||||
// no additional unit tests
|
||||
}
|
@ -97,4 +97,14 @@ public class RecordPatterns {
|
||||
System.out.println("String " + s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
record Empty(){}
|
||||
void foo(Object o) {
|
||||
if (o instanceof Empty
|
||||
|| o instanceof Empty())
|
||||
System.out.println("Empty " + o);
|
||||
}
|
||||
|
||||
;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
+- CompilationUnit[@PackageName = ""]
|
||||
+- ClassDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "RecordPatterns", @CanonicalName = "RecordPatterns", @EffectiveVisibility = Visibility.V_PUBLIC, @Enum = false, @Final = false, @Interface = false, @Local = false, @Nested = false, @PackageName = "", @Record = false, @RegularClass = true, @RegularInterface = false, @SimpleName = "RecordPatterns", @Static = false, @TopLevel = true, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PUBLIC]
|
||||
+- ModifierList[@EffectiveModifiers = (JModifier.PUBLIC), @ExplicitModifiers = (JModifier.PUBLIC)]
|
||||
+- ClassBody[@Empty = false, @Size = 18]
|
||||
+- ClassBody[@Empty = false, @Size = 21]
|
||||
+- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "RecordPatterns$Point", @CanonicalName = "RecordPatterns.Point", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "Point", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE]
|
||||
| +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()]
|
||||
| +- RecordComponentList[@Empty = false, @Size = 2, @Varargs = false]
|
||||
@ -512,38 +512,73 @@
|
||||
| +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String ", @Empty = false, @Image = "\"String \"", @Length = 7, @LiteralText = "\"String \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
|
||||
| +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
+- MethodDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "test4", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true]
|
||||
+- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
|
||||
+- VoidType[]
|
||||
+- FormalParameters[@Empty = false, @Size = 1]
|
||||
| +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL]
|
||||
| +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
|
||||
| +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"]
|
||||
| | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1]
|
||||
| | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"]
|
||||
| | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1]
|
||||
| | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"]
|
||||
| +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "bo", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL]
|
||||
+- Block[@Empty = false, @Size = 1, @containsComment = false]
|
||||
+- IfStatement[@Else = false]
|
||||
+- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "bo", @Name = "bo", @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| +- RecordPattern[]
|
||||
| +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"]
|
||||
| +- PatternList[@Empty = false, @Size = 1]
|
||||
| +- RecordPattern[]
|
||||
| +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"]
|
||||
| +- PatternList[@Empty = false, @Size = 1]
|
||||
| +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE]
|
||||
| +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
|
||||
| +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL]
|
||||
+- Block[@Empty = false, @Size = 1, @containsComment = false]
|
||||
+- ExpressionStatement[]
|
||||
+- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
+- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"]
|
||||
+- ArgumentList[@Empty = false, @Size = 1]
|
||||
+- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
+- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String ", @Empty = false, @Image = "\"String \"", @Length = 7, @LiteralText = "\"String \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
|
||||
+- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
|
||||
| +- VoidType[]
|
||||
| +- FormalParameters[@Empty = false, @Size = 1]
|
||||
| | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL]
|
||||
| | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
|
||||
| | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"]
|
||||
| | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1]
|
||||
| | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"]
|
||||
| | | +- TypeArguments[@Diamond = false, @Empty = false, @Size = 1]
|
||||
| | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "String"]
|
||||
| | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "bo", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL]
|
||||
| +- Block[@Empty = false, @Size = 1, @containsComment = false]
|
||||
| +- IfStatement[@Else = false]
|
||||
| +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "bo", @Name = "bo", @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| | +- RecordPattern[]
|
||||
| | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"]
|
||||
| | +- PatternList[@Empty = false, @Size = 1]
|
||||
| | +- RecordPattern[]
|
||||
| | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Box"]
|
||||
| | +- PatternList[@Empty = false, @Size = 1]
|
||||
| | +- TypePattern[@EffectiveVisibility = Visibility.V_PACKAGE, @Visibility = Visibility.V_PACKAGE]
|
||||
| | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
|
||||
| | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = false, @LambdaParameter = false, @LocalVariable = false, @Name = "s", @PatternBinding = true, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = true, @Unnamed = false, @Visibility = Visibility.V_LOCAL]
|
||||
| +- Block[@Empty = false, @Size = 1, @containsComment = false]
|
||||
| +- ExpressionStatement[]
|
||||
| +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"]
|
||||
| +- ArgumentList[@Empty = false, @Size = 1]
|
||||
| +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "String ", @Empty = false, @Image = "\"String \"", @Length = 7, @LiteralText = "\"String \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
|
||||
| +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "s", @Name = "s", @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
+- RecordDeclaration[@Abstract = false, @Annotation = false, @Anonymous = false, @BinaryName = "RecordPatterns$Empty", @CanonicalName = "RecordPatterns.Empty", @EffectiveVisibility = Visibility.V_PACKAGE, @Enum = false, @Final = true, @Interface = false, @Local = false, @Nested = true, @PackageName = "", @Record = true, @RegularClass = false, @RegularInterface = false, @SimpleName = "Empty", @Static = true, @TopLevel = false, @UnnamedToplevelClass = false, @Visibility = Visibility.V_PACKAGE]
|
||||
| +- ModifierList[@EffectiveModifiers = (JModifier.STATIC, JModifier.FINAL), @ExplicitModifiers = ()]
|
||||
| +- RecordComponentList[@Empty = true, @Size = 0, @Varargs = false]
|
||||
| +- RecordBody[@Empty = true, @Size = 0]
|
||||
+- MethodDeclaration[@Abstract = false, @Arity = 1, @EffectiveVisibility = Visibility.V_PACKAGE, @Final = false, @Name = "foo", @Overridden = false, @Static = false, @Varargs = false, @Visibility = Visibility.V_PACKAGE, @Void = true]
|
||||
| +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
|
||||
| +- VoidType[]
|
||||
| +- FormalParameters[@Empty = false, @Size = 1]
|
||||
| | +- FormalParameter[@EffectiveVisibility = Visibility.V_LOCAL, @Final = false, @Varargs = false, @Visibility = Visibility.V_LOCAL]
|
||||
| | +- ModifierList[@EffectiveModifiers = (), @ExplicitModifiers = ()]
|
||||
| | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Object"]
|
||||
| | +- VariableId[@ArrayType = false, @EffectiveVisibility = Visibility.V_LOCAL, @EnumConstant = false, @ExceptionBlockParameter = false, @Field = false, @Final = false, @ForLoopVariable = false, @ForeachVariable = false, @FormalParameter = true, @LambdaParameter = false, @LocalVariable = false, @Name = "o", @PatternBinding = false, @RecordComponent = false, @ResourceDeclaration = false, @Static = false, @TypeInferred = false, @Unnamed = false, @Visibility = Visibility.V_LOCAL]
|
||||
| +- Block[@Empty = false, @Size = 1, @containsComment = false]
|
||||
| +- IfStatement[@Else = false]
|
||||
| +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.CONDITIONAL_OR, @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| | | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| | | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| | | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Empty"]
|
||||
| | +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.INSTANCEOF, @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| | +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| | +- PatternExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| | +- RecordPattern[]
|
||||
| | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "Empty"]
|
||||
| | +- PatternList[@Empty = true, @Size = 0]
|
||||
| +- ExpressionStatement[]
|
||||
| +- MethodCall[@CompileTimeConstant = false, @Image = "println", @MethodName = "println", @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| +- FieldAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "out", @Name = "out", @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| | +- TypeExpression[@CompileTimeConstant = false, @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| | +- ClassType[@FullyQualified = false, @PackageQualifier = null, @SimpleName = "System"]
|
||||
| +- ArgumentList[@Empty = false, @Size = 1]
|
||||
| +- InfixExpression[@CompileTimeConstant = false, @Operator = BinaryOp.ADD, @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
| +- StringLiteral[@CompileTimeConstant = true, @ConstValue = "Empty ", @Empty = false, @Image = "\"Empty \"", @Length = 6, @LiteralText = "\"Empty \"", @ParenthesisDepth = 0, @Parenthesized = false, @TextBlock = false]
|
||||
| +- VariableAccess[@AccessType = AccessType.READ, @CompileTimeConstant = false, @Image = "o", @Name = "o", @ParenthesisDepth = 0, @Parenthesized = false]
|
||||
+- EmptyDeclaration[]
|
||||
|
@ -34,6 +34,18 @@ public class Foo {
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Should not match for boxed Boolean on multiple parameters by default (#5253)</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public Boolean getEnabled(boolean thisIsNotABean) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Should not match on methods annotated with @Override</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
@ -60,4 +72,93 @@ public class Foo {
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Bad name with boxed Boolean (#5253)</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public Boolean getEnabled() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Good name with boxed Boolean (#5253)</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public Boolean isEnabled() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Should not match for boxed Boolean on methods annotated with @Override (#5253)</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo implements Toggleable {
|
||||
@Override
|
||||
public Boolean getEnabled() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
interface Toggleable {
|
||||
Boolean getEnabled(); // NOPMD
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Should match for boxed Boolean on multiple parameters when checkParameterizedMethods = true (#5253)</description>
|
||||
<rule-property name="checkParameterizedMethods">true</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public Boolean getEnabled(boolean thisIsNotABean);
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Should match for boxed Boolean on multiple parameters when checkParameterizedMethods = true (#5253)</description>
|
||||
<rule-property name="checkParameterizedMethods">true</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public Boolean getEnabled(boolean thisIsNotABean) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Custom Boolean type (#5253)</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
class Boolean { }
|
||||
public class Foo {
|
||||
public Boolean getEnabled() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Custom Boolean type with returning value (#5253)</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
class Boolean { }
|
||||
public class Foo {
|
||||
public Boolean getEnabled() { return false; }
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
</test-data>
|
||||
|
@ -9,6 +9,9 @@
|
||||
<rule-property name="threshold">2</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>1</expected-linenumbers>
|
||||
<expected-messages>
|
||||
<message>A value of 3 may denote a high amount of coupling within the class (threshold: 2)</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
import java.util.*;
|
||||
public class Foo {
|
||||
@ -51,6 +54,9 @@ public interface Foo {
|
||||
<rule-property name="threshold">2</rule-property>
|
||||
<expected-problems>1</expected-problems>
|
||||
<expected-linenumbers>1</expected-linenumbers>
|
||||
<expected-messages>
|
||||
<message>A value of 3 may denote a high amount of coupling within the class (threshold: 2)</message>
|
||||
</expected-messages>
|
||||
<code><![CDATA[
|
||||
import java.util.*;
|
||||
public interface Foo {
|
||||
|
@ -2044,6 +2044,20 @@ public class CastedParameter {
|
||||
// doesn't need to be closed, it's still a paramter…
|
||||
}
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
<test-code>
|
||||
<description>#5067: FileSystems.getDefault() can't be closed </description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
|
||||
public class DefaultFileSystemUsage {
|
||||
public void useDefaultFS() {
|
||||
FileSystem defaultFS = FileSystems.getDefault();
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
@ -47,10 +47,10 @@
|
||||
<configuration>
|
||||
<target>
|
||||
<ant antfile="${javacc.ant.wrapper}" target="alljavacc">
|
||||
<property name="plugin-classpath" refid="maven.plugin.classpath"/>
|
||||
<property name="no-jjtree" value="true" /> <!-- This is a CPD module -->
|
||||
<property name="lang-name" value="Ecmascript5" />
|
||||
<property name="lang-id" value="ecmascript5" />
|
||||
<property name="javacc.jar" value="${javacc.jar}" />
|
||||
</ant>
|
||||
</target>
|
||||
</configuration>
|
||||
|
@ -40,7 +40,7 @@
|
||||
<configuration>
|
||||
<target>
|
||||
<ant antfile="${javacc.ant.wrapper}" target="alljavacc">
|
||||
<property name="javacc.jar" value="${javacc.jar}" />
|
||||
<property name="plugin-classpath" refid="maven.plugin.classpath"/>
|
||||
<property name="lang-name" value="Jsp" />
|
||||
<property name="lang-id" value="jsp" />
|
||||
</ant>
|
||||
|
@ -34,10 +34,10 @@
|
||||
<configuration>
|
||||
<target>
|
||||
<ant antfile="${javacc.ant.wrapper}" target="alljavacc">
|
||||
<property name="plugin-classpath" refid="maven.plugin.classpath"/>
|
||||
<property name="no-jjtree" value="true" /> <!-- This is a CPD module -->
|
||||
<property name="lang-name" value="Matlab" />
|
||||
<property name="lang-id" value="matlab" />
|
||||
<property name="javacc.jar" value="${javacc.jar}" />
|
||||
</ant>
|
||||
</target>
|
||||
</configuration>
|
||||
|
@ -64,7 +64,7 @@
|
||||
<configuration>
|
||||
<target>
|
||||
<ant antfile="${javacc.ant.wrapper}" target="alljavacc">
|
||||
<property name="javacc.jar" value="${javacc.jar}" />
|
||||
<property name="plugin-classpath" refid="maven.plugin.classpath"/>
|
||||
<property name="lang-name" value="Modelica" />
|
||||
<property name="lang-id" value="modelica" />
|
||||
</ant>
|
||||
|
@ -34,10 +34,10 @@
|
||||
<configuration>
|
||||
<target>
|
||||
<ant antfile="${javacc.ant.wrapper}" target="alljavacc">
|
||||
<property name="plugin-classpath" refid="maven.plugin.classpath"/>
|
||||
<property name="no-jjtree" value="true" /> <!-- This is a CPD module -->
|
||||
<property name="lang-name" value="ObjectiveC" />
|
||||
<property name="lang-id" value="objectivec" />
|
||||
<property name="javacc.jar" value="${javacc.jar}" />
|
||||
</ant>
|
||||
</target>
|
||||
</configuration>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user