2017年6月26日星期一

开发工具之 - CheckStyle

CheckStyle

http://checkstyle.sourceforge.net/config.html

概述

Checkstyle是在软件开发中的一种静态代码分析工具,用来检查Java源代码是否匹配编码规则。Checkstyle定义了一组可用的模块,每个模块都提供可配置严格程度的规则(强制性的、可选的等). Checkstyle的模块以树形结构组织,跟模块为【Checker】。它的下一级模块包括:
  • FileSetChecks - 使用一组输入文件并产生错误消息的模块。
  • Filters - 过滤审核事件的模块,包括错误消息以供接受。
  • AuditListeners - 报告接受事件的模块。
许多check是TreeWalker FileSetCheck模块的子模块。 TreeWalker通过将每个Java源文件单独转换为抽象语法树,然后将结果传递给每个子模块,每个子模块检查不同的内容。
Checkstyle从XML文档中获取配置,该文档的元素指定了模块的配置层次结构及其属性。 当您在命令行调用Checkstyle时,以及在ant中运行Checkstyle任务时,您将提供一个包含配置文档的文件。 Checkstyle发行版的文档目录包含一个示例配置文件sun_checks.xml ,它配置Checkstyle以检查Sun编码约定。

模块(Modules)

XML配置文档中的module元素通过元素的name属性来定义一个模块。
以下是典型配置文档的一个片段:
 <module name =“Checker”>
     <module name =“JavadocPackage”/>
     <module name =“TreeWalker”>
         <module name =“AvoidStarImport”/>
         <module name =“ConstantName”/>
         <module name =“EmptyBlock”/>
     </module>
 </module>
在此配置中:
  • 根模块Checker有子模块 FileSetChecks类型的 JavadocPackage和TreeWalker 。 (模块JavadocPackage检查所有包都有包文档。)
  • 模块TreeWalker具有子模块AvoidStarImport , ConstantName和EmptyBlock 。 (Modules AvoidStarImport , ConstantName和EmptyBlock检查Java源文件没有星号导入,分别具有有效的常量名称,并且没有空块)。
对于每个配置模块,Checkstyle加载由模块的name属性标识的类。 加载模块的类有几个规则:
  1. 根据包限定名称直接加载类,如加载类com.puppycrawl.tools.checkstyle.TreeWalker for element:
    <module name =“com.puppycrawl.tools.checkstyle.TreeWalker”/>
这对于将第三方模块插入到配置中很有用。
  1. 加载一个预定义的包,如加载类com.puppycrawl.tools.checkstyle.checks.AvoidStarImport 
    <module name =“AvoidStarImport”/>
Checkstyle应用包com.puppycrawl.tools.checkstyle , com.puppycrawl.tools.checkstyle.filters和com.puppycrawl.tools.checkstyle.checks及其子包(仅包含在Checkstyle发行版中的包)。 当您在命令行调用Checkstyle时,以及在ant中运行Checkstyle任务时,可以在包名称XML文档中指定其他包。
  1. 将上述规则应用于与“检查”连接的名称 ,如加载类com.puppycrawl.tools.checkstyle.checks.ConstantNameCheck for element
    <module name =“ConstantName”/>

属性(Properties)

模块的属性控制模块如何执行其任务。 每个模块属性都有一个默认值,如果默认值满意,则不需要在配置文档中定义一个属性。 要为模块的属性分配非默认值,请在配置XML文档中定义模块元素的子属性元素。 还为属性元素提供适当的名称和值属性。 例如, MethodLength模块的max属性指定方法或构造函数中允许的最大行数,并具有默认值150 。 这是一个模块MethodLength的配置,以便检查报告方法和构造函数有60行以上:
 <module name =“MethodLength”>
     <property name =“max”value =“60”/>
 </module>
命令行属性和ant Checkstyle task 属性适用于根检查器模块。 此外,属性在模块层次结构中是继承的。 这些功能可以轻松定义适用于许多模块的一个属性值。 例如,以下配置片段指定了一个tabWidth为4适用于TreeWalker及其子模块:
 <module name =“Checker”>
     <module name =“JavadocPackage”/>
     <module name =“TreeWalker”>
         <property name =“tabWidth”value =“4”/>
         <module name =“AvoidStarImport”/>
         <module name =“ConstantName”/>
         ...
     </module>
 </module>
可以使用$ { propertyname }表示法通过属性扩展来指定module属性的值,其中propertyname是命令行属性或ant Checkstyle任务属性。 例如,以下配置文档元素给出属性headerFile命令行属性的值checkstyle.header.file :
 <module name =“Header”>
     <property name =“headerFile ”value =“${checkstyle.header.file}”/>
 </module>
 
