Ugrás a tartalomhoz

Indexelt AST-keresés

Az indexelt AST-keresés az AST-keresés bemelegített gyorsítótárat használó változata. Az első hívás a csomópontok tényeit (hívásnevek, példányosítások, osztálydeklarációk, metódusdeklarációk) kinyeri, és egy lemezen tárolt tárba menti; a következő hívások ennek segítségével kihagyják azokat a fájlokat, amelyek nyilvánvalóan nem tartalmazhatnak strukturális egyezést. Ezután az egyeztető újra ellenőrzi a jelölteket a forrásban.

A tényindex a greph-index ast-index CLI alparancs, valamint a Greph::buildAstIndex() / Greph::searchAstIndexed() homlokzatmetódusok alatt érhető el. Részt vesz a bemelegített, több indexet használó és jegyzék által kezelt készletekkel végzett munkafolyamatokban is.

Az index létrehozása

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

A tényindex alapértelmezés szerint itt tárolódik: <root>/.greph-ast-index/.

A sikeres létrehozás egyetlen soros összefoglalót ír ki:

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

A négy számláló az utolsó létrehozás óta hozzáadott, frissített, törölt és változatlan fájlok számát mutatja.

Az index frissítése

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

A refresh újra bejárja az indexelt gyökérkönyvtárat, újra feldolgozza a módosult fájlokat, és csak az áthelyezett tényrekordokat írja újra. A kimenet a szöveges indexszel azonos négy számlálót használja.

Az életciklus-profilok ugyanúgy működnek, mint a bemelegített szöveges indexeknél:

  • static: soha nem ellenőrzi automatikusan az aktualitást, és nem módosít automatikusan
  • manual-refresh: jelzi az elavult állapotot a stats kimenetében, de keresés közben soha nem frissít
  • opportunistic-refresh: kereséskor csak akkor frissít, ha a módosult fájlok halmaza még kellően kicsi
  • strict-stale-check: frissítés helyett elutasítja az elavult indexű kereséseket

Lekérdezés az indexben

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

A met változók szintaxisa megegyezik a natív AST-keresésével. A teljes nyelvtanért lásd: Módok / AST-keresés.

Beállítások

Kapcsoló Jelentés
--lang NAME AST-nyelv. Alapértelmezett: php
-j N, --jobs N Párhuzamos feldolgozók száma
-l, --files-with-matches Csak az egyező fájlok listázása
--glob GLOB Csak a GLOB mintára illeszkedő útvonalú fájlok felvétele
--type NAME / --type-not NAME Fájltípus-szűrő
--json JSON kimenet létrehozása
--no-ignore A .gitignore és a .grephignore figyelmen kívül hagyása
--hidden Rejtett fájlok felvétele
--strict-parse Feldolgozási hibák esetén kihagyás helyett hiba jelzése
--fallback MODE Hiányzó index kezelése: fail (alapértelmezett) vagy scan
--index-dir DIR Nem alapértelmezett indexkönyvtár használata
--trace-plan Bemelegített AST-tervezői diagnosztika kiírása a stderr fájlba
--show-index-origin Kimenet előtagolása az egyező index címkéjével több indexet vagy készletet használó módban

Visszaállás hiányzó index esetén

Alapértelmezés szerint a ast-index search hibát jelez, ha a kért helyen nincs index. Adja meg a --fallback scan kapcsolót, ha helyette natív AST-vizsgálatra szeretne visszaállni. Ez a megfelelő beállítás olyan eszközökhöz, amelyek az index meglétekor indexelt keresést használnak, de akkor is eredményt adnak, ha az indexet még nem hozták létre.

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

Több bemelegített AST-indexben is kereshet egyetlen paranccsal a --index-dir ismételt megadásával. Ez hasznos például olyan elrendezéseknél, ahol a WordPress alapkód mellett egy bővítmény vagy sablon is szerepel.

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

Ha a --show-index-origin engedélyezve van, a kimenet az egyező bemelegített index bejegyzésének nevével kezdődik, így látható, melyik gyökérkönyvtárban született a találat.

Jegyzék által kezelt indexkészletek

Stabil, bemelegített összeállításokhoz hozzon létre jegyzéket, és futtassa a greph-index set parancsot a csoportosított indexeken:

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

A készlet alparancsai ugyanazt az életciklus-kezelést, elavultság-ellenőrzést és tervezői diagnosztikát használják, mint a ast-index közvetlen használata.

Tervezői diagnosztika

A --trace-plan megmutatja, hogyan szűkítette le a Greph a lekérdezést a teljes illesztő futtatása előtt. ast-index esetén ez általában a következőket tartalmazza:

  • a mintából kinyert durva tényaláírás
  • a keresésben részt vevő bemelegített indexek száma
  • a tényalapú szűrő által elutasított fájlok száma
  • a pontos strukturális ellenőrzéshez újra feldolgozott jelölt fájlok száma

Mit tárol az index

A AST-ténykinyerő minden indexelt fájlhoz egy-egy sort rögzít az „érdekes” csomópontokról. A ténytípusok lefedik azokat a szerkezeteket, amelyekre az AST-minták a leggyakrabban céloznak:

  • Függvény- és metódushívások (a hívott név alapján)
  • Osztálypéldányosítások (osztálynév alapján)
  • Osztály-, interfész-, trait- és enumdeklarációk (név alapján)
  • Függvénydeklarációk (név alapján)
  • Metódusdeklarációk (név és láthatóság alapján)
  • Use utasítások

Lekérdezéskor a Greph\Ast\AstFactQuery durva tényaláírássá alakítja a keresési mintát (például: „tartalmaznia kell egy tetszőleges osztályú new elemet”), majd összeveti a ténytárral. A szűrésen átjutó fájlokat újra feldolgozza, és összeveti a teljes mintával.

Ez azt jelenti, hogy a tényindex előszűrő, nem pedig teljes pontosságú egyezéstároló. Az egyeztetés továbbra is elemzi a forrást, így a strukturális helyesség megegyezik a natív AST-keresésével; csak a jelöltek halmaza kisebb.

Mikor használja

Az indexelt AST-mód akkor a megfelelő eszköz, ha:

  • Ugyanazokat a strukturális lekérdezéseket futtatja ismételten ugyanazon a kódbázison.
  • A minták olyan felismerhető szerkezeteket céloznak (hívásnév, osztálynév, deklarációtípus), amelyeket a ténykinyerő tárol.
  • Az összes fájl ismételt elemzésénél rövidebb válaszidőt szeretne.

Azokhoz a mintákhoz, amelyek megkülönböztető jegye nem szerepel a tények között (például felismerhető kezdőelem nélküli, összetett beágyazott kifejezésekhez), általában a gyorsítótárazott AST-mód a jobb választás, mert a durva aláírásra támaszkodás nélkül teljesen kihagyja az elemzési lépést.

Programozott használat

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),
);

A searchAstIndexed ugyanazokat a AstSearchOptions fogadja, mint a natív AST-keresés, és ugyanolyan alakú list<AstMatch> értéket ad vissza. Több indexet vagy jegyzék által kezelt munkafolyamatot használva alkalmazza a searchAstIndexedMany(...) és a searchAstIndexedSet(...) parancsot.