什么是PMD?

10 Sept 2024 | 5 分钟阅读

PMD是一个开源的静态源代码分析器,用于报告应用程序代码中发现的问题。PMD集成了规则集中的工作,并支持编写自定义规则的能力。PMD不报告编译错误,因为它只能处理格式正确的源文件。PMD报告的问题是效率低下的代码或不良的编程习惯,如果它们积累起来,会降低程序的性能和效率。它可以分析用Java、JavaScript、Apex和Visualforce、PLSQL、Apache Velocity、XML和XSL编写的文件。

此外,它还包含CPD,即复制粘贴检测器。CPD在Java、C、C++、C#、Groovy、PHP、Ruby、Fortran、JavaScript、PLSQL、Apache Velocity、Scala、Objective C、Matlab、Python、Go、Swift和Salesforce.com Apex和Visualforce中查找重复代码。

虽然PMD没有正式代表任何东西,但已经提出了一些逆向首字母缩略词,例如“编程错误检测器”(Programming Mistake Detector)和“项目按时完成”(Project Meets Deadlines)。

PMD的工作原理

  1. 解析命令行参数(参见net.sourceforge.pmd.cli.PMDParameters),同时加载稳定分析缓存文件
  2. 加载规则集/规则
  3. 确定语言(不同语言的规则可以混合在规则集中)
  4. 确定文件(使用给定的源目录,按语言的文件扩展名过滤)
  5. 设置渲染器
  6. 按名称排序文件
  7. 检查是否可以使用稳定分析缓存(如果规则集发生更改,它将无效)
  8. 根据配置设置SourceCodeProcessor
  9. 分析文件。可以是单线程或多线程并行。此任务封装在net.Sourceforge.pmd.processor.PMDRunnable中
  10. 创建输入流
  11. 调用源代码处理器(net.Sourceforge.pmd.SourceCodeProcessor)
  12. 确定语言
  13. 检查文件是否已分析,并且分析缓存中是否有结果可用。
  14. 解析源代码。结果是根AST节点。
  15. 持续运行SymbolFacade访问者。它构建作用域,并查找声明和使用。
  16. 运行DFA(数据流分析)访问者(如果至少有一个规则需要它),用于构建控制流图和数据流节点。
  17. 运行TypeResolution访问者(如果至少有一个规则需要它)
  18. 未来:运行多文件分析(如果至少有一个规则需要它)
  19. 执行规则
  20. 首先,运行为标准链组件选择的规则
  21. 运行所有其他规则,让它们遍历AST。这些规则可以使用符号表、类型解析信息和DFA节点。
  22. 规则将把发现的问题报告为RuleViolations。
  23. 将发现的违规渲染成所需的格式(XML、文本、HTML等)
  24. 存储稳定分析缓存
  25. 根据发现的违规数量,以代码0或4退出。

PMD工作规则

在运行规则之前,PMD会将源文件解析成一个名为抽象语法树(AST)的数据结构。此树表示代码的句法结构,并编码源代码组件之间的句法关系。

例如,在Java中,方法声明属于一个类:在AST中,表示方法声明的节点将是表示其封闭类声明的节点的后代。因此,这种表示比原始源代码(对于程序而言,只是一串字符)或词法分析器生成的符号链(例如Checkstyle处理的)要丰富得多。

从概念上讲,PMD规则通过将“模式”与文档的AST进行匹配来工作。规则检查AST并找到满足特定项目所需条件的节点,这些条件是规则试图标记的。然后,规则会在这些节点上报告违规。

在不同操作系统中安装PMD

1. Windows

  • 通过https://github.com/pmd/pmd/releases/download/pmd_releases%2F6.49.0/pmd-bin-6.49.0.zip下载pmd
  • 解压zip压缩包,例如到C:\pmd-bin-6.49.0
  • 将文件夹C:\pmd-bin-6.49.0\bin添加到路径中
    永久:使用“框架属性”对话框 > “环境变量” > “附加到路径变量”
    暂时:在命令行中:SET PATH=C:\pmd-bin-6.49.0\bin;%PATH%
  • 在命令行执行:pmd.bat -d c:\src -R rulesets/java/quickstart.xml -f text

2. Linux操作系统

3. Mac操作系统

4. Windows (Chocolatey)

  • 如果您还没有安装Chocolatey,请先安装!
  • 安装PMD:choco install -y pmd
  • 从命令行运行!pmd -d c:\src -R rulesets/java/quickstart.xml -f text

编写新规则

PMD支持两种定义规则的方法:使用XPath查询或使用Java访问者。XPath规则设置起来容易得多,因为它们直接在您的规则集XML中定义,并且对于几乎任何任务都足够表达。

另一方面,PMD的一些编程接口只能从Java访问,例如获取语句的使用。此外,Java规则允许您进行一些复杂的处理,这是XPath规则无法实现的。

最终,选择哪种方法取决于您的规则的难度。除非您没有其他选择,否则我建议您坚持使用XPath。

在XML中定义新规则

新规则在被引用之前必须在规则集中声明。XPath和Java规则都是如此。为此,使用标准元素,但不是引用ref属性,而是指定具有标准执行类的类特性。

示例

https://github.com/pmd/pmd/releases/download/pmd_releases%2F6.49.0/pmd-bin-6.49.0.zip

PMD中的文档

文档源可以根据其生成方式在两个地方找到

  • 手动编写的(如您正在阅读的);
  • 以及从类文件自动生成的。所有标准文档页面都是这样生成的。

手写文档

所有手写文档都存储在docs/pages下的子文件夹中。文件夹结构类似于侧边栏结构。由于所有页面都使用简单的永久链接,因此在渲染的HTML页面中,所有页面都平铺在一个目录中。这使得离线查看文档也很容易。

规则文档

语言%lang%的类位于pmd-%lang%/src/primary/assets/classification/%lang%。因此,对于Java,可以在pmd-java/src/primary/assets/classification/java下找到这些类。此目录中的XML分类文件在集成期间转换为描述其所含规则的Markdown页面。这些页面像手写文档一样放置在docs/下,然后像大多数文档一样使用Jekyll进行渲染。标准文档生成器是不同的子模块pmd-doc。

因此,更改标准文档不应在Markdown页面上进行,而应直接在与标准对应的XML规则标签中,在重要的分类文件中进行。

规则的XML文档可以包含GitHub风味的Markdown。只需将Markdown包含在XML的CDATA区域内即可。CDATA区域保护分隔符内的所有格式,并允许它们编写代码示例而无需转义特殊的XML字符。

示例