扩展Alibaba P3C 实现自定义代码规范检查
P3C (源码地址: https://github.com/alibaba/p3c ):
一款代码规范的检查工具,有对应的ide插件,能在编码过程中对设置的规则进行提示,可以针对公司编码规范对它原来基础上做了进一步的拓展;
p3c主要包括3部分:
- PMD实现(p3c-pmd):使用PMD来实现代码规范检查
- Intellij IDEA插件
- Eclipse插件
《阿里巴巴Java开发手册》中的大部分规则都是在p3c-pmd模块中实现的,该部分也是这节研究的主要部分
PMD
p3c使用了PMD。PMD是一款静态代码扫描工具,该工具可以做到检查Java代码中是否含有未使用的变量、是否含有空的抓取块、是否含有不必要的对象等。PMD使用JavaCC生成解析器来解析源代码并生成AST(抽象语法树),通过对AST的检查可以直接从源代码文本层面来对代码进行检查,在PMD内部称为规则。即是否符合规则指的是,穷举源码各种可能的写法,然后在AST上检查是否出现。而规则的实现,重点便在对AST的处理上
1.1 pmd-bin-5.4.1【PMD可执行版本】 (https://pmd.github.io/)
- bin
- designer.bat【界面工具,能将java源代码转化为AST(抽象语法树),个人推荐使用】
- bgastviewer.bat【界面工具,与designer.bat功能相似】
- cpd.bat【用来查找重复代码的工具,命令行版】
- cpdgui.bat【用来查找重复代码的工具,GUI版】
- pmd.bat【Window平台下运行PMD需要使用的文件】
- run.sh【Linux平台下运行PMD需要使用的文件】
- lib【该目录存放PMD运行依赖的jar包,包括第三方jar包和各种语言的模块jar包】
1.2. AST
关于AST的介绍网上有很多,可以直接搜索,这里重要提两点:
- AST是源代码的抽象语法结构的树状表示
- 抽象语法树并不依赖于原语言的语法,也就是说同语法分析阶段所采用的上下文无关
PMD使用JavaCC来生成AST。关于JavaCC也可以在网上查看相关资料,这里不多介绍,只要知道JavaCC是一个词法分析生成器和语法分析生成器便行。
1.3. 自定义规则
- 1. 明确想要自定义的规则。
自定义规则: 方法参数不能超过5个,如果参数无法减少,可以将多个参数封装成一个对象
- 2. 列举会触犯这种规则的所有不同的写法。
public void fn(int a, int b, int c,int d, int f, int g) {dosomething();}
- 3. 使用designer.bat分析所有写法的抽象语法树的特点。
注意: 这个树形结构和源代码是有对应关系的。其中我们需要重点关注的 `FormalParameters ` 的抽象树结构如下:注意标红的节点,根据定义的方法参数,`FormalParameter`这个节点会对应的增加或减少,这样我们只需要写一个规则检查 `FormalParameters` 下的 `FormalParameter ` 节点是否大于5就可以了,就可以报警告知这里是有问题的。
具体详细的节点的信息可以看对应的jar文件
- 4. 编写规则代码捕捉这种特点。
代码规范实现的主要模块,使用pmd来实现。p3c-pmd模块在代码组织上很工整,可以按照相同的模式增加自定义的规则/规则集。对于本文需求,打算在该模块的基础上增加一个extend模块,用于实现自定义规则集。如下,为对应的源码路径好规则集路径
具体代码实现
public class MethodParamsNumRule extends AbstractAliRule {private static final int PARAMSNUM = 5;@Overridepublic Object visit(ASTFormalParameters node, Object data) {if (node.jjtGetNumChildren()>PARAMSNUM) {addViolationWithMessage(data,node,"java.extend.MethodParamsNumRule.rule.msg");};return super.visit(node, data);}}这段代码意思:
1. 访问文件中的 `ASTFormalParameters` 节点
2. 获取 `ASTFormalParameters` 节点下所有的子节点
3. 判断子节点的数量是否大于5
4. 如果是,说明我们的目标实现,触犯规则
5. 使用 `addViolationWithMessage(data, node,message);` 语句记录触犯该规则的节点相关数据注意:1:类 `MethodParamsNumRule ` 继承自 `com.alibaba.p3c.pmd.lang.java.rule.AbstractAliRule` ,AbstractAliRule继承自AbstractJavaRule,重写了setDescription,setMessage和addViolationWithMessage等方法,这里提到的3个方法,增加了多语言支持。2:addViolationWithMessage()方法中的node参数是你触犯规则的具体的代码,切记不要写上一级或者是方法级的节点,这样会造成误报;3:p3c-pmd使用Resource Bundle来提供多语言支持。每个消息都有一个唯一id来对应,p3c-pmd通过重写方法,将方法参数映射为消息的id,以统一消息的配置。如下为本地对应的消息提示内容:<entry key="java.extend.StringSplitRule.rule.msg"><![CDATA[ 云充吧: 使用String.split(String regex)时, 注意regex是否是正则表达式 ]]></entry>
- 5. 创建自己的xml规则文件,内容包括规则的相关信息。
现在规则已经写完了,我们需要告诉PMD运行时执行这条规则,就得将这个规则文件的相关信息放在XML规则集文件中。例如: `pmd-java/src/main/resources/rulesets/java/extend.xml` ;这里面有很多规则的定义,复制粘贴一下,改成一个新的规则集文件,名字自己随便取: `MethodParamsNumRule.xml` ,自己填充一下元素和属性。name - MethodParamsNumRulemessage - java.extend.MethodParamsNumRule.rule.msgclass - com.alibaba.p3c.pmd.lang.java.rule.extend.MethodParamsNumRul 放哪都行. 注意,没有必要放在 `net.sourceforge.pmd` 目录下,可以放在 `com.yourcompany.util.pmd` description - 具体描述信息example - 通过代码片段展示违反的规则样例
<!-- 方法的参数 --><rule name="MethodParamsNumRule"language="java"message="java.extend.MethodParamsNumRule.rule.msg"class="com.alibaba.p3c.pmd.lang.java.rule.extend.MethodParamsNumRule"><priority>2</priority><example><![CDATA[public class Example {public void fn(int a, int b, int c,int d, int f, int g) {dosomething();}
}]]></example></rule>
- 6: 测试规则
PMD推荐对于每个规则,至少要有一个正向和逆向的测试用例,来验证规则出现和不出现的情况。对于规则的测试,PMD也提供了一套框架,只要按照约定好的方式添加xml测试文件即可。PMD约定了几个规则,用来加载测试案例- 测试类要继承 `net.sourceforge.pmd.testframework.SimpleAggregatorTst类,该整合了Junt,可以在里面增加需要的测试方法。
- 对于在 `src/test/resource` 和测试类对应的路径下增加一个xml目录,在增加同第一步同名的xml文件,该文件用于书写测试集。
例子:
规则实现类路径如下:net.sourceforge.pmd.lang.java.rule.extend.EntityNullRuleTest
测试案例集如下:src/test/resources/net/sourceforge/pmd/lang/java/rule/extend/xml/MethodParamsNumRule.xml
按照规则建出文件进行测试,
- 7: 本地 mvn install
测试通过,已经完成了自定义规则的实现,现在就是要把该内容应用到ide上了。首先,需要将该模块进行编译,这里直接保存到本地maven参考,好在本地调试。 直接将p3c-pmd的版本升级为2.0.1,然后执行mvn install,可以在本地仓库看到对应的版本
- 8:buildPlugin (本案例选用的是idea-plugin);
idea-plugin主要实现了idea的插件,能够对代码进行实时检查。这里涉及到idea自定义插件的开发,这里就不深入了,网上有很多教程。这里只介绍如何将上面自定义的规则接入该模块。
注意: 配置gradle对应的版本, 本次pmd 使用的是gradle-4.4,高版本可能会build失败
allprojects {group 'com.alibaba.p3c.idea'apply plugin: 'java'apply plugin: 'kotlin'apply plugin: 'maven-publish'sourceCompatibility = 1.8compileJava.options.encoding = 'UTF-8'configurations.all {resolutionStrategy.cacheChangingModulesFor 0, 'seconds'}repositories {mavenLocal() //注意jcenter()mavenCentral()}dependencies {compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"testCompile group: 'junit', name: 'junit', version: '4.11'}
}
1.修改idea-plugin模块的build.gradle文件,开启本地仓库配置,以便从本地直接加载最新的p3c-pmd依赖。
如上,增加了 `mavenLocal()`
2.修改p3c-common的build.gradle,更改p3c-pmd的版本为2.0.1
3.修改p3c-common模块resources/rulesets/java/ali=pmd.xml,增加`<rule ref="rulesets/java/ali-extend.xml"/>`
以增加自定义规则检查。
4.在p3c-common模块下,执行 `gradle clean buildPlugin` ,生成对应的插件。
- 9. 验证
本地安装该插件,可以得到如下效果
扩展Alibaba P3C 实现自定义代码规范检查相关推荐
- swift/dart代码规范检查工具介绍
swift/dart代码规范检查工具介绍 简介: 本篇主要介绍swift和dart代码规范检查工具,以及他们的工作原理,操作过程,代码规范规则. 1 swift代码检查工具-swiftlint 1.1 ...
- IDEA安装阿里代码规范检查插件
IDEA安装阿里代码规范检查插件 1.安装插件 2.下载本地zip包插件并安装 3.代码检查 观前提示: 本文所使用的IDEA版本为ultimate 2019.1. 近来,公司要求代码规范检查,自己想 ...
- 代码规范检查工具+代码规范生成工具
代码规范检查工具: 1. arc lint arc diff时会自动执行arc lint,arc lint会根据配置文件(.arclint)进行代码规范检查,并且只检查最新的提交:需要在每个git仓库 ...
- php SonarLint 代码规范检查提示整理
php SonarLint 代码规范检查提示整理 **1. add curly braces around the nested statement(在嵌套语句周围添加花括号)** 2.Refacto ...
- PhpStorm添加PHP代码规范检查CodeSniffer(phpcs)和PHP代码静态分析工具Mess Detector(phpmd)
首先需要了解一下这些工具是用来干什么: PHPCS 是 PHP Code Sniffer,一款代码规范检查工具,可以根据你的设置来检查代码规范性问题. PHPCBF 是PHPCS 内置的代码规范修复工 ...
- Java代码规范检查插件调研及总结
代码规范工具对比 代码规范工具是什么 大家应该都有过写完代码后review的情况:用于提高编码质量,尽早的发现问题:节约开发时间和成本. 但review 这个过程往往要消耗 更多的开发资源. 所以就出 ...
- IDEA工具(阿里巴巴)代码规范检查插件
1.代码规范 因为软件是需要人来维护的.这个人在未来很可能不是你.所以首先是为人编写程序,其次才是计算机 不要过分追求技巧,降低程序可读性. 简洁的代码可以让BUG无处藏身.要写出明显没有BUG的代码 ...
- 使用Pylint进行Python代码规范检查
在上一篇中讲了autopep8的应用<使用aotupep8自动批量调整代码以符合PEP-8规范>,有时候只需要检查并提示,并不希望"自动修改",这个时候就该Pylint ...
- 玩转Eclipse — 自动代码规范检查工具Checkstyle
大项目都需要小组中的多人共同完成,但是每个人都有自己的编码习惯,甚至很多都是不正确的.那么如何使小组所有开发人员都遵循某些编码规范,以保证项目代码风格的一致性呢?如果硬性地要求每个开发人员在提交代码之 ...
- IDEA 阿里巴巴代码规范检查插件使用
1.问题概要 大家都想写出规范的代码,可规范的标准是什么勒,估计每个人心中的标准都不是完全一致的 在分工合作越来越精细化的时代,我们需要一个最大程度接近公认的规范,这里我们以阿里巴巴的代码规范作为参考 ...
最新文章
- 中国队蝉联国际奥数冠军,6名选手获5金1银,3人保送北大、3人保送清华
- python语言教程-Python语言教程手册
- spring和mybatis整合进行事务管理
- 8.初探python之集合
- TypeError: 'dict' object is not callable
- 如何开启一个Django项目
- 【ES】ES检索的时候特殊字符该怎么处理
- 思科模拟器去除登陆界面
- C++ Learning (Next)
- 区块链技术应用与安全发展
- Windows Live Writer插件开发经验
- com lofter android,LOFTER
- 华为服务器自检信息怎么开,hp服务器开机自检报错提示
- HTML中的 后代选择器 和 子代选择器
- androidP Surface到SurfaceFlinger -->surface -> BufferQueue(一)
- 年薪50万,淘宝特价版重金招人
- 程序,人生,人生,程序。。。
- codeforces 1299A Anu Has a Function
- Android解锁黑屏问题完美解决!
- canvas 刻度尺