DDev Comment Gen — C 项目注释审查与生成
在 ddev-gate 的代码评审 subagent 中,与 ddev-c-pro(规范 + 质量)、ddev-clean(清理项识别,只出清单)同一轮加载,对代码注释做系统性审查和补全,结论与其它维度合并输出。
定位
- 触发时机:ddev-gate 代码评审 subagent 加载(与一致性审查并行;不再要求 c-pro 先通过,也不再有独立注释审查阶段)
- 输入:代码评审范围内的最终代码(
.c/.h) - 输出:
pass(注释齐全)或blocked(附缺失项清单 + 补全建议),并入代码评审合并结论 - 审查范围:与代码评审范围一致的文件集合
审查维度
审查 agent 必须逐文件、逐函数、逐结构体/枚举核验,不得仅凭印象判断。
1. 文件头注释
- 每个
.h和.c文件必须包含@file+@brief头注释 @brief须说明本文件的主要职责,不能仅重复文件名@brief只写当前职责,禁止迁移背景、阶段/演进标注("阶段 N""已迁移""已释放""占位/恢复")、方案/验证过程等说明,一律进 commit message
/**
* @file module.h
* @brief 模块公开 API 定义,提供初始化和数据处理接口
*/
2. 公开 API 函数注释
每个在 .h 中声明的公开函数必须包含完整 Doxygen 注释:
@brief:一句话说明函数做什么@param:每个参数一个,说明含义、约束(是否可为 NULL、取值范围)@return:返回值含义(无返回值写"无"或"void")@note/@warning/@see:按需添加
/**
* @brief 模块初始化,分配并配置硬件资源。
* @param cfg 配置参数,不可为 NULL,baud 须 > 0。
* @return MODULE_OK (0) 成功,其他为错误码。
* @note 重复调用前须先 module_deinit。
*/
module_status_t module_init(const module_cfg_t *cfg);
3. 结构体与枚举注释
- 每个
struct/union定义必须有@brief说明用途 - 每个结构体成员必须有
/**< 说明 */行内注释 - 每个
enum必须有@brief说明枚举用途 - 枚举值有非直观含义时必须加
/**< 说明 */行内注释
/** @brief 模块运行时上下文 */
typedef struct {
uint32_t baud; /**< 当前波特率 */
volatile bool running; /**< ISR 与主循环共享,仅原子读写 */
uint8_t rx_buf[256]; /**< 接收环形缓冲区 */
} module_t;
/** @brief 模块操作状态码 */
typedef enum {
MODULE_OK = 0, /**< 成功 */
MODULE_ERR_INVALID_ARG, /**< 参数非法 */
MODULE_ERR_TIMEOUT, /**< 操作超时 */
} module_status_t;
4. 私有函数注释
static函数不强制 Doxygen 格式,但复杂逻辑必须说明意图- 超过 30 行的
static函数建议添加简要块注释说明职责
5. 关键逻辑注释
- 非直观算法、状态机切换、边界条件处理须有少量行内注释
- 注释解释"为什么这样做",不重复代码本身
- 中断回调、错误恢复路径、硬件 workaround 必须有注释说明
6. 注释一致性
- 注释内容必须与实际代码行为一致
- 修改函数签名时必须同步更新注释
- 修改函数行为时必须同步更新注释
7. 注释语言
- 注释必须使用中文。本项目注释以中文为准,禁止英文注释(除专用术语、寄存器名、宏名、结构体/函数名等代码标识符外)
- Doxygen 标签(
@brief/@param/@return等)保持英文标签本身,描述内容用中文 - 行内注释
/**< */内容用中文 - 若文件历史中有英文注释,本次改动范围内必须改为中文
8. 注释简洁性(Anti-Verbosity)
注释补充代码不可见的信息(为什么 / 约束 / 并发语义),不是复述代码本身。缺失注释与注释过密同为缺陷,双向核验:
- 名可自释不注释:字段、函数名已充分表达语义时,允许无注释或单行注释,不强制"每个成员必须有注释"
- 单条注释 ≤ 1 行:字段、宏、枚举值的行内注释超过 1 行视为冗余(复杂并发协议、硬件 workaround 除外,说明放函数文档)
- 逻辑块注释 ≤ 2 行:行内
/* */逻辑注释最多 2 行(What + 必要一句 Why);方案背景、验证过程、替代方案、历史原因等说明写 commit message,不进代码注释;超过 2 行即冗余 - 不复述代码:注释不得复述可见信息——"锁内提交""跨线程""读取并清零"等若在函数名、lock/unlock 调用、变量名中可见,不写入注释
- 同一语义只写一次:在唯一权威位置说明(函数文档),调用点 / 字段用指针引用(如"见 ble_request_*()"),不重复展开
- static 函数不贴 Doxygen:
static辅助函数不强制@brief/@param/@return;仅复杂逻辑加 2~3 行块注释说明意图 - 调试/追溯标签不进注释:
[P1_XXX]等打点日志标签、迭代追溯标签不得进入注释正文(仓库统一约定除外) - 背景/演进内容不进注释(全注释类型):迁移背景、阶段/演进标注("阶段 N""已迁移""已释放""占位/恢复")、方案/实验/验证过程、历史原因等说明一律写 commit message,任何代码注释都不得包含——含文件头
@brief、常量移除处、字段/成员注释、逻辑块注释。反例:文件头@brief只写当前职责,不写迁移史;常量移除处不写背景说明(直接删除即可,必要时只写"见 commit XXXX") - 冗余判据:单处冗余计 1 项;累计 ≥ 3 处 →
blocked,1~2 处列为建议项
注释规范
- 使用简洁中文描述"做了什么 + 为什么/约束",宁缺毋滥:名可自释者不注释,同一语义只写一次
- 使用项目统一的 Doxygen 风格(
/** */或///) - 常用 Doxygen 标签:
@brief/@param/@return/@note/@warning/@see/@todo/@retval
审查流程
- 遍历所有目标
.h文件,逐一检查文件头、公开函数、结构体、枚举的注释完整性 - 遍历所有目标
.c文件,逐一检查文件头、私有函数的注释完整性 - 检查关键逻辑(中断 ISR、错误恢复、状态机、复杂算法)的注释覆盖
- 检查注释语言是否使用中文(专有术语、标识符除外)
- 检查注释简洁性(维度 8):名可自释却硬补注释、单条超 1 行、逻辑块注释超 2 行、复述代码、static 贴 Doxygen、调试标签进注释,以及文件头
@brief/常量移除处/字段成员处的迁移背景与阶段/演进标注("阶段 N""已迁移""已释放""占位/恢复")和方案/验证过程说明等 - 缺失项与冗余项分别记录(文件:行号 + 类型 + 描述 + 处理建议文本)
- 全部通过 →
pass;任一缺失,或冗余项累计 ≥ 3 →blocked+ 附清单
审查结论格式
ddev-comment-gen 审查结论:[pass | blocked]
若 blocked,清单:
- module.h:42 — [缺失] module_init 缺少 @param cfg 注释
- module.c:10 — [缺失] 缺少 @file 头注释
- module.h:25 — [缺失] module_cfg_t 结构体缺少 @brief,成员 baud 缺少行内注释
- module.c:88 — [缺失] ISR 回调缺少说明注释
- module.c:60 — [冗余] 字段注释 3 行复述锁逻辑,字段名已自释,压到 ≤1 行
- module.c:120 — [冗余] static 辅助函数贴完整 Doxygen,应降为 2~3 行块注释
- module.c:88 — [冗余] 逻辑块注释 5 行含方案背景与验证过程,压到 ≤2 行,背景进 commit message
- prt_z5_cfg.h:432 — [冗余] 常量移除处写"补光灯控制权已迁移小核"迁移背景,应删除该注释,背景进 commit message
- prt_light.c:1 — [冗余] 文件头 @brief 含"阶段 2:torch 恢复真实下发""控制权已迁移"演进标注,@brief 只保留当前职责,迁移史进 commit message
审查模式
当本 skill 被 ddev-gate 的代码评审 subagent 加载时,必须使用 reviewer-prompt.md 作为任务模板执行审查。该模板定义了审查输入、审查维度优先级和输出格式;审查结论并入代码评审合并结论。
进度记录
审查完成后将结果写入项目根目录的 progress.md:
- 通过:记录"comment-gen 审查通过",附检查项通过数/总项数
- 阻塞:记录"comment-gen 审查发现 N 个阻塞项",逐项列出文件:行号 + 问题描述
- 追加时间戳和审查结论到最近一次执行日志后