ast-grep
Workflow
- Écrire un snippet de test représentant le code cible
- Écrire la règle (commencer par
pattern, escalader àkind+has/insidesi nécessaire) - Tester avec
--stdinavant de chercher dans le codebase - Chercher dans le codebase une fois que la règle correspond
Pièges critiques
Toujours utiliser stopBy: end sur les règles relationnelles
Sans cela, has/inside s'arrêtent au premier nœud non correspondant au lieu de parcourir tout le sous-arbre :
# MAUVAIS — manquera les correspondances imbriquées profondément
has:
pattern: await $EXPR
# BON
has:
pattern: await $EXPR
stopBy: end
Échapper les métavariables dans le shell
$VAR est interprété par le shell. Échappez-le ou utilisez des guillemets simples :
# Guillemets doubles : échapper avec un antislash
ast-grep scan --inline-rules "id: test
language: javascript
rule:
pattern: await \$EXPR" .
# Guillemets simples : pas besoin d'échappement
ast-grep scan --inline-rules 'id: test
language: javascript
rule:
pattern: await $EXPR' .
Les métavariables doivent être le contenu unique d'un nœud AST
Ceci ne fonctionne pas : obj.on$EVENT, "Hello $WORLD", a $OP b, $jq
Utilisez $$OP pour les nœuds sans nom (opérateurs, ponctuation). Utilisez $$$ARGS pour zéro ou plusieurs nœuds.
Tester avec --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
Déboguer avec --debug-query
Lorsque les règles ne correspondent pas, inspectez l'AST pour trouver les bonnes valeurs kind :
ast-grep run --pattern 'your code here' --lang javascript --debug-query=cst
Formats : cst (tous les nœuds), ast (nommés uniquement), pattern (comment ast-grep voit votre motif).
Syntaxe des règles
Voir references/rule_reference.md pour la référence complète des règles (règles atomiques, relationnelles, composites et métavariables).