pmd/docs/pages/7_0_0_release_notes.md
2021-04-16 15:24:00 +02:00

16 KiB

title permalink keywords
PMD Release Notes pmd_release_notes.html changelog, release notes

{{ site.pmd.date }} - {{ site.pmd.version }}

The PMD team is pleased to announce PMD {{ site.pmd.version }}.

This is a {{ site.pmd.release_type }} release.

{% tocmaker is_release_notes_processor %}

New and noteworthy

Full Antlr support

Languages backed by an Antlr grammar are now fully supported. This means, it's now possible not only to use Antlr grammars for CPD, but we can actually build full-fledged PMD rules for them as well. Both the traditional Java visitor rules, and the simpler XPath rules are available to users.

We expect this to enable both our dev team and external contributors to largely extend PMD usage for more languages.

Swift support

Given the full Antlr support, PMD now fully supports Swift. We are pleased to announce we are shipping a number of rules starting with PMD 7.

  • {% rule "swift/errorprone/ForceCast" %} (swift-errorprone) flags all force casts, making sure you are defensively considering all types. Having the application crash shouldn't be an option.
  • {% rule "swift/errorprone/ForceTry" %} (swift-errorprone) flags all force tries, making sure you are defensively handling exceptions. Having the application crash shouldn't be an option.
  • {% rule "swift/bestpractices/ProhibitedInterfaceBuilder" %} (swift-bestpractices) flags any usage of interface builder. Interface builder files are prone to merge conflicts, and are impossible to code review, so larger teams usually try to avoid it or reduce it's usage.
  • {% rule "swift/bestpractices/UnavailableFunction" %} (swift-bestpractices) flags any function throwing a fatalError not marked as @available(*, unavailable) to ensure no calls are actually performed in the codebase.

XPath 3.1 support

Support for XPath versions 1.0, 1.0-compatibility was removed, support for XPath 2.0 is deprecated. The default (and only) supported XPath version is now XPath 3.1. This version of the XPath language is mostly identical to XPath 2.0. Notable changes:

  • The deprecated support for sequence-valued attributes is removed. Sequence-valued properties are still supported.
  • Refer to the Saxonica documentation for an introduction to new features in XPath 3.1.

Node stream API

This version includes a powerful API to navigate trees, similar in usage to the Java 8 Stream API:

node.descendants(ASTMethodCall.class)
    .filter(m -> "toString".equals(m.getMethodName()))
    .map(m -> m.getQualifier())
    .filter(q -> TypeTestUtil.isA(String.class, q))
    .foreach(System.out::println);

A pipeline like shown here traverses the tree lazily, which is more efficient than traversing eagerly to put all descendants in a list. It is also much easier to change than the old imperative way.

To make this API as accessible as possible, the {% jdoc core::lang.ast.Node %} interface has been fitted with new methods producing node streams. Those methods replace previous tree traversal methods like Node#findDescendantsOfType. In all cases, they should be more efficient and more convenient.

See {% jdoc core::lang.ast.NodeStream %} for more details.

JavaScript support

The JS specific parser options have been removed. The parser now always retains comments and uses version ES6. The language module registers only one version (as before), now correctly with version "ES6" instead of "3". Since there is only one version available for JavaScript there is actually no need to selected a specific version. The default version is always ES6.

New Rules

  • The Apex rule {% rule "apex/design/UnusedMethod" %} finds unused methods in your code.

Changed Rules

Java
  • {% rule "java/codestyle/UnnecessaryFullyQualifiedName" %} has two new properties, to selectively disable reporting on static field and method qualifiers. The rule also has been improved to be more precise.
  • The rule {% rule "java/codestyle/UselessParentheses" %} has two new properties which control how strict the rule should be applied. With ignoreClarifying (default: true) parentheses that are strictly speaking not necessary are allowed, if they separate expressions of different precedence. The other property ignoreBalancing (default: true) is similar, in that it allows parentheses that help reading and understanding the expressions.
  • The rule {% rule "java/bestpractices/LooseCoupling" %} has a new property to allow some types to be coupled to (allowedTypes).
  • {% rule "java/errorprone/EmptyCatchBlock" %}: CloneNotSupportedException and InterruptedException are not special-cased anymore. Rename the exception parameter to ignored to ignore them.

