Aller au contenu

Recherche AST indexée

La recherche AST indexée est la version avec cache préchauffé de la recherche AST. Le premier appel extrait des faits au niveau des nœuds (noms d’appels, instanciations, déclarations de classes et déclarations de méthodes) et les stocke sur disque ; les appels suivants utilisent le stockage pour ignorer les fichiers qui ne peuvent manifestement pas contenir de correspondance structurelle. Le moteur vérifie ensuite à nouveau les candidats dans le code source.

L’index de faits est accessible avec la sous-commande greph-index ast-index CLI et les méthodes de façade Greph::buildAstIndex() / Greph::searchAstIndexed(). Il est également utilisé pour les recherches préchauffées multi-index et celles sur des ensembles définis par manifeste.

Création de l’index

Shell
# Full build at the current directory
./vendor/bin/greph-index ast-index build .

# Full build at an explicit root
./vendor/bin/greph-index ast-index build path/to/repo

# Use a non-default index directory
./vendor/bin/greph-index ast-index build . --index-dir /tmp/greph-ast-index

# Build a mutable overlay that can refresh cheaply on demand
./vendor/bin/greph-index ast-index build . \
  --lifecycle opportunistic-refresh \
  --auto-refresh-max-files 32 \
  --auto-refresh-max-bytes 1048576

Par défaut, l’index de faits est stocké dans <root>/.greph-ast-index/.

Une création réussie affiche un résumé sur une seule ligne :

Text
Built AST index for 2547 files in .greph-ast-index (84931 fact rows, +2547 ~0 -0 =0)

Les quatre compteurs indiquent le nombre de fichiers ajoutés, mis à jour, supprimés et inchangés depuis la dernière création.

Actualisation de l’index

Shell
./vendor/bin/greph-index ast-index refresh .

refresh reparcourt la racine indexée, analyse à nouveau les fichiers modifiés et ne réécrit que les lignes de faits qui ont changé. La sortie utilise les mêmes quatre compteurs que l’index de texte.

Les profils de cycle de vie fonctionnent comme pour les index de texte préchauffés :

  • static : ne vérifie jamais la fraîcheur et n’effectue aucune modification automatique
  • manual-refresh : signale les données obsolètes dans stats, mais n’actualise jamais l’index pendant la recherche
  • opportunistic-refresh : actualise l’index pendant la recherche uniquement si l’ensemble des fichiers modifiés reste assez petit
  • strict-stale-check : refuse les recherches sur des données obsolètes au lieu d’actualiser l’index

Interrogation de l’index

Shell
./vendor/bin/greph-index ast-index search 'new $CLASS()' src
./vendor/bin/greph-index ast-index search '$obj->$method($$$ARGS)' src
./vendor/bin/greph-index ast-index search --json 'array($$$ITEMS)' src
./vendor/bin/greph-index ast-index search -l 'array($$$ITEMS)' src
./vendor/bin/greph-index ast-index search --trace-plan 'new $CLASS()' src

La syntaxe des métavariables est identique à celle de la recherche AST native. Consultez Modes / Recherche AST pour connaître toute la grammaire.

Options

Option Signification
--lang NAME Langage AST. Par défaut : php
-j N, --jobs N Nombre de processus de travail parallèles
-l, --files-with-matches Lister uniquement les fichiers correspondants
--glob GLOB Inclure uniquement les fichiers dont le chemin correspond à GLOB
--type NAME / --type-not NAME Filtre par type de fichier
--json Émettre une sortie JSON
--no-ignore Ignorer .gitignore et .grephignore
--hidden Inclure les fichiers masqués
--strict-parse Échouer en cas d’erreur d’analyse au lieu de l’ignorer
--fallback MODE Comportement si l’index manque : fail (par défaut) ou scan
--index-dir DIR Utiliser un répertoire d’index autre que celui par défaut
--trace-plan Émettre les diagnostics du planificateur AST préchauffé dans stderr
--show-index-origin Préfixer la sortie avec le libellé de l’index correspondant en mode multi-index ou ensemble

Repli si l’index manque

Par défaut, ast-index search génère une erreur lorsqu’aucun index n’existe à l’emplacement demandé. Passez --fallback scan pour effectuer une analyse AST native à la place. Ce paramètre convient aux outils qui privilégient la recherche indexée lorsqu’elle est possible, tout en devant produire des résultats si l’index n’a pas encore été créé.