您可以使用属性扩展来重新指定模块属性值,而无需更改配置文档。
property元素提供了一个可选的默认属性,当该值中的属性无法解析时使用。 例如,来自中央配置文件的此配置代码段会检查方法是否具有javadoc,但允许单个项目通过在命令行属性checkstyle.javadoc.severity中指定所需的值来覆盖严重性:
 <module name =“JavadocMethod”>
   <property name =“severity”
               key= “${checkstyle.javadoc.severity}
               default= “error”/>
 </module>
 
当设置集中式配置文件(例如整个公司的一个文件)以降低配置维护成本时,此功能非常有帮助。 对默认情况下满意的项目可以直接使用该配置文件,但具有特殊需求的单个项目可以灵活调整几个设置以满足其需要,而无需复制和维护整个配置。
您可以在属性类型页面上找到有关属性类型的信息。

检测器 (Checker )

描述

所有配置都有根模块Checker 。 检查器(Checker)包含:
  • FileSetCheck 子模块:检查文件集的模块。
  • Filter 子模块:过滤审核事件的模块。
  • FileFilter 子模块:过滤Checkstyle进行处理的文件的模块。
  • AuditListener 子模块:报告过滤事件的模块。
Checker还定义了由配置文件中所有其他模块继承的属性。

属性

名称描述类型默认值
basedir 基本目录名称;stringnull
cacheFile 缓存有关已经检查OK的文件的信息; 用于避免重复检查相同的文件string null 
localeCountry 消息的本地化设置(国家/地区)/td>string ISO 3166 2-letter codeJava虚拟机的默认区域设置国家/地区
localeLanguage 消息的语言环境ISO 639 codeJava虚拟机的默认语言环境语言
charset 文件字符集的名称String System property "file.encoding"
fileExtensions 可接受的文件扩展名String Setnull
severity 所有违规的默认严重级别Severityerror
haltOnException 如果单个文件在验证期间产生任何类型的异常,是否停止Checkstyle的执行Booleantrue

实例

例如,以下配置片段指定所有模块的基本目录src/checkstyle ,缓存文件target/ cachefile和德语语言环境:
  <module name="Checker">
      <property name="basedir" value="src/checkstyle"/>
      <property name="cacheFile" value="target/cachefile"/>
      <property name="localeCountry" value="DE"/>
      <property name="localeLanguage" value="de"/>
      <module name="JavadocPackage"/>
      <module name="TreeWalker">
          ...
      </module>
  </module>
配置Checker以便使用UTF-8字符集处理文件:<module name =“Checker”> <property name =“charset”value =“UTF-8”/> ... </模块>
配置Checker,以便它处理java,xml properties 扩展名的文件:
   <module name =“Checker”>
       <property name =“fileExtensions”value =“java,xml,properties”/>
       ...
   </module>
配置Checker,以便它不会在异常中停止执行,而是将其打印为违规:
   <module name =“Checker”>
       <property name =“haltOnException”value =“false”/>
       ...
   </module>
   
配置Checker以便它处理任何扩展名的文件:
   <module name =“Checker”>
       <property name =“fileExtensions”value =“null”/>
       ...
   </module>
或者
   <module name =“Checker”>
       <property name =“fileExtensions” value =“”/>
       ...
   </module>
   

TreeWalker

描述

FileSetCheck TreeWalker检查各个Java源文件,并定义适用于检查这些文件的属性。

属性

名称描述类型默认值
tabWidth 标签字符('\ t')的空白字符数,用于需要标签宽度的消息和检查,例如LineLengthInteger8
fileExtensions 标识Java文件的文件类型扩展名。通常只有在编译之前对Java源代码进行预处理并且原始文件没有扩展名.java时,才需要设置此属性。String Setjava

例子

例如,以下配置片段指定TreeWalker的tabWidth为4 :
   <module name =“Checker”>
       <module name =“TreeWalker”>
           <property name =“tabWidth”value =“4”/>
           ...
       </模块>
   </模块>
将Checkstyle与BEA Weblogic Workshop 8.1集成:
   <module name =“Checker”>
       <module name =“TreeWalker”>
           <property name =“fileExtensions”value =“java,ejb,jpf”/>
           ...
       </module>
   </module>
要配置TreeWalker以便它使用java扩展名处理文件:<module name =“TreeWalker”> <property name =“fileExtensions”value =“java”/> ... </module>
配置TreeWalker,以便它处理任何扩展名的文件:
   <module name =“TreeWalker”>
       <property name =“fileExtensions”value =“null”/>
       ...
   </module>
