Căutare AST indexată
Căutarea AST indexată este versiunea cu cache încălzit a căutării AST. La primul apel, extrage fapte la nivel de nod (nume de apeluri, instanțieri, declarații de clase și declarații de metode) într-o stocare pe disc; apelurile ulterioare folosesc stocarea pentru a omite fișierele care, în mod evident, nu pot conține o potrivire structurală. Apoi, potrivitorul verifică din nou candidații în raport cu sursa.
Indexul de fapte este disponibil prin subcomanda greph-index ast-index CLI și metodele fațadei Greph::buildAstIndex() / Greph::searchAstIndexed(). Participă și la fluxurile de lucru încălzite cu mai multe indexuri și seturi susținute de manifest.
Construirea indexului
# 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
În mod implicit, indexul de fapte este stocat în <root>/.greph-ast-index/.
O construire reușită afișează un rezumat pe o singură linie:
Built AST index for 2547 files in .greph-ast-index (84931 fact rows, +2547 ~0 -0 =0)
Cei patru contori urmăresc fișierele adăugate, actualizate, șterse și neschimbate de la ultima construire.
Reîmprospătarea indexului
./vendor/bin/greph-index ast-index refresh .
refresh parcurge din nou rădăcina indexată, analizează din nou fișierele modificate și rescrie doar rândurile de fapte care s-au schimbat. Ieșirea folosește aceiași patru contori ca indexul de text.
Profilurile ciclului de viață se comportă la fel ca în cazul indexurilor de text încălzite:
static: nu verifică niciodată actualitatea și nu modifică automatmanual-refresh: raportează starea învechită înstats, dar nu reîmprospătează niciodată în timpul căutăriiopportunistic-refresh: reîmprospătează la căutare doar când setul modificat este suficient de micstrict-stale-check: respinge căutările învechite în loc să reîmprospăteze
Interogarea indexului
./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
Sintaxa metavariabilelor este identică cu cea a căutării AST native. Consultați Moduri / Căutare AST pentru gramatica completă.
Opțiuni
| Opțiune | Semnificație |
|---|---|
--lang NAME |
Limbaj AST. Implicit: php |
-j N, --jobs N |
Numărul de procese de lucru paralele |
-l, --files-with-matches |
Afișează doar fișierele potrivite |
--glob GLOB |
Include doar fișierele ale căror căi se potrivesc cu GLOB |
--type NAME / --type-not NAME |
Filtru după tipul fișierului |
--json |
Generează ieșire JSON |
--no-ignore |
Ignoră .gitignore și .grephignore |
--hidden |
Include fișierele ascunse |
--strict-parse |
Eșuează la erori de analizare în loc să le omită |
--fallback MODE |
Comportament pentru index lipsă: fail (implicit) sau scan |
--index-dir DIR |
Folosește un director de index care nu este implicit |
--trace-plan |
Afișează diagnosticele planificatorului AST încălzit în stderr |
--show-index-origin |
Prefixează ieșirea cu eticheta indexului potrivit în modul cu mai multe indexuri sau seturi |
Rezervă când lipsește indexul
În mod implicit, ast-index search afișează o eroare dacă nu există niciun index în locația solicitată. Transmiteți --fallback scan pentru a reveni la o scanare AST nativă. Aceasta este setarea potrivită pentru instrumentele care doresc să folosească o căutare indexată când este disponibilă, dar să afișeze rezultate și când indexul nu a fost încă construit.
./vendor/bin/greph-index ast-index search --fallback scan 'new $CLASS()' src
Căutare în mai multe indexuri
Puteți căuta într-o singură comandă în mai multe indexuri AST încălzite, repetând --index-dir. Acest lucru este util pentru structuri precum WordPress de bază împreună cu un plugin sau o temă.
./vendor/bin/greph-index ast-index search \
--index-dir ../wordpress/.greph-ast-index \
--index-dir ./.greph-ast-index \
--show-index-origin \
'new $CLASS()' .
Când --show-index-origin este activată, ieșirea este prefixată cu numele intrării din indexul încălzit potrivit, astfel încât să puteți vedea ce rădăcină a produs rezultatul.
Seturi de indexuri susținute de manifest
Pentru configurații încălzite stabile, definiți un manifest și permiteți-i lui greph-index set să opereze asupra indexurilor grupate:
./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()' .
Subcomenzile setului folosesc aceeași gestionare a ciclului de viață, aceleași verificări ale elementelor învechite și aceleași diagnostice ale planificatorului ca utilizarea directă a ast-index.
Diagnosticarea planificatorului
--trace-plan arată cum a restrâns Greph interogarea înainte de rularea potrivitorului complet. Pentru ast-index, aceasta include de obicei:
- semnătura aproximativă a faptelor extrase din tipar
- numărul indexurilor încălzite căutate
- numărul fișierelor respinse de filtrul de fapte
- numărul fișierelor candidate analizate din nou pentru verificarea structurală exactă
Ce stochează indexul
Pentru fiecare fișier indexat, extractorul de fapte AST înregistrează câte un rând pentru fiecare nod „interesant”. Setul de tipuri de fapte acoperă construcțiile vizate cel mai frecvent de tiparele AST:
- Apeluri de funcții și metode (după numele apelat)
- Instanțieri de clase (după numele clasei)
- Declarații de clase, interfețe, trăsături și enumuri (după nume)
- Declarații de funcții (după nume)
- Declarații de metode (după nume și vizibilitate)
- Instrucțiuni use
Când sosește o interogare, Greph\Ast\AstFactQuery transformă tiparul de căutare într-o semnătură aproximativă de fapte (de exemplu, „trebuie să conțină un new din orice clasă”) și intersectează stocarea de fapte. Fișierele care rămân după intersecție sunt apoi analizate din nou și potrivite cu tiparul complet.
Așadar, indexul de fapte este un filtru preliminar, nu o stocare a potrivirilor cu fidelitate completă. Etapa de potrivire analizează în continuare sursa, astfel încât corectitudinea structurală este identică cu cea a căutării AST native; doar setul de candidați este mai mic.
Când să îl folosiți
Modul AST indexat este potrivit când:
- Rulați în mod repetat aceleași interogări structurale asupra aceleiași baze de cod.
- Tiparele vizează forme identificabile (numele apelului, numele clasei, tipul declarației) stocate de extractorul de fapte.
- Doriți o latență mai mică decât la analizarea din nou a fiecărui fișier.
Pentru tiparele a căror caracteristică distinctivă nu se găsește în setul de fapte (de exemplu, expresii imbricate complexe fără un element de început recognoscibil), modul AST memorat în cache este de obicei mai potrivit, deoarece omite complet etapa de analizare fără să se bazeze pe o semnătură aproximativă.
Utilizare programatică
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 acceptă același AstSearchOptions ca și căutarea AST nativă și returnează aceeași structură list<AstMatch>. Pentru fluxuri cu mai multe indexuri sau susținute de manifest, folosiți searchAstIndexedMany(...) și searchAstIndexedSet(...).