Removed Rules

The following previously deprecated rules have been finally removed:

  • AbstractNaming (java-codestyle)
  • AvoidFinalLocalVariable (java-codestyle)
  • AvoidPrefixingMethodParameters (java-codestyle)
  • DataflowAnomalyAnalysis (java-errorprone)
  • ForLoopsMustUseBraces (java-codestyle)
  • IfElseStmtsMustUseBraces (java-codestyle)
  • IfStmtsMustUseBraces (java-codestyle)
  • LoggerIsNotStaticFinal (java-errorprone)
  • MIsLeadingVariableName (java-codestyle)
  • ModifiedCyclomaticComplexity (java-design)
  • PositionLiteralsFirstInCaseInsensitiveComparisons (java-bestpractices)
  • PositionLiteralsFirstInComparisons (java-bestpractices)
  • StdCyclomaticComplexity (java-design)
  • SuspiciousConstantFieldName (java-codestyle)
  • UnsynchronizedStaticDateFormatter (java-multithreading)
  • VariableNamingConventions (apex-codestyle)
  • VariableNamingConventions (java-codestyle)
  • WhileLoopsMustUseBraces (java-codestyle)

Fixed Issues

  • apex-design

    • #2667: [apex] Integrate nawforce/ApexLink to build robust Unused rule
  • core

    • #1451: [core] RulesetFactoryCompatibility stores the whole ruleset file in memory as a string
  • java-bestpractices

    • #342: [java] AccessorMethodGeneration: Name clash with another public field not properly handled
    • #755: [java] AccessorClassGeneration false positive for private constructors
    • #770: [java] UnusedPrivateMethod yields false positive for counter-variant arguments
    • #807: [java] AccessorMethodGeneration false positive with overloads
    • #833: [java] ForLoopCanBeForeach should consider iterating on this
    • #1189: [java] UnusedPrivateMethod false positive from inner class via external class
    • #1212: [java] Don't raise JUnitTestContainsTooManyAsserts on JUnit 5's assertAll
    • #1422: [java] JUnitTestsShouldIncludeAssert false positive with inherited @Rule field
    • #1565: [java] JUnitAssertionsShouldIncludeMessage false positive with AssertJ
    • #1969: [java] MissingOverride false-positive triggered by package-private method overwritten in another package by extending class
    • #1998: [java] AccessorClassGeneration false-negative: subclass calls private constructor
    • #2130: [java] UnusedLocalVariable: false-negative with array
    • #2147: [java] JUnitTestsShouldIncludeAssert - false positives with lambdas and static methods
    • #2464: [java] LooseCoupling must ignore class literals: ArrayList.class
    • #2542: [java] UseCollectionIsEmpty can not detect the case foo.bar().size()
    • #2650: [java] UseTryWithResources false positive when AutoCloseable helper used
    • #2796: [java] UnusedAssignment false positive with call chains
    • #2797: [java] MissingOverride long-standing issues
    • #2806: [java] SwitchStmtsShouldHaveDefault false-positive with Java 14 switch non-fallthrough branches
    • #2822: [java] LooseCoupling rule: Extend to cover user defined implementations and interfaces
    • #2882: [java] UseTryWithResources - false negative for explicit close
    • #2883: [java] JUnitAssertionsShouldIncludeMessage false positive with method call
    • #2890: [java] UnusedPrivateMethod false positive with generics
  • java-codestyle

    • #1208: [java] PrematureDeclaration rule false-positive on variable declared to measure time
    • #1429: [java] PrematureDeclaration as result of method call (false positive)
    • #1673: [java] UselessParentheses false positive with conditional operator
    • #1790: [java] UnnecessaryFullyQualifiedName false positive with enum constant
    • #1918: [java] UselessParentheses false positive with boolean operators
    • #2299: [java] UnnecessaryFullyQualifiedName false positive with similar package name
    • #2528: [java] MethodNamingConventions - JUnit 5 method naming not support ParameterizedTest
    • #2739: [java] UselessParentheses false positive for string concatenation
    • #3195: [java] Improve rule UnnecessaryReturn to detect more cases
    • #3221: [java] PrematureDeclaration false positive for unused variables
  • java-errorprone

    • #1005: [java] CloneMethodMustImplementCloneable triggers for interfaces
    • #2532: [java] AvoidDecimalLiteralsInBigDecimalConstructor can not detect the case new BigDecimal(Expression)
    • #2716: [java] CompareObjectsWithEqualsRule: False positive with Enums
    • #2880: [java] CompareObjectsWithEquals - false negative with type res
    • #3071: [java] BrokenNullCheck FP with PMD 6.30.0
  • java-multithreading

    • #2537: [java] DontCallThreadRun can't detect the case that call run() in this.run()
    • #2538: [java] DontCallThreadRun can't detect the case that call run() in foo.bar.run()
    • #2577: [java] UseNotifyAllInsteadOfNotify falsely detect a special case with argument: foo.notify(bar)
  • java-performance

    • #1224: [java] InefficientEmptyStringCheck false negative in anonymous class
    • #2712: [java] SimplifyStartsWith false-positive with AssertJ

