-1

I am trying to create a custom PMD rule that will cause a violation if an instance of org.jooq.DSLContext is being referenced in a loop.

I am completely new to PMD so I have no idea where to start.

Can anyone help?

  • Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. – Community Sep 05 '21 at 00:29

1 Answers1

0

the starting point is clear: https://pmd.github.io/latest/pmd_userdocs_extending_writing_rules_intro.html

For the concrete question, I'd suggest to create a XPath based rule. You can use the custom XPath function "pmd-java:typeIs" to check for a specific type.

E.g. to find all usages, you can use this query:

//PrimaryPrefix[pmd-java:typeIs("org.jooq.DSLContext")]

In order to restict the query for something inside a loop, you'll need to write probably this:

//(ForStatement | WhileStatement | DoStatement)
    //PrimaryPrefix[pmd-java:typeIs("org.jooq.DSLContext")]

Note: Due to a bug in PMD (https://github.com/pmd/pmd/pull/3499) this query needs to be expanded manually, see below the final expression in the XML rule snippet.

The complete rule XML snippet might look like this:

<rule name="DontReferenceDSLContextInLoops"
      language="java"
      message="Do not reference DSLContext in Loops"
      class="net.sourceforge.pmd.lang.rule.XPathRule" >
    <description>
TODO

Why is it bad to reference DSLContext?

What should you do instead?

Are there exceptions - when is it valid to suppress this violation?
    </description>
    <priority>3</priority>
    <properties>
        <property name="version" value="2.0"/>
        <property name="xpath">
            <value>
<![CDATA[
//ForStatement//PrimaryPrefix[pmd-java:typeIs("org.jooq.DSLContext")]
|
//WhileStatement//PrimaryPrefix[pmd-java:typeIs("org.jooq.DSLContext")]
|
//DoStatement//PrimaryPrefix[pmd-java:typeIs("org.jooq.DSLContext")]
]]>
            </value>
        </property>
    </properties>
</rule>

adangel
  • 1,816
  • 14
  • 17
  • Thank you @adangel that is very helpful. I got it working now but I had to split it up into different rules because if I tried to use `//(ForStatement | WhileStatement | DoStatement)` then it would just mark every occasion of DSLContext as a violation. – Niels Frederiksen Sep 03 '21 at 11:07
  • I think you could write `(//ForStatement | //WhileStatement | //DoStatement)//PrimaryPrefix[...]` instead of splitting into different rules – oowekyala Sep 08 '21 at 17:24
  • Hm... true, this seems to be a bug in PMD. I've created a fix (https://github.com/pmd/pmd/pull/3499). Note: There is still a single rule possible - I'll edit my answer accordingly – adangel Sep 10 '21 at 08:19