Shell
./vendor/bin/greph-index ast-index search --fallback scan 'new $CLASS()' src

Vous pouvez rechercher dans plusieurs index AST préchauffés avec une seule commande en répétant --index-dir. C’est utile pour des configurations telles qu’un noyau WordPress accompagné d’une extension ou d’un thème.

Shell
./vendor/bin/greph-index ast-index search \
  --index-dir ../wordpress/.greph-ast-index \
  --index-dir ./.greph-ast-index \
  --show-index-origin \
  'new $CLASS()' .

Lorsque --show-index-origin est activé, la sortie est précédée du nom de l’entrée d’index préchauffée correspondante, afin d’indiquer quelle racine contient le résultat.

Ensembles d’index définis par manifeste

Pour les configurations préchauffées stables, définissez un manifeste et demandez à greph-index set d’utiliser les index regroupés :

Shell
./vendor/bin/greph-index set build
./vendor/bin/greph-index set stats --mode ast-index --dry-refresh
./vendor/bin/greph-index set search --mode ast-index --show-index-origin 'new $CLASS()' .

Les sous-commandes d’ensemble appliquent la même gestion du cycle de vie, les mêmes vérifications des données obsolètes et les mêmes diagnostics du planificateur que l’utilisation directe de ast-index.

Diagnostics du planificateur

--trace-plan montre comment Greph a réduit le nombre de résultats potentiels avant l’exécution du moteur de correspondance complet. Pour ast-index, cela comprend généralement :

  • la signature de faits générale extraite du motif
  • le nombre d’index préchauffés parcourus
  • le nombre de fichiers écartés par le filtre de faits
  • le nombre de fichiers candidats analysés à nouveau pour vérifier précisément la structure

Contenu de l’index

Pour chaque fichier indexé, l’extracteur de faits AST enregistre une ligne par nœud « intéressant ». Les types de faits couvrent les constructions généralement ciblées par les motifs AST :

  • Appels de fonctions et de méthodes (par nom appelé)
  • Instanciations de classes (par nom de classe)
  • Déclarations de classes, d’interfaces, de traits et d’énumérations (par nom)
  • Déclarations de fonctions (par nom)
  • Déclarations de méthodes (par nom et visibilité)
  • Instructions d’utilisation

À la réception d’une requête, Greph\Ast\AstFactQuery traduit le motif de recherche en une signature de faits générale (par exemple, « doit contenir une new de n’importe quelle classe ») et effectue une intersection avec le stockage de faits. Les fichiers qui restent sont ensuite analysés à nouveau et comparés au motif complet.

L’index de faits est donc un préfiltre, et non un stockage de correspondances exhaustives. L’étape de correspondance analyse toujours le code source ; la recherche structurelle reste donc aussi exacte qu’avec la recherche AST native, mais l’ensemble des candidats est réduit.

Quand l’utiliser

Le mode AST indexé est adapté lorsque :

  • Vous exécutez régulièrement les mêmes requêtes structurelles sur la même base de code.
  • Les motifs ciblent des formes identifiables (nom d’appel, nom de classe, type de déclaration) stockées par l’extracteur de faits.
  • Vous souhaitez réduire la latence par rapport à une nouvelle analyse de chaque fichier.

Pour les motifs dont la caractéristique distinctive ne figure pas dans l’ensemble de faits (par exemple, des expressions imbriquées complexes sans en-tête reconnaissable), le mode AST mis en cache est généralement plus adapté, car il ignore entièrement l’étape d’analyse sans dépendre d’une signature générale.

Utilisation par programmation

PHP
use Greph\Greph;
use Greph\Ast\AstSearchOptions;
use Greph\Index\IndexLifecycleProfile;

Greph::buildAstIndex('.', lifecycle: IndexLifecycleProfile::OpportunisticRefresh);

$matches = Greph::searchAstIndexed(
    'new $CLASS()',
    'src',
    new AstSearchOptions(jobs: 4, tracePlan: true),
);

searchAstIndexed accepte le même AstSearchOptions que la recherche AST native et renvoie une structure list<AstMatch> identique. Pour les flux de travail multi-index ou définis par manifeste, utilisez searchAstIndexedMany(...) et searchAstIndexedSet(...).