
# Indexelt AST-keresés

Az indexelt AST-keresés az [AST-keresés](https://greph.inline0.dev/hu/docs/modes/ast) 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

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

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

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

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

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](https://greph.inline0.dev/hu/docs/modes/ast).

### 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.

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

### Keresés több indexben

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.

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

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

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](https://greph.inline0.dev/hu/docs/indexed/cache) 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.
