ast-grep
工作流程
- 编写一个代表目标代码的测试片段
- 编写规则(从
pattern开始,必要时升级为kind+has/inside) - 使用
--stdin进行测试,然后再搜索整个代码库 - 规则匹配后,搜索整个代码库
关键陷阱
始终在关系规则中使用 stopBy: end
如果不这样做,has/inside 会在第一个不匹配的节点处停止,而不是遍历完整的子树:
# 错误——会漏掉深层嵌套的匹配
has:
pattern: await $EXPR
# 正确
has:
pattern: await $EXPR
stopBy: end
在 shell 中转义元变量
$VAR 会被 shell 解释。要么转义,要么用单引号:
# 双引号:使用反斜杠转义
ast-grep scan --inline-rules "id: test
language: javascript
rule:
pattern: await \$EXPR" .
# 单引号:无需转义
ast-grep scan --inline-rules 'id: test
language: javascript
rule:
pattern: await $EXPR' .
元变量必须是 AST 节点的唯一内容
以下写法不起作用:obj.on$EVENT, "Hello $WORLD", a $OP b, $jq
对于未命名节点(运算符、标点符号),请使用 $$OP。对于零个或多个节点,请使用 $$$ARGS。
使用 --stdin 进行测试
echo "async function test() { await fetch(); }" | ast-grep scan --inline-rules 'id: test
language: javascript
rule:
kind: function_declaration
has:
pattern: await $EXPR
stopBy: end' --stdin
使用 --debug-query 进行调试
当规则不匹配时,检查 AST 以找到正确的 kind 值:
ast-grep run --pattern 'your code here' --lang javascript --debug-query=cst
格式:cst(所有节点)、ast(仅命名节点)、pattern(ast-grep 如何看待你的模式)。
规则语法
完整的规则参考请参见 references/rule_reference.md(包含原子规则、关系规则、复合规则和元变量)。