Preskoči na vsebino

Indeksirano iskanje AST

Indeksirano iskanje AST je različica iskanja AST z ogretim predpomnilnikom. Pri prvem klicu izlušči dejstva na ravni vozlišč (imena klicev, primerke, deklaracije razredov in deklaracije metod) v shrambo na disku; pri naslednjih klicih ta shramba omogoči preskočiti datoteke, ki očitno ne morejo vsebovati strukturnega ujemanja. Ujemalnik nato kandidate znova preveri glede na izvorno kodo.

Indeks dejstev je na voljo prek podukaza greph-index ast-index CLI ter fasadnih metod Greph::buildAstIndex() / Greph::searchAstIndexed(). Podpira tudi poteke dela z ogretimi indeksi in manifestno podprtimi nabori.

Izdelava indeksa

Lupina
# 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

Indeks dejstev je privzeto shranjen v <root>/.greph-ast-index/.

Uspešna izdelava izpiše enovrstični povzetek:

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

Štirje števci prikazujejo dodane, posodobljene, izbrisane in nespremenjene datoteke od zadnje izdelave.

Osveževanje indeksa

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

refresh znova pregleda indeksirano korensko mapo, znova razčleni spremenjene datoteke in prepiše samo spremenjene vrstice dejstev. Izhod uporablja enake štiri števce kot besedilni indeks.

Profili življenjskega cikla delujejo enako kot pri ogretih besedilnih indeksih:

  • static: nikoli samodejno ne preverja svežine ali spreminja
  • manual-refresh: poroča o zastarelem stanju v stats, med iskanjem pa nikoli ne osvežuje
  • opportunistic-refresh: med iskanjem osveži le, če je nabor sprememb še dovolj majhen
  • strict-stale-check: zavrne zastarela iskanja, namesto da bi jih osvežil

Poizvedovanje po indeksu

Lupina
./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

Sintaksa metaspremenljivk je enaka kot pri izvornem iskanju AST. Celotno slovnico najdete v Načini / iskanje AST.

Možnosti

Zastavica Pomen
--lang NAME Jezik AST. Privzeto: php
-j N, --jobs N Število vzporednih delavcev
-l, --files-with-matches Izpiše samo ujemajoče se datoteke
--glob GLOB Vključi samo datoteke, katerih poti ustrezajo vzorcu GLOB
--type NAME / --type-not NAME Filter vrste datoteke
--json Ustvari izhod JSON
--no-ignore Prezre .gitignore in .grephignore
--hidden Vključi skrite datoteke
--strict-parse Ob napakah pri razčlenjevanju konča z napako, namesto da bi jih preskočil
--fallback MODE Ravnanje ob manjkajočem indeksu: fail (privzeto) ali scan
--index-dir DIR Uporabi neprivzeti imenik indeksa
--trace-plan Pošlje diagnostiko ogretega načrtovalnika AST v stderr
--show-index-origin V večindeksnem načinu ali načinu nabora doda predpono z oznako ustreznega indeksa

Nadomestno delovanje ob manjkajočem indeksu

Privzeto ast-index search sproži napako, če na zahtevani lokaciji ni indeksa. Podajte --fallback scan, da namesto tega preklopite na izvorno pregledovanje AST. Ta nastavitev je primerna za orodja, ki želijo uporabiti indeksirano iskanje, kadar je na voljo, a morajo še vedno vrniti rezultate, če indeks še ni zgrajen.

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

Z večkratno uporabo --index-dir lahko v enem ukazu iščete po več ogretih indeksih AST. To je uporabno pri razporeditvah, kot sta jedro WordPress in vtičnik ali tema.

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

Ko je omogočeno --show-index-origin, je pred izhod dodano ime vnosa ustreznega ogretega indeksa, da lahko vidite, iz katere korenske mape izvira zadetek.

Nabori indeksov, podprti z manifestom

Za stabilne ogrete nastavitve določite manifest in omogočite, da greph-index set deluje z združenimi indeksi:

Lupina
./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()' .

Podukazi za nabore uporabljajo enako upravljanje življenjskega cikla, preverjanje zastarelosti in diagnostiko načrtovalnika kot neposredna uporaba ast-index.

Diagnostika načrtovalnika

--trace-plan pokaže, kako je Greph zožil poizvedbo, preden se je zagnal polni ujemalnik. Za ast-index to običajno vključuje:

  • grobi podpis dejstev, izluščen iz vzorca
  • število pregledanih ogretih indeksov
  • število datotek, ki jih je filter dejstev zavrnil
  • število kandidatnih datotek, ki so bile znova razčlenjene za natančno strukturno preverjanje

Kaj indeks shranjuje

Izluščevalnik dejstev AST v vsaki indeksirani datoteki zabeleži vrstico za vsako »zanimivo« vozlišče. Nabor vrst dejstev zajema konstrukte, na katere ciljajo najpogostejši vzorci AST:

  • Klici funkcij in metod (po klicanem imenu)
  • Ustvarjeni primerki razredov (po imenu razreda)
  • Deklaracije razredov, vmesnikov, traitov in naštevanj (po imenu)
  • Deklaracije funkcij (po imenu)
  • Deklaracije metod (po imenu in vidnosti)
  • Stavki use

Ko prispe poizvedba, Greph\Ast\AstFactQuery pretvori vzorec iskanja v grobi podpis dejstev (na primer »vsebovati mora new poljubnega razreda«) in preseka shrambo dejstev. Preostale datoteke se nato znova razčlenijo in primerjajo s celotnim vzorcem.

To pomeni, da je indeks dejstev predfilter, ne pa shramba popolnih ujemanj. Korak ujemanja še vedno razčleni izvorno kodo, zato je strukturna pravilnost enaka kot pri izvornem iskanju AST; manjši je le nabor kandidatov.

Kdaj jo uporabiti

Način indeksiranega AST je prava izbira, kadar:

  • Večkrat izvajate iste strukturne poizvedbe nad isto kodno zbirko.
  • Vzorci ciljajo prepoznavne oblike (ime klica, ime razreda, vrsto deklaracije), ki jih izluščevalnik dejstev shranjuje.
  • Želite krajši odzivni čas kot pri ponovnem razčlenjevanju vsake datoteke.

Pri vzorcih, katerih značilnost ni v naboru dejstev (na primer pri zapletenih gnezdenih izrazih brez prepoznavnega začetnega elementa), je način s predpomnjenim AST običajno primernejši, saj v celoti preskoči razčlenjevanje in se ne opira na grobi podpis.

Uporaba v kodi

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 sprejema enak AstSearchOptions kot izvorno iskanje AST in vrne enako obliko list<AstMatch>. Za poteke dela z več indeksi ali z manifestom uporabite searchAstIndexedMany(...) in searchAstIndexedSet(...).