
# Indeksirano iskanje AST

Indeksirano iskanje AST je različica [iskanja AST](https://greph.inline0.dev/sl/docs/modes/ast) z ogretim predpomnilnikom. Pri prvem klicu izlušči dejstva na ravni vozlišč (imena klicev, primerke, deklaracije razredov in deklaracije metod) v shrambo na disku; pri naslednjih klicih ta shramba omogoči preskočiti datoteke, ki očitno ne morejo vsebovati strukturnega ujemanja. Ujemalnik nato kandidate znova preveri glede na izvorno kodo.

Indeks dejstev je na voljo prek podukaza `greph-index ast-index` CLI ter fasadnih metod `Greph::buildAstIndex()` / `Greph::searchAstIndexed()`. Podpira tudi poteke dela z ogretimi indeksi in manifestno podprtimi nabori.

## Izdelava indeksa

```bash
# 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
```

Indeks dejstev je privzeto shranjen v `<root>/.greph-ast-index/`.

Uspešna izdelava izpiše enovrstični povzetek:

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

Štirje števci prikazujejo dodane, posodobljene, izbrisane in nespremenjene datoteke od zadnje izdelave.

## Osveževanje indeksa

```bash
./vendor/bin/greph-index ast-index refresh .
```

`refresh` znova pregleda indeksirano korensko mapo, znova razčleni spremenjene datoteke in prepiše samo spremenjene vrstice dejstev. Izhod uporablja enake štiri števce kot besedilni indeks.

Profili življenjskega cikla delujejo enako kot pri ogretih besedilnih indeksih:

- `static`: nikoli samodejno ne preverja svežine ali spreminja
- `manual-refresh`: poroča o zastarelem stanju v `stats`, med iskanjem pa nikoli ne osvežuje
- `opportunistic-refresh`: med iskanjem osveži le, če je nabor sprememb še dovolj majhen
- `strict-stale-check`: zavrne zastarela iskanja, namesto da bi jih osvežil

## Poizvedovanje po indeksu

```bash
./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
```

Sintaksa metaspremenljivk je enaka kot pri izvornem iskanju AST. Celotno slovnico najdete v [Načini / iskanje AST](https://greph.inline0.dev/sl/docs/modes/ast).

### Možnosti

| Zastavica | Pomen |
|---|---|
| `--lang NAME` | Jezik AST. Privzeto: `php` |
| `-j N`, `--jobs N` | Število vzporednih delavcev |
| `-l`, `--files-with-matches` | Izpiše samo ujemajoče se datoteke |
| `--glob GLOB` | Vključi samo datoteke, katerih poti ustrezajo vzorcu GLOB |
| `--type NAME` / `--type-not NAME` | Filter vrste datoteke |
| `--json` | Ustvari izhod JSON |
| `--no-ignore` | Prezre `.gitignore` in `.grephignore` |
| `--hidden` | Vključi skrite datoteke |
| `--strict-parse` | Ob napakah pri razčlenjevanju konča z napako, namesto da bi jih preskočil |
| `--fallback MODE` | Ravnanje ob manjkajočem indeksu: `fail` (privzeto) ali `scan` |
| `--index-dir DIR` | Uporabi neprivzeti imenik indeksa |
| `--trace-plan` | Pošlje diagnostiko ogretega načrtovalnika AST v `stderr` |
| `--show-index-origin` | V večindeksnem načinu ali načinu nabora doda predpono z oznako ustreznega indeksa |

### Nadomestno delovanje ob manjkajočem indeksu

Privzeto `ast-index search` sproži napako, če na zahtevani lokaciji ni indeksa. Podajte `--fallback scan`, da namesto tega preklopite na izvorno pregledovanje AST. Ta nastavitev je primerna za orodja, ki želijo uporabiti indeksirano iskanje, kadar je na voljo, a morajo še vedno vrniti rezultate, če indeks še ni zgrajen.

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

### Iskanje po več indeksih

Z večkratno uporabo `--index-dir` lahko v enem ukazu iščete po več ogretih indeksih AST. To je uporabno pri razporeditvah, kot sta jedro WordPress in vtičnik ali tema.

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

Ko je omogočeno `--show-index-origin`, je pred izhod dodano ime vnosa ustreznega ogretega indeksa, da lahko vidite, iz katere korenske mape izvira zadetek.

### Nabori indeksov, podprti z manifestom

Za stabilne ogrete nastavitve določite manifest in omogočite, da `greph-index set` deluje z združenimi indeksi:

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

Podukazi za nabore uporabljajo enako upravljanje življenjskega cikla, preverjanje zastarelosti in diagnostiko načrtovalnika kot neposredna uporaba `ast-index`.

### Diagnostika načrtovalnika

`--trace-plan` pokaže, kako je Greph zožil poizvedbo, preden se je zagnal polni ujemalnik. Za `ast-index` to običajno vključuje:

- grobi podpis dejstev, izluščen iz vzorca
- število pregledanih ogretih indeksov
- število datotek, ki jih je filter dejstev zavrnil
- število kandidatnih datotek, ki so bile znova razčlenjene za natančno strukturno preverjanje

## Kaj indeks shranjuje

Izluščevalnik dejstev AST v vsaki indeksirani datoteki zabeleži vrstico za vsako »zanimivo« vozlišče. Nabor vrst dejstev zajema konstrukte, na katere ciljajo najpogostejši vzorci AST:

- Klici funkcij in metod (po klicanem imenu)
- Ustvarjeni primerki razredov (po imenu razreda)
- Deklaracije razredov, vmesnikov, traitov in naštevanj (po imenu)
- Deklaracije funkcij (po imenu)
- Deklaracije metod (po imenu in vidnosti)
- Stavki use

Ko prispe poizvedba, `Greph\Ast\AstFactQuery` pretvori vzorec iskanja v grobi podpis dejstev (na primer »vsebovati mora `new` poljubnega razreda«) in preseka shrambo dejstev. Preostale datoteke se nato znova razčlenijo in primerjajo s celotnim vzorcem.

To pomeni, da je indeks dejstev *predfilter*, ne pa shramba popolnih ujemanj. Korak ujemanja še vedno razčleni izvorno kodo, zato je strukturna pravilnost enaka kot pri izvornem iskanju AST; manjši je le nabor kandidatov.

## Kdaj jo uporabiti

Način indeksiranega AST je prava izbira, kadar:

- Večkrat izvajate iste strukturne poizvedbe nad isto kodno zbirko.
- Vzorci ciljajo prepoznavne oblike (ime klica, ime razreda, vrsto deklaracije), ki jih izluščevalnik dejstev shranjuje.
- Želite krajši odzivni čas kot pri ponovnem razčlenjevanju vsake datoteke.

Pri vzorcih, katerih značilnost ni v naboru dejstev (na primer pri zapletenih gnezdenih izrazih brez prepoznavnega začetnega elementa), je [način s predpomnjenim AST](https://greph.inline0.dev/sl/docs/indexed/cache) običajno primernejši, saj v celoti preskoči razčlenjevanje in se ne opira na grobi podpis.

## Uporaba v kodi

```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` sprejema enak `AstSearchOptions` kot izvorno iskanje AST in vrne enako obliko `list<AstMatch>`. Za poteke dela z več indeksi ali z manifestom uporabite `searchAstIndexedMany(...)` in `searchAstIndexedSet(...)`.
