198 lines
7.5 KiB
Markdown
198 lines
7.5 KiB
Markdown
---
|
||
name: codegraph-guide
|
||
description: |
|
||
CodeGraph 辅助 Fortran→Rust 重构。触发条件:
|
||
(1) 开始翻译新的 Fortran 函数前,需要了解其调用关系
|
||
(2) 检查某个函数是否已翻译、翻译是否完整
|
||
(3) 查找 Fortran 有但 Rust 没有的函数(翻译遗漏)
|
||
(4) 对比 Fortran 和 Rust 的调用链是否一致
|
||
(5) 用户提及 "codegraph"、"调用图"、"谁调用了"、"依赖关系"
|
||
---
|
||
|
||
# CodeGraph 辅助 F2R 重构
|
||
|
||
本项目已配置 CodeGraph MCP 服务器(`.mcp.json`),Claude 启动时自动加载。
|
||
CodeGraph 索引了 Fortran 原始文件(`tlusty/tlusty208.f`、`synspec/synspec54.f`)和
|
||
Rust 源码(`src/`),生成统一的 SQLite 代码图谱。
|
||
|
||
## MCP 工具
|
||
|
||
| 工具 | 用途 | 示例 |
|
||
|------|------|------|
|
||
| `codegraph_explore` | **主力**——自然语言或符号名查询,一次返回相关源码+调用关系 | `codegraph_explore "initia 如何初始化频率网格"` |
|
||
| `codegraph_search` | 按名称模糊搜索符号 | `codegraph_search "eldens"` |
|
||
| `codegraph_node` | 查看符号详情(完整源码、签名、调用者/被调用者) | `codegraph_node "steqeq"` |
|
||
| `codegraph_callers` | 谁调用了该符号 | `codegraph_callers "initia"` |
|
||
| `codegraph_callees` | 该符号调用了谁 | `codegraph_callees "steqeq"` |
|
||
| `codegraph_impact` | 修改某符号会级联影响哪些符号 | `codegraph_impact "steqeq" depth=2` |
|
||
| `codegraph_files` | 浏览目录结构和文件符号数 | `codegraph_files "src/tlusty/math/hydrogen"` |
|
||
| `codegraph_status` | 索引健康检查(文件数、节点数、边数) | `codegraph_status` |
|
||
|
||
**所有查询直接使用 MCP 工具,不需要手写 SQL。**
|
||
|
||
## 命名约定
|
||
|
||
### 函数命名:Fortran 与 Rust 完全对应
|
||
|
||
所有 TLUSTY Fortran 函数在 Rust 中都有**同名小写**版本。不再使用 `_pure` 后缀
|
||
(已于 2026-06-05 批量清理)。
|
||
|
||
```
|
||
Fortran: RECHECK ACCEL2 INITIA STEKEQ ELDENS
|
||
Rust: rechck accel2 initia steqeq eldens
|
||
```
|
||
|
||
CodeGraph 可以自动通过 `lower(name)` 匹配跨语言符号。
|
||
|
||
### `_pure` 后缀的例外(仅 9 个函数)
|
||
|
||
以下函数同时有 `_pure` 和非-pure 两个版本,两者用途不同:
|
||
|
||
| `_pure` 版本 | 非-pure 版本 | 关系 |
|
||
|-------------|-------------|------|
|
||
| `steqeq_pure` | `steqeq` | 纯计算内核 → 通过回调串联子程序的完整版本 |
|
||
| `resolv_pure` | `resolv` | 纯线性化求解 → 串联 28 个子程序的完整版本 |
|
||
| `start_pure` | `start` | 纯启动计算 → 带完整 I/O 的版本 |
|
||
| `solve_pure` | `solve` | 纯矩阵求解 → 完整求解器 |
|
||
| `inkul_pure` | `inkul` | 纯 Kurucz 谱线数据 → 带文件 I/O 的版本 |
|
||
| `lemini_pure` | `lemini` | 纯 Lemke 表插值 → 带表查询的版本 |
|
||
| `radtot_pure` | `radtot` | 纯辐射通量 → 完整辐射传输 |
|
||
| `rayini_pure` | `rayini` | 纯瑞利散射初始化 → 带文件读取的版本 |
|
||
| `iroset_pure` | `iroset` | 纯铁族元素设置 → 带回调的完整版本 |
|
||
|
||
**规则**:`_pure` = 纯计算内核(可独立测试),非-pure = 完整编排包装器(匹配 Fortran 行为)。
|
||
|
||
## F2R 翻译工作流
|
||
|
||
### Step 0: 数据同步
|
||
|
||
每次 Rust 代码修改后,MCP 文件监视器会自动同步(2秒延迟)。如有疑问可手动触发:
|
||
|
||
```bash
|
||
cd /home/fmq/program/SpectraRust
|
||
node /home/fmq/program/codegraph/dist/bin/codegraph.js sync
|
||
```
|
||
|
||
如果添加了新目录或数据异常,重建:
|
||
```bash
|
||
rm -rf .codegraph
|
||
node /home/fmq/program/codegraph/dist/bin/codegraph.js init -i
|
||
```
|
||
|
||
### Step 1: 选择翻译目标
|
||
|
||
使用 `fortran-analyzer` skill 获取优先模块。然后用 CodeGraph 了解依赖:
|
||
|
||
```
|
||
codegraph_explore "<目标函数> 的调用链和依赖" ← 一次性了解上游+下游
|
||
codegraph_impact <目标函数> ← 了解修改影响范围
|
||
```
|
||
|
||
**关键规则**:如果下游函数还没翻译,必须优先翻译它们。
|
||
|
||
### Step 2: 翻译函数
|
||
|
||
用 `codegraph_node <函数名>` 获取完整信息:
|
||
- Fortran 源码(完整函数体)
|
||
- 所在文件和行号
|
||
- 签名、参数、返回值
|
||
- 所有调用者和被调用者列表
|
||
|
||
对照 Fortran 源码逐行翻译。翻译后的 Rust 函数直接使用 Fortran 同名小写,
|
||
例如 `ELDENS` → `pub fn eldens(...)`。
|
||
|
||
### Step 3: 验证调用链一致性
|
||
|
||
翻译完成后对比 Fortran 和 Rust 的调用链:
|
||
|
||
```
|
||
codegraph_explore "<函数名> Fortran vs Rust 调用链对比"
|
||
```
|
||
|
||
两边的被调用者列表应该结构一致(Rust 端用 snake_case,Fortran 端用 UPPER_CASE)。
|
||
如果 Rust 端缺少被调用者 → 可能需要创建非-pure 编排包装器。
|
||
|
||
### Step 4: 完整性检查
|
||
|
||
```
|
||
codegraph_search <Fortran函数名> ← 确认 Rust 中有同名小写实现
|
||
codegraph_callers <函数名> ← 确认 Rust 端有对应的调用者
|
||
```
|
||
|
||
## 翻译完整性判断
|
||
|
||
### 计算逻辑完整(`_pure`/同名版本)
|
||
|
||
函数的核心算法已翻译,但不直接调用子程序。占 TLUSTY 的绝大多数。
|
||
|
||
### 编排完整(非-pure 包装器)
|
||
|
||
函数不仅包含计算逻辑,还通过回调或直接调用来串联子程序,完整匹配 Fortran 行为。
|
||
目前仅 9 个函数有此版本。
|
||
|
||
### 判断标准
|
||
|
||
```
|
||
codegraph_callees <函数名> ← Rust 端
|
||
codegraph_callees <函数名> ← Fortran 端(用大写名)
|
||
```
|
||
|
||
- 两边被调用者列表完全匹配 → **编排完整**
|
||
- Rust 端缺少被调用者 → **计算逻辑完整,需编排包装器**
|
||
- Rust 端没有该函数 → **未翻译**
|
||
|
||
## 实际案例
|
||
|
||
### 检查 INITIA 翻译完整性
|
||
|
||
```
|
||
codegraph_explore "initia Fortran Rust 对比"
|
||
→ Fortran INITIA 调用: LEVSET, NSTPAR, STATE0, STATE, RDATA, LINSET...
|
||
→ Rust initia 调用: generate_log_frequency_grid, init_reciprocal_powers...
|
||
→ 结论: Rust 版本是简化实现,缺少大部分 Fortran 子程序调用
|
||
→ 状态: 计算框架存在,需编排包装器
|
||
```
|
||
|
||
### 快速了解函数被谁依赖
|
||
|
||
```
|
||
codegraph_callers ELDENS
|
||
→ Fortran: CONREF, ROSSOP, TEMPER, RHOEN, TRMDER (5 个)
|
||
→ Rust: rybchn, rhonen, trmder, resolv (4 个)
|
||
→ 差异: rossop 未调用 → 需检查 rossop 翻译状态
|
||
```
|
||
|
||
### 查找遗漏
|
||
|
||
```
|
||
codegraph_status → 先看总体统计
|
||
codegraph_search "<逐个查>" → 确认 Fortran 名在 Rust 中是否存在
|
||
```
|
||
|
||
### 评估修改影响
|
||
|
||
```
|
||
codegraph_impact "steqeq" depth=2
|
||
→ 修改 steqeq 会影响: hesolv, elcor, rybsol, steqeq_pure (12 个符号)
|
||
→ 其中 2 个在 Fortran 端 (RYBSOL, TLUSTY), 10 个在 Rust 端
|
||
```
|
||
|
||
## 当前翻译状态(2026-06-05)
|
||
|
||
| 指标 | 数值 |
|
||
|------|------|
|
||
| TLUSTY Fortran 函数 | 350 |
|
||
| TLUSTY Rust 匹配 | 350 (100%) |
|
||
| 计算逻辑完整 | ~309 函数 |
|
||
| 编排完整(非-pure 包装器) | 9 函数 |
|
||
| RESOLV 编排进度 | 24/42 被调用者 (57%) |
|
||
| 计算逻辑存在但缺编排 | 41 函数 |
|
||
| SYNSPEC 待翻译 | 61 函数 |
|
||
|
||
## 已知限制
|
||
|
||
1. **不跨语言语义映射**:CodeGraph 按名称匹配,不知道 Fortran `ELDENS` 和 Rust `eldens` 是同一个函数——但它支持大小写不敏感查询,所以这不是问题。
|
||
2. **文件监视器 2 秒延迟**:修改 Rust 代码后等 2 秒再查询,或手动 `codegraph sync`。
|
||
3. **提取文件可能有冗余**:`tlusty/extracted/` 和 `synspec/extracted/` 中的函数与原始文件重复(平均 2.2 次),MCP 工具查询时可能返回重复结果。优先信任原始文件(`tlusty/tlusty208.f`)中的结果。
|
||
4. **Fortran 调用边覆盖率 ~98.3%**:约 1.7% 的调用(~22 条)来自语法解析错误的区域,caller 显示为 `<anonymous>`。
|