Preskočiť na obsah

Indexované vyhľadávanie v AST

Indexované vyhľadávanie v AST je verzia vyhľadávania AST so zahriatou vyrovnávacou pamäťou. Pri prvom volaní sa extrahujú fakty na úrovni uzlov (názvy volaní, vytváranie inštancií, deklarácie tried a deklarácie metód) a uložia sa na disk. Ďalšie volania využívajú toto úložisko na preskočenie súborov, ktoré zjavne nemôžu obsahovať štrukturálnu zhodu. Následne porovnávač kandidátov opätovne overí podľa zdrojového kódu.

Index faktov je dostupný cez podpríkaz greph-index ast-index CLI a metódy fasády Greph::buildAstIndex() / Greph::searchAstIndexed(). Podporuje aj zahriate postupy s viacerými indexmi a súpravami založenými na manifeste.

Zostavenie indexu

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

Index faktov sa predvolene ukladá do <root>/.greph-ast-index/.

Úspešné zostavenie vypíše súhrn v jednom riadku:

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

Štyri počítadlá sledujú od posledného zostavenia pridané, aktualizované, odstránené a nezmenené súbory.

Obnovenie indexu

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

refresh znova prejde indexovaný koreňový adresár, opätovne spracuje zmenené súbory a prepíše iba riadky faktov, ktoré sa zmenili. Výstup používa rovnaké štyri počítadlá ako textový index.

Profily životného cyklu fungujú rovnako ako pri zahriatych textových indexoch:

  • static: nikdy automaticky nekontrolovať aktuálnosť ani nevykonávať zmeny
  • manual-refresh: hlásiť zastaraný stav v stats, no počas vyhľadávania nikdy neobnovovať
  • opportunistic-refresh: počas vyhľadávania obnoviť iba vtedy, ak je množina zmien stále dostatočne malá
  • strict-stale-check: odmietnuť zastarané vyhľadávanie namiesto obnovenia

Vyhľadávanie v indexe

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

Syntax metavariabilných premenných je rovnaká ako pri natívnom vyhľadávaní v AST. Úplnú gramatiku nájdete v časti Režimy / Vyhľadávanie v AST.

Možnosti

Príznak Význam
--lang NAME Jazyk AST. Predvolené: php
-j N, --jobs N Počet paralelných pracovníkov
-l, --files-with-matches Zobraziť iba zodpovedajúce súbory
--glob GLOB Zahrnúť iba súbory, ktorých cesty zodpovedajú GLOB
--type NAME / --type-not NAME Filter typu súboru
--json Vytvoriť výstup JSON
--no-ignore Ignorovať .gitignore a .grephignore
--hidden Zahrnúť skryté súbory
--strict-parse Pri chybách parsovania skončiť s chybou namiesto ich preskočenia
--fallback MODE Správanie pri chýbajúcom indexe: fail (predvolené) alebo scan
--index-dir DIR Použiť iný než predvolený adresár indexu
--trace-plan Vypísať diagnostiku plánovača zahriateho AST do stderr
--show-index-origin V režime s viacerými indexmi alebo súpravami označiť výstup názvom zodpovedajúceho indexu

Náhradné správanie pri chýbajúcom indexe

Predvolene ast-index search vyvolá chybu, ak na požadovanom mieste neexistuje index. Ak chcete namiesto toho použiť natívne skenovanie AST, zadajte --fallback scan. Toto nastavenie je vhodné pre nástroje, ktoré majú využívať indexované vyhľadávanie, keď je k dispozícii, no majú stále zobrazovať výsledky aj vtedy, keď index ešte nebol zostavený.

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

Vo viacerých zahriatych indexoch AST môžete vyhľadávať v jednom príkaze opakovaným použitím --index-dir. Hodí sa to pri rozloženiach, ako je jadro WordPress spolu s doplnkom alebo témou.

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

Keď je povolené --show-index-origin, pred výstup sa pridá názov položky zodpovedajúcej zahriatej položky indexu, aby ste videli, ktorý koreňový adresár obsahuje zhodu.

Súpravy indexov založené na manifeste

Pri stabilných nastaveniach zahriatych indexov definujte manifest a nechajte greph-index set pracovať so zoskupenými indexmi:

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

Podpríkazy súprav používajú rovnaké spracovanie životného cyklu, kontroly zastaraných dát a diagnostiku plánovača ako pri priamom použití ast-index.

Diagnostika plánovača

--trace-plan ukazuje, ako Greph zúžil dopyt pred spustením úplného porovnávača. V prípade ast-index to zvyčajne zahŕňa:

  • hrubý podpis faktov extrahovaný zo vzoru
  • počet prehľadaných zahriatych indexov
  • počet súborov vyradených filtrom faktov
  • počet kandidátskych súborov opätovne spracovaných na presné štrukturálne overenie

Čo index ukladá

Extraktor faktov AST zaznamenáva pre každý indexovaný súbor riadok pre každý „zaujímavý“ uzol. Súbor druhov faktov pokrýva konštrukcie, na ktoré sa vzory AST zameriavajú najčastejšie:

  • Volania funkcií a metód (podľa názvu volania)
  • Vytváranie inštancií tried (podľa názvu triedy)
  • Deklarácie tried, rozhraní, traitov a enumov (podľa názvu)
  • Deklarácie funkcií (podľa názvu)
  • Deklarácie metód (podľa názvu a viditeľnosti)
  • Príkazy use

Po prijatí dopytu Greph\Ast\AstFactQuery prevedie vzor vyhľadávania na hrubý podpis faktov (napríklad „musí obsahovať new ľubovoľnej triedy“) a vyhľadá jeho prienik v úložisku faktov. Súbory, ktoré zostanú, sa potom znova spracujú a porovnajú s úplným vzorom.

To znamená, že index faktov je predbežný filter, nie úplné úložisko zhôd. Pri porovnávaní sa zdrojový kód stále parsuje, takže štrukturálna presnosť je rovnaká ako pri natívnom vyhľadávaní v AST; menšia je iba množina kandidátov.

Kedy ho použiť

Indexovaný režim AST je vhodný, keď:

  • opakovane spúšťate rovnaké štrukturálne dopyty nad rovnakou kódovou základňou.
  • vzory sa zameriavajú na rozpoznateľné tvary (názov volania, názov triedy, druh deklarácie), ktoré extraktor faktov ukladá.
  • chcete nižšiu latenciu než pri opätovnom parsovaní každého súboru.

Pri vzoroch, ktorých rozlišovacia vlastnosť nie je v množine faktov (napríklad pri zložitých vnorených výrazoch bez rozpoznateľného začiatku), sa zvyčajne viac hodí režim AST s vyrovnávacou pamäťou, pretože úplne preskočí parsovanie a nespolieha sa na hrubý podpis.

Programové použitie

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 prijíma rovnaký AstSearchOptions ako natívne vyhľadávanie v AST a vracia výsledok v rovnakom tvare list<AstMatch>. Pri práci s viacerými indexmi alebo manifestom používajte searchAstIndexedMany(...) a searchAstIndexedSet(...).