Aller au contenu
An abstract, 8-bit style image featuring several bold, geometric code block shapes overlapping within a 128x128 pixel space, each shape in one of five distinct colors. Select blocks contain minimal, branching line patterns evoking nodes of an abstract syntax tree. Thin connectors link some blocks, suggesting searching and transformation between nodes. Small, crisp programming icons—such as a curly bracket, a 'py' for Python, and a diamond for SQL—are embedded within some shapes. The scene is entirely flat, 2D, with sharp, clean edges, no background, and no human figures.

ast-grep

AI generated translation.

ast-grep est un outil rapide et polyglotte pour la recherche structurelle dans le code, le linting et la réécriture à grande échelle.

GenAIScript fournit un wrapper autour de ast-grep pour rechercher des motifs dans l’AST d’un script, et transformer l’AST ! C’est une méthode très efficace pour créer des scripts qui modifient le code source puisqu’elle permet de cibler de manière chirurgicale des parties spécifiques du code.

La fonctionnalité ast-grep est fournie sous forme de plugin, il faut donc l’installer au préalable :

Terminal window
npm i @genaiscript/plugin-ast-grep
  • charger le module ast-grep
import { astGrep } from "@genaiscript/plugin-ast-grep";
const sg = await astGrep();

La méthode search vous permet de rechercher des motifs dans l’AST d’un script. Le premier argument est la langue, le deuxième argument est les correspondances de fichiers, et le troisième argument est le motif à rechercher.

  • trouver toutes les instructions console.log en TypeScript. Cet exemple utilise la syntaxe ‘pattern’.
// matches is an array of AST (immutable) nodes
const { matches } = await sg.search(
"ts",
"src/*.ts",
"console.log($META)",
);
  • trouver toutes les fonctions TypeScript sans commentaires. Cet exemple utilise la syntaxe des règles.
const { matches } = await sg.search("ts", "src/fib.ts", {
rule: {
kind: "function_declaration",
not: {
precedes: {
kind: "comment",
stopBy: "neighbor",
},
},
},
});

ou si vous copiez les règles depuis le terrain de jeu ast-grep en utilisant YAML,

const { matches } = await sg.search(
"ts",
"src/fib.ts",
YAML`
rule:
kind: function_declaration
not:
precedes:
kind: comment
stopBy: neighbor
`,
);

Un cas d’utilisation courant consiste à restreindre le motif au code impacté par un diff de code. Vous pouvez passer une chaîne de caractères diff à la méthode search, et elle filtrera les correspondances qui n’intersectent pas avec les fichiers to du diff.

const diff = await git.diff({ base: "main" })
const { matches } = await sg.search("ts", "src/fib.ts", {...}, { diff })

Un cas d’utilisation courant consiste à rechercher un motif et à le remplacer par un autre motif. La phase de transformation peut tirer parti des requêtes intégrées pour effectuer des transformations LLM. Cela peut être réalisé avec la méthode replace.

const edits = sg.changeset();

La méthode replace crée une modification qui remplace le contenu d’un nœud par un nouveau texte. La modification est stockée en interne mais n’est pas appliquée avant que commit soit appelé.

edits.replace(matches[0], "console.log('replaced')");

Bien sûr, les choses deviennent plus intéressantes lorsque vous utilisez des requêtes intégrées pour générer le texte de remplacement.

for (const match of matches) {
const updated = await prompt`... ${match.text()} ...`;
edits.replace(
match.node,
`console.log
('${updated.text}')`,
);
}

Ensuite, vous pouvez valider les modifications pour créer un ensemble de fichiers en mémoire. Les modifications ne sont pas encore appliquées au système de fichiers.

const newFiles = edits.commit();

Si vous souhaitez appliquer les modifications au système de fichiers, vous pouvez utiliser la fonction writeFiles.

await workspace.writeFiles(newFiles);

Cette version de ast-grep prend en charge les langages intégrés suivants :

  • Html
  • JavaScript
  • TypeScript
  • Tsx
  • Css
  • C
  • C++
  • Python
  • C#

Les langages suivants nécessitent l’installation d’un package additionnel (liste complète) :

  • SQL, @ast-grep/lang-sql
  • Angular, @ast-grep/lang-angular
Fenêtre de terminal
npm install -D @ast-grep/lang-sql

Les extensions de fichiers suivantes sont mappées aux langages correspondants :

  • HTML : html, htm
  • JavaScript : cjs, mjs, js
  • TypeScript : cts, mts, ts
  • TSX : tsx
  • CSS : css
  • c : c
  • cpp : cpp, cxx, h, hpp, hxx
  • python : py
  • C# : cs
  • sql : sql

GenAIScript a un mappage par défaut des extensions de fichiers bien connues vers les langages. Cependant, vous pouvez remplacer cela en passant l’option lang à la méthode search.

const { matches } = await sg.search("ts", "src/fib.ts", {...}, { lang: "ts" })

Il y a une courbe d’apprentissage pour maîtriser le langage de requêtes d’ast-grep.

Vous pouvez activer l’espace de noms genaiscript:astgrep pour voir les requêtes et les résultats dans les journaux.

Fenêtre de terminal
DEBUG=genaiscript:astgrep ...