30 October 2021
The PMD team is pleased to announce PMD 6.40.0.
This is a minor release.
EagerlyLoadedDescribeSObjectResult
finds
DescribeSObjectResult
s which could have been loaded eagerly via SObjectType.getDescribe()
. <rule ref="category/apex/performance.xml/EagerlyLoadedDescribeSObjectResult" />
The Apex rule ApexUnitTestClassShouldHaveAsserts
has a new property
additionalAssertMethodPattern
. When specified the pattern is evaluated against each invoked
method name to determine whether it represents a test assertion in addition to the standard names.
The Apex rule ApexDoc
has a new property reportMissingDescription
.
If set to false
(default is true
if unspecified) doesn’t report an issue if the @description
tag is missing. This is consistent with the ApexDoc dialect supported by derivatives such as
SfApexDoc and also with analogous documentation tools for
other languages, e.g., JavaDoc, ESDoc/JSDoc, etc.
The Apex rule ApexCRUDViolation
has a couple of new properties:
These allow specification of regular-expression-based patterns for additional methods that should
be considered valid for pre-CRUD authorization beyond those offered by the system Apex checks and
ESAPI, e.g., sirono-common
’s AuthorizationUtil
class.
Two new properties have been added per-CRUD operation, one to specify the naming pattern for a method
that authorizes that operation and another to specify the argument passed to that method that contains
the SObjectType
instance of the type being authorized. Here is an example of these new properties:
<rule ref="category/apex/security.xml/ApexCRUDViolation" message="...">
<priority>3</priority>
<properties>
<property name="createAuthMethodPattern" value="AuthorizationUtil\.(is|assert)(Createable|Upsertable)"/>
<!--
There's one of these properties for each operation, and the default value is 0 so this is technically
superfluous, but it's included it here for example purposes.
-->
<property name="createAuthMethodTypeParamIndex" value="0"/>
<property name="readAuthMethodPattern" value="AuthorizationUtil\.(is|assert)Accessible"/>
<property name="updateAuthMethodPattern" value="AuthorizationUtil\.(is|assert)(Updateable|Upsertable)"/>
<property name="deleteAuthMethodPattern" value="AuthorizationUtil\.(is|assert)Deletable"/>
<property name="undeleteAuthMethodPattern" value="AuthorizationUtil\.(is|assert)Undeletable"/>
<property name="mergeAuthMethodPattern" value="AuthorizationUtil\.(is|assert)Mergeable"/>
</properties>
</rule>
The Apex rule EmptyStatementBlock
has two new properties:
Setting reportEmptyPrivateNoArgConstructor
to false
ignores empty private no-arg constructors
that are commonly used in singleton pattern implementations and utility classes in support of
prescribed best practices.
Setting reportEmptyVirtualMethod
to false
ignores empty virtual methods that are commonly used in
abstract base classes as default no-op implementations when derived classes typically only override a
subset of virtual methods.
By default, both properties are true
to not change the default behaviour of this rule.
The Apex rule EmptyCatchBlock
has two new properties modeled after the analgous Java rule:
The allowCommentedBlocks
property, when set to true
(defaults to false
), ignores empty blocks containing comments, e.g.:
try {
doSomethingThatThrowsAnExpectedException();
System.assert(false, 'Expected to catch an exception.');
} catch (Exception e) {
// Expected
}
The allowExceptionNameRegex
property is a regular expression for exception variable names for which empty catch blocks should be ignored by this rule. For example, using the default property value of ^(ignored|expected)$
, the following empty catch blocks will not be reported:
try {
doSomethingThatThrowsAnExpectedException();
System.assert(false, 'Expected to catch an exception.');
} catch (IllegalStateException ignored) {
} catch (NumberFormatException expected) {
}
The Apex rule OneDeclarationPerLine
has a new property reportInForLoopInitializer
:
If set to false
(default is true
if unspecified) doesn’t report an issue for multiple declarations in
a for
loop’s initializer section. This is support the common idiom of one declaration for the loop variable
and another for the loop bounds condition, e.g.,
for (Integer i = 0, numIterations = computeNumIterations(); i < numIterations; i++) {
}
The Java rule ClassNamingConventions
uses a different default value of the
property utilityClassPattern
: This rule was detecting utility classes by default since PMD 6.3.0
and enforcing the naming convention that utility classes has to be suffixed with Util or Helper or Constants.
However this turned out to be not so useful as a default configuration, as there is no standard
naming convention for utility classes.
With PMD 6.40.0, the default value of this property has been changed to [A-Z][a-zA-Z0-9]*
(Pascal case), effectively disabling the special handling of utility classes. This is the same default
pattern used for concrete classes.
This means, that the feature to enforce a naming convention for utility classes is now a opt-in feature and can be enabled on demand.
To use the old behaviour, the property needs to be configured as follows:
<rule ref="category/java/codestyle.xml/ClassNamingConventions">
<properties>
<property name="utilityClassPattern" value="[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)" />
</properties>
</rule>
ASTCommentContainer
has been added to the Apex AST.
It provides a way to check whether a node contains at least one comment. Currently this is only implemented for
ASTCatchBlockStatement
and used by the rule
EmptyCatchBlock
.
This information is also available via XPath attribute @ContainsComment
.