Google checkstyle实战

news2024/11/17 17:52:03

概述

CheckStyle检查代码是否符合制定的规范。CheckStyle检查是基于源码的,无需编译,执行速度快。

CheckStyle的主要流程是:

  1. 对Java文件进行词法语法分析,生成语法树。
  2. 载入配置文件(checkstyle-metadata.xml以及自定义的配置文件)register check事件。
  3. 按照深度优先遍历对语法树进行解析,按照注册的事件,在到达某些节点(AST)时进行style检查。AST,A child-Sibling Tree,是语法树中的某个节点,其类型在TokenTypes类中定义。
  4. 自定义Style的检查,就是在第二步设定的。实现com.puppycrawl.tools.checkstyle.api.Check类,重载其中的两个方法:public int[] getDefaultTokens()public void visitToken(DetailAST ast)。这两个方法的含义为,在遍历语法树的过程中,每当到达getDefaultTokens函数所返回的AST类型,程序就进入visitToken进行具体的检查和分析,即真正的分析检查过程是在visitToken中实现的。

CheckStyle有针对不同IDE和构建工具的各种插件,如 maven-checkstyle-plugin 插件,配置很简单:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-checkstyle-plugin</artifactId>
    <version>3.3.1</version>
    <configuration>
    	<!--内置4种规范:config/sun_checks.xml、config/maven_checks.xml、config/turbine_checks.xml、config/avalon_checks.xml、其中sun_checks.xml为默认值。修改默认配置-->
    	<configLocation>google_checkstyle.xml</configLocation>
    </configuration>
    <executions>
        <execution>
            <id>checkstyle</id>
            <phase>validate</phase>
            <goals>
                <goal>check</goal>
            </goals>
            <configuration>
                <failOnViolation>true</failOnViolation>
            </configuration>
        </execution>
    </executions>
</plugin>

定义在maven lifecycle的validate阶段执行check task,并且如果发现有违反标准的情况就会fail当前的build。运行checkstyle检查:mvn checkstyle:checkstyle

跳过对指定文件的某些检查

  • suppression:忽略指定文件的问题检查,不推荐;
  • 新增checkstyle-suppressions.xml文件suppressions配置项:
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
        "-//Puppy Crawl//DTD Suppressions 1.0//EN"
        "http://www.puppycrawl.com/dtds/suppressions_1_0.dtd">
<suppressions>
    <suppress checks="LineLengthCheck"
              files="SessionMessageSource.java"/>
</suppressions>

<suppressionsLocation>${basedir}/src/config/checkstyle-suppressions.xml</suppressionsLocation>
然后在配置文件里面可以定义一系列可用的模块,每一个模块提供严格程度(强制的,可选的…)可配置的检查规则。规则可以触发通知(notification),警告(warning)和错误(error)。
附:google-checkstyle

特点:

  1. 它可以有效的帮助我们检视代码以便更好的遵循代码编写标准,特别适用于小组开发时彼此间的样式规范和统一。
  2. Checkstyle提供高可配置性,以便适用于各种代码规范,所以除了使用它提供的几种常见标准之外,你也可以定制自己的标准。
  3. Checkstyle提供支持大多数常见IDE的插件,大部分插件中就含有最新的Checkstyle。
  4. Checkstyle可以检查代码的很多方面,从传统观点看,它主要是用来检查代码层面的,自从第三版以后,它的内部架构作了重大改变,很多其它意图的检测加了进来,现在Checkstyle可以检查像类设计的问题,重复代码,如锁的双重检查的bug模式。

报错

Token “METHOD_REF” was not found in Acceptable tokens list in check SeparatorWrapCheck

在IDEA的Terminal执行mvn clean compile报错:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-checkstyle-plugin:3.0.0:check (checkstyle) on project test: Failed during checkstyle configuration: cannot initialize module TreeWalker - Token "METHOD_REF" was not found in Acceptable tokens list in check com.puppycrawl.tools.checkstyle.checks.whitespace.SeparatorWrapCheck.

参考stackoverflow问答java-google-checkstyle-maven:

You are trying to use a newer configuration with an old version of Checkstyle.

上面的报错信息提示,使用的Maven插件版本为3.0.0,升级到当前最新版3.3.1解决问题。

