Pereiti prie turinio

Indeksuota AST paieška

Indeksuota AST paieška – tai AST paieškos versija su įkeltu podėliu. Pirmo iškvietimo metu mazgų lygmens faktai (iškvietimų pavadinimai, egzempliorių kūrimas, klasių ir metodų deklaracijos) įrašomi į diske saugomą saugyklą; vėliau ši saugykla naudojama praleisti failus, kuriuose akivaizdžiai negali būti struktūrinės atitikties. Tada kandidatai iš naujo tikrinami su šaltinio kodu.

Faktų indeksą galima pasiekti naudojant subkomandą greph-index ast-index CLI ir fasadinius metodus Greph::buildAstIndex() / Greph::searchAstIndexed(). Jis taip pat naudojamas įkeltų indeksų paieškoje keliuose indeksuose ir manifestais pagrįstuose rinkiniuose.

Indekso kūrimas

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

Pagal numatytuosius nustatymus faktų indeksas saugomas <root>/.greph-ast-index/.

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

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

Keturi skaitikliai rodo nuo paskutinio kūrimo pridėtų, atnaujintų, ištrintų ir nepakitusių failų skaičių.

Indekso atnaujinimas

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

refresh iš naujo pereina indeksuojamą šakninį katalogą, iš naujo analizuoja pakeistus failus ir perrašo tik pasikeitusius faktų įrašus. Išvedami tie patys keturi skaitikliai kaip ir teksto indekso atveju.

Gyvavimo ciklo profiliai veikia taip pat kaip ir įkelti teksto indeksai:

  • static: niekada automatiškai netikrina aktualumo ir nekeičia indekso
  • manual-refresh: praneša apie pasenusią būseną stats, tačiau paieškos metu indekso neatnaujina
  • opportunistic-refresh: paieškos metu atnaujina tik tada, kai pakeitimų rinkinys dar pakankamai mažas
  • strict-stale-check: vietoj atnaujinimo atmeta paieškas su pasenusiu indeksu

Užklausos indeksui

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

Metakintamųjų sintaksė tokia pati kaip įprastoje AST paieškoje. Visą gramatiką rasite skiltyje Režimai / AST paieška.

Parinktys

Vėliavėlė Reikšmė
--lang NAME AST kalba. Numatytoji: php
-j N, --jobs N Lygiagrečių procesų skaičius
-l, --files-with-matches Rodyti tik atitinkančius failus
--glob GLOB Įtraukti tik failus, kurių keliai atitinka GLOB
--type NAME / --type-not NAME Failo tipo filtras
--json Išvesti JSON formatą
--no-ignore Nepaisyti .gitignore ir .grephignore
--hidden Įtraukti paslėptus failus
--strict-parse Aptikus analizės klaidų, nutraukti darbą, o ne jas praleisti
--fallback MODE Trūkstamo indekso veiksena: fail (numatytoji) arba scan
--index-dir DIR Naudoti nenumatytąjį indekso katalogą
--trace-plan Į stderr išvesti įkelto AST planavimo diagnostiką
--show-index-origin Naudojant kelis indeksus arba rinkinį, prieš išvestį nurodyti atitinkančio indekso žymą

Atsarginė veiksena, kai indekso nėra

Pagal numatytuosius nustatymus ast-index search pateikia klaidą, jei nurodytoje vietoje indekso nėra. Perduokite --fallback scan, kad vietoj to būtų vykdoma įprasta AST paieška. Ši parinktis tinka įrankiams, kurie, kai įmanoma, naudoja indeksuotą paiešką, bet turi pateikti rezultatus ir tada, kai indeksas dar nesukurtas.

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

Galite ieškoti keliuose įkeltuose AST indeksuose viena komanda, pakartodami --index-dir. Tai naudinga tokiems išdėstymams kaip WordPress branduolys su papildiniu ar tema.

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

Kai įjungta --show-index-origin, prieš išvestį nurodomas atitinkančio įkelto indekso įrašo pavadinimas, kad matytumėte, iš kurio šakninio katalogo gautas rezultatas.

Manifestais pagrįsti indeksų rinkiniai

Jei norite sukurti stabilią įkeltų indeksų konfigūraciją, aprašykite manifestą ir leiskite greph-index set veikti su sugrupuotais indeksais:

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

Rinkinių subkomandose naudojamas tas pats gyvavimo ciklo valdymas, pasenusių indeksų tikrinimas ir planavimo diagnostika kaip ir tiesiogiai naudojant ast-index.

Planavimo diagnostika

--trace-plan parodo, kaip Greph susiaurino užklausą prieš pradedant veikti visam šablonų atitikimo mechanizmui. Naudojant ast-index paprastai rodoma:

  • iš šablono išgautas apytikslis faktų parašas
  • kiek įkeltų indeksų buvo peržiūrėta
  • kiek failų atmetė faktų filtras
  • kiek failų kandidatų iš naujo analizuota, kad būtų tiksliai patvirtinta struktūrinė atitiktis

Kas saugoma indekse

Kiekvienam indeksuojamam failui AST faktų ištraukiklis įrašo po eilutę kiekvienam „įdomiam“ mazgui. Faktų tipai apima konstrukcijas, į kurias dažniausiai taikomi AST šablonai:

  • Funkcijų ir metodų iškvietimai (pagal iškviečiamo elemento pavadinimą)
  • Klasių egzempliorių kūrimas (pagal klasės pavadinimą)
  • Klasių, sąsajų, trait ir enum tipų deklaracijos (pagal pavadinimą)
  • Funkcijų deklaracijos (pagal pavadinimą)
  • Metodų deklaracijos (pagal pavadinimą ir matomumą)
  • Use sakiniai

Gavęs užklausą, Greph\Ast\AstFactQuery paverčia paieškos šabloną apytiksliu faktų parašu (pavyzdžiui, „turi būti bet kurios klasės new“) ir ieško faktų saugykloje. Tada iš naujo analizuojami failai, likę po šio filtro, ir tikrinama, ar jie atitinka visą šabloną.

Tai reiškia, kad faktų indeksas yra išankstinis filtras, o ne visą atitiktį sauganti saugykla. Atitikties tikrinimo žingsnyje šaltinis vis tiek analizuojamas, todėl struktūrinis tikslumas toks pat kaip įprastoje AST paieškoje; skiriasi tik mažesnis kandidatų rinkinys.

Kada naudoti

Indeksuotas AST režimas tinka, kai:

  • pakartotinai vykdote tas pačias struktūrines užklausas tai pačiai kodų bazei;
  • šablonai taikomi atpažįstamoms formoms (iškvietimo pavadinimui, klasės pavadinimui ar deklaracijos tipui), kurias saugo faktų ištraukiklis;
  • norite mažesnio delsos laiko nei iš naujo analizuojant kiekvieną failą.

Šablonams, kurių skiriamasis požymis nepatenka į faktų rinkinį (pavyzdžiui, sudėtingoms įdėtinėms išraiškoms be atpažįstamos pradžios), paprastai labiau tinka AST režimas su podėliu, nes jis visiškai praleidžia analizės etapą ir nesiremia apytiksliu parašu.

Naudojimas programoje

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 priima tą patį AstSearchOptions kaip ir įprasta AST paieška ir grąžina tokios pačios struktūros list<AstMatch>. Jei naudojate kelis indeksus ar manifestais pagrįstus rinkinius, naudokite searchAstIndexedMany(...) ir searchAstIndexedSet(...).