ast-grep について
ast-grep Code Searchは、自然言語の検索要望をast-grepのルールに変換し、コードを構造的に検索するスキルです。ルールの作成、テスト、デバッグから、ast-grepコマンドラインでのコードベース検索まで扱います。
主な機能
- 01検索要望を構造ルールに変換
- 02単純なルールと関係ルールの作成
- 03コード片やファイルでルールをテスト
- 04ASTを確認してマッチをデバッグ
- 05コマンドラインでコードベースを検索
活用シーン
- 01awaitを含む非同期関数の検索
- 02指定引数を持つ呼び出しの特定
- 03期待するパターンがないコードの検索
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ coleam00/ skills --skill ast-grepインストール後、Claude Code で/ast-grepを入力して読み込まれたか確認します。
同梱ファイルreferences/rule_reference.md
詳細
ast-grep コード検索
概要
このスキルは、自然言語のクエリを ast-grep のルールに変換し、構造的なコード検索を行えるようにします。ast-grep は、単なるテキストではなくコードの構造に基づいて一致する抽象構文木(AST)パターンを使用するため、大規模なコードベースでも強力で正確なコード検索ができます。
このスキルを使うタイミング
次のような場合に、このスキルを使用します。
- 構造的なマッチングを使ってコードパターンを検索したい場合(例:「エラー処理のないすべての非同期関数を探す」)
- 特定の言語構造を見つけたい場合(例:「特定のパラメーターを持つすべての関数呼び出しを探す」)
- 単なるテキストではなく、コード構造の理解が必要な検索を依頼された場合
- 特定の AST の特性を持つコードの検索を依頼された場合
- 従来のテキスト検索では対応できない複雑なコードクエリを実行する必要がある場合
一般的なワークフロー
効果的な ast-grep ルールをユーザーが作成できるよう、次の手順に従います。
ステップ 1:クエリを理解する
ユーザーが何を見つけたいのかを明確に理解します。必要に応じて、確認の質問をします。
- どのようなコードパターンや構造を探していますか?
- どのプログラミング言語ですか?
- 考慮すべき特定のエッジケースやバリエーションはありますか?
- 一致に含めるもの、または除外するものは何ですか?
ステップ 2:サンプルコードを作成する
ユーザーが一致させたい対象を表す簡単なコードスニペットを作成します。テスト用に、一時ファイルに保存します。
例: 「await を使用する非同期関数」を検索する場合、テストファイルを作成します。
// test_example.js
async function example() {
const result = await fetchData();
return result;
}
ステップ 3:ast-grep ルールを作成する
パターンを ast-grep ルールに変換します。まずはシンプルなルールから始め、必要に応じて複雑さを加えます。
主な原則:
- リレーショナルルール(
inside、has)では、検索が方向の終端まで進むよう、常にstopBy: endを使用します - 単純な構造には
patternを使用します - 複雑な構造には
kindとhas/insideを使用します - 複雑なクエリは
all、any、notを使って小さなサブルールに分割します
ルールファイルの例(test_rule.yml):
id: async-with-await
language: javascript
rule:
kind: function_declaration
has:
pattern: await $EXPR
stopBy: end
ルールの詳細については、references/rule_reference.md を参照してください。
ステップ 4:ルールをテストする
ast-grep CLI を使って、ルールがサンプルコードに一致することを確認します。主な方法は 2 つあります。
方法 A:インラインルールでテストする(迅速な反復向け)
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
方法 B:ルールファイルでテストする(複雑なルールに推奨)
ast-grep scan --rule test_rule.yml test_example.js
一致しない場合のデバッグ:
- ルールをシンプルにします(サブルールを削除します)
- リレーショナルルールに
stopBy: endがない場合は追加します --debug-queryを使って AST の構造を確認します(下記参照)kindの値がその言語で正しいか確認します
ステップ 5:コードベースを検索する
サンプルコードにルールが正しく一致したら、実際のコードベースを検索します。
シンプルなパターン検索の場合:
ast-grep run --pattern 'console.log($ARG)' --lang javascript /path/to/project
複雑なルールベースの検索の場合:
ast-grep scan --rule my_rule.yml /path/to/project
インラインルールの場合(ファイルを作成しない場合):
ast-grep scan --inline-rules "id: my-rule
language: javascript
rule:
pattern: \$PATTERN" /path/to/project
ast-grep CLI コマンド
コード構造を確認する(--debug-query)
コードがどのように解析されるかを理解するため、AST 構造を出力します。
ast-grep run --pattern 'async function example() { await fetch(); }' \
--lang javascript \
--debug-query=cst
使用可能な形式:
cst:具象構文木(句読点を含むすべてのノードを表示)ast:抽象構文木(名前付きノードのみを表示)pattern:ast-grep がパターンをどのように解釈するかを表示
次の目的で使用します:
- ノードの正しい
kindの値を見つける - 一致させたいコードの構造を理解する
- パターンが一致しない理由をデバッグする
例:
# See the structure of your target code
ast-grep run --pattern 'class User { constructor() {} }' \
--lang javascript \
--debug-query=cst
# See how ast-grep interprets your pattern
ast-grep run --pattern 'class $NAME { $$$BODY }' \
--lang javascript \
--debug-query=pattern
ルールをテストする(--stdin でスキャン)
ファイルを作成せずに、コードスニペットに対してルールをテストします。
echo "const x = await fetch();" | ast-grep scan --inline-rules "id: test
language: javascript
rule:
pattern: await \$EXPR" --stdin
構造化出力には --json を追加します:
echo "const x = await fetch();" | ast-grep scan --inline-rules "..." --stdin --json
パターンで検索する(run)
単一の AST ノードに一致する、シンプルなパターンベースの検索です。
# Basic pattern search
ast-grep run --pattern 'console.log($ARG)' --lang javascript .
# Search specific files
ast-grep run --pattern 'class $NAME' --lang python /path/to/project
# JSON output for programmatic use
ast-grep run --pattern 'function $NAME($$$)' --lang javascript --json .
使用する場面:
- シンプルな単一ノードの一致
- 複雑なロジックを使わない簡易検索
- リレーショナルルール(inside/has)が不要な場合
ルールを使った検索(scan)
複雑な構造クエリに対応する、YAML ベースのルール検索です。
# With rule file
ast-grep scan --rule my_rule.yml /path/to/project
# With inline rules
ast-grep scan --inline-rules "id: find-async
language: javascript
rule:
kind: function_declaration
has:
pattern: await \$EXPR
stopBy: end" /path/to/project
# JSON output
ast-grep scan --rule my_rule.yml --json /path/to/project
使用する場面:
- 複雑な構造検索
- 関係ルール(inside、has、precedes、follows)
- 複合ロジック(all、any、not)
- 完全な YAML ルールの機能が必要な場合
ヒント: 関係ルール(inside/has)では、完全に探索できるように、必ず stopBy: end を追加してください。
効果的なルールを書くためのヒント
常に stopBy: end を使用する
関係ルールでは、特別な理由がない限り、必ず stopBy: end を使用してください。
has:
pattern: await $EXPR
stopBy: end
これにより、最初に一致しないノードで停止するのではなく、検索でサブツリー全体を探索できます。
まずシンプルに始めてから、複雑にする
機能する可能性のある、最もシンプルなルールから始めます。
- まず
patternを試します - 機能しない場合は、ノードの種類に一致させるため
kindを試します - 必要に応じて関係ルール(
has、inside)を追加します - 複雑なロジックには、複合ルール(
all、any、not)を組み合わせます
適切なルールの種類を使う
- Pattern:シンプルで直接的なコードマッチングに使用します(例:
console.log($ARG)) - Kind + Relational:複雑な構造に使用します(例:「await を含む関数」)
- Composite:論理的な組み合わせに使用します(例:「try-catch の外にある await を含む関数」)
AST の検査でデバッグする
ルールが一致しない場合:
--debug-query=cstを使って、実際の AST 構造を確認します- メタ変数が正しく検出されているか確認します
- ノードの
kindが想定どおりか確認します - 関係ルールが適切な方向に検索しているか確認します
インラインルールでのエスケープ
--inline-rules を使用する場合は、シェルコマンド内のメタ変数をエスケープしてください。
$はシェルで変数として解釈されるため、$VARではなく\$VARを使用します- または、シングルクォートを使用します。ほとんどのシェルでは
'$VAR'が機能します
例:
# Correct: escaped $
ast-grep scan --inline-rules "rule: {pattern: 'console.log(\$ARG)'}" .
# Or use single quotes
ast-grep scan --inline-rules 'rule: {pattern: "console.log($ARG)"}' .
一般的な使用例
特定の内容を含む関数を検索する
await を使用する async 関数を検索します。
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 のない async 関数を検索します。
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:アトミックルール、関係ルール、複合ルール、メタ変数を網羅した、ast-grep ルールの包括的なドキュメントです
詳細なルール構文の情報が必要な場合は、これらのリファレンスを読み込んでください。