API Changes

  • #1648: [apex,vf] Remove CodeClimate dependency - Robert Sösemann Properties "cc_categories", "cc_remediation_points_multiplier", "cc_block_highlighting" can no longer be overridden in rulesets. They were deprecated without replacement.

  • The old GUI applications accessible through run.sh designerold and run.sh bgastviewer (and corresponding Batch scripts) have been removed from the PMD distribution. Please use the newer rule designer with run.sh designer. The corresponding classes in packages java.net.sourceforge.pmd.util.viewer and java.net.sourceforge.pmd.util.designer have all been removed.

  • All API related to XPath support has been moved to the package {% jdoc_package core::lang.rule.xpath %}. This includes API that was previously dispersed over net.sourceforge.pmd.lang, net.sourceforge.pmd.lang.ast.xpath, net.sourceforge.pmd.lang.rule.xpath, net.sourceforge.pmd.lang.rule, and various language-specific packages (which were made internal).

Metrics framework

The metrics framework has been made simpler and more general.

  • The metric interface takes an additional type parameter, representing the result type of the metric. This is usually Integer or Double. It avoids widening the result to a double just to narrow it down.

    This makes it so, that Double.NaN is not an appropriate sentinel value to represent "not supported" anymore. Instead, computeFor may return null in that case (or a garbage value). The value null may have caused problems with the narrowing casts, which through unboxing, might have thrown an NPE. But when we deprecated the language-specific metrics façades to replace them with the generic MetricsUtil, we took care of making the new methods throw an exception if the metric cannot be computed on the parameter. This forces you to guard calls to MetricsUtil::computeMetric with something like if (metric.supports(node)). If you're following this pattern, then you won't observe the undefined behavior.

  • The MetricKey interface is not so useful and has been merged into the Metric interface and removed. So the Metric interface has the new method String name().

  • The framework is not tied to at most 2 node types per language anymore. Previously those were nodes for classes and for methods/constructors. Instead, many metrics support more node types. For example, NCSS can be computed on any code block.

    For that reason, keeping around a hard distinction between "class metrics" and "operation metrics" is not useful. So in the Java framework for example, we removed the interfaces JavaClassMetric, JavaOperationMetric, abstract classes for those, JavaClassMetricKey, and JavaOperationMetricKey. Metric constants are now all inside the JavaMetrics utility class. The same was done in the Apex framework.

    We don't really need abstract classes for metrics now. So AbstractMetric is also removed from pmd-core. There is a factory method on the Metric interface to create a metric easily.

  • This makes it so, that {% jdoc core::lang.metrics.LanguageMetricsProvider %} does not need type parameters. It can just return a Set<Metric<?, ?>> to list available metrics.

  • {% jdoc_old core::lang.metrics.Signature %}s, their implementations, and the interface SignedNode have been removed. Node streams allow replacing their usages very easily.

External Contributions

{% endtocmaker %}