TreeWalker is not allowed as a parent of LineLength Please review ‘Parent Module’ section for this Check in web documentation if Check is standard.

继续执行mvn clean compile报错:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-checkstyle-plugin:3.3.1:check (checkstyle) on project test: Failed during checkstyle configuration: cannot initialize module TreeWalker - TreeWalker is not allowed as a parent of LineLength Please review 'Parent Module' section for this Check in web documentation if Check is standard.

参考GitHub issue,LineLength本来在TreeWalker module下面,提升到与TreeWalker同级的module,解决问题。
在这里插入图片描述
虽然解决问题,但是这样下去感觉问题会无穷无尽。

升级配置文件

考虑到上面升级过maven插件,即maven-checkstyle-plugin到最新版,那配置文件是不是也得一起升级下?打开托管在GitHub的官方配置文件google_checks,借助于diffchecker这类在线文本对比工具,好家伙。本地配置文件和GitHub里的配置文件相差也太大了吧。是该更新一下了!!

至于为何不直接使用存放在GitHub上的配置文件?这样的话,可以保证一直使用最新的配置文件。而要使用一个下载到本地的必定会过期的备份配置文件?主要是两点考量:

  1. The Wall的存在,访问GitHub速度不是很快很稳定;
  2. 一份可用的配置文件可以保证团队成员使用尽可能相同的编码规范。

Token “LITERAL_SWITCH” was not found in Acceptable tokens list in check RightCurlyCheck.

继续执行mvn clean compile依旧报错:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-checkstyle-plugin:3.3.1:check (checkstyle) on project test: Failed during checkstyle configuration: cannot initialize module TreeWalker - Token "LITERAL_SWITCH" was not found in Acceptable tokens list in check com.puppycrawl.tools.checkstyle.checks.blocks.RightCurlyCheck.

不会吧。插件和配置文件都是最新的,配置文件是官方提供的,没有任何修改。

搜索google_checkstyle.xml文件,可以找到LITERAL_SWITCH及RightCurly。分析此最新版配置文件,不难得出结论:

  • checkstyle有若干个module组成,表示各个不同检查环节
  • LineLength不再是TreeWalker module下的子module,而是和TreeWalker同级,这也正好印证上面一个问题
  • TreeWalker下有若干个module,一个module对应一个方法,如com.puppycrawl.tools.checkstyle.checks.blocks.RightCurlyCheck
  • 那token是什么呢?进阶章节会继续研究

回到问题本身。分析报错,大意是在RightCurly这个module里有个tokens属性字段里不能出现LITERAL_SWITCH?

抱着试一试的想法,修改官方提供的配置文件,删除RightCurly module下LITERAL_SWITCH这个token。

再次执行mvn clean compile,上面这个报错消失。出现新的报错,不过其形式和上面的报错一模一样。那就依样画瓢,找到报错的module和token,删除。最后执行mvn clean compile成功。

进阶

源码分析

上面留下一个疑问:token是什么?

看到完整包路径com.puppycrawl.tools.checkstyle.checks.blocks.RightCurlyCheck,不难找到maven依赖:

<dependency>
    <groupId>com.puppycrawl.tools</groupId>
    <artifactId>checkstyle</artifactId>
    <version>10.13.0</version>
</dependency>

包结构如下:
在这里插入图片描述
配置文件google_checkstyle.xml里的module对应的**Check类全部位于com.puppycrawl.tools.checkstyle.checks包下面。并且Check也模块化,有一下几种类型:
在这里插入图片描述
与此同时,在目录com.puppycrawl.tools.checkstyle.meta.blocks.blocks下面有一个xml文件RightCurlyCheck.xml,和Check方法一一对应。配置文件里的module对应一个继承AbstractCheck的Check方法,对应一个**Check.xml配置文件。

NoLineWrapCheck.xml文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<checkstyle-metadata>
   <module>
      <check fully-qualified-name="com.puppycrawl.tools.checkstyle.checks.whitespace.NoLineWrapCheck"
             name="NoLineWrap"
             parent="com.puppycrawl.tools.checkstyle.TreeWalker">
         <description>Checks that chosen statements are not line-wrapped. By default, this Check restricts wrapping import and package statements, but it's possible to check any statement.</description>
         <properties>
            <property default-value="PACKAGE_DEF,IMPORT,STATIC_IMPORT"
                      name="tokens"
                      type="java.lang.String[]"
                      validation-type="tokenSet">
               <description>tokens to check</description>
            </property>
         </properties>
         <message-keys>
            <message-key key="no.line.wrap"/>
         </message-keys>
      </check>
   </module>
