Tuesday, September 10, 2013

Suppressing PMD alerts for Lombok generated code

As you know from my previous post, Lombok offers Java programmers a convenient equivalent to Scala's Case Classes. And the lombok-maven-plugin allows for easy integration of Lombok into a Maven project.

I am a big fan of Static Code Analysis tools like PMD and FindBugs. Generally, one could argue that it is not necessary to run checks against generated code because it is not the source code that you are maintaining. For code generation tools like ANTLR, I think skipping checks is prudent because if the generated code does not comply with your quality standards, there may be little that one can do — the source code that should be scrutinized is the ANTLR grammar.

When using Lombok, the tool may generate some boiler-plate code for you, like getters, setters, equals, and hashCode, but you often write some additional methods that you would want to have PMD analyze. As a result, excluding PMD from processing your classes is not recommended. And then you get second thoughts after seeing the consequences of running PMD against a generated equals and hashCode implementation, complaining about missing braces, multiple exit points, complexity, etc. Worse is that all that crying wolf makes it hard to focus on the real problems that you need to address.

You may notice, however, that Lombok always adds an annotation to generated code:

@java.lang.SuppressWarnings("all")
This annotation is supposed to hint to tools that this code can be ignored because it is generated.

Prior to PMD 5, you could suppress PMD for a class or a line, but not for a method. PMD 5 offers two new suppression techniques, one of which we can leverage for suppressing checks against Lombok code: Violation Suppress XPath.

Certain rules have a tendency to fire false alarms for Lombok generated code:

For these rules, we can add an XPath expression for the Suppress Warnings annotation so that those rules will be skipped for Lombok generated methods.

The XPath expression for the Suppress Warnings annotation is:

//MethodDeclaration[../Annotation/SingleMemberAnnotation[ (Name/@Image='java.lang.SuppressWarnings') and (MemberValue/PrimaryExpression/PrimaryPrefix/Literal/@Image='"all"')]]

The rule can be configured with the Violation Suppress XPath like this:

<rule
  ref="rulesets/java/braces.xml/IfStmtsMustUseBraces">
  <properties>
    <property name="violationSuppressXPath"
      value="//MethodDeclaration[../Annotation/SingleMemberAnnotation[
(Name/@Image='java.lang.SuppressWarnings') and (MemberValue/PrimaryExpression/PrimaryPrefix/Literal/@Image='"all"')]]" />
  </properties>
</rule>

The Sample Maven Lombok Project has been enhanced to demonstrate this.

No comments:

Post a Comment