How to use PMD to customize rules

Source: Internet
Author: User

Preparatory work

First download the latest version of the file on the PMD website, currently the latest version is 5.4.1.
After downloading Pmd-bin-5.4.1.zip and Pmd-src-5.4.1.zip, unzip the backup.
pmd-src-5.4.1 is the PMD source package, it cannot be executed directly.
pmd-bin-5.4.1 is the PMD executable package

Catalog Introduction

pmd-src-5.4.1In addition pmd-core to the core of PMD execution scheduling module, the other folders are the various language check rules of the module.
The pmd-bin-5.4.1\lib directory in which the execution is dependent on the jar package.
pmd-bin-5.4.1\binDescription of the file in the directory:
pmd.batAnd the run.sh files are run under Windows and Linux platforms, respectively.
Examples of Use:

c:\tmp\pmd-bin-5.4.1\pmd\bin>pmd-d c:\data\pmd\pmd\test-data\Unused1.java-f Xml-r Rulesets/java/unusedcode.xml<?xml version= "1.0",  < PMD ;  <file  Span class= "Hljs-attribute" >name  = "C:\data\pmd\pmd\test-data\Unused1.java" ; <violation  line  = "5"  rule  = "unusedlocalvariable" ;  Avoid unused local variables such as ' FR ' Span class= "Hljs-tag" ></violation ; </< Span class= "Hljs-title" >file ; </PMD   

bgastviewer.batAnd designer.bat is an interface tool that transforms source code into an AST (abstract syntax tree), which is designer.bat more commonly used.
cpd.batAnd cpdgui.bat is a tool for finding duplicate code (cpd:copy/paste Detector).

Custom rule Implementation Ideas
    1. Define the rules you want to customize.
    2. Enumerate all the different ways in which this rule will be violated.
    3. Use Designer.bat to analyze the characteristics of all abstract syntax trees.
    4. Write rule code to capture this feature.
    5. Create your own XML rule file that includes information about the rule.
    6. Run the PMD scan error code to verify that the custom rule can be triggered.
The following is a simple example of the rules, detailed elaboration of the implementation of the rules of the specific steps. Java or XPath?

Here are two ways to write rules:
1. Writing with Java
2. Using an XPath expression

Want to know what you're looking for

Let's find out the problem we want to locate. The following is the code for the problem sample, with the "while loop must use parentheses" rule as an example. Without parentheses it is easy to confuse the code structure.

void bar() {  while (baz)   buz.doSomething(); }}

Figuring out what the sample code looks like, it's half done.

To write an example of a test data, view the AST

The

PMD scan does not use the source code directly; it uses the JavaCC build parser to parse the source and generate the AST (Abstract syntax tree). The above code is parsed into an abstract syntax tree as follows:

compilationunit typedeclaration classdeclaration: (package  private )  Unmodifiedclassdeclaration  (Example) classbody classbodydeclaration methoddeclaration: (package  private ) resulttype Method            Declarator  (bar) formalparameters Block blockstatement Statement whilestatement            Expression primaryexpression primaryprefix Name:baz Statement Statementexpression:null  primaryexpression Primaryprefi X Name:buz.doSomething primarysuffix Arguments  

You can use the designer tools from PMD to parse the code.
directory where the tool is located: Pmd-bin-5.4.1/bin/designer.bat
After double-clicking Designer.bat, an interface appears, fill in source code, and click the Go button:

The position of abstract Syntax Tree/xpath/symbol table in the picture is the tree structure after abstraction, and the tree structure is related to the source code.
Where we need to focus on the WhileStatement abstract tree structure is as follows:

Expression Statement  StatementExpression

This is the abstract tree structure of the wrong code example, and if the while loop is enclosed in parentheses, the structure of the abstract tree becomes:

Expression Statement  Block   BlockStatement    Statement     StatementExpression

