【CodeReview Automation】编写自己的PMD规则

      什么样的代码叫做一个好的代码,相信每个人都有自己心中的一杆秤,而繁荣的Java社区也给了我们很多优秀的代码异味检测工具,Checkstyle,Findbug,PMD就是广为人知的几个。但是针对不同的问题,其中的异味和优秀实践各有不同,为了能够更好的Review迎合具体问题的代码,就需要我们能够在对问题有了了解之后,实现一些自己独有的代码检查规则,那么,以后我们针对这一问题的Code Review效率就会有明显提升。

PMD的工作原理
      PMD通过JavaCC 解析器把源代码解析为一颗AST(Abstract Syntax Tree),然后通过对这个语法树的特征辨识,从而识别出这份源代码是否有自定义的异味。在PMD的代码包中包含了通过源代码一个生成AST的小工具, 启动该工具,我们就可以查看一个类的AST结构了(在Windows直接运行bin目录下的designer.bat, Unix系统运行./run.sh designer)
【CodeReview Automation】编写自己的PMD规则_第1张图片

编写一个自己的规则
1、定义规则
     没有任何行为的Enum都是坏味道
2、找出规则在AST中的特征
     AST是一个高度结构化的数据,代码上的变化都会在AST结构上留下痕迹,通过PMD designer可以发现,有行为的Enum和没有行为的Enum之间最大的差别就是在EnumBody这个节点下面没有任何方法声明语句MehodDeclaration的存在。
3、编写代码
     编写PMD的Rule必须引入PMD的包,
<dependency>
            <groupId>pmd</groupId>
            <artifactId>pmd</artifactId>
            <version>${pmd.version}</version>
            <scope>compile</scope>
        </dependency>

新的JavaRule必须继承AbstractJavaRule。
public class EnumWithoutBehavior extends AbstractJavaRule {
    @Override
    public Object visit(ASTEnumBody node, Object data) {
        if (!hasMethodDeclared(node)) addViolation(data, node);
        return data;
    }

    private boolean hasMethodDeclared(ASTEnumBody node) {
        return !node.findChildrenOfType(ASTMethodDeclaration.class).isEmpty();
    }
}


4、配置规则信息
代码写完之后,需要配置相应的rulesets.xml,该文件主要就是配置PMD运行时执行哪些规则,当触犯规则的时候应该显示什么样的错误信息
<?xml version="1.0"?>
<ruleset name="Mars Rover Rules"
         xmlns="http://pmd.sf.net/ruleset/1.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
        xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
    <description>
    </description>
    <rule name="EnumWithoutBehavior"
          message="Enumeration without any behavior"
          class="com.thoughtworks.cerberus.marsrover.java.EnumWithoutBehavior">
        <description></description>
        <priority>3</priority>
        <example></example>
    </rule>
</ruleset>

你可能感兴趣的:(automation)