Files
2026Technology-Competition/data/demo-pmd/reports/demo-pmd-coverage-report.md
T
范智鹏 3c390cfa90 feat: demo-pmd 样本工程入库 + Windows spawn cmd EINVAL 修复 + 实测报告清理
- data/demo-pmd 全量入库(26 源文件 + pom/mvnw/lib/reports),.gitignore 排除 target/
- 归档 demo-pmd 实测覆盖率报告(279/279 全覆盖)至 reports/
- 删除 4 份覆盖率报告中的后续建议/实测进度总览(全部实测已收官)
- 修复 Windows spawn .cmd/.bat EINVAL(auxClasspath.ts 经 cmd.exe /d /s /c 间接执行)
2026-08-26 22:04:47 +08:00

175 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# demo-pmd 插件实测覆盖率报告
> **工程**`demo-pmd`PMD 内置规则集形态:`jars/pmd/pmd-java-ruleset.xml` + `pmd-jsp-ruleset.xml`
> **测试对象**:插件 PMD 适配器(引擎 PMD 7.26.0Java 269 条 / JSP 10 条内置规则)
> **实测日期**2026-08-26(当日完成含辅助 classpath 的全量复测收官)
> **比对基线**:插件同版本引擎 + 同规则集独立复现的基线(比对键 = 规则 + 行号;JSP 另含三层架构逐层复现)
---
## 一、核心结论
| 指标 | 结果 | 状态 |
|---|---|---|
| 插件行为一致性(vs 基线) | **1813/1813 条逐条一致,零偏差** | ✅ 100% |
| Java 规则覆盖率 | **269/269 种(100%** | ✅ 7/7 类满覆盖 |
| JSP 规则覆盖率 | **10/10 种(100%** | ✅ 全覆盖 |
| 规则总覆盖率 | **279/279 种(100%** | ✅ 全覆盖 |
| 解析错误 | **0 处** | ✅ |
| 静态诊断总数 | 1819 条(PMD 1813 + ESLint 6 | — |
**实测完全达成全覆盖基准**:演示工程全部 26 个文件(23 Java + 3 JSP)的插件报告,共 1813 条 PMD 静态诊断与独立基线**规则名、行号逐条完全一致**,零误报、零漏报、零解析错误;Java 269 条与 JSP 10 条内置规则**全部触发**,两类规则集均达 100% 覆盖。**PMD 适配器静态分析链路(规则加载、Java/JSP 双语言路由、scriptlet 包装、诊断映射、辅助 classpath 自动解析)验证通过。**
---
## 二、逐文件比对(实测 vs 基线)
**Java 23 份**(基线 = PMD 7.26.0 + `pmd-java-ruleset.xml`;★ 为启用辅助 classpath 后复测的文件):
| 文件 | 实测 | 基线 | 一致性 | 说明 |
|---|---:|---:|---|---|
| `DesignErrorProne.java` | 762 | 762 | ✅ 逐条一致 | 单文件最大(design + errorprone 主样例) |
| `BestPracticesCodeStyle.java` | 517 | 517 | ✅ 逐条一致 | bestpractices + codestyle 主样例 |
| `MultiPerfSecurity.java` | 190 | 190 | ✅ 逐条一致 | multithreading + performance + security 样例 |
| `GodClassDemo.java` | 79 | 79 | ✅ 逐条一致 | design 类规则样例 |
| `JUnit4RulesTest.java` ★ | 67 | 67 | ✅ 逐条一致 | JUnit4 相关规则样例(classpath 后 +16 |
| `AccessorAndIpDemo.java` | 14 | 14 | ✅ 逐条一致 | 访问器 + 硬编码 IP 样例 |
| `JUnit3RulesTest.java` | 15 | 15 | ✅ 逐条一致 | JUnit3 相关规则样例 |
| `AccessorDemo.java` | 12 | 12 | ✅ 逐条一致 | 访问器生成样例 |
| `FileItemDemo.java` | 12 | 12 | ✅ 逐条一致 | commons-fileupload 样例 |
| `AssertStmtTest.java` | 10 | 10 | ✅ 逐条一致 | 断言语句样例 |
| `LoggerDemo.java` ★ | 11 | 11 | ✅ 逐条一致 | 日志调用样例(classpath 后 +1 |
| `AccessorGen2.java` | 11 | 11 | ✅ 逐条一致 | 内部类访问器样例 |
| `StaticEJBFieldDemo.java` | 9 | 9 | ✅ 逐条一致 | EJB 静态字段样例 |
| `JUnit5RulesTest.java` | 9 | 9 | ✅ 逐条一致 | JUnit5 相关规则样例 |
| `JUnit5ArgOrderTest.java` ★ | 9 | 9 | ✅ 逐条一致 | 断言参数顺序样例(classpath 后 +2 |
| `EJBNamingDemo.java` | 8 | 8 | ✅ 逐条一致 | EJB 命名样例 |
| `AfterBeforeTest.java` | 7 | 7 | ✅ 逐条一致 | setUp/tearDown 样例 |
| `CallSuperDemo.java` | 7 | 7 | ✅ 逐条一致 | CallSuper 样例 |
| `InvalidBeanDemo.java` | 7 | 7 | ✅ 逐条一致 | JavaBean 规范样例 |
| `ApiService.java` | 2 | 2 | ✅ 逐条一致 | 接口设计样例 |
| `NoPackageDemo.java` | 4 | 4 | ✅ 逐条一致 | 无包声明样例 |
| `PackageCaseDemo.java` | 4 | 4 | ✅ 逐条一致 | 包命名规范样例 |
| `LoosePackageCouplingDemo.java` | 3 | 3 | ✅ 逐条一致 | 包耦合度样例 |
| **Java 合计** | **1769** | **1769** | **✅ 零偏差** | — |
> ★ 三份复测说明:`JUnit4RulesTest` / `JUnit5ArgOrderTest` / `LoggerDemo` 首轮以无 classpath 模式测得 51 / 7 / 10 条(与 noaux 基线逐条一致);辅助 classpath 生效后复测为 67 / 9 / 11 条(与 aux 基线逐条一致),新增的 19 条全部来自 4 个类型解析规则(见第三节)。两轮均零偏差。
**JSP 3 份**(基线 = 三层架构逐层复现,见第四节):
| 文件 | PMD 实测 | PMD 基线 | ESLint | 一致性 |
|---|---:|---:|---:|---|
| `JspFix.jsp` | 35 | 35 | 3 | ✅ 逐条一致 |
| `DemoJsp.jsp` | 9 | 9 | 3 | ✅ 逐条一致 |
| `SecurityDemo.jsp` | 0 | 0 | 0 | ✅ 一致(无 scriptlet/script,三层均无输出) |
| **JSP 合计** | **44** | **44** | **6** | **✅ 零偏差** |
> 比对方法:将插件报告中的每条静态诊断(规则名 + 行号)与基线做多重集合比对;26 个文件全部 `missing = 0`、`extra = 0`。
---
## 三、覆盖率分布与最后 4 条规则的达成
**Java 规则集按类别**269 条,7 类,全部满覆盖):
| 类别 | 总数 | 已覆盖 | 覆盖率 |
|---|---:|---:|---:|
| Error Prone | 90 | 90 | 100% |
| Best Practices | 58 | 58 | 100% |
| Code Style | 57 | 57 | 100% |
| Design | 29 | 29 | 100% |
| Performance | 24 | 24 | 100% |
| Multithreading | 9 | 9 | 100% |
| Security | 2 | 2 | 100% |
| **合计** | **269** | **269** | **100%** |
**JSP 规则集**bestpractices / codestyle / design / errorprone 四类共 10 条全部触发(`JspFix` 贡献 6 种、`DemoJsp` 贡献 6 种,并集 10/10)。
**最后 4 条规则的两阶段达成过程**
| 规则 | 类别 | 触发依赖 | 达成方式 |
|---|---|---|---|
| `UnitTestAssertionsShouldIncludeMessage` | Best Practices | JUnit `assertEquals` 类型解析 | classpath 后 `JUnit4RulesTest` +15、`JUnit5ArgOrderTest` +1 |
| `SimplifiableTestAssertion` | Best Practices | JUnit 断言 API 类型解析 | classpath 后 `JUnit4RulesTest` +1 |
| `AssertEqualsArgumentOrder` | Error Prone | JUnit `assertEquals` 签名解析 | classpath 后 `JUnit5ArgOrderTest` +1 |
| `UseCorrectExceptionLogging` | Error Prone | commons-logging `Logger` 类型解析 | classpath 后 `LoggerDemo` +1 |
该 4 条规则依赖**辅助 classpath 的类型解析**,触发条件是工程根有 `pom.xml`/`build.gradle` 且插件成功解析依赖。演示工程 `pom.xml` 声明了 junit 4.13.2、junit-jupiter-api 5.10.2、commons-logging 1.3.4、slf4j-api 2.0.16(恰为 4 条规则所需),配合 `mvnw` 包装器在复测轮成功解析依赖后全部触发。
---
## 四、JSP 三层架构验证
插件对 `.jsp` 文件采用三层分析(`src/adapters/jsp.ts`),本次全部逐层复现:
1. **层 1 · PMD JSP 规则集**:整文件跑 `pmd-jsp-ruleset.xml`10 条规则);
2. **层 2 · scriptlet 包装**`<% %>`/`<%! %>`/`<%= %>` 分别按 statement/declaration/expression 三种模板包装成合法 Java 类,跑 Java 规则集,行号经 headerLines 偏移精确映射回原文件(`JspFix` 的 28 条 scriptlet 诊断零行号误差);
3. **层 3 · ESLint**`<script>` 块内容交 ESLint 适配器(`no-var``no-unused-vars``no-undef`)。
三层合计 50 条诊断(44 PMD + 6 ESLint)与报告完全一致。两层补充验证:
- **AI 审查补位 security 盲区**`pmd-jsp-ruleset.xml` 未引用 JSP security 分类(`IframeMissingSrcAttribute``NoUnsanitizedJSPExpression` 不在规则集内),`SecurityDemo.jsp` 的 8 条 AI 建议恰好覆盖了该盲区(2 条 XSS 转义 + 3 条 iframe 问题)。
- **超时降级容错**`MultiPerfSecurity.java`1750+ 行、190 条诊断)AI 审查 301s 超时后,报告自动降级为纯静态分析并明确标注,静态部分不受影响。
---
## 五、诊断分布统计
**按严重级别**PMD 静态 1813 条):
| 级别 | 数量 | 占比 |
|---|---:|---:|
| error(🔴) | 288 | 15.9% |
| warning(🟡) | 1471 | 81.1% |
| info(🔵) | 54 | 3.0% |
**按语言**Java 1769 条 · JSP 44 条(另 ESLint 6 条)。
**按文件 Top5**DesignErrorProne 762 · BestPracticesCodeStyle 517 · MultiPerfSecurity 190 · GodClassDemo 79 · JUnit4RulesTest 67。
> 注:26 份报告另有 AI 审查建议 103 条(平均耗时 155.3s,区间 52.0s~301.2s),属 AI 增强能力,不计入静态规则覆盖口径。
---
## 六、实测环境判定与缺陷修复记录
实测报告的文件路径与预期部署一致(`f:\XunHeCode\演示资料\demo-pmd\src\...`Java 23 文件 + `src/jsp/` 3 文件,共 26 个源文件全部覆盖、无遗漏)。
**辅助 classpath 两阶段验证**
1. **首轮(无 classpath 模式)**:插件当时无法解析依赖,26 个文件以无辅助 classpath 模式运行,1794 条诊断与 noaux 基线逐条一致。
2. **复测轮(classpath 模式)**:依赖解析打通后,3 个 JUnit/日志样例文件复测(67 / 9 / 11 条),与 aux 基线逐条一致;其余 20 个文件经本地 aux 基线逐一核验,诊断数均不变(其代码不含依赖类型解析场景)。
**过程中发现并修复的插件缺陷**(本轮测试的额外收获):Windows 下插件直接 `spawn` 拉起 `mvnw.cmd` 会抛 `EINVAL`Node 18.20+/20.12+ 修复 CVE-2024-27980 后,无 shell 执行 `.cmd`/`.bat` 一律被拒绝),导致辅助 classpath 解析**静默失败**且仅 `console.warn` 降级——影响所有 Windows 用户的 Maven/Gradle 依赖解析。已在 `src/services/auxClasspath.ts` 修复(`.cmd`/`.bat``cmd.exe /d /s /c` 间接执行),编译验证通过并提交(`ab9c386`)。复测轮的 3 份报告即为修复生效后的实测结果。
---
## 七、数据口径说明
| 项 | 说明 |
|---|---|
| 覆盖率口径 | Java 269 条 = `pmd-java-ruleset.xml` 经 PMD `RuleSetLoader` API 实际加载数(7 类别引用 + exclude 排除后);JSP 10 条同法核验;纯规则口径,不含 parse-error |
| 比对引擎 | PMD 7.26.0(与插件 `jars/pmd` 内置引擎逐字一致),JDK 17 运行 |
| 基线数据 | noaux 基线:`pmd-baseline-noaux/`(初批 14)、`pmd-batch2-noaux/`(批 2)、`/tmp/*-noaux.json`(批 3+收尾 4);aux 基线:`pmd-aux-predict/`23 文件全量,注入 `lib/` 全部 jar);JSP`pmd-jsp-baseline/` + scriptlet 复现 |
| 比对键 | 规则名 + 行号(多重集合比对,容忍同规则同行多次) |
| classpath 口径 | 3 个复测文件以 aux 基线比对(插件 Maven 解析输出与 lib/ jar 列表等价);其余 20 个文件经 aux 基线核验无差异;`DesignErrorProne` 在 aux 下多 1 条 `UseCorrectExceptionLogging`(763),报告为复测前的 762 条版本,两轮各自与对应基线一致,不影响覆盖结论 |
| 已知口径差异 | 工程自带演示说明中的部分文件(如 `SecurityDemo.jsp` 注释期望的 JSP security 规则)不在规则集内,属演示注释与规则集的口径差 |
| ESLint 条目 | JSP 报告中 6 条 `eslint:` 前缀条目来自 ESLint 适配器(层 3),不计入 PMD 规则覆盖口径;行号映射逻辑已验证 |
---
## 八、结论与后续
**demo-pmd 工程的插件实测验证完成,达成全覆盖**
1. ✅ 插件行为零偏差(1813/1813 逐条一致,26/26 文件,含 classpath 修复后的复测轮)
2. ✅ 规则覆盖:Java 269/269100%7/7 类满覆盖)+ JSP 10/10100%= **279/279 全覆盖**
3. ✅ JSP 三层分析架构(JSP 规则集 + scriptlet 包装 + ESLint)完整验证,行号映射零误差
4. ✅ 辅助 classpath 自动解析链路(Maven `dependency:build-classpath` → PMD aux classpath)实测打通
5. ✅ 容错路径验证(AI 超时自动降级,静态结果不受影响)
6. ✅ 额外收获:发现并修复 Windows 下 `spawn mvnw.cmd``EINVAL` 的插件缺陷(影响全部 Windows 用户的依赖解析)
---
*报告生成于 2026-08-26 · demo-pmd 插件实测(含辅助 classpath 复测轮) · 比对脚本:`compare-pmd.py` / `replay-jsp.py` / `collect-stats.py` / `run-aux-predict.sh` · 数据:`pmd-baseline-noaux/` / `pmd-aux-predict/` / `report-data.json`*