Pereiti prie turinio

AST paieška podėlyje

AST paieška podėlyje papildo faktų indeksą kaip šiltosios talpyklos režimas. Užuot saugojus išgautus faktus ir iš naujo analizavus atitinkančius failus, podėlyje diske saugomi serializuoti išanalizuoti sintaksės medžiai. Vėlesnių užklausų metu medžiai deserializuojami ir šablonų atitikimo mechanizmas paleidžiamas tiesiogiai, visiškai praleidžiant PHP-Parser konvejerį.

Podėlį galima pasiekti naudojant subkomandą greph-index ast-cache CLI ir fasadinius metodus Greph::buildAstCache() / Greph::searchAstCached(). Jis taip pat leidžia ieškoti keliuose indeksuose ir manifestais pagrįstuose rinkiniuose.

Podėlio kūrimas

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

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

# Build a cache that may refresh automatically for small changes
./vendor/bin/greph-index ast-cache build . \
  --lifecycle opportunistic-refresh \
  --auto-refresh-max-files 32 \
  --auto-refresh-max-bytes 1048576

Pagal numatytuosius nustatymus podėlis saugomas <root>/.greph-ast-cache/. Podėlio kūrimas paprastai užtrunka ilgiausiai iš trijų indeksavimo režimų, nes kiekvieną failą reikia išanalizuoti vieną kartą.

Sėkmingai sukūrus indeksą, išvedama vienos eilutės suvestinė:

Text
Built AST cache for 2547 files in .greph-ast-cache (2541 cached trees, +2541 ~0 -0 =0)

Podėlyje saugomų medžių paprastai būna šiek tiek mažiau nei failų, nes nepavykus išanalizuoti failų (klaidos praleidžiamos tyliai), podėlio įrašai nesukuriami. Jei norite matyti analizės klaidas, paieškos komandai perduokite --strict-parse.

Podėlio atnaujinimas

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

refresh iš naujo pereina indeksuojamą šakninį katalogą, iš naujo analizuoja pakeistus failus ir perrašo tik pasikeitusius podėlyje saugomus medžius.

Gyvavimo ciklo profiliai tokie patys kaip ir kituose įkeltuose režimuose:

  • static: niekada automatiškai netikrina aktualumo ir nekeičia podėlio
  • manual-refresh: praneša apie pasenusią būseną stats, tačiau paieškos metu podėlio neatnaujina
  • opportunistic-refresh: paieškos metu atnaujina tik tada, kai pakeitimų rinkinys neviršija sukonfigūruotų ribų
  • strict-stale-check: vietoj atnaujinimo atmeta paieškas su pasenusiu podėliu

Užklausos podėliui

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

Vėliavėlių rinkinys toks pats kaip ast-index search, įskaitant --fallback scan, skirtą trūkstamam podėliui.

Pakartokite --index-dir, jei viena komanda norite ieškoti keliuose įkeltuose podėliuose:

Shell
./vendor/bin/greph-index ast-cache search \
  --index-dir ../wordpress/.greph-ast-cache \
  --index-dir ./.greph-ast-cache \
  --show-index-origin \
  'array($$$ITEMS)' .

Manifestais pagrįsti podėlių rinkiniai

Jei jau turite pavadintus įkeltų indeksų rinkinius, AST paieškai podėlyje galite naudoti tą patį manifestą:

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

Planavimo diagnostika

--trace-plan pateikia į AST podėlį nukreipto planavimo sprendimus stderr, įskaitant:

  • kuriuose įkeltuose podėliuose atlikta paieška
  • ar buvo vykdomas pasenusio podėlio atnaujinimas
  • kiek kandidatų failų liko po susiaurinimo failų lygmeniu
  • kiek podėlyje saugomų medžių deserializuota tikslios struktūrinės atitikties paieškai

Podėlio ir faktų indekso palyginimas

Abu režimai paspartina AST paiešką, tačiau yra optimizuoti skirtingoms užduotims.

Aspektas Faktų indeksas (ast-index) Talpykla (ast-cache)
Kas saugoma Išgauti faktai (iškvietimų pavadinimai, klasių pavadinimai, deklaracijos) Serializuoti išanalizuoti medžiai
Kūrimo sąnaudos Mažesnės Didesnės (analizuojama viskas)
Kūrimo dydis Mažesnis Didesnis
Užklausos eiga Filtruojama pagal faktus, tada analizuojami ir tikrinami kandidatai Deserializuojamas medis, tada atliekama atitikties paieška
Geriausiai tinka Šablonams su atpažįstama pradžia (iškvietimo ar klasės pavadinimu) Šablonams, kurių skiriamasis požymis yra struktūrinis, o ne vardinis
Blogiausiai tinka Šablonams, kurių pradžia yra metavariantas Šaltoms užklausoms medyje, kuris nebetelpa į OS puslapių talpyklą

Praktikoje faktų indeksas užtikrina greičiausias šaltas užklausas, o talpykla – greičiausias šiltas užklausas. Naudokite tai, kas labiausiai tinka jūsų darbo krūviui, arba sukurkite abu ir leiskite įrankiams pasirinkti.

Naudojimas programoje

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

Greph::buildAstCache('.', lifecycle: IndexLifecycleProfile::Static);

$matches = Greph::searchAstCached(
    'array($$$ITEMS)',
    'src',
    new AstSearchOptions(jobs: 4, tracePlan: true),
);

searchAstCached priima tuos pačius AstSearchOptions kaip ir AST paieška ir grąžina tokios pačios formos list<AstMatch>. Skiriasi tik tai, kad analizatoriaus eiga praleidžiama failams, kurie jau yra talpykloje. Kelių indeksų ar manifestu pagrįstoms eigoms naudokite searchAstCachedMany(...) ir searchAstCachedSet(...).

Kada naudoti

Talpykloje saugomas AST režimas tinkamas, kai:

  • Vykdote pasikartojančias struktūrines užklausas tai pačiai kodų bazei.
  • Ankstesnių vykdymų siauroji vieta buvo PHP-Parser (profiliuose matomas laikas, praleistas leksinėje analizėje ir analizatoriuje).
  • Galite skirti disko vietos serializuotų medžių saugyklai.

Jei užklausos paprastai aprėpia nedidelę kodų bazės dalį, o atitikmenys telkiasi ties atpažįstamais iškvietimų ar klasių pavadinimais, faktų indeksas paprastai tinka geriau. Jei užklausos plačiai aprėpia kodų bazę, bet galite skirti laiko vienkartinei analizei, laimi talpykla.