或者
   <module name =“TreeWalker”>
       <property name =“fileExtensions”value =“”/>
       ...
   </module>

TreeWalker 检查 (Checks)

TreeWalker模块为Java源文件创建一个语法树,并在树的节点的遍历或遍历期间调用其子模块(称为“检查Checks ”)。 语法树的每个节点都有一个令牌。 在遍历期间访问节点会触发为其令牌配置的所有检查。 例如,如果Check MethodLength已被配置为TreeWalker的子模块,则使用方法或构造函数定义令牌访问节点将触发MethodLength来检查节点代码块的行数。
一些检查(Checks),如FileLength和LineLength ,直接应用于源文件,不涉及语法树的令牌。 其他检查与可配置的令牌触发检查相关联。 例如,该元素配置检查 MethodLength :
 <module name =“MethodLength”/>
MethodLength的默认令牌集是{METHODDEF,CTORDEF} ,方法定义和构造函数定义令牌,所以当TreeWalker访问具有METHODDEF或CTORDEF令牌的节点时,它将调用MethodLength 。
您可以使用属性令牌指定检查的触发令牌 。 令牌的值是表示Check的令牌的子集的列表,如下面的元素,配置Check MethodLength仅检查方法行的数量:
 <module name =“MethodLength”>
     <property name =“tokens”value =“METHOD_DEF”/>
 </module>
要将特定属性应用于检查的不同子标记,重复检查。 例如,要检查每个方法的长度最多为150行( MethodLength属性max的默认值),并且每个构造函数的长度最多为60行,请在TreeWalker配置中包含以下内容:
 <module name =“MethodLength”>
     <property name =“tokens”value =“METHOD_DEF”/>
 </module>
 <module name =“MethodLength”>
     <property name =“tokens”value =“CTOR_DEF”/>
     <property name =“max”value =“60”/>
 </module>
标准配置在此处的页面中查看。

严重性 (Severity)

每个检查都有一个严重性属性,Checkstyle分配给所有违反检查的违规。 检查的默认严重性级别为error(错误) 。
您可以使用severity属性来控制命令行工具和ANT任务的普通格式化程序的输出。 普通格式化程序不报告严重性级别忽略的违规,并注意违反严重性级别警告 。 例如,根据以下配置片段,普通格式化器输出用于Translation违例的警告:
 <module name =“Translation”>
     <property name =“severity”value =“warning”/>
 </module>
XML格式化程序将每个违规的严重性级别作为违规错误元素的属性报告。

自定义消息

从Checkstyle 5起,所有检查都可以配置为报告自定义的配置特定消息,而不是Checkstyle的默认消息。 这在检查消息应该引用编码样式文档中的相应部分的情况下可能是有用的,或者默认对于开发人员来说是非常通用的。
示例用法是:
 <module name =“MemberName”>
     <property name =“format” value =“^m[a-zA-Z0-9] * $”/>
     <message key =“name.invalidPattern”
              value="Member ''{0}'' must start with a lowercase ''m'' (checked pattern ''{1}'')."
             />)。
              />
 </module>
 
每个检查配置元素可以具有零个或多个消息元素。 每个检查使用一个或多个不同的消息key来记录违规。 如果要自定义某个消息,则需要在消息元素的key属性中指定消息key。
value属性指定自定义消息模式,如上面的示例所示。 默认消息中使用的占位符也可以在自定义消息中使用。 请注意,消息模式必须是有效的java.text.MessageFormat样式模式,因此请注意占位符定义外的花括号。
明显的问题是您如何知道Check使用哪些消息键,以便您可以覆盖它们? 您可以检验配置文档中的所有键。 每个检查都有一个名为“错误信息”的部分。 本节列出了检查使用的每个键和链接到checkstyle使用的默认消息。

过滤器 (Filters)

Checker模块具有一组Filter子模块来过滤审核事件,包括Checks发出的错误消息。 过滤器可以接受或拒绝审核事件。 如果所有过滤器都接受审核事件,则Checker会报告事件。 如果任何Filter拒绝事件,则Checker不会报告事件。 有关更多信息,请访问Filter过滤器页面 。

执行文件过滤器之前

检查器模块具有“执行前文件过滤器”子模块,用于过滤文件由该程序处理。 执行前文件过滤器可以按其名称接受或拒绝文件。 如果所有执行文件过滤器都接受文件,则Checker将处理并验证文件。 如果任何执行前文件过滤器拒绝文件,则Checker将跳过该文件,并且其行为类似于它不存在。 有关更多信息,请访问文件过滤器页面 。

AuditListeners

