当前位置:首页 > 技术 > 正文内容

打造企业自己代码规范IDEA插件(中)

Lotus2022-10-06 19:05技术

一些基本概念

在开始独立研发公司自己的代码规范检查规则之前,先介绍一些相关的基本概念。阿里巴巴代码规范很多规则其实都是基于开源框架PMD进行的研发。PMD用官方的话语介绍来说:PMD是一个源代码分析器。它可以发现常见的编程缺陷,如未使用的变量、空catch块、不必要的对象创建等。它支持多种语言。它可以用自定义规则进行扩展。它使用JavaCC和Antlr将源文件解析为抽象语法树(AST),并对其运行规则以查找冲突。规则可以用Java编写,也可以使用XPath查询。开源代码库:​https://github.com/pmd/pmd

这里涉及到一个很关键的概念——AST 抽象语法树(Abstract Syntax Tree)。AST运用场景其实非常多,日常我们研发过程中错误提示、代码高亮、代码格式化、代码转译等等实现的基础都基于AST。简单说,会通过词法分析和语法分析将代码转化成一种类似树样层次结构来进行描述,当然这种描述可以用XML格式。文字描述比较抽象,不妨看一个“Hello world”的具体AST语法树(Java 1.8),这样就很容易进行理解了。

打造企业自己代码规范IDEA插件(中)_3c

另外一个概念XPath 是一门在XML 文档中查找信息的语言。本身和代码解析没有关系,但当AST通过XML格式描述时,XPath能够很好完成对相关节点进行查找。两者的结合就能进行违规代码的检查,这就是XPath规则代码规范检查基本原理。此外,与其配套的PMD-Designer规则可视化工具也很好用。

​例如阿里巴巴代码规范中 PackageNamingRule 就是非常典型的XPath规则。包名只能由小写字母、数字来组成,具体的XPath:

private static final String XPATH = "//PackageDeclaration/Name"
+ "[not (matches(@Image, '^[a-z0-9]+(\\.[a-z][a-z0-9]*)*$'))]";

下面先写个规则的例子来感受下自定义规则具体的操作;从检查代码中System.out 类似的日志输出开始。

​Example :检查代码中System.out 类似的日志输出。

步骤一,运用PMD-Designer 来辅助编写具体XPath的检查规则;这个工具也可以验证各种代码写法下,规则是否都能起到很好的作用。最终XPath 具体规则如下:

//Name[starts-with(@Image, 'System.out.print') or starts-with(@Image, 'System.err.print')]

步骤二,新建一个具体的规则类,继承AbstractXpathRule ;其中AbstractXpathRule 本身是继承 PMD 中 XPathRule,主要扩展了多语言的设计。详细如下:

package com.alibaba.p3c.pmd.lang.java.rule.emo;  
  
import com.alibaba.p3c.pmd.I18nResources;  
import com.alibaba.p3c.pmd.lang.AbstractXpathRule;  
import com.alibaba.p3c.pmd.lang.java.util.ViolationUtils;  
import net.sourceforge.pmd.lang.ast.Node;  
  
import static net.sourceforge.pmd.lang.rule.xpath.XPathRuleQuery.XPATH_2_0;  
  
public class VoidSystemPrintRule extends AbstractXpathRule {  
    private static final String XPATH =  
            "//Name[starts-with(@Image, 'System.out.print') or starts-with(@Image, 'System.err.print')]";  
  
    public VoidSystemPrintRule() {  
        setXPath(XPATH);  
        setVersion(XPATH_2_0);  
    }  
  
    @Override  
    public void addViolation(Object dataNode nodeString arg) {  
        ViolationUtils.addViolationWithPrecisePosition(thisnodedata,  
                I18nResources.getMessage("java.naming.VoidSystemPrintRule.violation.msg"node.getImage()));  
    }  
}  

步骤三:在messages.xml 和 messages_en.xml 分别添加检查出错后给出相关中英文提示。

