Merge branch 'master' into pmd/7.0.x
This commit is contained in:
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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"
|
||||
|
@ -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>
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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() > 0, size() < 1) with calls to isEmpty()"
|
||||
class="net.sourceforge.pmd.lang.java.rule.bestpractices.UseCollectionIsEmptyRule"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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({
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
})
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.ast
|
||||
|
||||
import io.kotlintest.shouldBe
|
||||
import io.kotest.matchers.shouldBe
|
||||
|
||||
/**
|
||||
* @author Clément Fournier
|
||||
|
@ -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
Reference in New Issue
Block a user