tp/docs/CODE-ANALYSIS.md
Kinneyzhang 2b33495898 Align README (EN/CN) and docs/ with modular architecture and 0.2.0 semantics
README.md/README_CN.md: new verified Quick Start (fixes the dead
#quick-start nav link); Installation rewritten for the tp-*.el module
family; every broken or drifted example fixed and executed in batch
Emacs (mandatory () ARGLIST and quoted reactive keywords in all
define-tp/define-tps calls, corrected tp-search-map argument order,
interval-list returns, stacked duplicate-face results, gap intervals,
last-wins tp-plist, non-destructive string forms, per-pattern match
ordering, case-fold regexp outputs, rewired end-to-end theme example);
documents the symmetric tp-backward contract, the length-changing
replacement rules, all four tp-put-layer layer specs, and the
previously-missing tp-member, buffer/display macros, and palette
system; state resets now use tp-layer-reset; license corrected to
GPLv3+. CN mirrors EN exactly (119 headings / 258 fences each; code
blocks identical, comments translated).

docs/ARCHITECTURE.md rewritten around the real nine-module layering
and hook-variable inversions; nonexistent helper names removed.
docs/CODE-ANALYSIS.md marked as pre-split historical analysis with
locations/counts corrected. Reactive docs aligned with the fixed
engine semantics (replace-not-accumulate, buffer-local isolation,
nil computed values, batching union, first-render transform).

287 fenced blocks from both READMEs executed: 0 failures; 56-example
assertion suite passes; combined ERT suite 439/439 green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 21:01:01 +08:00

804 lines
24 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.

# tp.el 代码分析报告
> **历史文档说明2026-07 更新)**:本报告分析的是拆分前的单文件 tp.el0.1.0)。
> 自 0.2.0 起代码库已模块化为九个分层模块tp-core.el → tp-reactive.el → tp-layer.el →
> tp-ops.el → tp-search.el → tp-render.el → tp-stack.el → tp-palette.el → tp-builtins.el
> tp.el 仅作总入口),并修复了大量已确认的 bug。当前架构请以
> [ARCHITECTURE.md](ARCHITECTURE.md) 为准,本次变更明细见 [CHANGELOG.md](../CHANGELOG.md)。
> 下文的调用堆栈与问题分析保留为历史分析;"文件结构"与"关键代码位置"表已更新为当前模块位置。
本报告旨在帮助想要参与 tp.el 开发的开发者快速了解项目结构、核心功能实现、以及潜在的优化方向。
## 目录
- [项目概述](#项目概述)
- [文件结构](#文件结构)
- [核心功能函数调用堆栈](#核心功能函数调用堆栈)
- [1. 文本属性设置 tp-set](#1-文本属性设置-tp-set)
- [2. 深度合并属性 tp-add](#2-深度合并属性-tp-add)
- [3. 属性层推送 tp-push-layer](#3-属性层推送-tp-push-layer)
- [4. 响应式层定义 define-tp](#4-响应式层定义-define-tp)
- [5. 响应式更新触发](#5-响应式更新触发)
- [6. 模式匹配 tp-match-set](#6-模式匹配-tp-match-set)
- [7. 搜索与遍历 tp-search-map](#7-搜索与遍历-tp-search-map)
- [关键数据结构](#关键数据结构)
- [潜在问题分析](#潜在问题分析)
- [架构优化建议](#架构优化建议)
- [开发入门指南](#开发入门指南)
---
## 项目概述
tp.el 是一个 Emacs Lisp 文本属性操作库,拆分前的单文件版本采用概念上的 **五层架构设计**
```
┌─────────────────────────────────────────────────────────────────┐
│ 第五层:高级 API │
│ tp-match-set, tp-regexp-set, tp-forward-do, tp-search-map │
├─────────────────────────────────────────────────────────────────┤
│ 第四层:响应式系统 │
│ define-tp, define-tps, tp--reactive-variable-watcher │
├─────────────────────────────────────────────────────────────────┤
│ 第三层:属性层系统 │
│ tp-push-layer, tp-pop-layer, tp-rotate-layer │
├─────────────────────────────────────────────────────────────────┤
│ 第二层:核心属性操作 │
│ tp-set, tp-reset, tp-add, tp-get, tp-at, tp-remove │
├─────────────────────────────────────────────────────────────────┤
│ 第一层:基础工具函数 │
│ tp--parse-args, tp--deep-merge-plist, tp-intervals │
└─────────────────────────────────────────────────────────────────┘
```
0.2.0 的模块拆分大体沿用了这一分层思路,并把"响应式系统向上调用高级 API"的
矛盾收拢为 tp-render.el 安装的钩子变量,详见 [ARCHITECTURE.md](ARCHITECTURE.md)。
---
## 文件结构
当前0.2.0)文件结构:
```
tp/
├── tp.el # 总入口按序加载全部模块62 行)
├── tp-core.el # 区间遍历、plist/face 合并引擎、调试、$var 工具781 行)
├── tp-reactive.el # 响应式依赖注册表、变量监听、批量队列370 行)
├── tp-layer.el # define-tp / define-tps、层注册表与解析1295 行)
├── tp-ops.el # 核心属性操作 tp-set/get/at/remove/...916 行)
├── tp-search.el # 模式匹配、搜索与导航810 行)
├── tp-render.el # 响应式重渲染引擎501 行)
├── tp-stack.el # 属性层栈操作709 行)
├── tp-palette.el # 明/暗主题调色板数据351 行)
├── tp-builtins.el # 内置层与辅助工具193 行)
├── tp-tests.el # 综合 ERT 测试套件4123 行280 个测试)
├── tp-*-tests.el # 各模块回归测试套件7 个文件159 个测试;全套共 439 个测试)
├── Makefile # test / compile / clean
├── docs/
│ ├── ARCHITECTURE.md # 架构文档
│ ├── CODE-ANALYSIS.md # 代码分析报告(本文档)
│ ├── reactive-text-properties.md # 响应式功能文档(中文)
│ ├── reactive-text-properties-en.md # 响应式功能文档(英文)
│ ├── reactive-optimization.md # 优化文档(中文)
│ └── reactive-optimization-en.md # 优化文档(英文)
├── README.md # 英文说明文档
└── README_CN.md # 中文说明文档
```
---
## 核心功能函数调用堆栈
### 1. 文本属性设置 tp-set
`tp-set` 是最核心的属性设置函数,支持三种调用方式。
#### 调用堆栈
```
tp-set (用户调用入口)
├─→ tp--parse-args (解析参数格式)
│ │
│ └─→ tp--resolve-props (解析属性,包括层名称)
│ │
│ ├─→ tp-layer-props (获取层定义的属性)
│ ├─→ tp--collect-reactive-symbols (收集 $var 符号)
│ ├─→ tp--resolve-reactive-symbols (解析为实际值)
│ └─→ tp--register-reactive-deps (注册响应式依赖)
├─→ tp--handle-tp-text-property (处理 tp-text 特殊属性)
│ │
│ └─→ (替换文本内容,如果 tp-text 存在)
└─→ put-text-property / propertize (Emacs 原生 API)
```
#### 关键代码位置
0.2.0 模块化后按"函数 → 模块文件"定位;文件内具体行号请用 `M-x xref-find-definitions` 查找。)
| 函数 | 模块文件 | 作用 |
|------|----------|------|
| `tp-set` | tp-ops.el | 主入口函数 |
| `tp--parse-args` | tp-ops.el | 解析多种调用格式 |
| `tp--resolve-props` | tp-layer.el | 展开层名称和响应式变量 |
| `tp--handle-tp-text-property` | tp-render.el | 处理 tp-text 文本替换(经钩子 `tp--tp-text-handler-function` 安装到 tp-ops |
| `tp-add` | tp-ops.el | 深度合并属性 |
| `tp-push-layer` | tp-stack.el | 推送层到栈顶 |
| `tp-put-layer` | tp-stack.el | 在指定位置放置层 |
| `define-tp` | tp-layer.el | 定义自定义层(宏)|
| `define-tps` | tp-layer.el | 定义层组(宏)|
| `tp--reactive-variable-watcher` | tp-reactive.el | 响应式变量监听器回调 |
| `tp--update-layer-regions` | tp-render.el | 更新使用层的文本区域 |
| `tp-search-map` | tp-search.el | 搜索并应用函数 |
| `tp--match-apply` | tp-search.el | 模式匹配内部实现 |
---
### 2. 深度合并属性 tp-add
`tp-add` 实现属性的深度合并,特别是 face 属性的智能合并。
#### 调用堆栈
```
tp-add (用户调用入口)
├─→ tp--parse-args (解析参数)
├─→ tp--handle-tp-text-property (处理 tp-text)
├─→ text-properties-at (获取现有属性)
├─→ tp--prepend-face (智能合并 face 属性)
│ │
│ └─→ tp--deep-merge-plist (递归合并 plist)
├─→ tp--deep-merge-plist (合并其他嵌套属性)
└─→ put-text-property (设置合并后的属性)
```
#### Face 合并逻辑
```elisp
;; 输入
(tp-add 1 10 '(face (:foreground "red"))) ; 已存在
(tp-add 1 10 '(face bold)) ; 新增
;; 结果: face 是 (bold (:foreground "red"))
;; - 符号 face 被前置到列表
;; - plist face 被深度合并
```
---
### 3. 属性层推送 tp-push-layer
`tp-push-layer` 将属性层推送到栈顶,实现多层属性的堆叠管理。
#### 调用堆栈
```
tp-push-layer (用户调用入口)
└─→ tp-put-layer (在指定索引放置层)
├─→ tp--normalize-layer-spec (规范化层规格)
│ │
│ └─→ tp-layer-props (获取层属性,添加 tp-name)
├─→ tp-group-props (如果是层组,获取所有层属性)
├─→ tp-empty-p (检查是否为空)
├─→ tp--get-layer-stack (获取现有层栈)
├─→ tp--build-layer-props (构建包含 tp-layers 的属性)
└─→ tp-intervals-map (遍历区间应用属性)
└─→ set-text-properties / put-text-property
```
#### 层栈存储结构
```elisp
;; 可见层属性直接存储为文本属性
;; 隐藏层存储在 tp-layers 属性中
;; 例如:两层栈
'(face (:foreground "red") ; 顶层(可见)属性
tp-name layer1 ; 顶层名称
tp-layers ; 下层列表
((face (:background "blue") ; 第一个隐藏层
tp-name layer2)))
```
---
### 4. 响应式层定义 define-tp
`define-tp` 宏定义支持响应式变量的自定义层。
#### 宏展开流程
```
define-tp (宏调用)
├─→ tp--parse-define-layer-args (解析 :props, :data, :compute, :watch, :transform)
├─→ tp--collect-reactive-symbols (收集所有 $var 符号)
├─→ tp--unregister-reactive-deps (如果重新定义,先清除旧依赖)
├─→ tp--ensure-reactive-variables (确保 $var 对应的变量已定义)
├─→ tp--register-layer-data (注册 :data 变量)
│ │
│ └─→ add-variable-watcher (为每个变量添加监听器)
├─→ tp--register-layer-computed (注册 :compute 计算属性)
├─→ tp--apply-initial-computed (计算初始值)
├─→ tp--register-reactive-deps (注册响应式依赖)
├─→ tp--register-layer-watchers (注册 :watch 回调)
├─→ tp--resolve-reactive-symbols (解析 $var 为当前值)
└─→ tp--set-layer-props (存储到 tp-layer-alist)
```
#### 关键数据结构
```elisp
;; 层定义存储
tp-layer-alist
;; => ((layer-name arglist body-form) ...)
;; 或 ((layer-name nil resolved-props) ...) ; 非参数化层
;; 响应式依赖
tp-reactive-deps
;; => ((my-color . ((my-layer . '(face (:foreground $my-color)))))
;; (my-bg . ((my-layer . '(face (:background $my-bg))))))
;; 计算属性
tp-layer-computed
;; => ((my-layer . ((full-name . (lambda () (concat first last))))))
;; 数据变量
tp-layer-data
;; => ((my-layer . (first-name last-name)))
;; 监听回调
tp-layer-watchers
;; => ((my-layer . ((first-name . (lambda (new old layer) ...)))))
;; 转换函数
tp-layer-transforms
;; => ((my-layer . (lambda (text) (upcase text))))
```
---
### 5. 响应式更新触发
当响应式变量通过 `setq` 改变时,自动触发更新。
#### 调用堆栈
```
(setq my-color "blue") ; 用户改变变量
└─→ tp--reactive-variable-watcher (由 add-variable-watcher 注册)
├─→ (检查是否在批量更新模式)
│ └─→ 如果是,添加到 tp--batch-update-pending 并返回
├─→ tp--invoke-layer-watchers (调用 :watch 回调)
├─→ tp--update-layer-computed (更新计算属性)
│ │
│ ├─→ (调用计算函数)
│ ├─→ tp--resolve-reactive-symbols (解析新值)
│ └─→ tp--set-layer-props (更新层定义)
├─→ tp--update-layer-regions (更新文本区域)
│ │
│ ├─→ tp-layer-props (获取新属性)
│ │
│ └─→ tp-search-map (遍历所有使用该层的区域)
│ │
│ └─→ tp-add (合并新属性)
└─→ tp--update-reactive-text (如果 tp-text 依赖该变量)
└─→ tp--replace-reactive-text-in-buffer
└─→ (删除旧文本,插入新文本)
```
#### 批量更新优化
```elisp
(tp-with-batch-updates
(setq my-color "red") ; 不立即更新
(setq my-bg "blue")) ; 不立即更新
;; 退出时一次性更新所有变化
;; 内部实现:
;; 1. 设置 tp--batch-update-active = t
;; 2. 变量变化被记录到 tp--batch-update-pending
;; 3. 退出时调用 tp--flush-batch-updates
```
---
### 6. 模式匹配 tp-match-set
`tp-match-set` 在字符串匹配处设置属性。
#### 调用堆栈
```
tp-match-set (用户调用入口)
└─→ tp--match-apply (内部实现)
├─→ (如果 OBJECT 是字符串copy-sequence 创建副本)
├─→ (循环搜索 PATTERN)
│ │
│ ├─→ search-forward / string-match
│ │
│ └─→ tp-set (在匹配区域设置属性)
└─→ (返回匹配区域列表或带属性字符串)
```
#### 支持多模式
```elisp
(tp-match-set '("TODO" "FIXME") '(face warning))
;; => 匹配所有 TODO 和 FIXME
```
---
### 7. 搜索与遍历 tp-search-map
`tp-search-map` 对所有匹配属性的区域应用转换函数。
#### 调用堆栈
```
tp-search-map (用户调用入口)
└─→ tp--search-do (内部搜索实现)
├─→ (区分字符串和缓冲区处理)
├─→ (对于字符串)
│ │
│ ├─→ text-property-search-forward (搜索)
│ │
│ └─→ (调用 FUNCTION传入 text, start, end, idx)
│ │
│ └─→ (替换匹配文本为函数返回值)
└─→ (对于缓冲区)
├─→ text-property-search-forward
└─→ (相同处理,但修改缓冲区)
```
#### 函数签名
```elisp
(tp-search-map
(lambda (text &optional start end idx)
(upcase text)) ; 返回值替换原文本
'marker ; 搜索的属性名
nil ; 值nil 表示不匹配值)
my-string ; 目标对象
0 ; 起始位置(可选)
100) ; 结束位置(可选)
```
---
## 关键数据结构
### 1. tp-layer-alist
存储所有层定义。
```elisp
;; 非参数化层
((highlight nil '(face (:background "yellow")))
(error nil '(face (:foreground "red"))))
;; 参数化层
((tp-space (pixel) `(display (space :width (,pixel)))))
```
### 2. tp-layer-groups
存储层组定义。
```elisp
((status-colors . (highlight error info))
(moon-phases . (moon-phases-new moon-phases-full)))
```
### 3. tp-reactive-deps
存储响应式依赖关系。
```elisp
;; 变量 -> ((层名 . 使用该变量的属性列表) ...)
((my-color . ((my-layer . '(face (:foreground $my-color)))
(other-layer . '(face (:background $my-color)))))
(my-size . ((size-layer . '(display (space :width $my-size))))))
```
### 4. 层栈结构
文本区域的层栈通过 `tp-name``tp-layers` 属性存储。
```elisp
;; 位置 1-10 的属性
'(face (:foreground "red") ; 可见属性
tp-name layer1 ; 顶层名称
help-echo "tip" ; 可见属性
tp-layers ; 隐藏层列表
((face (:background "blue") tp-name layer2)
(face (:underline t) tp-name layer3)))
```
---
## 潜在问题分析
### 1. 性能问题
#### 问题 1.1:响应式更新可能导致性能瓶颈
**现象**:当一个响应式变量被多个层使用,且这些层被应用到大量文本区域时,变量变化会触发大量更新。
**代码位置**`tp--update-layer-regions` 函数
**问题代码**
```elisp
(defun tp--update-layer-regions (var layer-name)
;; 遍历所有缓冲区
(dolist (buf (buffer-list))
;; 在每个缓冲区中搜索所有使用该层的区域
(tp-search-map (lambda (txt) ...) 'tp-name layer-name nil buf)))
```
**建议**
- 添加缓冲区级别的响应式依赖跟踪
- 只更新实际使用该层的缓冲区
- 考虑使用惰性更新策略
#### 问题 1.2tp-intervals 可能在大文件中变慢
**现象**`object-intervals` 返回整个对象的所有区间,然后过滤。
**建议**:对于大文件,考虑使用 `next-property-change` 进行增量遍历。
---
### 2. 内存问题
#### 问题 2.1:匿名层名称无限增长
**现象**`tp--anonymous-layer-counter` 只增不减,匿名层名称永不重用。
**代码位置**`tp--generate-anonymous-layer-name`
**建议**
- 使用弱引用跟踪匿名层
- 当层不再被使用时自动清理
#### 问题 2.2:响应式依赖可能泄漏
**现象**:如果缓冲区被杀死,但响应式依赖未清理,可能导致内存泄漏。
**建议**
- 添加 `kill-buffer-hook` 来清理缓冲区相关的依赖
- 定期检查并清理无效依赖
---
### 3. 功能问题
#### 问题 3.1:层栈深度无限制
**现象**:没有限制层栈的最大深度,可能导致性能问题。
**建议**:添加可配置的最大深度限制。
#### 问题 3.2:参数化层的参数验证不足
**现象**:参数化层不验证传入参数的类型和数量。
```elisp
(define-tp tp-space (pixel)
`(display (space :width (,pixel))))
;; 错误调用不会报错
(tp-set "test" 'tp-space) ; 缺少参数
```
**建议**:在层调用时添加参数验证。
---
### 4. 代码质量问题
#### 问题 4.1:部分函数过长
**现象**:某些函数超过 100 行,如 `tp--parse-args`、`tp-set`。
**建议**:拆分为更小的辅助函数。
#### 问题 4.2:文档字符串不一致
**现象**:部分内部函数缺少文档字符串。
**建议**:为所有公开函数和重要内部函数添加文档。
#### 问题 4.3:错误处理不完善
**现象**:某些边界情况没有清晰的错误消息。
```elisp
;; 调用未定义的层
(tp-set 1 10 'undefined-layer)
;; 可能静默失败或产生不明确的错误
```
**建议**:添加清晰的错误检查和消息。
---
### 5. 测试覆盖问题
#### 问题 5.1:某些边界情况未测试
**现象**:测试主要覆盖正常流程,边界情况覆盖不足。
**需要补充的测试**
- 空字符串/空缓冲区处理
- 极端层栈深度
- 循环依赖检测
- 并发修改场景
---
## 架构优化建议
### 1. 短期优化(低成本高收益)
#### 1.1 添加错误边界
```elisp
(defun tp-set (...)
"..."
(condition-case err
(tp--set-internal ...)
(error
(tp-debug-log "Error in tp-set: %s" err)
(signal (car err) (cdr err)))))
```
#### 1.2 添加性能日志
```elisp
(defmacro tp--with-timing (name &rest body)
"Execute BODY and log timing if tp-debug-mode is enabled."
`(let ((start (float-time)))
(prog1 (progn ,@body)
(when tp-debug-mode
(tp-debug-log "%s took %.3fms"
,name
(* 1000 (- (float-time) start)))))))
```
#### 1.3 参数验证
```elisp
(defun tp-layer-props (name &optional include-tp-name)
"Get properties for layer NAME."
(unless (symbolp name)
(error "Layer name must be a symbol: %S" name))
...)
```
### 2. 中期优化(改进用户体验)
#### 2.1 层定义的本地化
当前所有层定义是全局的。考虑支持缓冲区本地层:
```elisp
(define-tp-local my-local-layer ()
'(face bold))
```
#### 2.2 层的命名空间
避免层名冲突:
```elisp
(define-tp (my-package . highlight) ()
'(face (:background "yellow")))
```
#### 2.3 属性继承
允许层继承其他层:
```elisp
(define-tp error-highlight ()
:inherit 'base-highlight
:props '(face (:foreground "red")))
```
### 3. 长期优化(架构改进)
#### 3.1 响应式系统优化
考虑采用脏标记 + 批量更新模式:
```elisp
;; 标记脏数据
(defvar tp--dirty-layers nil)
;; 在 idle 时更新
(run-with-idle-timer 0.1 t #'tp--flush-dirty-layers)
```
#### 3.2 层栈优化
使用更高效的数据结构:
```elisp
;; 当前:列表
tp-layers -> ((props1) (props2) (props3))
;; 优化:使用向量
tp-layers -> [props1 props2 props3]
```
#### 3.3 增量更新
对于大区域,考虑增量更新:
```elisp
(defun tp--update-region-incremental (start end new-props)
"Update region incrementally using property change boundaries."
(let ((pos start))
(while (< pos end)
(let ((next (next-single-property-change pos 'tp-name nil end)))
(tp--update-single-interval pos next new-props)
(setq pos next)))))
```
---
## 开发入门指南
### 1. 开发环境设置
```elisp
;; 加载开发版本
(add-to-list 'load-path "/path/to/tp")
(require 'tp)
;; 启用调试模式
(setq tp-debug-mode t)
(setq tp-debug-echo t)
;; 运行测试(全套 439 个 ERT 测试)
;; make test
```
### 2. 添加新功能的步骤
1. **理解分层架构**
- 确定新功能属于哪个模块(见 [ARCHITECTURE.md](ARCHITECTURE.md)
- 遵循模块间调用规则(只调用前置模块的函数)
2. **编写测试用例**
- 在对应模块的 `tp-*-tests.el`(或综合套件 `tp-tests.el`)中添加测试
- 覆盖正常流程和边界情况
3. **实现功能**
- 添加必要的辅助函数
- 添加文档字符串
- 处理错误情况
4. **更新文档**
- 更新 README.md / README_CN.md
- 如果涉及架构变化,更新 ARCHITECTURE.md
### 3. 调试技巧
```elisp
;; 查看层定义
tp-layer-alist
;; 查看响应式依赖
tp-reactive-deps
;; 查看位置属性
(tp-at 5)
(tp-at 5 'face)
(tp-at 5 '(face :foreground))
;; 查看区间
(tp-intervals 1 100)
;; 查看调试日志
(tp-debug-show)
```
### 4. 常见开发任务
#### 添加新的核心属性函数
1.`tp-ops.el` 添加函数
2. 使用 `tp--parse-args` 解析参数
3. 调用 Emacs 原生 API
4. 添加测试用例
#### 添加新的层栈操作函数
1.`tp-stack.el` 添加函数
2. 使用 `tp--stack-map-region` 遍历区域内层栈
3. 使用 `tp--get-layer-stack` 获取层栈
4. 添加测试用例
#### 扩展响应式系统
1. 注册/监听逻辑放在 `tp-reactive.el`,渲染逻辑放在 `tp-render.el`
2. 使用 `add-variable-watcher` 注册监听
3. 在适当位置调用 `tp--update-layer-regions`(下层模块经钩子变量触发)
4. 添加测试用例
---
## 总结
tp.el 是一个设计精良的文本属性操作库,其核心创新包括:
1. **统一的 API 设计**:同一函数支持多种调用方式
2. **属性层系统**:实现了类似图层的属性管理
3. **响应式更新**:借鉴前端框架思想,实现数据驱动 UI
主要的改进方向:
1. **性能优化**:响应式更新的效率、大文件处理
2. **错误处理**:参数验证、清晰的错误消息
3. **代码质量**:函数拆分、文档完善、测试覆盖
对于想要参与开发的贡献者,建议:
1. 从理解测试用例开始
2. 使用调试模式跟踪执行流程
3. 遵循分层架构原则
4. 先写测试,后写实现
---
*报告生成时间: 2026-01-10分析对象拆分前的单文件 tp.el 0.1.0*
*文件结构与"关键代码位置"表更新于 2026-07-26tp 0.2.0 模块化后)*