用途
ast-grep 用于结构化代码搜索,即按照代码的语法结构而不是纯文本或正则表达式来查找语言构造与代码模式。当需要查找文本或正则无法表达的代码模式时,可以使用该技能编写 ast-grep 规则。
主要能力
该技能的核心工作是把自然语言查询翻译成 ast-grep 规则,先针对示例验证规则,再在代码库上运行。它支持完整的规则语法,包括原子规则、关系规则(has/inside)、组合规则(all/any/not)以及元变量。更复杂的规则语法、故障排查和完整示例位于 references/rule_reference.md,在编写超出简单模式的规则时应阅读该参考文件。
使用方式
前置条件:ast-grep --version 必须可正常执行。若缺失,可安装:macOS 使用 brew install ast-grep,或 npm i -g @ast-grep/cli,或 cargo install ast-grep。调用时使用 ast-grep(sg 别名会与系统 sg 冲突)。
工作流程:
- 澄清——语言是什么?要匹配的确切结构是什么?需要包含或排除哪些边界情况?
- 制作示例——编写一个应当匹配的小片段,保存到临时文件。
- 编写规则——从最简单可行的写法开始,再逐步增加复杂度:pattern 用于直接代码形状 → kind 用于节点类型 → 关系规则(has/inside)→ 组合规则(all/any/not)。关系规则始终要加上 stopBy: end,使其遍历整个子树,而不是在第一个不匹配处停止。
- 针对示例测试直到匹配(见下方调试)。
- 匹配后在代码库上运行。
常用命令:
- 简单模式搜索:ast-grep run --pattern 'console.log($ARG)' --lang js .
- 规则文件搜索:ast-grep scan --rule rule.yml /path
- 内联规则、无需文件:ast-grep scan --inline-rules "$YAML" /path
- 在片段上测试规则:echo '<code>' | ast-grep scan --inline-rules "$YAML" --stdin
- 查看 AST 以获取 kind 值:ast-grep run --pattern '<code>' --lang js --debug-query=cst
以上任意命令都可加 --json 获得结构化输出。--debug-query 接受 cst(所有节点)、ast(仅命名节点)或 pattern(ast-grep 如何读取你的模式)。简单单节点匹配使用 run --pattern;需要关系或组合逻辑时使用 scan(规则文件或内联)。
内联规则中的转义:shell 会展开 $,因此在双引号包裹的 --inline-rules 中应写 $VAR,或用单引号包裹 YAML: ast-grep scan --inline-rules "rule: {pattern: 'console.log($ARG)'}" . ast-grep scan --inline-rules 'rule: {pattern: "console.log($ARG)"}' .
适用场景
适用于查找文本或正则表达式无法表达的代码模式,例如按语法结构定位特定语言构造、匹配具有特定父子或包含关系的代码节点,以及需要组合多个条件(全部满足、任一满足、取反)的复杂搜索。
限制
使用前必须确保 ast-grep 已安装且命令可用;调用时应使用 ast-grep 而非 sg 别名,因为 sg 会与系统 sg 冲突。规则不匹配时的调试方法包括:简化——把子规则剥离到最小的失败片段;确认关系规则带有 stopBy: end;用 --debug-query=cst 读取真实节点结构并验证 kind 值;检查元变量是否被识别(参见参考文件中的元变量说明)。
资源
- references/rule_reference.md——完整规则语法与示例。
- ast-grep 文档与 playground,可在线测试模式。