ast-grep:13300⭐的 Rust 代码结构搜索工具,用模式代码找代码
在代码重构和迁移的日常工作中,我们常常需要批量查找特定模式的代码——比如找到所有使用旧 API 的调用点,或者找出不符合新规范的写法。传统的文本搜索(grep)在面对复杂语法时往往力不从心,而编写完整的静态分析工具又过于笨重。
ast-grep 提供了一个优雅的中间方案。这款由 Rust 编写的 CLI 工具让你可以用「写代码的方式」来搜索代码——它基于抽象语法树(AST)进行匹配,能理解代码的语法结构而非仅仅是文本。
项目速览
| 属性 | 内容 |
|---|---|
| GitHub | ast-grep/ast-grep |
| ⭐ Stars | 13.3k |
| 🔧 语言 | Rust |
| ⚡ 特点 | AST 结构匹配、20+ 语言支持、代码重写 |
| 📅 更新 | 活跃开发中 |
核心概念
ast-grep 的核心理念很简单:用代码搜代码。
传统的 grep 只能处理文本,而 ast-grep 解析代码的 AST 后进行结构匹配。你可以写一个模式代码(pattern code),ast-grep 会找到所有语法结构与之匹配的代码片段。
# 搜索所有 console.log 调用
sg --pattern 'console.log($ARGS)' --lang ts
安装
支持多种安装方式:
# npm
npm install --global @ast-grep/cli
# Homebrew
brew install ast-grep
# Cargo
cargo install ast-grep
# pip
pip install ast-grep-cli
基础用法
1. 命令行搜索
# 查找所有未使用的变量(以 _ 开头)
sg --pattern 'const $_ = $INIT' --lang ts
# 查找所有 setState 调用
sg --pattern 'setState($VALUE)' --lang ts
2. 使用规则文件
创建 .ast-grep/rules/no-console.yml:
id: no-console
language: ts
rule:
pattern: console.log($$$ARGS)
message: 请勿在生产代码中保留 console.log
severity: warning
然后运行:
sg scan
3. 代码重写
# 将所有 var 替换为 const
sg --pattern 'var $NAME = $INIT' --rewrite 'const $NAME = $INIT' --lang ts
高级特性
多语言支持
基于 tree-sitter 解析器,ast-grep 支持 20+ 编程语言:
- JavaScript / TypeScript
- Python
- Rust
- Go
- Java
- C / C++
- Ruby
- 更多…
元变量
使用 $ 开头的标识符作为通配符:
$MATCH- 匹配任意单个 AST 节点$$$ARGS- 匹配多个节点(展开匹配)
# 匹配任意函数调用
sg --pattern '$FUNC($$$ARGS)' --lang ts
在线 Playground
ast-grep Playground 提供了实时测试环境,可以即时验证你的搜索模式:
// 输入模式
const $NAME = require('$MODULE')
// 匹配结果
const fs = require('fs') // ✓ 匹配
const path = require('path') // ✓ 匹配
import { readFile } from 'fs' // ✗ 不匹配(不同的语法结构)
典型应用场景
| 场景 | 示例 |
|---|---|
| 代码迁移 | 批量替换弃用的 API 调用 |
| 规范检查 | 强制团队代码风格一致性 |
| 漏洞扫描 | 查找潜在的安全风险模式 |
| 重构辅助 | 识别需要拆分的复杂函数 |
| 教学演示 | 展示代码模式的分布情况 |
与同类工具对比
| 工具 | 匹配方式 | 重写能力 | 易用性 |
|---|---|---|---|
| grep | 文本 | 有限 | ⭐⭐⭐ |
| ast-grep | AST 结构 | 强 | ⭐⭐⭐⭐ |
| ESLint | AST + 规则 | 中等 | ⭐⭐⭐ |
| Semgrep | AST 结构 | 强 | ⭐⭐⭐⭐ |
相比 Semgrep,ast-grep 更轻量、启动更快;相比 ESLint,它的搜索语法更直观,无需编写复杂的访问者模式代码。
总结
ast-grep 填补了「文本搜索」和「完整静态分析」之间的空白。对于需要批量处理代码但又不想投入大量工具链建设的团队来说,它是一个高效的折中选择。
# 一句话总结
sg --pattern '旧代码模式' --rewrite '新代码模式' --lang ts
如果你经常需要处理代码迁移、规范落地或批量重构,ast-grep 值得加入你的工具箱。