</checkstyle-metadata>

check下的name和配置文件google_checkstyle.xml的module name正好对应,parent指向TreeWalker,fully-qualified-name指向Java类文件。properties定义检查的token。

token是什么,回到文章开头,提到AST语法树及TokenTypes类。

借助于IDEA Double Shift快捷键以及左侧的项目视图,不难快速找到com.puppycrawl.tools.checkstyle.api.TokenTypes类文件,定义194个静态常量。以及tokentypes.properties配置文件,里面正好也是194行。经过对比,是一一对应的。

tokentypes.properties文件样例:

OBJBLOCK=An object block.

message-keys

参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1476383.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解密逃脱路径判断算法

介绍 在计算机科学领域&#xff0c;有许多有趣的算法问题需要解决。其中之一就是判断在给定条件下是否存在逃脱路径的问题。本篇博客将介绍如何使用广度优先搜索&#xff08;BFS&#xff09;算法来解决这个问题。 问题背景 假设有一个二维平面上的迷宫&#xff0c;某人被困在…

【AI绘画·24年1月最新】Stable Diffusion整合包安装!解压即用--秋葉aaaki 大佬的作品,试用

前言 Stable Diffusion 之前费老大的劲部署安装&#xff0c;解决报错。搞完之后&#xff0c;突然发现有个现成集成包可以用&#xff0c;真是效率高到不行&#xff0c;今天搞下来试试 我电脑配置&#xff1a; CPU: 12th Gen Intel Core™ i7-12700F 2.10 GHz 内存32G&#xff0…

解决鸿蒙模拟器卡顿的问题

缘起 最近在学习鸿蒙的时候&#xff0c;发现模拟器非常卡&#xff0c;不要说体验到鸿蒙的丝滑&#xff0c;甚至到严重影响使用的程度。 根据我开发Android的经验和在论坛翻了一圈&#xff0c;最终总结出了以下几个方案。 创建模拟器 1、在DevEco Virtual Device Configurat…

【Go语言】Go语言中的指针

Go语言中的指针 变量的本质是对一块内存空间的命名&#xff0c;我们可以通过引用变量名来使用这块内存空间存储的值&#xff0c;而指针则是用来指向这些变量值所在内存地址的值。 注&#xff1a;变量值所在内存地址的值不等于该内存地址存储的变量值。 Go语言中&#xff0c;…

vue3+vite+ts配置多个代理并解决报404问题

之前配置接口代理总是报404,明明接口地址是对的但还是报是因数写法不对;用了vue2中的写法 pathRewrite改为rewrite 根路径下创建env文件根据自己需要名命 .env.development文件内容 # just a flag ENVdevelopment# static前缀 VITE_APP_PUBLIC_PREFIX"" # 基础模块…

Dockerfile(2) - LABEL 指令详解

LABEL 可以为生成的镜像添加元数据标签信息&#xff0c;这些信息可以用来辅助过滤出特定镜像 LABEL <key><value> <key><value> <key><value> ... 栗子一 # key 加了 " LABEL "com.example.vendor""ACME Incorpor…

【活动】前端世界的“祖传代码”探秘:从古老魔法到现代重构

作为一名前端工程师&#xff0c;我时常在项目中邂逅那些被岁月打磨过的“祖传代码”。它们就像古老的魔法书页&#xff0c;用HTML标签堆砌起的城堡、CSS样式表中的炼金术&#xff0c;以及JavaScript早期版本中舞动的符咒。这些代码承载着先驱们的探索精神和独特智慧&#xff0c…

postman测试接口

1、postman测试接口 &#xff08;1&#xff09;首先安装postman 下载地址&#xff1a;Download Postman | Get Started for Free 选择对应版本下载&#xff0c;然后安装即可 &#xff08;2&#xff09;使用postman发送请求 比如以下这个请求例子&#xff1a; 使用postman发…

ArmV8架构

Armv8/armv9架构入门指南 — Armv8/armv9架构入门指南 v1.0 documentation 上面只是给了一个比较好的参考文档 其他内容待补充

