


修改并测试为多种语言生成原生库包装代码的代码生成器
在修改一个把原生库声明转成多语言包装代码的编译器式工具时使用。追查错误最早出现的处理阶段,运行与改动规模相符的测试,补充回归测试,并更新更改日志。
要使用这个AI规则
## 先读任务专用指南,修改输入而不是生成文件
### 从任务专用指南开始
在修改代码或运行专用命令之前,先找到仓库中简短的任务专用指南。阅读与当前工作匹配的指南,不要从宽泛的概述中重新拼凑流程。常见指南涵盖:
- 运行完整测试套件、单个目标语言测试套件或单个测试用例;
- 调试编译器、检查解析树和追踪内存故障;
- 编辑用户手册并验证其结构;
- 源代码格式化、注释、贡献规范和提交消息;
- 复现只在持续集成中发生的故障。
当这些聚焦指南给出准确的命令、标志或规范时,应将其视为正本。如果发现用别名或符号链接把同一指南映射到多个工具专用位置,应只维护一个正本,并确认这些链接能够在贡献者的平台上正确建立。
### 编辑前先了解系统
该仓库实现了一个编译器式生成器。它读取原生声明和接口描述,然后生成包装代码,使多种目标语言能够调用原生库。这个模型带来三项实际影响:
- 生成文件是产物,不是修正行为的主要位置;
- 跨语言行为应放在共享接口输入中,目标语言专用的运行时检查应放在对应的目标测试目录中;
- 对解析、类型解析、所有权或包装代码生成的更改可能影响多个后端,即使报告的症状只出现在一个后端。
将仓库自身的指南、构建文件和测试作为证据。不要只根据看似熟悉的目录名或其他项目采用的规范来推断工作流。
## 使用CI的构建系统构建,并选择最小的有效测试
### 从正确的源代码形态构建
使用持续集成采用的主要构建系统。从版本控制系统检出的工作树可能需要先执行引导步骤来生成配置文件,而发布归档中可能已经包含这些文件。正常顺序是:需要时先引导,然后配置,最后构建。保留受支持的配置开关,例如安装前缀和可选依赖项控制。
项目可能还提供辅助构建系统,但在诊断主要流水线故障时,不要在未说明的情况下用它替代主要系统。测试和示例可能调用未安装工作树专用的启动器,将运行时指向刚构建的库目录;应使用该启动器,让测试检验当前工作树而不是已安装副本。如果辅助编译器缓存组件属于默认构建和测试图,除非规范指南明确缩小运行范围,否则应将它包括在内。
### 选择有意义的最小测试
使命令与更改范围相匹配:
- 迭代检查局部行为时,运行单个生成包装代码测试;
- 后端行为发生变化时,运行受影响目标语言的完整测试套件;
- 解析器、类型系统、所有权或公共生成逻辑发生变化时,运行共享测试套件;
- 只有仓库支持时才使用并行执行;
- 进行大范围测试时,如果收集所有故障比在第一个故障处停止更有价值,就使用持续执行模式。
测试目标通常会编码源代码形态,例如原生语言模式、面向对象模式或多模块模式。使用与用例匹配的后缀,并先运行相应的清理目标,再把陈旧的生成产物判定为新故障。
### 验证自动化采用的同一路径
如果故障只在持续集成中发生,应使用仓库维护的容器镜像和真实安装脚本复现执行环境。优先使用能够复现托管执行环境的辅助工具,而不是临时拼装环境。在把差异归因于源代码之前,确认依赖项版本、环境变量、构建模式和测试目标完全一致。
修复缺陷或添加功能通常应包含回归测试。不要因为编译器构建成功就声称更改已经验证;包装代码生成、生成代码的编译和目标语言的运行时行为是三个独立检查点。
## 找出错误最早出现的流水线阶段,不要嵌套调用解析器
### 按顺序跟踪处理阶段
按照流水线顺序追踪行为:
1. 预处理器展开接口输入和条件指令。
2. 扫描器把输入文本转换为词法单元。
3. 解析器应用语法,并创建由带属性节点组成的树。
4. 类型系统解析名称、等价关系、模板和转换。
5. 树级处理过程添加或规范化后续阶段所需的信息。
6. 目标语言后端遍历树并生成包装代码。
找出实际状态最早偏离预期状态的阶段。包装代码格式错误并不能证明后端有错;后端可能只是忠实生成了由更早阶段产生的错误解析节点、类型、所有权标志或转换规则。
### 使用模型的核心抽象
解析节点的行为类似键值对象,并由共享处理过程和语言后端遍历。在属性创建时检查一次,在属性使用时再检查一次。类型转换映射控制原生值如何跨越边界变成目标语言值;转换行为错误时,应先检查选择优先级和类型等价关系,再修改生成文本。
模板实例化依赖同一套类型等价机制,因此应把特化匹配与包装代码格式化分开分析。在添加后端局部的生命周期变通方案之前,应先检查共享的所有权和分配分析。
### 遵守非重入解析器边界
除非实现能够证明相反情况,否则应假定解析器不可重入。包装解析器的入口点可能覆盖全局解析器状态,包括当前输入位置、语义值和向前查看状态。绝不要从语法动作内部递归调用这些入口点。
当语法规则需要构建新的参数列表或相关子语法时,应在当前解析过程中复用已有语法产生式,而不是启动嵌套解析。使用引入该语法功能的最早语言标准所对应的回归用例验证更改。
### 使用受支持的调试入口
使用仓库已有文档说明的调试标志、文本或结构化树转储、调试器辅助工具、执行包装器、功能选择变量和内存池诊断。对于只在自动化中发生的故障,应先复现自动化环境,再扩大检测手段。诊断性更改应保持临时性质;没有能够证明必要性的失败测试时,不要把局部变通方案变成生产行为。
## 把回归测试分别放进共享输入和目标语言脚本
### 将行为放在正确层级
测试通常包含驱动生成过程的共享接口输入,以及可选的目标语言运行时脚本,后者用于执行生成的包装代码。把与语言无关的语法和包装代码要求放入共享输入。把目标语言语法、运行时断言和语言专用边界用例放入相应的运行时脚本。
将新用例注册到与真实作用域相符的测试分组中。与语言标准绑定的测试名称前缀必须代表引入该语法功能的最早标准,而不是某个方便示例所使用的更新标准。先单独确定该功能,再把测试放入匹配的标准分组。
### 让故障可观察
使用在优化运行时模式下仍然有效的断言辅助工具。如果目标语言能够在优化期间停用其内置断言语句,回归覆盖绝不能依赖该语句。应使用明确的相等、条件和预期异常辅助工具,在失败时报告有用的值。
测试注释应简短,并只说明代码本身无法显现的信息。用简洁的一行解释编译器变通方案或语义陷阱;不要复述代码已经表达的内容。回归测试应在修复前失败、修复后通过,并检验对外行为,而不是偶然使用的内部辅助函数。
### 验证共享影响
对于解析器或公共类型系统更改,如果受影响路径是共享的,应测试最初失败后端之外的后端。对于仅涉及后端的行为,不要在没有证据时扩大运行范围。在实质不同的测试配置之间清理生成文件,并在报告中区分生成失败、原生编译失败和运行时失败。
## 提交中不混入无关改动,并把用户可见的变化写进更改日志
### 遵循源代码和注释规范
使用仓库的格式检查和格式化工具,不要手动规范化无关代码。遵循既有的原生语言注释样式、词法单元引用方式、行宽和函数头规范。语法文件可能对新代码有更严格的规则;应遵守这些规则,并在修改生产解析器时避免无关重构。
提交前检查差异中是否包含生成文件、意外的大范围替换,以及预期子系统之外的更改。提交文本必须平实、简洁且准确。不要把自动化工具列为共同作者。如果项目要求披露重要的自动化协助,应使用项目认可的协助尾注,但不要加入电子邮件身份。
### 记录用户可见的更改
每项用户可见的缺陷修复、功能、行为变化、警告变化或弃用,都必须在当前更改日志中加入条目。描述用户能够观察到的变化,而不是内部辅助函数名称或重构细节。遵循仓库既有的日期和issue格式,按预期顺序放置新条目,并明确标出兼容性风险。没有可观察影响的纯内部更改不需要用户条目。
### 维护开发者文档和用户文档
编辑手册时,应保留稳定且能够描述内容的标题锚点,不要改用自动生成的数字锚点。对代码、目标语言示例、shell会话和图表使用已有文档规定的内容类别。让跨文档链接指向稳定目标,然后运行目录生成器和文档检查。
开发者文档应说明内部对象模型、树属性、类型系统和扩展路径。用户文档应聚焦受支持的语法和可观察行为。验证渲染后的结构和链接目标;仅仅成功编辑源文件,并不能证明手册仍然便于导航。