<entry key="java.naming.VoidSystemPrintRule.violation.msg">
<![CDATA[程序中避免直接使用 System 对相关日志信息输出]]>
</entry>
——
<entry key="java.naming.VoidSystemPrintRule.violation.msg">
<![CDATA[Avoid using system print]]>
</entry>

步骤四:新建emo-common.xml 的规则集合,并将实现的规则配置进去。

<ruleset name="AlibabaJavaNaming" 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">
<description>EmoJavaCommonRule</description>
<rule name="VoidSystemPrintRule"
language="java"
since="1.6"
message="java.naming.VoidSystemPrintRule.violation.msg"
class="com.alibaba.p3c.pmd.lang.java.rule.emo.VoidSystemPrintRule">
<priority>3</priority>
<example>
<![CDATA[
System.out.println(message);
]]>
</example>
</rule>
</ruleset>

​步骤五:在ali-pmd.xml 中引入我们新加的规则集合 emo-common.xml。

<rule ref="rulesets/java/emo-common.xml"/>

最后运行下修改完的代码程序,效果如下:

打造企业自己代码规范IDEA插件(中)_xml_02

打造企业自己代码规范IDEA插件(中)_java_03

附上相关代码github链接:​​https://github.com/ariesfly/emo-coding-guardian​​ 如有遇到问题欢迎公众号(Java研究者)私信留言!

打造企业自己代码规范IDEA插件(中)_xml_04

扫描二维码推送至手机访问。

版权声明:本文来源于网络,仅供学习,如侵权请联系站长删除。

本文链接:https://news.layui.org.cn/post/139.html

分享给朋友:

“打造企业自己代码规范IDEA插件(中)” 的相关文章

第三章 知己知彼

知彼知己,百战不殆;不知彼而知己,一胜一负;不知彼,不知己,每战必殆。《谋攻篇》 前面两章其实重点是在掰扯数智化,IT研发本身的数字化其实除了DevOps这一种手段之外还有很多,比如Low Code、RPA等等,AI都可以自动写代码了,还有啥是不可能的呢!不过本人能力有限,这点斤两也就敢玩玩DevOps,其他的碰都就不敢碰,接下来聚焦到DevOps的一些见解上。 3.1 剑锋所指      ...

多功能手持VH501TC采集仪如何设置振弦传感器的激励方法和激励电压

河北稳控科技多功能手持VH501TC采集仪如何设置振弦传感器的激励方法和激励电压 VH501TC 提供多种振弦传感器激励方法,以最大限度兼容所有厂家和型号的振弦传感器。 振弦传感器激励方法参数位于实时数据窗口右侧,共有 5 种方法可选,分别用 MODTH0~MODTH4 表示。各方法说明如下: 激励电压数据在屏幕上显示为 xxx/xxx 的形式,其中前面的数字表示实际的激励电压,后面的数字...

C++浅拷贝深拷贝

1. C++ 浅拷贝 什么是浅拷贝? 一般比较形象的理解,浅拷贝可以理解"值"层面的拷贝,深拷贝可以理解成"内存"上的拷贝,特别是类里面含有指针类型的。 // .h文件class HasPtrMem{public:HasPtrMem();HasPtrMem(const HasPtrMem& h);~HasPtrMem();void print();int *p;};// .cpp 文件H...

前端三剑客快速入门(二)

前言 本文书接上回,继续css的知识,序号就重新开始了。上篇内容:前端三剑客快速入门(一) CSS 盒子模型 盒子模型属性: border外框 margin外边距 padding内边距 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <me...

十年技术进阶路,让我明白了三件要事(8000字长文)

前言   【本文于2022-5-10日首发于ITPUB微信公众号平台】   该篇文章是我第一次跟DTCC合作编写的,整篇文章大概8000字,可能花您15分钟阅读。我和DTCC的韩楠老师,共花7了天时间,每天把该文章打磨到晚上12点,在这非常感谢编辑老师的负责与付出。   这篇也是我分享里为数不多“进阶”与“成长经历”的文章之一。被别人送到嘴边的食物永远是最香的,但是咱们还是得学会主动去"如何找吃的...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。