> For the complete documentation index, see [llms.txt](https://code-visualization.shawnxie.top/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://code-visualization.shawnxie.top/di-san-pian-cheng-xu-fen-xi-yu-dai-ma-tu-pu/static-analysis.md).

# 静态分析：不运行代码时能知道什么

## 本章要解决的问题

静态分析能提取哪些事实，边界在哪里？它如何为代码图谱提供边？

## 读者读完应获得什么

1. 能列举静态分析的典型产出与误差来源。
2. 能说明调用图、依赖图、规则检查与测试无关路径的差异。
3. 能在 `mini-shop` 上给出静态可得的关系集合。

## 本章不讲什么

* 不测评具体商业工具。
* 不展开完整抽象解释理论。

***

静态分析在不执行程序的情况下，从源码、字节码或 IR 推导事实。它是代码可视化最常用的事实来源之一：结构稳定、可重复、可在 CI 中运行。

## 静态分析能知道什么

| 类别 | 例子          | 工程用途    |
| -- | ----------- | ------- |
| 结构 | 类/方法/字段     | 大纲、图谱节点 |
| 依赖 | import、模块依赖 | 架构图     |
| 调用 | 直接调用边       | 影响面     |
| 规则 | 分层违规、禁用 API | 治理      |
| 度量 | 复杂度、耦合      | 热点辅助    |

对 `mini-shop`，静态阶段至少能得到：

```
OrderController.create -> OrderService.createOrder
OrderService.createOrder -> PricingService.calculateTotal
PricingService.calculateTotal -> DiscountPolicy.apply
OrderService.createOrder -> PaymentClient.charge
```

以及模块依赖：`order -> pricing`、`order -> payment`。

## 基本流程

```mermaid
flowchart LR
 Src[源码/字节码] --> Parse[解析]
 Parse --> Model[程序模型]
 Model --> Rules[规则/查询]
 Model --> Graph[导出节点与边]
 Rules --> Report[告警/报告]
```

![多源事实融合到代码图谱](https://3345947848-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Los8dUHu_Mz6c2fmLt8%2Fuploads%2Fgit-blob-4f0f9f29e46fc3d4ab7c6d058abb87553e2ab3bb%2Ffig-06-fact-fusion.svg?alt=media)

## 误报与漏报

静态分析必须诚实面对不确定性：

* **漏报**：反射、依赖注入、动态代理让调用不可见
* **误报**：保守分析把不会发生的路径标成可能

因此图谱边最好带属性：

```
confidence: high | medium | low
source: static
evidence: file:line
```

## 在 PR 与 AI 中的位置

`PR-42` 不需要运行系统，也能先做：

1. 变更实体定位
2. 反向调用静态追踪
3. 规则检查（pricing 是否错误依赖 payment）

AI Review 可以先消费这些静态证据，再决定是否要求补充运行时或测试结果。

## 静态分析在工程叙事里的位置

静态分析常被窄化成“找 bug 的工具”。在本书主线里，它更基础的角色是**生产结构与关系事实**：谁调用谁、谁依赖谁、哪些调用尚未解析。告警只是这些事实之上的一种规则消费方式。

对 AI 工作流，这个区分很关键。Agent 不需要你每次都丢给它一份安全扫描长文；它更需要可查询的 `calls` 边、`unresolved` 列表和 limitations。没有事实层，扫描报告也无法接到影响面与上下文包。

`PR-42` 上静态分析的正确贡献是：把 diff 锚到 `DiscountPolicy.apply`，再给出反向调用事实，而不是直接宣布“无安全问题所以可合并”。

## 局限

* 不知真实流量是否走到某路径
* 难证明性能与并发问题
* 框架魔法需要专用规则补充

## 小结

1. 静态分析提供可重复的结构与关系事实。
2. 调用/依赖/规则是代码图谱的核心输入。
3. 必须标注置信度，避免虚假确定。
4. 它是影响面与 Agent 上下文的第一层来源。

## 进阶要点：把规则变成可查询事实

静态规则只有进入图谱或报告，才会成为持续能力。例如：

```
rule:pricing-no-payment
if exists edge depends_on(pricing, payment): fail
```

对 `mini-shop`，当前应通过。若 Agent 为“复用支付费率”而让 pricing 依赖 payment，系统应在验证报告中直接 fail，而不是等人工读 diff 才发现。

## 静态分析输出如何服务 AI

给 Agent 的不应是“告警洪水”，而是可操作子集：

1. 与当前任务符号相交的告警
2. 架构规则结果
3. 高置信调用边
4. 需要人工确认的低置信候选

若把全量静态告警塞进上下文，模型会过载并忽略关键约束。静态分析要会做**任务裁剪**。

## 工作示例：规则检查输出

```json
{
 "rule_id": "pricing-no-payment",
 "status": "pass",
 "evidence": [],
 "checked_modules": ["pricing", "payment"]
}
```

若失败：

```json
{
 "rule_id": "pricing-no-payment",
 "status": "fail",
 "evidence": [
 {"from": "class:PricingService", "to": "class:PaymentClient", "via": "import_or_call"}
 ]
}
```

该输出应同时进入：架构治理面板、PR 检查、Agent 验证报告。同一规则，三处消费，避免多套口径。

## 常见问题：静态分析

### 静态分析能证明没 bug 吗？

不能。它提供事实与候选问题，不是完备证明。

### 误报多是不是没用？

关键是分置信度与任务裁剪，不是放弃。

### 和测试什么关系？

互补：静态广覆盖，测试给行为证据。

## 本章检查清单

1. 是否区分漏报误报
2. 是否标注置信度
3. 是否支持规则查询
4. 是否服务 PR/Agent 裁剪

## 关键要点复盘

围绕「静态分析：不运行代码时能知道什么」，读者离开本章前应能做到：

1. 说明静态分析产出关系事实而不只是告警
2. 写出 calls 边与 unresolved 列表契约
3. 解释 limitations 字段为何必须保留
4. 把静态事实接到影响面输入
5. 衔接到动态分析

若任一做不到，请先复习本章例子与练习，再继续向后读。

## 静态分析输出契约（教学）

一次静态分析 run 至少应留下可机器消费的结果：

```json
{
  "analyzer": "mini-static",
  "target": "method:DiscountPolicy#apply",
  "findings": [],
  "facts": {
    "calls": [
      {"from": "method:PricingService#calculateTotal", "to": "method:DiscountPolicy#apply", "confidence": "high"}
    ],
    "unresolved_calls": []
  },
  "limitations": ["no reflection", "no dynamic proxies"]
}
```

注意：`findings` 为空不等于“无风险”；它只说明规则集未触发。影响面仍要结合调用图与测试。

## 工作示例：PR-42 上的静态事实

1. Diff 定位变更方法 `DiscountPolicy.apply`
2. 静态调用图给出反向路径到 `OrderController.create`
3. 未发现 `pricing -> payment` 依赖边
4. 输出给影响面模块，而不是直接宣称“安全”

## 常见失败

| 失败              | 后果        | 缓解               |
| --------------- | --------- | ---------------- |
| 只报 bug 不产图谱事实   | 无法服务影响面   | 同时输出关系事实         |
| 把 unresolved 丢掉 | 假完整       | 保留 unresolved 列表 |
| 规则集过小却写“全面扫描”   | 误导 Review | 明确 limitations   |

## 练习

1. 列出 `mini-shop` 仅靠静态分析可得的 5 条边。
2. 给出 1 个会漏报、1 个会误报的场景，并说明如何在图谱中标注置信度。
3. 写一条架构规则检查：`pricing` 不得依赖 `payment`。

## 本章导航

* 上一章：[IR、SSA、CFG 与 DFG](/di-er-pian-yuan-ma-jie-gou-hua-yuan-li/ir-ssa-cfg-dfg.md)
* 下一章：[动态分析：运行起来之后才能知道什么](/di-san-pian-cheng-xu-fen-xi-yu-dai-ma-tu-pu/dynamic-analysis.md)
* 相关章：[变更影响分析与验证](/di-si-pian-san-ge-he-xin-gong-cheng-chang-jing/change-impact-verification.md)；[构建代码图谱](/di-liu-pian-shi-jian-xiang-mu/build-code-graph.md)

## 延伸阅读与参考资料

* [CodeQL docs](https://codeql.github.com/docs/)：查询式静态分析。资料卡：`../docs/research-cards/rc-codeql-dataflow.md`
* [Semgrep docs](https://semgrep.dev/docs/)：模式化静态规则。
* [SpotBugs](https://spotbugs.github.io/)：字节码级缺陷模式检测。
* [Error Prone](https://errorprone.info/)：编译期静态检查实践。
* [ArchUnit](https://www.archunit.org/)：架构规则测试化。
* 本书案例：[`examples/mini-shop/artifacts/code-graph.json`](https://github.com/Xiaoxie1994/code-visualization-book/tree/main/examples/mini-shop/artifacts/code-graph.json)。