除了用于文本或XML输出的记录之外,Checker还可以具有处理audit事件的自定义AuditListeners 。 为了使用自定义侦听器 ,为侦听器及其属性添加一个Checker子模块。 例如,要配置Checker,以便它使用自定义侦听器VerboseListener将审核消息打印到名为“audit.txt”的文件中,请在配置文件中包含以下模块:
 <module name =“com.mycompany.listeners.VerboseListener”>
     <property name =“file”value =“audit.txt”/>
 </module>

包 (Packages)

Checkstyle根据模块元素的名称加载模块类,并在搜索可加载类时自动将预先指定的包前缀附加到该名称 。 默认情况下,Checkstyle应用包com.puppycrawl.tools.checkstyle , com.puppycrawl.tools.checkstyle.filters和com.puppycrawl.tools.checkstyle.checks以及com.puppycrawl.tools.checkstyle的任何子包。 然而,标准checkstyle模块的内部映射名称被加载到完全限定名称。
要指定要应用的其他软件包,请在名为checkstyle_packages.xml的 文件中创建软件包名称XML文档 ,并将该文件提供到包含自定义检查的.jar的根目录中。
请注意,通过命令行选项或Ant Checkstyle任务的属性提供包名称XML文档的支持已经使用Checkstyle 5.0删除。
包名称XML文档指定包名称列表。 以下是软件包名称XML文档的示例com.puppycrawl.tools.checkstyle和com.puppycrawl.tools.checkstyle.checks:

<checkstyle-packages> 
<package name =“com.puppycrawl.tools.checkstyle”> 
  <package name =“checking”/> 
</package > 
</checkstyle-packages>
请注意,包是递归指定的 - 子包元素是其父包元素的子包 。
例如,要将包含com.mycompany.checks的模块与Checkstyle模块相结合,请在下面创建XML文件,并将该文件放入包含自定义检查模块的jar文件的根目录中 。 XML文件必须完全命名为checkstyle_packages.xml :
<?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE checkstyle-packages PUBLIC
    "-//Puppy Crawl//DTD Package Names 1.0//EN"
    "http://checkstyle.sourceforge.net/dtds/packages_1_0.dtd">

<checkstyle-packages>
  <package name="com.mycompany.checks"/>
</checkstyle-packages>
      
现在,您可以配置com.mycompany.checks的模块,例如
com.mycompany.checks.MethodLimitCheck ,并在配置文档中使用缩短的模块元素:
 <module name =“MethodLimit”/>
注意
从Checkstyle 5.0起,您无需在自定义checkstyle_packages.xml文件中重复Checkstyle软件包的软件包。

XML结构

配置XML文档

配置XML文档的以下DTD指定模块及其属性的层次结构:
 
 <?xml version="1.0" encoding="UTF-8"?>

<!ELEMENT module (module|property)*>
<!ATTLIST module name NMTOKEN #REQUIRED>

<!ELEMENT property EMPTY>
<!ATTLIST property
        name NMTOKEN #REQUIRED
        value CDATA #REQUIRED
>
      
      
Checkstyle在加载文档时验证配置XML文档。 要验证上述配置DTD,请在配置XML文档中包含以下文档类型声明:
<!DOCTYPE module PUBLIC
    "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
    "http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">
    
Checkstyle还严格执行XML声明的encoding属性。 如果Checkstyle拒绝配置文档的编码,请更正编码属性的值,或者完全删除编码属性。
有关配置XML文档的完整示例,请检查检查Sun编码约定的文件docs / sun_checks.xml 。

软件包名称XML文档 (Package Names XML Document)

这是一个包名称XML文档的DTD:

<?xml version="1.0" encoding="UTF-8"?>

<!ELEMENT checkstyle-packages (package)*>

<!ELEMENT package (package)*>
<!ATTLIST package name NMTOKEN #REQUIRED>
Checkstyle在加载文档时也会验证包名称XML文档。 要验证上述软件包名称DTD,请在您的软件包名称XML文档中包含以下文档类型声明:

 <!DOCTYPE checkstyle-packages PUBLIC
"-//Puppy Crawl//DTD Package Names 1.1//EN"
"http://checkstyle.sourceforge.net/dtds/packages_1_1.dtd">

抑制XML文档 (Suppressions XML Document)

这是一个抑制XML文档的DTD:
<?xml version="1.0" encoding="UTF-8"?>

<!ELEMENT suppressions (suppress*)>

<!ELEMENT suppress EMPTY>
<!ATTLIST suppress files CDATA #REQUIRED
                   checks CDATA #IMPLIED
                   id CDATA #IMPLIED
                   lines CDATA #IMPLIED
                   columns CDATA #IMPLIED>
发表评论