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 实现自定义代码规范检查相关推荐

  1. swift/dart代码规范检查工具介绍

    swift/dart代码规范检查工具介绍 简介: 本篇主要介绍swift和dart代码规范检查工具,以及他们的工作原理,操作过程,代码规范规则. 1 swift代码检查工具-swiftlint 1.1 ...

  2. IDEA安装阿里代码规范检查插件

    IDEA安装阿里代码规范检查插件 1.安装插件 2.下载本地zip包插件并安装 3.代码检查 观前提示: 本文所使用的IDEA版本为ultimate 2019.1. 近来,公司要求代码规范检查,自己想 ...

  3. 代码规范检查工具+代码规范生成工具

    代码规范检查工具: 1. arc lint arc diff时会自动执行arc lint,arc lint会根据配置文件(.arclint)进行代码规范检查,并且只检查最新的提交:需要在每个git仓库 ...

  4. php SonarLint 代码规范检查提示整理

    php SonarLint 代码规范检查提示整理 **1. add curly braces around the nested statement(在嵌套语句周围添加花括号)** 2.Refacto ...

  5. PhpStorm添加PHP代码规范检查CodeSniffer(phpcs)和PHP代码静态分析工具Mess Detector(phpmd)

    首先需要了解一下这些工具是用来干什么: PHPCS 是 PHP Code Sniffer,一款代码规范检查工具,可以根据你的设置来检查代码规范性问题. PHPCBF 是PHPCS 内置的代码规范修复工 ...

  6. Java代码规范检查插件调研及总结

    代码规范工具对比 代码规范工具是什么 大家应该都有过写完代码后review的情况:用于提高编码质量,尽早的发现问题:节约开发时间和成本. 但review 这个过程往往要消耗 更多的开发资源. 所以就出 ...

  7. IDEA工具(阿里巴巴)代码规范检查插件

    1.代码规范 因为软件是需要人来维护的.这个人在未来很可能不是你.所以首先是为人编写程序,其次才是计算机 不要过分追求技巧,降低程序可读性. 简洁的代码可以让BUG无处藏身.要写出明显没有BUG的代码 ...

  8. 使用Pylint进行Python代码规范检查

    在上一篇中讲了autopep8的应用<使用aotupep8自动批量调整代码以符合PEP-8规范>,有时候只需要检查并提示,并不希望"自动修改",这个时候就该Pylint ...

  9. 玩转Eclipse — 自动代码规范检查工具Checkstyle

    大项目都需要小组中的多人共同完成,但是每个人都有自己的编码习惯,甚至很多都是不正确的.那么如何使小组所有开发人员都遵循某些编码规范,以保证项目代码风格的一致性呢?如果硬性地要求每个开发人员在提交代码之 ...

  10. IDEA 阿里巴巴代码规范检查插件使用

    1.问题概要 大家都想写出规范的代码,可规范的标准是什么勒,估计每个人心中的标准都不是完全一致的 在分工合作越来越精细化的时代,我们需要一个最大程度接近公认的规范,这里我们以阿里巴巴的代码规范作为参考 ...

最新文章

  1. 中国队蝉联国际奥数冠军,6名选手获5金1银,3人保送北大、3人保送清华
  2. python语言教程-Python语言教程手册
  3. spring和mybatis整合进行事务管理
  4. 8.初探python之集合
  5. TypeError: 'dict' object is not callable
  6. 如何开启一个Django项目
  7. 【ES】ES检索的时候特殊字符该怎么处理
  8. 思科模拟器去除登陆界面
  9. C++ Learning (Next)
  10. 区块链技术应用与安全发展
  11. Windows Live Writer插件开发经验
  12. com lofter android,LOFTER
  13. 华为服务器自检信息怎么开,hp服务器开机自检报错提示
  14. HTML中的 后代选择器 和 子代选择器
  15. androidP Surface到SurfaceFlinger -->surface -> BufferQueue(一)
  16. 年薪50万,淘宝特价版重金招人
  17. 程序,人生,人生,程序。。。
  18. codeforces 1299A Anu Has a Function
  19. Android解锁黑屏问题完美解决!
  20. canvas 刻度尺

热门文章

  1. .net 事务嵌套存储过程事务的处理方法
  2. 模糊C均值聚类算法matlab实现,FCMClust(模糊c均值聚类算法MATLAB实现)
  3. 数据清洗案例 OpenRefine入门
  4. 【MATLAB项目实战】基于SPI指数的某地区地区干旱时空特征分析
  5. k8s集群的搭建-云服务器
  6. pycharm安装jpype报错及解决方法
  7. 素数筛 python
  8. 动态规划-自底向上的 0-1 背包问题
  9. 微信小程序 抓css,微信小程序css篇
  10. 计数器代码php,php的计数器程序_php