Индексирано търсене в AST
Индексираното търсене в AST е вариантът с предварително зареден кеш на търсенето в AST. При първото извикване се извличат факти на ниво възел (имена на извиквания, инстанции, декларации на класове и декларации на методи) и се записват на диска; при следващите извиквания хранилището се използва за пропускане на файлове, които очевидно не могат да съдържат структурно съвпадение. След това съпоставителят проверява отново кандидатите спрямо изходния код.
Индексът на факти е достъпен чрез подкомандата greph-index ast-index CLI и методите на фасада Greph::buildAstIndex() / Greph::searchAstIndexed(). Той участва и в работните процеси с предварително заредени индекси в няколко набора, както и в тези, чиито набори се описват с манифест.
Създаване на индекса
# 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
По подразбиране индексът на факти се съхранява в <root>/.greph-ast-index/.
При успешно създаване се извежда едноредово обобщение:
Built AST index for 2547 files in .greph-ast-index (84931 fact rows, +2547 ~0 -0 =0)
Четирите брояча показват добавените, обновените, изтритите и непроменените файлове след последното създаване.
Обновяване на индекса
./vendor/bin/greph-index ast-index refresh .
refresh обхожда отново индексирания корен, анализира отново променените файлове и пренаписва само променените редове с факти. Изходът използва същите четири брояча като текстовия индекс.
Профилите за жизнения цикъл работят по същия начин като при предварително заредените текстови индекси:
static: никога не проверява актуалността и не променя автоматичноmanual-refresh: отчита остаряло състояние вstats, но никога не обновява при търсенеopportunistic-refresh: обновява при търсене само ако наборът от промени е достатъчно малъкstrict-stale-check: отхвърля търсенията с остарели данни, вместо да обновява
Заявки към индекса
./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
Синтаксисът на метапроменливите е идентичен с този при нативното търсене в AST. Вижте Режими / Търсене в AST за пълната граматика.
Опции
| Флаг | Значение |
|---|---|
--lang NAME |
Език на AST. По подразбиране: php |
-j N, --jobs N |
Брой паралелни работници |
-l, --files-with-matches |
Изброява само съвпадащите файлове |
--glob GLOB |
Включва само файлове, чиито пътища съвпадат с GLOB |
--type NAME / --type-not NAME |
Филтър по тип файл |
--json |
Извежда изход във формат JSON |
--no-ignore |
Игнорира .gitignore и .grephignore |
--hidden |
Включва скритите файлове |
--strict-parse |
Прекратява при грешки при анализиране, вместо да ги пропуска |
--fallback MODE |
Поведение при липсващ индекс: fail (по подразбиране) или scan |
--index-dir DIR |
Използва директория за индекс, различна от тази по подразбиране |
--trace-plan |
Извежда диагностиката на планировчика за предварително зареден AST в stderr |
--show-index-origin |
Добавя към изхода етикета на съвпадащия индекс в режим с няколко индекса или набори |
Резервен режим при липсващ индекс
По подразбиране ast-index search извежда грешка, когато на посоченото място няма индекс. Подайте --fallback scan, за да преминете към нативно сканиране на AST. Това е подходящата настройка за инструменти, които използват индексирано търсене, когато има индекс, но трябва да извеждат резултати и преди създаването му.
./vendor/bin/greph-index ast-index search --fallback scan 'new $CLASS()' src
Търсене в няколко индекса
Можете да търсите в няколко предварително заредени индекса на AST с една команда, като повторите --index-dir. Това е полезно за оформления като ядро на WordPress плюс плъгин или тема.
./vendor/bin/greph-index ast-index search \
--index-dir ../wordpress/.greph-ast-index \
--index-dir ./.greph-ast-index \
--show-index-origin \
'new $CLASS()' .
Когато --show-index-origin е активиран, към изхода се добавя името на съвпадналия запис в предварително заредения индекс, за да виждате кой корен е дал резултата.
Набори от индекси с манифест
За стабилни конфигурации с предварително заредени индекси задайте манифест и позволете на greph-index set да работи с групираните индекси:
./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()' .
Подкомандите за набори споделят същата обработка на жизнения цикъл, проверки за остарели данни и диагностика на планировчика като прякото използване на ast-index.
Диагностика на планировчика
--trace-plan показва как Greph е стеснил заявката, преди да стартира пълният съпоставител. За ast-index това обикновено включва:
- грубия подпис на факти, извлечен от шаблона
- броя на претърсените предварително заредени индекси
- броя на файловете, отхвърлени от филтъра за факти
- броя на файловете кандидати, анализирани повторно за точна структурна проверка
Какво съхранява индексът
За всеки индексиран файл извличателят на факти от AST записва по един ред за всеки „интересен“ възел. Видовете факти обхващат конструкциите, към които най-често са насочени шаблоните за AST:
- Извиквания на функции и методи (по име на извиканото)
- Инстанции на класове (по име на класа)
- Декларации на класове, интерфейси, трейтове и enum-и (по име)
- Декларации на функции (по име)
- Декларации на методи (по име и видимост)
- Инструкции use
Когато постъпи заявка, Greph\Ast\AstFactQuery преобразува шаблона за търсене в груб подпис на факти (например „трябва да съдържа new от произволен клас“) и търси пресечението в хранилището с факти. След това оцелелите при тази проверка файлове се анализират отново и се съпоставят с пълния шаблон.
Това означава, че индексът на факти е предварителен филтър, а не хранилище за пълноценни съвпадения. Стъпката на съпоставяне все пак анализира изходния код, така че структурната коректност е същата като при нативното търсене в AST; по-малък е само наборът от кандидати.
Кога да го използвате
Индексираният режим на AST е подходящият инструмент, когато:
- Повтаряте едни и същи структурни заявки върху една и съща кодова база.
- Шаблоните търсят разпознаваеми форми (име на извикване, име на клас, вид декларация), които извличателят на факти съхранява.
- Искате по-ниска латентност от тази при повторно анализиране на всеки файл.
За шаблони, чиято отличителна черта не присъства в набора от факти (например сложни вложени изрази без разпознаваема начална част), кешираният режим на AST обикновено е по-подходящ, защото изцяло пропуска стъпката на анализиране, без да разчита на груб подпис.
Програмно използване
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 приема същия AstSearchOptions като нативното търсене в AST и връща същата структура на list<AstMatch>. За работни процеси с няколко индекса или с набори, описани чрез манифест, използвайте searchAstIndexedMany(...) и searchAstIndexedSet(...).