Ricerca AST indicizzata
La ricerca AST indicizzata è la versione con cache precaricata della ricerca AST. Alla prima chiamata estrae i fatti a livello di nodo (nomi delle chiamate, istanziazioni, dichiarazioni di classi e di metodi) e li salva in un archivio su disco; le chiamate successive usano l'archivio per saltare i file che chiaramente non possono contenere una corrispondenza strutturale. Il motore di ricerca verifica quindi di nuovo i candidati sul codice sorgente.
L'indice dei fatti è esposto nel sottocomando greph-index ast-index CLI e nei metodi della facciata Greph::buildAstIndex() / Greph::searchAstIndexed(). Partecipa inoltre ai flussi di lavoro precaricati con più indici e ai gruppi definiti da manifest.
Creazione dell'indice
# 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
Per impostazione predefinita, l'indice dei fatti viene salvato in <root>/.greph-ast-index/.
Una creazione riuscita stampa un riepilogo su una riga:
Built AST index for 2547 files in .greph-ast-index (84931 fact rows, +2547 ~0 -0 =0)
I quattro contatori indicano i file aggiunti, aggiornati, eliminati e invariati dall'ultima creazione.
Aggiornamento dell'indice
./vendor/bin/greph-index ast-index refresh .
refresh ripercorre la radice indicizzata, analizza di nuovo i file modificati e riscrive solo le righe dei fatti che sono cambiate. L'output usa gli stessi quattro contatori dell'indice testuale.
I profili del ciclo di vita funzionano come per gli indici testuali precaricati:
static: non verificare mai l'aggiornamento né modificare automaticamentemanual-refresh: segnalare i dati obsoleti instats, senza mai aggiornare durante la ricercaopportunistic-refresh: aggiornare durante la ricerca solo se l'insieme delle modifiche è ancora abbastanza ridottostrict-stale-check: rifiutare le ricerche con dati obsoleti invece di aggiornarli
Interrogazione dell'indice
./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 sintassi delle metavariabili è identica a quella della ricerca AST nativa. Consultate Modalità / Ricerca AST per la grammatica completa.
Opzioni
| Opzione | Significato |
|---|---|
--lang NAME |
Linguaggio AST. Predefinito: php |
-j N, --jobs N |
Numero di worker paralleli |
-l, --files-with-matches |
Elenca solo i file corrispondenti |
--glob GLOB |
Includi solo i file i cui percorsi corrispondono a GLOB |
--type NAME / --type-not NAME |
Filtro per tipo di file |
--json |
Genera output JSON |
--no-ignore |
Ignora .gitignore e .grephignore |
--hidden |
Includi file nascosti |
--strict-parse |
Interrompi in caso di errori di analisi invece di ignorarli |
--fallback MODE |
Comportamento in assenza dell'indice: fail (predefinito) oppure scan |
--index-dir DIR |
Usa una directory dell'indice non predefinita |
--trace-plan |
Genera la diagnostica del pianificatore AST precaricato in stderr |
--show-index-origin |
Anteponi all'output l'etichetta dell'indice corrispondente in modalità multi-indice o gruppo |
Ripiego in assenza dell'indice
Per impostazione predefinita, ast-index search genera un errore se non esiste alcun indice nella posizione richiesta. Passate --fallback scan per ripiegare su una scansione AST nativa. È l'impostazione giusta per gli strumenti che preferiscono la ricerca indicizzata quando disponibile, ma devono comunque restituire risultati se l'indice non è ancora stato creato.
./vendor/bin/greph-index ast-index search --fallback scan 'new $CLASS()' src
Ricerca su più indici
Potete cercare in più indici AST precaricati con un solo comando ripetendo --index-dir. È utile per strutture come il core di WordPress insieme a un plugin o a un tema.
./vendor/bin/greph-index ast-index search \
--index-dir ../wordpress/.greph-ast-index \
--index-dir ./.greph-ast-index \
--show-index-origin \
'new $CLASS()' .
Quando --show-index-origin è abilitato, all'output viene anteposto il nome della voce dell'indice precaricato corrispondente, così potete vedere quale radice ha prodotto il risultato.
Gruppi di indici definiti da manifest
Per configurazioni precaricate stabili, definite un manifest e fate operare greph-index set sugli indici raggruppati:
./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()' .
I sottocomandi dei gruppi condividono la stessa gestione del ciclo di vita, gli stessi controlli dei dati obsoleti e la stessa diagnostica del pianificatore dell'uso diretto di ast-index.
Diagnostica del pianificatore
--trace-plan mostra come Greph ha ristretto la query prima dell'esecuzione del motore di ricerca completo. Per ast-index ciò include in genere:
- la firma approssimativa dei fatti estratta dal pattern
- quanti indici precaricati sono stati consultati
- quanti file sono stati esclusi dal filtro dei fatti
- quanti file candidati sono stati analizzati di nuovo per la verifica strutturale esatta
Dati salvati nell'indice
Per ogni file indicizzato, l'estrattore dei fatti AST registra una riga per ogni nodo "interessante". I tipi di fatti comprendono i costrutti più spesso cercati dai pattern AST:
- Chiamate a funzioni e metodi (in base al nome chiamato)
- Istanze di classi (in base al nome della classe)
- Dichiarazioni di classi, interfacce, trait ed enum (in base al nome)
- Dichiarazioni di funzioni (in base al nome)
- Dichiarazioni di metodi (in base al nome e alla visibilità)
- Istruzioni use
Quando arriva una query, Greph\Ast\AstFactQuery traduce il pattern di ricerca in una firma approssimativa dei fatti (per esempio, "deve contenere un new di qualsiasi classe") e interseca l'archivio dei fatti. I file che superano l'intersezione vengono quindi analizzati di nuovo e confrontati con il pattern completo.
Ciò significa che l'indice dei fatti è un prefiltro, non un archivio di corrispondenze completo. La fase di corrispondenza analizza comunque il codice sorgente, quindi la correttezza strutturale è identica a quella della ricerca AST nativa; cambia solo l'insieme dei candidati, che è più piccolo.
Quando usarlo
La modalità AST indicizzata è la scelta giusta quando:
- Eseguite ripetutamente le stesse query strutturali sulla stessa base di codice.
- I pattern cercano forme identificabili (nome della chiamata, nome della classe, tipo di dichiarazione) registrate dall'estrattore dei fatti.
- Volete una latenza inferiore rispetto alla nuova analisi di ogni file.
Per i pattern il cui tratto distintivo non è nell'insieme dei fatti (per esempio, espressioni annidate complesse senza un elemento iniziale riconoscibile), la modalità AST memorizzata nella cache è di solito più adatta, perché salta del tutto la fase di analisi senza basarsi su una firma approssimativa.
Uso programmatico
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 accetta lo stesso AstSearchOptions della ricerca AST nativa e restituisce dati con la stessa struttura list<AstMatch>. Per i flussi multi-indice o basati su manifest, usate searchAstIndexedMany(...) e searchAstIndexedSet(...).