Merge branch 'master' into pmd/7.0.x

This commit is contained in:
Andreas Dangel
2020-07-30 11:51:53 +02:00
50 changed files with 359 additions and 117 deletions

View File

@ -120,6 +120,11 @@ Example:
</rule>
```
{% include note.html content="In PMD 7, the `language` attribute will be required on all `rule`
elements that declare a new rule. Some base rule classes set the language implicitly in their
constructor, and so this is not required in all cases for the rule to work. But this
behavior will be discontinued in PMD 7, so missing `language` attributes are
reported beginning with PMD 6.27.0 as a forward compatibility warning." %}
## Resource index

View File

@ -21,11 +21,26 @@ This is a {{ site.pmd.release_type }} release.
### Fixed Issues
* core
* [#724](https://github.com/pmd/pmd/issues/724): \[core] Avoid parsing rulesets multiple times
* [#2653](https://github.com/pmd/pmd/issues/2653): \[lang-test] Upgrade kotlintest to Kotest
* java-performance
* [#2441](https://github.com/pmd/pmd/issues/2441): \[java] RedundantFieldInitializer can not detect a special case for char initialize: `char foo = '\0';`
### API Changes
* XML rule definition in rulesets: In PMD 7, the `language` attribute will be required on all `rule`
elements that declare a new rule. Some base rule classes set the language implicitly in their
constructor, and so this is not required in all cases for the rule to work. But this
behavior will be discontinued in PMD 7, so missing `language` attributes are now
reported as a forward compatibility warning.
#### Deprecated API
##### For removal
* {% jdoc !!pmd-java::lang.java.ast.ASTThrowStatement#getFirstClassOrInterfaceTypeImage() %}
### External Contributions
* [#2677](https://github.com/pmd/pmd/pull/2677): \[java] RedundantFieldInitializer can not detect a special case for char initialize: `char foo = '\0';` - [Mykhailo Palahuta](https://github.com/Drofff)

View File

@ -10,6 +10,7 @@ Rules which enforce generally accepted best practices.
</description>
<rule name="ApexAssertionsShouldIncludeMessage"
language="apex"
since="6.13.0"
message="Apex test assert statement should make use of the message parameter."
class="net.sourceforge.pmd.lang.apex.rule.bestpractices.ApexAssertionsShouldIncludeMessageRule"
@ -37,6 +38,7 @@ public class Foo {
</rule>
<rule name="ApexUnitTestClassShouldHaveAsserts"
language="apex"
since="5.5.1"
message="Apex unit tests should System.assert() or assertEquals() or assertNotEquals()"
class="net.sourceforge.pmd.lang.apex.rule.bestpractices.ApexUnitTestClassShouldHaveAssertsRule"
@ -62,6 +64,7 @@ public class Foo {
</rule>
<rule name="ApexUnitTestMethodShouldHaveIsTestAnnotation"
language="apex"
since="6.13.0"
message="Apex test methods should have @isTest annotation."
class="net.sourceforge.pmd.lang.apex.rule.bestpractices.ApexUnitTestMethodShouldHaveIsTestAnnotationRule"
@ -94,6 +97,7 @@ private class ATest {
</rule>
<rule name="ApexUnitTestShouldNotUseSeeAllDataTrue"
language="apex"
since="5.5.1"
message="Apex unit tests should not use @isTest(seeAllData = true)"
class="net.sourceforge.pmd.lang.apex.rule.bestpractices.ApexUnitTestShouldNotUseSeeAllDataTrueRule"
@ -118,6 +122,7 @@ public class Foo {
</rule>
<rule name="AvoidGlobalModifier"
language="apex"
since="5.5.0"
message="Avoid using global modifier"
class="net.sourceforge.pmd.lang.apex.rule.bestpractices.AvoidGlobalModifierRule"
@ -139,6 +144,7 @@ global class Unchangeable {
</rule>
<rule name="AvoidLogicInTrigger"
language="apex"
since="5.5.0"
message="Avoid logic in triggers"
class="net.sourceforge.pmd.lang.apex.rule.bestpractices.AvoidLogicInTriggerRule"

View File

@ -10,6 +10,7 @@ Rules which enforce a specific coding style.
</description>
<rule name="ClassNamingConventions"
language="apex"
since="5.5.0"
message="The {0} name ''{1}'' doesn''t match ''{2}''"
class="net.sourceforge.pmd.lang.apex.rule.codestyle.ClassNamingConventionsRule"
@ -129,6 +130,7 @@ class Foo {
</rule>
<rule name="FieldNamingConventions"
language="apex"
since="6.15.0"
message="The {0} name ''{1}'' doesn''t match ''{2}''"
class="net.sourceforge.pmd.lang.apex.rule.codestyle.FieldNamingConventionsRule"
@ -189,6 +191,7 @@ for (int i = 0; i < 42; i++) { // preferred approach
</rule>
<rule name="FormalParameterNamingConventions"
language="apex"
since="6.15.0"
message="The {0} name ''{1}'' doesn''t match ''{2}''"
class="net.sourceforge.pmd.lang.apex.rule.codestyle.FormalParameterNamingConventionsRule"
@ -214,6 +217,7 @@ public class Foo {
</rule>
<rule name="LocalVariableNamingConventions"
language="apex"
since="6.15.0"
message="The {0} name ''{1}'' doesn''t match ''{2}''"
class="net.sourceforge.pmd.lang.apex.rule.codestyle.LocalVariableNamingConventionsRule"
@ -241,6 +245,7 @@ public class Foo {
</rule>
<rule name="MethodNamingConventions"
language="apex"
since="5.5.0"
message="The {0} name ''{1}'' doesn''t match ''{2}''"
class="net.sourceforge.pmd.lang.apex.rule.codestyle.MethodNamingConventionsRule"
@ -265,6 +270,7 @@ public class Foo {
</rule>
<rule name="OneDeclarationPerLine"
language="apex"
since="6.7.0"
message="Use one statement for each line, it enhances code readability."
class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule"
@ -307,6 +313,7 @@ Integer b;
</rule>
<rule name="PropertyNamingConventions"
language="apex"
since="6.15.0"
message="The {0} name ''{1}'' doesn''t match ''{2}''"
class="net.sourceforge.pmd.lang.apex.rule.codestyle.PropertyNamingConventionsRule"
@ -331,7 +338,6 @@ public class Foo {
</example>
</rule>
<rule name="WhileLoopsMustUseBraces"
language="apex"
since="5.6.0"

View File

@ -10,6 +10,7 @@ Rules that help you discover design issues.
</description>
<rule name="AvoidDeeplyNestedIfStmts"
language="apex"
since="5.5.0"
message="Deeply nested if..then statements are hard to read"
class="net.sourceforge.pmd.lang.apex.rule.design.AvoidDeeplyNestedIfStmtsRule"
@ -36,6 +37,7 @@ public class Foo {
</rule>
<rule name="CyclomaticComplexity"
language="apex"
message="The {0} ''{1}'' has a{2} cyclomatic complexity of {3}."
since="6.0.0"
class="net.sourceforge.pmd.lang.apex.rule.design.CyclomaticComplexityRule"
@ -87,6 +89,7 @@ public class Complicated {
</rule>
<rule name="CognitiveComplexity"
language="apex"
message="The {0} ''{1}'' has a{2} cognitive complexity of {3}."
since="6.22.0"
class="net.sourceforge.pmd.lang.apex.rule.design.CognitiveComplexityRule"
@ -149,6 +152,7 @@ public class Foo {
</rule>
<rule name="ExcessiveClassLength"
language="apex"
since="5.5.0"
message="Avoid really long classes."
class="net.sourceforge.pmd.lang.apex.rule.design.ExcessiveClassLengthRule"
@ -180,6 +184,7 @@ public class Foo {
</rule>
<rule name="ExcessiveParameterList"
language="apex"
since="5.5.0"
message="Avoid long parameter lists."
class="net.sourceforge.pmd.lang.apex.rule.design.ExcessiveParameterListRule"
@ -204,6 +209,7 @@ public void addPerson(Date birthdate, BodyMeasurements measurements, int ssn) {
</rule>
<rule name="ExcessivePublicCount"
language="apex"
since="5.5.0"
message="This class has a bunch of public methods and attributes"
class="net.sourceforge.pmd.lang.apex.rule.design.ExcessivePublicCountRule"
@ -233,6 +239,7 @@ public class Foo {
</rule>
<rule name="NcssConstructorCount"
language="apex"
since="5.5.0"
message="The constructor has an NCSS line count of {0}"
class="net.sourceforge.pmd.lang.apex.rule.design.NcssConstructorCountRule"
@ -261,6 +268,7 @@ public class Foo extends Bar {
</rule>
<rule name="NcssMethodCount"
language="apex"
since="5.5.0"
message="The method ''{0}()'' has an NCSS line count of {1}"
class="net.sourceforge.pmd.lang.apex.rule.design.NcssMethodCountRule"
@ -288,6 +296,7 @@ public class Foo extends Bar {
</rule>
<rule name="NcssTypeCount"
language="apex"
since="5.5.0"
message="The type has an NCSS line count of {0}"
class="net.sourceforge.pmd.lang.apex.rule.design.NcssTypeCountRule"
@ -317,6 +326,7 @@ public class Foo extends Bar {
</rule>
<rule name="StdCyclomaticComplexity"
language="apex"
since="5.5.0"
message="The {0} ''{1}'' has a Standard Cyclomatic Complexity of {2}."
class="net.sourceforge.pmd.lang.apex.rule.design.StdCyclomaticComplexityRule"
@ -371,6 +381,7 @@ public class Foo {
</rule>
<rule name="TooManyFields"
language="apex"
since="5.5.0"
message="Too many fields"
class="net.sourceforge.pmd.lang.apex.rule.design.TooManyFieldsRule"

View File

@ -10,6 +10,7 @@ Rules that are related to code documentation.
</description>
<rule name="ApexDoc"
language="apex"
since="6.8.0"
message="ApexDoc comment is missing or incorrect"
class="net.sourceforge.pmd.lang.apex.rule.documentation.ApexDocRule"

View File

@ -10,6 +10,7 @@ Rules to detect constructs that are either broken, extremely confusing or prone
</description>
<rule name="ApexCSRF"
language="apex"
since="5.5.3"
message="Avoid making DML operations in Apex class constructor or initializers"
class="net.sourceforge.pmd.lang.apex.rule.errorprone.ApexCSRFRule"
@ -50,6 +51,7 @@ public class Foo {
</rule>
<rule name="AvoidDirectAccessTriggerMap"
language="apex"
since="6.0.0"
message="Avoid directly accessing Trigger.old and Trigger.new"
class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule"
@ -82,6 +84,7 @@ trigger AccountTrigger on Account (before insert, before update) {
</rule>
<rule name="AvoidHardcodingId"
language="apex"
since="6.0.0"
message="Hardcoding Id's is bound to break when changing environments."
class="net.sourceforge.pmd.lang.apex.rule.errorprone.AvoidHardcodingIdRule"
@ -293,6 +296,7 @@ public void bar(Integer a, Integer b) {
</rule>
<rule name="MethodWithSameNameAsEnclosingClass"
language="apex"
since="5.5.0"
message="Classes should not have non-constructor methods with the same name as the class"
class="net.sourceforge.pmd.lang.apex.rule.errorprone.MethodWithSameNameAsEnclosingClassRule"
@ -314,6 +318,7 @@ public class MyClass {
</rule>
<rule name="AvoidNonExistentAnnotations"
language="apex"
since="6.5.0"
message="Use of non existent annotations will lead to broken Apex code which will not compile in the future."
class="net.sourceforge.pmd.lang.apex.rule.errorprone.AvoidNonExistentAnnotationsRule"
@ -336,6 +341,7 @@ public class MyClass {
</rule>
<rule name="TestMethodsMustBeInTestClasses"
language="apex"
since="6.22.0"
message="Test methods must be in test classes"
class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule"

View File

@ -10,6 +10,7 @@ Rules that flag suboptimal code.
</description>
<rule name="AvoidDmlStatementsInLoops"
language="apex"
since="5.5.0"
message="Avoid DML statements inside loops"
class="net.sourceforge.pmd.lang.apex.rule.performance.AvoidDmlStatementsInLoopsRule"
@ -34,6 +35,7 @@ public class Something {
</rule>
<rule name="AvoidSoqlInLoops"
language="apex"
since="5.5.0"
message="Avoid Soql queries inside loops"
class="net.sourceforge.pmd.lang.apex.rule.performance.AvoidSoqlInLoopsRule"
@ -56,6 +58,7 @@ public class Something {
</rule>
<rule name="AvoidSoslInLoops"
language="apex"
since="6.0.0"
message="Avoid Sosl queries inside loops"
class="net.sourceforge.pmd.lang.apex.rule.performance.AvoidSoslInLoopsRule"

View File

@ -10,6 +10,7 @@ Rules that flag potential security flaws.
</description>
<rule name="ApexBadCrypto"
language="apex"
since="5.5.3"
message="Apex classes should use random IV/key"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexBadCryptoRule"
@ -32,6 +33,7 @@ public without sharing class Foo {
</rule>
<rule name="ApexCRUDViolation"
language="apex"
since="5.5.3"
message="Validate CRUD permission before SOQL/DML operation"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexCRUDViolationRule"
@ -65,6 +67,7 @@ public class Foo {
<rule name="ApexCSRF" ref="category/apex/errorprone.xml/ApexCSRF" deprecated="true"/>
<rule name="ApexDangerousMethods"
language="apex"
since="5.5.3"
message="Calling potentially dangerous method"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexDangerousMethodsRule"
@ -92,6 +95,7 @@ public class Foo {
</rule>
<rule name="ApexInsecureEndpoint"
language="apex"
since="5.5.3"
message="Apex callouts should use encrypted communication channels"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexInsecureEndpointRule"
@ -114,6 +118,7 @@ public without sharing class Foo {
</rule>
<rule name="ApexOpenRedirect"
language="apex"
since="5.5.3"
message="Apex classes should safely redirect to a known location"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexOpenRedirectRule"
@ -136,6 +141,7 @@ public without sharing class Foo {
</rule>
<rule name="ApexSharingViolations"
language="apex"
since="5.5.3"
message="Apex classes should declare a sharing model if DML or SOQL/SOSL is used"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexSharingViolationsRule"
@ -155,6 +161,7 @@ public without sharing class Foo {
</rule>
<rule name="ApexSOQLInjection"
language="apex"
since="5.5.3"
message="Avoid untrusted/unescaped variables in DML query"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexSOQLInjectionRule"
@ -175,6 +182,7 @@ public class Foo {
</rule>
<rule name="ApexSuggestUsingNamedCred"
language="apex"
since="5.5.3"
message="Suggest named credentials for authentication"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexSuggestUsingNamedCredRule"
@ -209,6 +217,7 @@ public class Foo {
</rule>
<rule name="ApexXSSFromEscapeFalse"
language="apex"
since="5.5.3"
message="Apex classes should escape Strings in error messages"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexXSSFromEscapeFalseRule"
@ -229,6 +238,7 @@ public without sharing class Foo {
</rule>
<rule name="ApexXSSFromURLParam"
language="apex"
since="5.5.3"
message="Apex classes should escape/sanitize Strings obtained from URL parameters"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexXSSFromURLParamRule"

View File

@ -10,16 +10,19 @@
</description>
<rule name="CycloTest"
language="apex"
message = "''{0}'' has value {1}."
class="net.sourceforge.pmd.lang.apex.metrics.impl.CycloTestRule">
</rule>
<rule name="WmcTest"
language="apex"
message = "''{0}'' has value {1}."
class="net.sourceforge.pmd.lang.apex.metrics.impl.WmcTestRule">
</rule>
<rule name="CognitiveComplexityTest"
language="apex"
message = "''{0}'' has value {1}."
class="net.sourceforge.pmd.lang.apex.metrics.impl.CognitiveComplexityTestRule">
</rule>

View File

@ -8,9 +8,11 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Level;
@ -60,6 +62,8 @@ public class RuleSetFactory {
private final boolean warnDeprecated;
private final RuleSetFactoryCompatibility compatibilityFilter;
private final Map<RuleSetReferenceId, RuleSet> parsedRulesets = new HashMap<>();
/**
* @deprecated Use {@link RulesetsFactoryUtils#defaultFactory()}
*/
@ -338,10 +342,16 @@ public class RuleSetFactory {
private Rule createRule(RuleSetReferenceId ruleSetReferenceId, boolean withDeprecatedRuleReferences)
throws RuleSetNotFoundException {
if (ruleSetReferenceId.isAllRules()) {
throw new IllegalArgumentException(
"Cannot parse a single Rule from an all Rule RuleSet reference: <" + ruleSetReferenceId + ">.");
throw new IllegalArgumentException("Cannot parse a single Rule from an all Rule RuleSet reference: <" + ruleSetReferenceId + ">.");
}
RuleSet ruleSet;
// java8: computeIfAbsent
if (parsedRulesets.containsKey(ruleSetReferenceId)) {
ruleSet = parsedRulesets.get(ruleSetReferenceId);
} else {
ruleSet = createRuleSet(ruleSetReferenceId, withDeprecatedRuleReferences);
parsedRulesets.put(ruleSetReferenceId, ruleSet);
}
RuleSet ruleSet = createRuleSet(ruleSetReferenceId, withDeprecatedRuleReferences);
return ruleSet.getRuleByName(ruleSetReferenceId.getRuleName());
}
@ -610,12 +620,18 @@ public class RuleSetFactory {
// Stop if we're looking for a particular Rule, and this element is not
// it.
if (StringUtils.isNotBlank(ruleSetReferenceId.getRuleName())
&& !isRuleName(ruleElement, ruleSetReferenceId.getRuleName())) {
&& !isRuleName(ruleElement, ruleSetReferenceId.getRuleName())) {
return;
}
Rule rule = new RuleFactory(resourceLoader).buildRule(ruleElement);
rule.setRuleSetName(ruleSetBuilder.getName());
if (StringUtils.isBlank(ruleElement.getAttribute("language"))) {
LOG.warning("Rule " + ruleSetReferenceId.getRuleSetFileName() + "/" + rule.getName() + " does not mention attribute"
+ " language='" + rule.getLanguage().getTerseName() + "',"
+ " please mention it explicitly to be compatible with PMD 7");
}
ruleSetBuilder.addRule(rule);
}

View File

@ -152,9 +152,9 @@ public class RuleFactory {
String name = ruleElement.getAttribute(NAME);
RuleBuilder builder = new RuleBuilder(name,
resourceLoader,
ruleElement.getAttribute(CLASS),
ruleElement.getAttribute("language"));
resourceLoader,
ruleElement.getAttribute(CLASS),
ruleElement.getAttribute("language"));
if (ruleElement.hasAttribute(MINIMUM_LANGUAGE_VERSION)) {
builder.minimumLanguageVersion(ruleElement.getAttribute(MINIMUM_LANGUAGE_VERSION));

View File

@ -979,6 +979,7 @@ public class RuleSetFactoryTest {
+ " <description>testdesc</description>\n"
+ "<rule \n"
+ "\n"
+ "language=\"dummy\" \n"
+ "name=\"MockRuleName\" \n"
+ "message=\"avoid the mock rule\" \n"
+ "class=\"net.sourceforge.pmd.lang.rule.MockRule\">\n"
@ -991,6 +992,7 @@ public class RuleSetFactoryTest {
+ " <description>testdesc</description>\n"
+ "<rule \n"
+ "\n"
+ "language=\"dummy\" \n"
+ "name=\"MockRuleName\" \n"
+ "message=\"avoid the mock rule\" \n"
+ "class=\"net.sourceforge.pmd.lang.rule.MockRule\">\n"
@ -1028,6 +1030,7 @@ public class RuleSetFactoryTest {
+ "<ruleset name=\"test\">\n"
+ "<description>testdesc</description>\n"
+ "<rule \n"
+ "language=\"dummy\" \n"
+ "name=\"MockRuleName\" \n"
+ "message=\"avoid the mock rule\" \n"
+ "class=\"net.sourceforge.pmd.lang.rule.MockRule\">\n"
@ -1039,11 +1042,13 @@ public class RuleSetFactoryTest {
+ "\n"
+ "<description>testdesc</description>\n"
+ "<rule name=\"MockRuleName1\" \n"
+ "language=\"dummy\" \n"
+ "message=\"avoid the mock rule\" \n"
+ "class=\"net.sourceforge.pmd.lang.rule.MockRule\">\n"
+ "\n"
+ "</rule>\n"
+ "<rule name=\"MockRuleName2\" \n"
+ "language=\"dummy\" \n"
+ "message=\"avoid the mock rule\" \n"
+ "class=\"net.sourceforge.pmd.lang.rule.MockRule\">\n"
+ "\n"
@ -1053,6 +1058,7 @@ public class RuleSetFactoryTest {
+ "<ruleset name=\"test\">\n"
+ "<description>testdesc</description>\n"
+ "<rule name=\"MockRuleName\" \n"
+ "language=\"dummy\" \n"
+ "message=\"avoid the mock rule\" \n"
+ "class=\"net.sourceforge.pmd.lang.rule.MockRule\">\n"
+ "\n"
@ -1074,6 +1080,7 @@ public class RuleSetFactoryTest {
+ "<ruleset name=\"test\">\n"
+ "<description>testdesc</description>\n"
+ "<rule name=\"MockRuleName\" \n"
+ "language=\"dummy\" \n"
+ "message=\"avoid the mock rule\" \n"
+ "class=\"net.sourceforge.pmd.lang.rule.MockRule\">\n"
+ "<priority>3</priority>\n"
@ -1092,6 +1099,7 @@ public class RuleSetFactoryTest {
+ "<ruleset name=\"test\">\n"
+ "<description>testdesc</description>\n"
+ "<rule \n"
+ "language=\"dummy\" \n"
+ "name=\"MockRuleName\" \n"
+ "message=\"avoid the mock rule\" \n"
+ "class=\"net.sourceforge.pmd.lang.rule.MockRule\">\n"
@ -1104,7 +1112,8 @@ public class RuleSetFactoryTest {
+ "<rule \n"
+ "name=\"MockRuleName\" \n"
+ "message=\"avoid the mock rule\" \n"
+ "class=\"net.sourceforge.pmd.lang.rule.MockRule\" language=\"dummy\">\n"
+ "class=\"net.sourceforge.pmd.lang.rule.MockRule\" "
+ "language=\"dummy\">\n"
+ "</rule></ruleset>";
private static final String INCORRECT_LANGUAGE = "<?xml version=\"1.0\"?>\n"
@ -1180,8 +1189,8 @@ public class RuleSetFactoryTest {
+ "\n"
+ "<description>testdesc</description>\n"
+ "<rule \n"
+ "language=\"dummy\" \n"
+ "name=\"MockRuleName\" \n"
+ "\n"
+ "message=\"avoid the mock rule\" \n"
+ "class=\"net.sourceforge.pmd.lang.rule.MockRule\" deprecated=\"true\">\n"
+ "</rule></ruleset>";
@ -1210,6 +1219,7 @@ public class RuleSetFactoryTest {
+ "<ruleset name=\"test\">\n"
+ "<description>testdesc</description>\n"
+ "<rule \n"
+ "language=\"dummy\" \n"
+ "name=\"MockRuleName\" \n"
+ "message=\"avoid the mock rule\" \n"
+ "dfa=\"true\" \n"

View File

@ -173,13 +173,14 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.kotlintest</groupId>
<artifactId>kotlintest-assertions</artifactId>
<groupId>io.kotest</groupId>
<artifactId>kotest-assertions-core-jvm</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.kotlintest</groupId>
<artifactId>kotlintest-core</artifactId>
<!-- Contains stuff like FunSpec, etc -->
<groupId>io.kotest</groupId>
<artifactId>kotest-runner-junit5-jvm</artifactId>
<scope>test</scope>
</dependency>
<dependency>
@ -194,7 +195,7 @@
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<artifactId>kotlin-test-junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>

View File

@ -33,7 +33,10 @@ public class ASTThrowStatement extends AbstractJavaNode {
*
* @return the image of the first ASTClassOrInterfaceType node found or
* <code>null</code>
* @deprecated This method is too specific and doesn't support all cases.
* It will be removed with PMD 7.
*/
@Deprecated
public final String getFirstClassOrInterfaceTypeImage() {
final ASTClassOrInterfaceType t = getFirstDescendantOfType(ASTClassOrInterfaceType.class);
return t == null ? null : t.getImage();

View File

@ -6,6 +6,8 @@ package net.sourceforge.pmd.lang.java.rule.design;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import net.sourceforge.pmd.lang.java.ast.ASTCatchStatement;
import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
@ -35,8 +37,7 @@ public class ExceptionAsFlowControlRule extends AbstractJavaRule {
ASTFormalParameter fp = (ASTFormalParameter) catchStmt.getChild(0);
ASTType type = fp.getFirstDescendantOfType(ASTType.class);
ASTClassOrInterfaceType name = type.getFirstDescendantOfType(ASTClassOrInterfaceType.class);
if (node.getFirstClassOrInterfaceTypeImage() != null
&& node.getFirstClassOrInterfaceTypeImage().equals(name.getImage())) {
if (isExceptionOfTypeThrown(node, name.getImage())) {
addViolation(data, name);
}
}
@ -44,4 +45,9 @@ public class ExceptionAsFlowControlRule extends AbstractJavaRule {
return data;
}
private boolean isExceptionOfTypeThrown(ASTThrowStatement throwStatement, String typeName) {
final ASTClassOrInterfaceType t = throwStatement.getFirstDescendantOfType(ASTClassOrInterfaceType.class);
String thrownTypeName = t == null ? null : t.getImage();
return StringUtils.equals(thrownTypeName, typeName);
}
}

View File

@ -35,6 +35,7 @@ public abstract class Foo {
</rule>
<rule name="AccessorClassGeneration"
language="java"
since="1.04"
maximumLanguageVersion="10"
message="Avoid instantiation through private constructors from outside of the constructor's class."
@ -96,6 +97,7 @@ public class OuterClass {
</rule>
<rule name="ArrayIsStoredDirectly"
language="java"
since="2.2"
message="The user-supplied array ''{0}'' is stored directly."
class="net.sourceforge.pmd.lang.java.rule.bestpractices.ArrayIsStoredDirectlyRule"
@ -209,6 +211,7 @@ class Foo {
</rule>
<rule name="AvoidReassigningLoopVariables"
language="java"
since="6.11.0"
message="Avoid reassigning the loop control variable ''{0}''"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.AvoidReassigningLoopVariablesRule"
@ -257,6 +260,7 @@ public class Foo {
</rule>
<rule name="AvoidReassigningParameters"
language="java"
since="1.0"
message="Avoid reassigning parameters such as ''{0}''"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.AvoidReassigningParametersRule"
@ -307,6 +311,7 @@ public class Foo {
</rule>
<rule name="AvoidUsingHardCodedIP"
language="java"
since="4.1"
message="Do not hard code the IP address ${variableName}"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.AvoidUsingHardCodedIPRule"
@ -745,6 +750,7 @@ public class MyTest {
</rule>
<rule name="JUnitAssertionsShouldIncludeMessage"
language="java"
since="1.04"
message="JUnit assertions should include a message"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.JUnitAssertionsShouldIncludeMessageRule"
@ -824,6 +830,7 @@ public class MyTestCase extends TestCase {
</rule>
<rule name="JUnitTestsShouldIncludeAssert"
language="java"
since="2.0"
message="JUnit tests should include assert() or fail()"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.JUnitTestsShouldIncludeAssertRule"
@ -848,6 +855,7 @@ public class Foo extends TestCase {
</rule>
<rule name="JUnitUseExpected"
language="java"
since="4.0"
message="In JUnit4, use the @Test(expected) annotation to denote tests that should throw exceptions"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.JUnitUseExpectedRule"
@ -913,6 +921,7 @@ class Foo {
</rule>
<rule name="LooseCoupling"
language="java"
since="0.7"
message="Avoid using implementation types like ''{0}''; use the interface instead"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.LooseCouplingRule"
@ -948,6 +957,7 @@ public class Bar {
</rule>
<rule name="MethodReturnsInternalArray"
language="java"
since="2.2"
message="Returning ''{0}'' may expose an internal array."
class="net.sourceforge.pmd.lang.java.rule.bestpractices.MethodReturnsInternalArrayRule"
@ -972,6 +982,7 @@ public class SecureSystem {
<rule name="MissingOverride"
language="java"
since="6.2.0"
minimumLanguageVersion="1.5"
message="The method ''{0}'' is missing an @Override annotation."
@ -1090,6 +1101,7 @@ class Foo {
</rule>
<rule name="PreserveStackTrace"
language="java"
since="3.7"
message="New exception is thrown in catch block, original stack trace may be lost"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.PreserveStackTraceRule"
@ -1428,6 +1440,7 @@ public class Foo {
</rule>
<rule name="UnusedImports"
language="java"
since="1.0"
message="Avoid unused imports such as ''{0}''"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnusedImportsRule"
@ -1712,6 +1725,7 @@ public class MyTestCase extends TestCase {
</rule>
<rule name="UseCollectionIsEmpty"
language="java"
since="3.9"
message="Substitute calls to size() == 0 (or size() != 0, size() &gt; 0, size() &lt; 1) with calls to isEmpty()"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.UseCollectionIsEmptyRule"

View File

@ -34,6 +34,7 @@ public class Foo {
</rule>
<rule name="AvoidDollarSigns"
language="java"
since="1.5"
message="Avoid using dollar signs in variable/method/class/interface names"
class="net.sourceforge.pmd.lang.java.rule.codestyle.AvoidDollarSignsRule"
@ -235,6 +236,7 @@ public class Foo extends Bar{
</rule>
<rule name="ClassNamingConventions"
language="java"
since="1.2"
message="The {0} name ''{1}'' doesn''t match ''{2}''"
class="net.sourceforge.pmd.lang.java.rule.codestyle.ClassNamingConventionsRule"
@ -268,6 +270,7 @@ public class Éléphant {}
</rule>
<rule name="CommentDefaultAccessModifier"
language="java"
since="5.4.0"
class="net.sourceforge.pmd.lang.java.rule.codestyle.CommentDefaultAccessModifierRule"
message="Missing commented default access modifier"
@ -307,6 +310,7 @@ public class Foo {
</rule>
<rule name="ConfusingTernary"
language="java"
since="1.9"
message="Avoid if (x != y) ..; else ..;"
class="net.sourceforge.pmd.lang.java.rule.codestyle.ConfusingTernaryRule"
@ -435,6 +439,7 @@ or MethodDeclaration[@PackagePrivate= true()]
</rule>
<rule name="DontImportJavaLang"
language="java"
since="0.5"
message="Avoid importing anything from the package 'java.lang'"
class="net.sourceforge.pmd.lang.java.rule.codestyle.DontImportJavaLangRule"
@ -459,6 +464,7 @@ public class Foo {}
</rule>
<rule name="DuplicateImports"
language="java"
since="0.5"
message="Avoid duplicate imports such as ''{0}''"
class="net.sourceforge.pmd.lang.java.rule.codestyle.DuplicateImportsRule"
@ -582,6 +588,7 @@ public class HelloWorldBean {
<rule name="FieldNamingConventions"
language="java"
since="6.7.0"
message="The {0} name ''{1}'' doesn''t match ''{2}''"
class="net.sourceforge.pmd.lang.java.rule.codestyle.FieldNamingConventionsRule"
@ -653,6 +660,7 @@ public class Foo {
</rule>
<rule name="FormalParameterNamingConventions"
language="java"
since="6.6.0"
message="The {0} name ''{1}'' doesn''t match ''{2}''"
class="net.sourceforge.pmd.lang.java.rule.codestyle.FormalParameterNamingConventionsRule"
@ -911,6 +919,7 @@ public interface MissingProperSuffix extends javax.ejb.EJBLocalObject {} // n
</rule>
<rule name="LocalVariableCouldBeFinal"
language="java"
since="2.2"
message="Local variable ''{0}'' could be declared final"
class="net.sourceforge.pmd.lang.java.rule.codestyle.LocalVariableCouldBeFinalRule"
@ -932,6 +941,7 @@ public class Bar {
</rule>
<rule name="LocalVariableNamingConventions"
language="java"
since="6.6.0"
message="The {0} name ''{1}'' doesn''t match ''{2}''"
class="net.sourceforge.pmd.lang.java.rule.codestyle.LocalVariableNamingConventionsRule"
@ -1044,6 +1054,7 @@ public class MissingTheProperSuffix implements SessionBean {} // non-standard
</rule>
<rule name="MethodArgumentCouldBeFinal"
language="java"
since="2.2"
message="Parameter ''{0}'' is not assigned and could be declared final"
class="net.sourceforge.pmd.lang.java.rule.codestyle.MethodArgumentCouldBeFinalRule"
@ -1066,6 +1077,7 @@ public void foo2 (final String param) { // better, do stuff with param never ass
</rule>
<rule name="MethodNamingConventions"
language="java"
since="1.2"
message="The {0} name ''{1}'' doesn''t match ''{2}''"
class="net.sourceforge.pmd.lang.java.rule.codestyle.MethodNamingConventionsRule"
@ -1173,6 +1185,7 @@ public class Foo {
</rule>
<rule name="OnlyOneReturn"
language="java"
since="1.0"
message="A method should have only one exit point, and that should be the last statement in the method"
class="net.sourceforge.pmd.lang.java.rule.codestyle.OnlyOneReturnRule"
@ -1480,6 +1493,7 @@ import static Yoko; // Too much !
<rule name="UnnecessaryAnnotationValueElement"
language="java"
since="6.2.0"
message="Avoid the use of value in annotations when it's the only element"
class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryAnnotationValueElementRule"
@ -1592,6 +1606,7 @@ public class Foo {
</rule>
<rule name="UnnecessaryLocalBeforeReturn"
language="java"
since="3.3"
message="Consider simply returning the value vs storing it in local variable ''{0}''"
class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryLocalBeforeReturnRule"
@ -1651,6 +1666,7 @@ public class Bar {
</rule>
<rule name="UnnecessaryReturn"
language="java"
since="1.3"
message="Avoid unnecessary return statements"
class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryReturnRule"

View File

@ -91,6 +91,7 @@ public class PrimitiveType {
</rule>
<rule name="AvoidDeeplyNestedIfStmts"
language="java"
since="1.0"
message="Deeply nested if..then statements are hard to read"
class="net.sourceforge.pmd.lang.java.rule.design.AvoidDeeplyNestedIfStmtsRule"
@ -397,6 +398,7 @@ void bar() {
</rule>
<rule name="CouplingBetweenObjects"
language="java"
since="1.04"
message="High amount of different objects as members denotes a high coupling"
class="net.sourceforge.pmd.lang.java.rule.design.CouplingBetweenObjectsRule"
@ -429,6 +431,7 @@ public class Foo {
</rule>
<rule name="CyclomaticComplexity"
language="java"
message="The {0} ''{1}'' has a{2} cyclomatic complexity of {3}."
since="1.03"
class="net.sourceforge.pmd.lang.java.rule.design.CyclomaticComplexityRule"
@ -482,6 +485,7 @@ class Foo {
</rule>
<rule name="DataClass"
language="java"
since="6.0.0"
message="The class ''{0}'' is suspected to be a Data Class (WOC={1}, NOPA={2}, NOAM={3}, WMC={4})"
class="net.sourceforge.pmd.lang.java.rule.design.DataClassRule"
@ -548,6 +552,7 @@ public class Foo extends Error { }
</rule>
<rule name="ExceptionAsFlowControl"
language="java"
since="1.8"
message="Avoid using exceptions as flow control."
class="net.sourceforge.pmd.lang.java.rule.design.ExceptionAsFlowControlRule"
@ -575,6 +580,7 @@ public void bar() {
</rule>
<rule name="ExcessiveClassLength"
language="java"
since="0.6"
message="Avoid really long classes."
class="net.sourceforge.pmd.lang.java.rule.design.ExcessiveClassLengthRule"
@ -607,6 +613,7 @@ public class Foo {
</rule>
<rule name="ExcessiveImports"
language="java"
since="1.04"
message="A high number of imports can indicate a high degree of coupling within an object."
class="net.sourceforge.pmd.lang.java.rule.design.ExcessiveImportsRule"
@ -630,6 +637,7 @@ public class Foo {
</rule>
<rule name="ExcessiveMethodLength"
language="java"
since="0.6"
message="Avoid really long methods."
class="net.sourceforge.pmd.lang.java.rule.design.ExcessiveMethodLengthRule"
@ -653,6 +661,7 @@ public void doSomething() {
</rule>
<rule name="ExcessiveParameterList"
language="java"
since="0.9"
message="Avoid long parameter lists."
class="net.sourceforge.pmd.lang.java.rule.design.ExcessiveParameterListRule"
@ -680,6 +689,7 @@ public void addPerson( // preferred approach
</rule>
<rule name="ExcessivePublicCount"
language="java"
since="1.04"
message="This class has a bunch of public methods and attributes"
class="net.sourceforge.pmd.lang.java.rule.design.ExcessivePublicCountRule"
@ -763,6 +773,7 @@ of Object-Oriented Systems. Springer, Berlin, 1 edition, October 2006. Page 80.
</rule>
<rule name="ImmutableField"
language="java"
since="2.0"
message="Private field ''{0}'' could be made final; it is only initialized in the declaration or constructor."
class="net.sourceforge.pmd.lang.java.rule.design.ImmutableFieldRule"
@ -871,6 +882,7 @@ public boolean bar(int a, int b) {
</rule>
<rule name="LoosePackageCoupling"
language="java"
since="5.0"
message="Use of ''{0}'' outside of package hierarchy ''{1}'' is not recommended; use recommended classes instead"
class="net.sourceforge.pmd.lang.java.rule.design.LoosePackageCouplingRule"
@ -894,6 +906,7 @@ public class Bar {
</rule>
<rule name="NcssCount"
language="java"
message="The {0} ''{1}'' has a NCSS line count of {2}."
since="6.0.0"
class="net.sourceforge.pmd.lang.java.rule.design.NcssCountRule"
@ -937,6 +950,7 @@ class Foo { // +1, total Ncss = 12
</rule>
<rule name="NPathComplexity"
language="java"
since="3.9"
message="The {0} ''{1}'' has an NPath complexity of {2}, current threshold is {3}"
class="net.sourceforge.pmd.lang.java.rule.design.NPathComplexityRule"
@ -993,6 +1007,7 @@ public class Foo {
</rule>
<rule name="SignatureDeclareThrowsException"
language="java"
since="1.2"
message="A method/constructor should not explicitly throw java.lang.Exception"
class="net.sourceforge.pmd.lang.java.rule.design.SignatureDeclareThrowsExceptionRule"
@ -1160,6 +1175,7 @@ public class Bar {
</rule>
<rule name="SimplifyBooleanReturns"
language="java"
since="0.9"
message="Avoid unnecessary if..then..else statements when returning booleans"
class="net.sourceforge.pmd.lang.java.rule.design.SimplifyBooleanReturnsRule"
@ -1243,6 +1259,7 @@ class Foo {
</rule>
<rule name="SingularField"
language="java"
since="3.1"
message="Perhaps ''{0}'' could be replaced by a local variable."
class="net.sourceforge.pmd.lang.java.rule.design.SingularFieldRule"
@ -1267,6 +1284,7 @@ public class Foo {
</rule>
<rule name="SwitchDensity"
language="java"
since="1.02"
message="A high ratio of statements to labels in a switch statement. Consider refactoring."
class="net.sourceforge.pmd.lang.java.rule.design.SwitchDensityRule"
@ -1297,6 +1315,7 @@ public class Foo {
</rule>
<rule name="TooManyFields"
language="java"
since="3.0"
message="Too many fields"
class="net.sourceforge.pmd.lang.java.rule.design.TooManyFieldsRule"
@ -1381,6 +1400,7 @@ complexity and find a way to have more fine grained objects.
</rule>
<rule name="UselessOverridingMethod"
language="java"
since="3.3"
message="Overriding method merely calls super"
class="net.sourceforge.pmd.lang.java.rule.design.UselessOverridingMethodRule"
@ -1454,6 +1474,7 @@ public class MyClass {
</rule>
<rule name="UseUtilityClass"
language="java"
since="0.3"
message="All methods are static. Consider using a utility class instead. Alternatively, you could add a private constructor or make the class abstract to silence this warning."
class="net.sourceforge.pmd.lang.java.rule.design.UseUtilityClassRule"

View File

@ -10,6 +10,7 @@ Rules that are related to code documentation.
</description>
<rule name="CommentContent"
language="java"
since="5.0"
message="Invalid words or phrases found"
class="net.sourceforge.pmd.lang.java.rule.documentation.CommentContentRule"
@ -26,6 +27,7 @@ A rule for the politically correct... we don't want to offend anyone.
</rule>
<rule name="CommentRequired"
language="java"
since="5.1"
message="Comment is required"
class="net.sourceforge.pmd.lang.java.rule.documentation.CommentRequiredRule"
@ -46,6 +48,7 @@ Denotes whether javadoc (formal) comments are required (or unwanted) for specifi
</rule>
<rule name="CommentSize"
language="java"
since="5.0"
message="Comment is too large"
class="net.sourceforge.pmd.lang.java.rule.documentation.CommentSizeRule"

View File

@ -10,6 +10,7 @@ Rules to detect constructs that are either broken, extremely confusing or prone
</description>
<rule name="AssignmentInOperand"
language="java"
since="1.03"
message="Avoid assignments in operands"
class="net.sourceforge.pmd.lang.java.rule.errorprone.AssignmentInOperandRule"
@ -31,6 +32,7 @@ public void bar() {
</rule>
<rule name="AssignmentToNonFinalStatic"
language="java"
since="2.2"
message="Possible unsafe assignment to a non-final static field in a constructor."
class="net.sourceforge.pmd.lang.java.rule.errorprone.AssignmentToNonFinalStaticRule"
@ -155,6 +157,7 @@ public class A {
</rule>
<rule name="AvoidBranchingStatementAsLastInLoop"
language="java"
since="5.0"
class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidBranchingStatementAsLastInLoopRule"
message="Avoid using a branching statement as the last in a loop."
@ -185,6 +188,7 @@ for (int i = 0; i < 10; i++) {
</rule>
<rule name="AvoidCallingFinalize"
language="java"
since="3.0"
message="Avoid calling finalize() explicitly"
class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidCallingFinalizeRule"
@ -243,6 +247,7 @@ public class Foo {
</rule>
<rule name="AvoidCatchingThrowable"
language="java"
since="1.2"
message="A catch statement should never catch throwable since it includes errors."
class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidCatchingThrowableRule"
@ -313,6 +318,7 @@ BigDecimal bd = new BigDecimal(12); // preferred approach, ok for integ
</rule>
<rule name="AvoidDuplicateLiterals"
language="java"
since="1.0"
message="The String literal {0} appears {1} times in this file; the first occurrence is on line {2}"
class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidDuplicateLiteralsRule"
@ -362,6 +368,7 @@ public class A {
</rule>
<rule name="AvoidFieldNameMatchingMethodName"
language="java"
since="3.0"
message="Field {0} has the same name as a method"
class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidFieldNameMatchingMethodNameRule"
@ -385,6 +392,7 @@ public class Foo {
</rule>
<rule name="AvoidFieldNameMatchingTypeName"
language="java"
since="3.0"
message="It is somewhat confusing to have a field name matching the declaring class name"
class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidFieldNameMatchingTypeNameRule"
@ -574,6 +582,7 @@ public void bar() {
</rule>
<rule name="AvoidMultipleUnaryOperators"
language="java"
since="4.2"
class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidMultipleUnaryOperatorsRule"
message="Using multiple unary operators may be a bug, and/or is confusing."
@ -607,6 +616,7 @@ int j = -~7;
</rule>
<rule name="AvoidUsingOctalValues"
language="java"
since="3.9"
message="Do not start a literal by 0 unless it's an octal value"
class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidUsingOctalValuesRule"
@ -656,6 +666,7 @@ boolean x = (y == Double.NaN);
</rule>
<rule name="BeanMembersShouldSerialize"
language="java"
since="1.1"
message="Found non-transient, non-static member. Please mark as transient or provide accessors."
class="net.sourceforge.pmd.lang.java.rule.errorprone.BeanMembersShouldSerializeRule"
@ -686,6 +697,7 @@ private int getMoreFoo(){
</rule>
<rule name="BrokenNullCheck"
language="java"
since="3.8"
message="Method call on object which may be null"
class="net.sourceforge.pmd.lang.java.rule.errorprone.BrokenNullCheckRule"
@ -1031,6 +1043,7 @@ public class MyClass implements Cloneable{
</rule>
<rule name="CloseResource"
language="java"
since="1.2.2"
message="Ensure that resources like this {0} object are closed after use"
class="net.sourceforge.pmd.lang.java.rule.errorprone.CloseResourceRule"
@ -1080,6 +1093,7 @@ public class Bar {
</rule>
<rule name="CompareObjectsWithEquals"
language="java"
since="3.2"
message="Use equals() to compare object references."
class="net.sourceforge.pmd.lang.java.rule.errorprone.CompareObjectsWithEqualsRule"
@ -1101,6 +1115,7 @@ class Foo {
</rule>
<rule name="ConstructorCallsOverridableMethod"
language="java"
since="1.04"
message="Overridable {0} called during object construction"
class="net.sourceforge.pmd.lang.java.rule.errorprone.ConstructorCallsOverridableMethodRule"
@ -1140,6 +1155,7 @@ public class JuniorClass extends SeniorClass {
</rule>
<rule name="DataflowAnomalyAnalysis"
language="java"
since="3.9"
message="Found ''{0}''-anomaly for variable ''{1}'' (lines ''{2}''-''{3}'')."
class="net.sourceforge.pmd.lang.java.rule.errorprone.DataflowAnomalyAnalysisRule"
@ -1405,6 +1421,7 @@ public class Foo {
</rule>
<rule name="DontImportSun"
language="java"
since="1.5"
message="Avoid importing anything from the 'sun.*' packages"
class="net.sourceforge.pmd.lang.java.rule.errorprone.DontImportSunRule"
@ -2026,6 +2043,7 @@ public void finalize() {
</rule>
<rule name="IdempotentOperations"
language="java"
since="2.0"
message="Avoid idempotent operations (like assigning a variable to itself)."
class="net.sourceforge.pmd.lang.java.rule.errorprone.IdempotentOperationsRule"
@ -2047,6 +2065,7 @@ public class Foo {
</rule>
<rule name="ImportFromSamePackage"
language="java"
since="1.02"
message="No need to import a type that lives in the same package"
class="net.sourceforge.pmd.lang.java.rule.errorprone.ImportFromSamePackageRule"
@ -2213,6 +2232,7 @@ public class Foo extends TestCase {
</rule>
<rule name="MethodWithSameNameAsEnclosingClass"
language="java"
since="1.5"
message="Classes should not have non-constructor methods with the same name as the class"
class="net.sourceforge.pmd.lang.java.rule.errorprone.MethodWithSameNameAsEnclosingClassRule"
@ -2463,6 +2483,7 @@ public class Foo {
</rule>
<rule name="MoreThanOneLogger"
language="java"
since="2.0"
message="Class contains more than one logger."
class="net.sourceforge.pmd.lang.java.rule.errorprone.MoreThanOneLoggerRule"
@ -2555,6 +2576,7 @@ public class MyClass {
</rule>
<rule name="NullAssignment"
language="java"
since="1.02"
message="Assigning an Object to null is a code smell. Consider refactoring."
class="net.sourceforge.pmd.lang.java.rule.errorprone.NullAssignmentRule"
@ -2810,6 +2832,7 @@ public class Foo {
</rule>
<rule name="SingleMethodSingleton"
language="java"
since="5.4"
message="Class contains multiple getInstance methods. Please review."
class="net.sourceforge.pmd.lang.java.rule.errorprone.SingleMethodSingletonRule"
@ -2842,6 +2865,7 @@ public class Singleton {
</rule>
<rule name="SingletonClassReturningNewInstance"
language="java"
since="5.4"
message="getInstance method always creates a new object and hence does not comply to Singleton Design Pattern behaviour. Please review"
class="net.sourceforge.pmd.lang.java.rule.errorprone.SingletonClassReturningNewInstanceRule"
@ -3030,6 +3054,7 @@ public class Foo {
</rule>
<rule name="SuspiciousHashcodeMethodName"
language="java"
since="1.5"
message="The method name and return type are suspiciously close to hashCode()"
class="net.sourceforge.pmd.lang.java.rule.errorprone.SuspiciousHashcodeMethodNameRule"
@ -3050,6 +3075,7 @@ public class Foo {
</rule>
<rule name="SuspiciousOctalEscape"
language="java"
since="1.5"
message="Suspicious decimal characters following octal escape in string literal"
class="net.sourceforge.pmd.lang.java.rule.errorprone.SuspiciousOctalEscapeRule"
@ -3078,6 +3104,7 @@ public void foo() {
</rule>
<rule name="TestClassWithoutTestCases"
language="java"
since="3.0"
message="This class name ends with 'Test' but contains no test cases"
class="net.sourceforge.pmd.lang.java.rule.errorprone.TestClassWithoutTestCasesRule"
@ -3192,6 +3219,7 @@ public class SimpleTest extends TestCase {
</rule>
<rule name="UnnecessaryCaseChange"
language="java"
since="3.3"
message="Using equalsIgnoreCase() is cleaner than using toUpperCase/toLowerCase().equals()."
class="net.sourceforge.pmd.lang.java.rule.errorprone.UnnecessaryCaseChangeRule"
@ -3210,6 +3238,7 @@ boolean answer2 = buz.toUpperCase().equalsIgnoreCase("baz"); // another unnec
</rule>
<rule name="UnnecessaryConversionTemporary"
language="java"
since="0.1"
message="Avoid unnecessary temporaries when converting primitives to Strings"
class="net.sourceforge.pmd.lang.java.rule.errorprone.UnnecessaryConversionTemporaryRule"
@ -3381,6 +3410,7 @@ public boolean test(String s) {
</rule>
<rule name="UselessOperationOnImmutable"
language="java"
since="3.5"
message="An operation on an Immutable object (String, BigDecimal or BigInteger) won't change the object itself"
class="net.sourceforge.pmd.lang.java.rule.errorprone.UselessOperationOnImmutableRule"

View File

@ -253,6 +253,7 @@ public class Foo {
</rule>
<rule name="NonThreadSafeSingleton"
language="java"
since="3.4"
message="Singleton is not thread safe"
class="net.sourceforge.pmd.lang.java.rule.multithreading.NonThreadSafeSingletonRule"
@ -287,6 +288,7 @@ public static Foo getFoo() {
</rule>
<rule name="UnsynchronizedStaticFormatter"
language="java"
since="6.11.0"
message="Static Formatter objects should be accessed in a synchronized manner"
class="net.sourceforge.pmd.lang.java.rule.multithreading.UnsynchronizedStaticFormatterRule"

View File

@ -39,6 +39,7 @@ String t = Integer.toString(456); // preferred approach
</rule>
<rule name="AppendCharacterWithChar"
language="java"
since="3.5"
message="Avoid appending characters as strings in StringBuffer.append."
class="net.sourceforge.pmd.lang.java.rule.performance.AppendCharacterWithCharRule"
@ -246,6 +247,7 @@ that one covers both.
</rule>
<rule name="AvoidInstantiatingObjectsInLoops"
language="java"
since="2.2"
message="Avoid instantiating new objects inside loops"
class="net.sourceforge.pmd.lang.java.rule.performance.AvoidInstantiatingObjectsInLoopsRule"
@ -315,6 +317,7 @@ public class UsingShort {
</rule>
<rule name="BigIntegerInstantiation"
language="java"
since="3.9"
message="Don't create instances of already existing BigInteger and BigDecimal (ZERO, ONE, TEN)"
class="net.sourceforge.pmd.lang.java.rule.performance.BigIntegerInstantiationRule"
@ -336,6 +339,7 @@ bi4 = new BigInteger(0); // reference BigInteger.ZERO instead
</rule>
<rule name="BooleanInstantiation"
language="java"
since="1.2"
message="Avoid instantiating Boolean objects; reference Boolean.TRUE or Boolean.FALSE or call Boolean.valueOf() instead."
class="net.sourceforge.pmd.lang.java.rule.performance.BooleanInstantiationRule"
@ -413,6 +417,7 @@ buf.append("Hello").append(foo).append("World"); // good
</rule>
<rule name="ConsecutiveLiteralAppends"
language="java"
since="3.5"
message="StringBuffer (or StringBuilder).append is called {0} consecutive times with literals. Use a single append with a single combined String."
class="net.sourceforge.pmd.lang.java.rule.performance.ConsecutiveLiteralAppendsRule"
@ -439,8 +444,9 @@ buf.append("1m"); // good
</rule>
<rule name="InefficientEmptyStringCheck"
language="java"
since="3.6"
message="String.trim().length() == 0 / String.trim().isEmpty() is an inefficient way to validate a blank String."
message="String.trim().length() == 0 / String.trim().isEmpty() is an inefficient way to validate a blank String."
class="net.sourceforge.pmd.lang.java.rule.performance.InefficientEmptyStringCheckRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#inefficientemptystringcheck">
<description>
@ -481,6 +487,7 @@ public void bar(String string) {
</rule>
<rule name="InefficientStringBuffering"
language="java"
since="3.4"
message="Avoid concatenating nonliterals in a StringBuffer/StringBuilder constructor or append()."
class="net.sourceforge.pmd.lang.java.rule.performance.InefficientStringBufferingRule"
@ -503,6 +510,7 @@ sb.append(System.getProperty("java.io.tmpdir"));
</rule>
<rule name="InsufficientStringBufferDeclaration"
language="java"
since="3.6"
message="StringBuffer constructor is initialized with size {0}, but has at least {1} characters appended."
class="net.sourceforge.pmd.lang.java.rule.performance.InsufficientStringBufferDeclarationRule"
@ -759,6 +767,7 @@ public class Foo {
</rule>
<rule name="StringInstantiation"
language="java"
since="1.0"
message="Avoid instantiating String objects; this is usually unnecessary."
class="net.sourceforge.pmd.lang.java.rule.performance.StringInstantiationRule"
@ -775,6 +784,7 @@ private String bar = new String("bar"); // just do a String bar = "bar";
</rule>
<rule name="StringToString"
language="java"
since="1.0"
message="Avoid calling toString() on String objects; this is unnecessary."
class="net.sourceforge.pmd.lang.java.rule.performance.StringToStringRule"
@ -837,6 +847,7 @@ public class Foo {
</rule>
<rule name="UnnecessaryWrapperObjectCreation"
language="java"
since="3.8"
message="Unnecessary wrapper object creation"
class="net.sourceforge.pmd.lang.java.rule.performance.UnnecessaryWrapperObjectCreationRule"
@ -976,6 +987,7 @@ public class Test {
</rule>
<rule name="UseIndexOfChar"
language="java"
since="3.5"
message="String.indexOf(char) is faster than String.indexOf(String)."
class="net.sourceforge.pmd.lang.java.rule.performance.UseIndexOfCharRule"
@ -1054,6 +1066,7 @@ public class FileStuff {
</rule>
<rule name="UselessStringValueOf"
language="java"
since="3.8"
message="No need to call String.valueOf to append to a string."
class="net.sourceforge.pmd.lang.java.rule.performance.UselessStringValueOfRule"
@ -1075,6 +1088,7 @@ public String convert(int i) {
</rule>
<rule name="UseStringBufferForStringAppends"
language="java"
since="3.1"
message="Prefer StringBuilder (non-synchronized) or StringBuffer (synchronized) over += for concatenating strings"
class="net.sourceforge.pmd.lang.java.rule.performance.UseStringBufferForStringAppendsRule"
@ -1102,6 +1116,7 @@ public class Foo {
</rule>
<rule name="UseStringBufferLength"
language="java"
since="3.4"
message="This is an inefficient use of StringBuffer.toString; call StringBuffer.length instead."
class="net.sourceforge.pmd.lang.java.rule.performance.UseStringBufferLengthRule"

View File

@ -9,6 +9,7 @@ Rules that flag potential security flaws.
</description>
<rule name="HardCodedCryptoKey"
language="java"
since="6.4.0"
message="Do not use hard coded encryption keys"
class="net.sourceforge.pmd.lang.java.rule.security.HardCodedCryptoKeyRule"
@ -33,6 +34,7 @@ public class Foo {
</rule>
<rule name="InsecureCryptoIv"
language="java"
since="6.3.0"
message="Do not use hard coded initialization vector in crypto operations"
class="net.sourceforge.pmd.lang.java.rule.security.InsecureCryptoIvRule"

View File

@ -1,8 +1,8 @@
package net.sourceforge.pmd.lang.java.ast
import io.kotlintest.matchers.collections.shouldContainExactly
import io.kotlintest.matchers.string.shouldContain
import io.kotlintest.shouldBe
import io.kotest.matchers.collections.shouldContainExactly
import io.kotest.matchers.should
import io.kotest.matchers.shouldBe
import net.sourceforge.pmd.lang.java.ast.JavaVersion.*
import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.Earliest
import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.Latest

View File

@ -1,5 +1,5 @@
import io.kotlintest.shouldBe
import io.kotest.matchers.shouldBe
import net.sourceforge.pmd.lang.java.ast.*
import net.sourceforge.pmd.lang.java.ast.JavaVersion.*
import net.sourceforge.pmd.lang.java.ast.JavaVersion.Companion.Latest
@ -88,4 +88,4 @@ class Java11Test : ParserTestSpec({
}
}
})
})

View File

@ -2,10 +2,8 @@ package net.sourceforge.pmd.lang.java.ast
import com.github.oowekyala.treeutils.matchers.baseShouldMatchSubtree
import com.github.oowekyala.treeutils.printers.KotlintestBeanTreePrinter
import io.kotlintest.Matcher
import io.kotlintest.Result
import io.kotlintest.matchers.string.shouldContain
import io.kotlintest.shouldThrow
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.matchers.string.shouldContain
import net.sourceforge.pmd.lang.ast.Node
import net.sourceforge.pmd.lang.ast.ParseException
import net.sourceforge.pmd.lang.ast.test.*
@ -107,7 +105,7 @@ inline fun <reified N : Node> JavaNode?.shouldMatchNode(ignoreChildren: Boolean
*
* These are implicitly used by [matchExpr] and [matchStmt], which specify a matcher directly
* on the strings, using their type parameter and the info in this test context to parse, find
* the node, and execute the matcher in a single call. These may be used by [io.kotlintest.should],
* the node, and execute the matcher in a single call. These may be used by [io.kotest.matchers.should],
* e.g.
*
* parserTest("Test ShiftExpression operator") {
@ -120,7 +118,7 @@ inline fun <reified N : Node> JavaNode?.shouldMatchNode(ignoreChildren: Boolean
* Import statements in the parsing contexts can be configured by adding types to [importedTypes],
* or strings to [otherImports].
*
* Technically the utilities provided by this class may be used outside of [io.kotlintest.specs.FunSpec]s,
* Technically the utilities provided by this class may be used outside of [io.kotest.specs.FunSpec]s,
* e.g. in regular JUnit tests, but I think we should strive to uniformize our testing style,
* especially since KotlinTest defines so many.
*

View File

@ -1,15 +1,17 @@
package net.sourceforge.pmd.lang.java.ast
import io.kotlintest.AbstractSpec
import io.kotlintest.Matcher
import io.kotlintest.TestContext
import io.kotlintest.TestType
import net.sourceforge.pmd.lang.ast.Node
import net.sourceforge.pmd.lang.ast.ParseException
import io.kotest.core.config.Project
import io.kotest.core.spec.style.DslDrivenSpec
import io.kotest.core.spec.style.scopes.Lifecycle
import io.kotest.core.spec.style.scopes.RootScope
import io.kotest.core.spec.style.scopes.RootTestRegistration
import io.kotest.core.test.TestCaseConfig
import io.kotest.core.test.TestContext
import io.kotest.core.test.TestName
import io.kotest.core.test.TestType
import io.kotest.runner.junit.platform.IntelliMarker
import net.sourceforge.pmd.lang.ast.test.Assertions
import net.sourceforge.pmd.lang.ast.test.ValuedNodeSpec
import net.sourceforge.pmd.lang.ast.test.matchNode
import io.kotlintest.should as kotlintestShould
import io.kotest.matchers.should as kotlintestShould
/**
* Base class for grammar tests that use the DSL. Tests are layered into
@ -19,14 +21,23 @@ import io.kotlintest.should as kotlintestShould
*
* @author Clément Fournier
*/
abstract class ParserTestSpec(body: ParserTestSpec.() -> Unit) : AbstractSpec() {
abstract class ParserTestSpec(body: ParserTestSpec.() -> Unit) : DslDrivenSpec(), RootScope, IntelliMarker {
init {
body()
}
fun test(name: String, test: TestContext.() -> Unit) =
addTestCase(name, test, defaultTestCaseConfig, TestType.Test)
override fun lifecycle(): Lifecycle = Lifecycle.from(this)
override fun defaultConfig(): TestCaseConfig = actualDefaultConfig()
override fun registration(): RootTestRegistration = RootTestRegistration.from(this)
fun test(name: String, disabled: Boolean = false, test: suspend TestContext.() -> Unit) =
registration().addTest(
name = TestName(name),
xdisabled = disabled,
test = test,
config = actualDefaultConfig()
)
/**
* Defines a group of tests that should be named similarly,
@ -39,14 +50,19 @@ abstract class ParserTestSpec(body: ParserTestSpec.() -> Unit) : AbstractSpec()
* regression tests without bothering to find a name.
*
* @param name Name of the container test
* @param spec Assertions. Each call to [io.kotlintest.should] on a string
* @param spec Assertions. Each call to [io.kotest.matchers.should] on a string
* receiver is replaced by a [GroupTestCtx.should], which creates a
* new parser test.
*
*/
fun parserTestGroup(name: String,
spec: GroupTestCtx.() -> Unit) =
addTestCase(name, { GroupTestCtx(this).spec() }, defaultTestCaseConfig, TestType.Container)
disabled: Boolean = false,
spec: suspend GroupTestCtx.() -> Unit) =
registration().addContainerTest(
name = TestName(name),
test = { GroupTestCtx(this).spec() },
xdisabled = disabled
)
/**
* Defines a group of tests that should be named similarly.
@ -58,14 +74,14 @@ abstract class ParserTestSpec(body: ParserTestSpec.() -> Unit) : AbstractSpec()
*
* @param name Name of the container test
* @param javaVersion Language versions to use when parsing
* @param spec Assertions. Each call to [io.kotlintest.should] on a string
* @param spec Assertions. Each call to [io.kotest.matchers.should] on a string
* receiver is replaced by a [GroupTestCtx.should], which creates a
* new parser test.
*
*/
fun parserTest(name: String,
javaVersion: JavaVersion = JavaVersion.Latest,
spec: GroupTestCtx.VersionedTestCtx.() -> Unit) =
spec: suspend GroupTestCtx.VersionedTestCtx.() -> Unit) =
parserTest(name, listOf(javaVersion), spec)
/**
@ -79,44 +95,46 @@ abstract class ParserTestSpec(body: ParserTestSpec.() -> Unit) : AbstractSpec()
*
* @param name Name of the container test
* @param javaVersions Language versions for which to generate tests
* @param spec Assertions. Each call to [io.kotlintest.should] on a string
* @param spec Assertions. Each call to [io.kotest.matchers.should] on a string
* receiver is replaced by a [GroupTestCtx.should], which creates a
* new parser test.
*/
fun parserTest(name: String,
javaVersions: List<JavaVersion>,
spec: GroupTestCtx.VersionedTestCtx.() -> Unit) =
spec: suspend GroupTestCtx.VersionedTestCtx.() -> Unit) =
parserTestGroup(name) {
onVersions(javaVersions) {
spec()
}
}
private fun containedParserTestImpl(
private suspend fun containedParserTestImpl(
context: TestContext,
name: String,
javaVersion: JavaVersion,
assertions: ParserTestCtx.() -> Unit) {
context.registerTestCase(
name = name,
spec = this,
name = TestName(name),
test = { ParserTestCtx(javaVersion).assertions() },
config = defaultTestCaseConfig,
config = actualDefaultConfig(),
type = TestType.Test
)
}
private fun actualDefaultConfig() =
defaultTestConfig ?: defaultTestCaseConfig()
?: Project.testCaseConfig()
inner class GroupTestCtx(private val context: TestContext) {
fun onVersions(javaVersions: List<JavaVersion>, spec: VersionedTestCtx.() -> Unit) {
suspend fun onVersions(javaVersions: List<JavaVersion>, spec: suspend VersionedTestCtx.() -> Unit) {
javaVersions.forEach { javaVersion ->
context.registerTestCase(
name = "Java ${javaVersion.pmdName}",
spec = this@ParserTestSpec,
name = TestName("Java ${javaVersion.pmdName}"),
test = { VersionedTestCtx(this, javaVersion).spec() },
config = defaultTestCaseConfig,
config = actualDefaultConfig(),
type = TestType.Container
)
}
@ -124,7 +142,7 @@ abstract class ParserTestSpec(body: ParserTestSpec.() -> Unit) : AbstractSpec()
inner class VersionedTestCtx(private val context: TestContext, javaVersion: JavaVersion) : ParserTestCtx(javaVersion) {
infix fun String.should(matcher: Assertions<String>) {
suspend infix fun String.should(matcher: Assertions<String>) {
containedParserTestImpl(context, "'$this'", javaVersion = javaVersion) {
this@should kotlintestShould matcher
}

View File

@ -4,7 +4,7 @@
package net.sourceforge.pmd.lang.java.ast
import io.kotlintest.shouldBe
import io.kotest.matchers.shouldBe
/**
* @author Clément Fournier

View File

@ -1,6 +1,6 @@
package net.sourceforge.pmd.lang.java.ast
import io.kotlintest.shouldBe
import io.kotest.matchers.shouldBe
class WildcardBoundsTest : ParserTestSpec({

Some files were not shown because too many files have changed in this diff Show More