SuperAPI AI 工具集

ast-grep

编程与开发

查看项目

更新于 10-15 18:31

技能介绍

用途

ast-grep 是一个基于抽象语法树(AST)的结构化代码搜索与分析工具。它使用 AST 模式来匹配代码的结构,而不仅仅是文本,因此可以在大型代码库中进行强大而精确的代码搜索。本技能帮助用户将自然语言查询翻译为 ast-grep 规则。

适用场景

当用户有以下需求时可以使用本技能:

  • 需要使用结构化匹配搜索代码模式(例如“查找所有没有错误处理的异步函数”)
  • 想要定位特定的语言构造(例如“查找所有带特定参数的函数调用”)
  • 请求的搜索需要理解代码结构而非仅文本
  • 要求搜索具有特定 AST 特征的代码
  • 需要执行传统文本搜索无法处理的复杂代码查询

使用方式

总体工作流程

  1. 理解查询:明确用户想要查找的内容,必要时提出澄清问题,包括:具体的代码模式或结构、编程语言、需要考虑的边界情况或变体、匹配中应包含或排除的内容。

  2. 创建示例代码:编写一个代表用户想要匹配内容的简单代码片段,保存到临时文件用于测试。

  3. 编写 ast-grep 规则:将模式翻译为 ast-grep 规则。关键原则:关系规则(inside、has)始终使用 stopBy: end 以确保搜索进行到方向的末尾;简单结构使用 pattern;复杂结构使用 kind 配合 has/inside;使用 all、any 或 not 将复杂查询拆分为更小的子规则。

  4. 测试规则:使用 ast-grep CLI 验证规则是否匹配示例代码。

  5. 搜索代码库:规则正确匹配示例代码后,搜索实际代码库。

ast-grep CLI 命令

检查代码结构(--debug-query):

ast-grep run --pattern 'async function example() { await fetch(); }' \
  --lang javascript \
  --debug-query=cst

可用格式:cst(具体语法树,显示所有节点包括标点)、ast(抽象语法树,仅显示命名节点)、pattern(显示 ast-grep 如何解释你的模式)。

测试规则(scan with --stdin):

echo "const x = await fetch();" | ast-grep scan --inline-rules "id: test
language: javascript
rule:
  pattern: await \$EXPR" --stdin

添加 --json 可获得结构化输出。

使用模式搜索(run):

ast-grep run --pattern 'console.log($ARG)' --lang javascript .
ast-grep run --pattern 'class $NAME' --lang python /path/to/project
ast-grep run --pattern 'function $NAME($$$)' --lang javascript --json .

适用于简单、单节点匹配,快速搜索,不需要关系规则(inside/has)的场景。

使用规则搜索(scan):

ast-grep scan --rule my_rule.yml /path/to/project
ast-grep scan --inline-rules "id: find-async
language: javascript
rule:
  kind: function_declaration
  has:
    pattern: await \$EXPR
    stopBy: end" /path/to/project
ast-grep scan --rule my_rule.yml --json /path/to/project

适用于复杂结构搜索、关系规则(inside、has、precedes、follows)、复合逻辑(all、any、not),以及需要完整 YAML 规则能力的场景。

编写有效规则的技巧

  • 始终使用 stopBy: end:对于关系规则,除非有特定理由,否则始终使用 stopBy: end,确保搜索遍历整个子树而非在第一个不匹配节点处停止。
  • 从简单开始,再增加复杂度:先尝试 pattern;如果不行,尝试用 kind 匹配节点类型;按需添加关系规则(has、inside);用复合规则(all、any、not)组合复杂逻辑。
  • 使用正确的规则类型:pattern 用于简单直接的代码匹配;kind + 关系规则用于复杂结构;复合规则用于逻辑组合。
  • 用 AST 检查调试:规则不匹配时,使用 --debug-query=cst 查看实际 AST 结构,检查元变量是否正确检测,验证节点 kind 是否符合预期,确保关系规则搜索方向正确。
  • 内联规则中的转义:使用 --inline-rules 时,在 shell 命令中转义元变量,使用 \$VAR 代替 $VAR,或使用单引号。

常见用例

查找包含特定内容的函数(查找使用 await 的异步函数):

ast-grep scan --inline-rules "id: async-await
language: javascript
rule:
  all:
    - kind: function_declaration
    - has:
        pattern: await \$EXPR
        stopBy: end" /path/to/project

查找特定上下文中的代码(查找类方法中的 console.log):

ast-grep scan --inline-rules "id: console-in-class
language: javascript
rule:
  pattern: console.log(\$\$\$)
  inside:
    kind: method_definition
    stopBy: end" /path/to/project

查找缺少预期模式的代码(查找没有 try-catch 的异步函数):

ast-grep scan --inline-rules "id: async-no-trycatch
language: javascript
rule:
  all:
    - kind: function_declaration
    - has:
        pattern: await \$EXPR
        stopBy: end
    - not:
        has:
          pattern: try { \$\$\$ } catch (\$E) { \$\$\$ }
          stopBy: end" /path/to/project

资源

references/ 目录包含 ast-grep 规则语法的详细文档:rule_reference.md 涵盖原子规则、关系规则、复合规则和元变量。需要详细规则语法信息时可加载这些参考。

限制

资料中未提供关于支持的语言列表、性能限制、安装方式或收费信息的具体说明。