Rocky Linux 运维工具 firewall-cmd

一、firewall-cmd​的简介 ​​firewall-cmd​是基于firewalld的防火墙管理工具。用户可以使用它来配置、监控和管理防火墙规则&#xff0c;包括开放端口、设置服务规则等。 二、firewall-cmd​​的参数说明 序号参数描述1​​–zone指定防火墙区域2–add-portxxx/tcp允许特定…

【查漏补缺你的Vue基础】Vue数据监听深度解析

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【笔记】:更方便的将一个List中的数据传入另一个List中

这里是 simpleInfoList 集合&#xff0c;记为集合A&#xff08;传值对象&#xff09; List<CourseSimpleInfoDTO> simpleInfoList courseClient.getSimpleInfoList(courseIds);if(simpleInfoListnull){throw new BizIllegalException("当前课程不存在!");}这…

深度学习与神经网络:构建智能系统的基石

一、引言 1、介绍深度学习和神经网络的背景和发展历程 深度学习和神经网络的背景和发展历程可以追溯到上世纪40年代和50年代的人工神经网络研究。当时&#xff0c;研究人员开始尝试模拟生物神经元之间的连接方式&#xff0c;构建了早期的神经网络模型。然而&#xff0c;由于计…

【Redis】深入理解 Redis 常用数据类型源码及底层实现(5.详解List数据结构)

本文是深入理解 Redis 常用数据类型源码及底层实现系列的第5篇&#xff5e;前4篇可移步(&#xffe3;∇&#xffe3;)/ 【Redis】深入理解 Redis 常用数据类型源码及底层实现&#xff08;1.结构与源码概述&#xff09;-CSDN博客 【Redis】深入理解 Redis 常用数据类型源码及底…

“智农”-大棚可视化

基于自主可控的数字孪生技术、物联网技术、大数据技术&#xff0c;构建全流程的新型农业一体化管理平台&#xff0c;围绕产运销管理全流程&#xff0c;实现生产->存储->包装->运输->销售的全链条管理。融合农业数据管理、农业数据预警显示、多维数据综合显示、农产…

IDEA基础——Maven配置tomcat

配置方案 一、配置maven-tomcat plugin插件&#xff08;只最高支持到tomcat 8&#xff09;~~1.添加镜像源&#xff0c;获取tomcat 8插件配置~~~~1.1 在pom.xml里先添加镜像源~~~~1.2 添加tomcat插件配置~~ 2. 添加tomact官方发布的插件配置&#xff08;无需添加镜像源&#xff…

从 0 到 1 搭建亿级商品 ES 搜索引擎

建设并维护一个亿级的搜索引擎并非易事&#xff0c;也不存在一劳永逸的最优治理方法。本文是在实践中不断学习和总结的成果&#xff0c;介绍了如何搭建一个可支持从千万级到亿级商品量级的搜索系统&#xff0c;并实现查询总 QPS 从百级增长到千级&#xff0c;写入总 QPS 从百级…

数据卷(Data Volumes) 自定义镜像(dockerfile)

目录 一. 数据卷&#xff08;Data Volumes&#xff09; 1.1 什么是数据卷 1.2 为什么需要数据卷 1.3 数据卷的作用 1.4 数据卷的使用 二. 自定义镜像&#xff08;dockerfile&#xff09; 2.1 什么是dockerfile 2.2 自定义centos 2.3 自定义tomcat 一. 数据卷&#xff08;Data…

【学习记录】HC32F460USB——U盘IAP升级app

从头开始&#xff0c;万物从解压开始 直奔猪蹄&#xff0c;找到usb下的工程文件 开始移植 主要移植IAP的boot和fatfs的文件系统&#xff0c;fatfs官网去下载ff15.0版本&#xff0c;目前用这个 放到项目里 添加到工程文件中 改引脚&#xff0c;给USB放电 编译&#xff0c;可以…

java自动化之自动化框架项目(第三天-测试数据注入到测试方法)

接第二天 1.实现目标 这里我们是数据驱动方式&#xff0c;把数据注入到测试方法&#xff0c;在测试方法中就可以获取对象中的数据。 2.注入测试数据 上一篇我们已经把用例数据封装到对象并放到list中&#xff0c;这里我们把用例对象list中的对象分别放到Object类型的一维数…