Ha ha! This can obviously see more than before Block and BlockStatement these two nodes.
In this way we only need to write a rule check WhileStatement under no Block node, only Statement when the alarm can be notified here is a problem.
By the way, all structural information, such as one followed by Statement one Block , is defined in EBNF grammar. For example, in this syntax definition, one Statement of the definitions is this:

void Statement() :{}{  LOOKAHEAD( { isNextTokenAnAssert() } ) AssertStatement()| LOOKAHEAD(2";"| SwitchStatement()| IfStatement()| WhileStatement()| DoStatement()| ForStatement()| BreakStatement()| ContinueStatement()| ReturnStatement()| ThrowStatement()| SynchronizedStatement()| TryStatement()}

The above code lists Statement all the possible behind.

Write a rule class

Write a new Java class inheritance net.sourceforge.pmd.lang.java.rule.AbstractJavaRule :

import net.sourceforge.pmd.lang.java.rule.*;publicclass WhileLoopsMustUseBracesRule extends AbstractJavaRule {}

PMD works by recursively iterating through the resulting abstract syntax tree until the target is found and the result is returned.
The next goal is to find the nodes in the abstract syntax tree WhileStatement :

import net.sourceforge.pmd.lang.java.rule.*;import net.sourceforge.pmd.lang.java.ast.*;publicclass WhileLoopsMustUseBracesRule extends AbstractJavaRule {    publicvisit(ASTWhileStatement node, Object data) {        System.out.println("hello world");        return data;    }}

The printout of "Hello World" is the time when the rules we define are executed.

Put the Whileloopsmustusebracesrule rule in the XML ruleset file

Now that the rules have been written, we need to tell the PMD runtime to execute this rule by putting the relevant information for the rule file in the XML ruleset file. For example: pmd-java/src/main/resources/rulesets/java/basic.xml There are many definitions of rules, copy and paste, and change to a new ruleset file: Fill in the mycustomrules.xml elements and attributes yourself.
Name-whileloopsmustusebracesrule
Message-use braces for while loops
Class-Put it anywhere. Note that there is no need to put it in the net.sourceforge.pmd directory and can be placed in com.yourcompany.util.pmd
Description-use braces for while loops
Example-show violated rules through code snippets

<?xml version= "1.0"?><ruleset  name  =< Span class= "Hljs-value" > "My Custom Rules"  xmlns  =     "http://pmd.sourceforge.net/ruleset/2.0.0"  xmlns:xsi  = "http://www.w3.org/2001/ Xmlschema-instance " xsi:schemalocation  =" http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd ";     <rule name="Whileloopsmustusebracesrule"message="Avoid using" While ' statements without curly braces 'class=' Whileloopsmustusebracesrule '>                          <description>Avoid using ' while ' statements without using curly braces</Description>        <priority >3</priority >      <example><!    [cdata[public void dosomething () {while (true) x + +; }]]>      </Example>    </rule></ruleset>
Use PMD to execute your new rules

pmd.bat -d c:\path\to\my\src -f xml -R c:\path\to\mycustomrules.xml
You will see the previous "Hello World" output in the command line.

Create Ruleviolation

Want your test results to be shown in the report, you need to createRuleViolation

Importnet.sourceforge.pmd.lang.ast.*;Importnet.sourceforge.pmd.lang.java.ast.*;Importnet.sourceforge.pmd.lang.java.rule.*; Public  class whileloopsmustusebracesrule extends abstractjavarule {     PublicObjectVisit(astwhilestatement node, Object data) {Node firststmt = Node.jjtgetchild (1);if(!hasblockasfirstchild (FIRSTSTMT))        {addviolation (data, node); }return Super. Visit (Node,data); }Private Boolean Hasblockasfirstchild(Node node) {return(Node.jjtgetnumchildren ()! =0&& (Node.jjtgetchild (0)instanceofAstblock)); }}

Use this file to execute again
pmd.bat -d c:\path\to\my\src -f xml -R c:\path\to\mycustomrules.xml
You can view the results in the command line interface.

Reference documents

PMD site. How to write a PMD rule

How to use PMD to customize rules

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.