搜索/编写带自动修复的静态分析规则,且修复不改变代码的运行方式

编写带自动修复的静态分析规则,且修复不改变代码的运行方式

编写静态分析(lint)规则时使用。它只针对常见写法,复用现有的辅助函数,只在安全时提供自动修复,测试容易出错的语法,并重新生成文档而不是手改。

要使用这个AI规则
## 只针对常见写法,把少见情况排除在外 每条规则在概念上都应保持简单。应针对反复出现且价值较高的模式;如果覆盖罕见边界条件会使规则难以理解或增加修复风险,则不必支持这些条件。 使用创建函数和元数据定义稳定的规则契约。在基于事件的适配器中,应通过提供的钩子注册进入和退出监听器,而不是返回传统的访问器映射。监听器应返回或yield问题对象,并由适配器执行报告。 每个问题都应标明相关节点和消息,并且只在需要时添加数据、修复或建议。如果修复器API提供中止机制,只要无法证明编辑安全,就应使用该机制。把选项的默认值放在元数据中,让框架以一致方式合并,而不是在规则中重复实现合并逻辑。 ## 决定规则放进哪个预设,选项名以 check 开头 将预设位置视为产品决策: - 把没有争议的规则放入最安全的预设以及所有范围更广的预设。 - 仅把有用但带有明确倾向的默认设置放入推荐预设和范围更广的集合。 - 不要把小众行为或需要明确启用的行为放入默认预设。 不要混淆“不带立场”和“立场过强”。如果不确定,应说明建议的级别并让维护者决定。 面向用户的布尔选项应采用`check*`形式的肯定名称,使`true`始终表示启用行为。被忽略模式的列表仍可使用`ignore`等惯用名称。明确声明支持的每一种语言。如果逻辑只依赖文件名、原始文本、注释或指令,应在可行的情况下支持多种语言,并使用根节点辅助函数和注释辅助函数来抽象不同语言特有的节点类型。 ## 按返回内容给辅助函数命名,并复用现有工具函数 根据可观察到的契约为私有辅助函数命名。`is*`、`has*`、`should*`、`can*`和`needs*`必须返回布尔值,最好明确返回`false`,而不是意外得到undefined。一个可选问题使用`get*Problem`,多个问题使用`get*Problems`。`report*`只用于直接执行报告的辅助函数。 不要把报告或yield与谓词结果合并。先单独构建问题,再在调用位置进行布尔判断。 添加辅助函数前,先检查仓库中的AST、通用工具、修复器和共享规则模块,然后检查可信的生态系统工具。对于静态求值、变量查找、副作用检测、token检查、引用解析、括号、分号和修复构建,应复用统一入口导出和已有辅助函数。只有在明确可复用时才把辅助函数提升为共享工具;小型的规则专用逻辑应保留在本地。 ## 只在判断代码是否一定退出时使用控制流分析 如果规则必须判断某个分支或函数是否总会通过return、throw、break、continue、穷尽式选择或无限循环等结构退出,应使用框架的控制流分析。在异常处理、标签、嵌套和不可达区段周围,手动遍历AST通常不够准确。 进行分支分析时,注册仓库的分支退出跟踪器,并在外层条件语句退出后查询它。进行函数分析时,为每条代码路径维护独立的区段集合,防止嵌套函数污染其父函数。在相关AST节点退出时记录可达性;如果框架已经清除了当前区段,不要等到代码路径结束。 如果只需判断最后一条语句是否属于特定类型、return出现在哪里,或局部修复器是否以return或throw结束,应使用更简单的语法检查。没有真实的可达性要求时,不要引入控制流机制。 ## 自动生成的索引和文档头部要重新生成,不要手改 编辑前识别自动生成文件和自动生成区域。绝不要手动编辑自动生成的索引、表格或文档页眉。添加、移除或重命名源规则后,应运行负责这些内容的生成器。解决冲突时,应保留正本条目并重新生成具有确定性的结果,不要手动重建。 人工编写的文档应放在所有自动生成页眉边界之下。示例应使用仓库首选的配置语法;除非示例明确采用JSON,否则不要改用带引号的类JSON示例。 如果相关仓库或软件包中也存在共享规则模式,应考虑是否移植同一变更。应把这视为明确的兼容性决策,而不是自动执行的跨项目编辑。 ## 开发中只跑正在编写的规则的测试,最后再跑全部测试 在实现前或实现过程中编写目标明确的测试。如果测试工具能够同时捕获诊断、修复和建议,应优先采用快照测试;专用解析器模式只用于确有需要的场景。 开发期间只运行目标规则的测试。应有意识地更新快照,并在完成前移除临时的聚焦测试标记。不要把耗时的集成测试加入常规编辑循环。实现新规则后以及每次修正逻辑后,都要进行内部试用测试,因为修复往往会暴露其他位置的违规。 最后,依次运行仓库实际使用的linter、目标测试和内部试用测试,然后只运行一次完整测试套件。不要仅仅因为其他lint工具报告没有问题,就用它替代仓库原有的linter。 ## 用注释和容易出错的语法测试修复 测试行为、不匹配、修复和建议,同时避免重复覆盖。应从以下类别中加入相关案例: - 类型化语法、类型断言、泛型和可选链; - JSX、注释、多余括号、嵌套表达式和链式表达式; - 计算属性、模板、展开语法和解构; - return值被使用和未被使用的情况; - 当规则依赖类型时,仅解析语法与使用完整类型信息的情况。 测试规则有意忽略的案例,以便记录边界。在存在注释以及可能触发自动分号插入风险的情况下验证修复。如果某个案例需要不同的解析器,应在能够表达该要求的最小测试范围内配置。 ## 只在不改变代码运行方式时提供自动修复,并保留注释 只有在自动修复不会改变运行时行为时才提供修复。如果行为可能改变,应优先提供建议。必须保留注释:如果替换或移除的范围包含注释,应中止修复,或使用能够让注释留在原位的范围感知编辑。 生成修复前,检查替换内容是否需要括号、开头的方括号或圆括号是否要求分号,以及相邻token之间是否需要空格。多处编辑操作应使用生成器修复。保持可选链的行为;如果某个值的使用方式与独立表达式不同,应避免不安全的编辑。 除非仓库已有简单的本地保护措施,否则不要仅仅为了保留被遮蔽的内置对象、访问器或代理的副作用以及稀疏数组的空位,而让修复变得不成比例地复杂。无法确认安全性时,只报告问题,不提供修复。 ## 给规则命名,用脚手架创建,从测试一直走到提交 选择能够说明目标结构和意图的名称:如果`no-`、`prefer-`、`require-`或`consistent-`等前缀能够明确行为,就使用它们。名称应描述目标,而不是建议的替代方案,并避免含糊的名称。 使用仓库的脚手架创建实现、测试、文档和自动生成的索引条目。然后按以下顺序执行: 1. 添加会失败的测试或具有代表性的测试。 2. 实现能够满足测试的最小规则逻辑。 3. 记录行为和有意排除的情况。 4. 运行目标测试和权威的lint命令。 5. 进行内部试用测试,最后运行完整测试套件。 6. 确认自动生成文件为最新版本,并且临时文件已清理。 遵循项目的提交消息规范,包括规则名称和选项名称周围要求的标点。只有当源代码、测试、文档、自动生成区域和验证结果一致时,交付才算完成。