
# Căutare AST indexată

Căutarea AST indexată este versiunea cu cache încălzit a [căutării AST](https://greph.inline0.dev/ro/docs/modes/ast). La primul apel, extrage fapte la nivel de nod (nume de apeluri, instanțieri, declarații de clase și declarații de metode) într-o stocare pe disc; apelurile ulterioare folosesc stocarea pentru a omite fișierele care, în mod evident, nu pot conține o potrivire structurală. Apoi, potrivitorul verifică din nou candidații în raport cu sursa.

Indexul de fapte este disponibil prin subcomanda `greph-index ast-index` CLI și metodele fațadei `Greph::buildAstIndex()` / `Greph::searchAstIndexed()`. Participă și la fluxurile de lucru încălzite cu mai multe indexuri și seturi susținute de manifest.

## Construirea indexului

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

În mod implicit, indexul de fapte este stocat în `<root>/.greph-ast-index/`.

O construire reușită afișează un rezumat pe o singură linie:

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

Cei patru contori urmăresc fișierele adăugate, actualizate, șterse și neschimbate de la ultima construire.

## Reîmprospătarea indexului

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

`refresh` parcurge din nou rădăcina indexată, analizează din nou fișierele modificate și rescrie doar rândurile de fapte care s-au schimbat. Ieșirea folosește aceiași patru contori ca indexul de text.

Profilurile ciclului de viață se comportă la fel ca în cazul indexurilor de text încălzite:

- `static`: nu verifică niciodată actualitatea și nu modifică automat
- `manual-refresh`: raportează starea învechită în `stats`, dar nu reîmprospătează niciodată în timpul căutării
- `opportunistic-refresh`: reîmprospătează la căutare doar când setul modificat este suficient de mic
- `strict-stale-check`: respinge căutările învechite în loc să reîmprospăteze

## Interogarea indexului

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

Sintaxa metavariabilelor este identică cu cea a căutării AST native. Consultați [Moduri / Căutare AST](https://greph.inline0.dev/ro/docs/modes/ast) pentru gramatica completă.

### Opțiuni

| Opțiune | Semnificație |
|---|---|
| `--lang NAME` | Limbaj AST. Implicit: `php` |
| `-j N`, `--jobs N` | Numărul de procese de lucru paralele |
| `-l`, `--files-with-matches` | Afișează doar fișierele potrivite |
| `--glob GLOB` | Include doar fișierele ale căror căi se potrivesc cu GLOB |
| `--type NAME` / `--type-not NAME` | Filtru după tipul fișierului |
| `--json` | Generează ieșire JSON |
| `--no-ignore` | Ignoră `.gitignore` și `.grephignore` |
| `--hidden` | Include fișierele ascunse |
| `--strict-parse` | Eșuează la erori de analizare în loc să le omită |
| `--fallback MODE` | Comportament pentru index lipsă: `fail` (implicit) sau `scan` |
| `--index-dir DIR` | Folosește un director de index care nu este implicit |
| `--trace-plan` | Afișează diagnosticele planificatorului AST încălzit în `stderr` |
| `--show-index-origin` | Prefixează ieșirea cu eticheta indexului potrivit în modul cu mai multe indexuri sau seturi |

### Rezervă când lipsește indexul

În mod implicit, `ast-index search` afișează o eroare dacă nu există niciun index în locația solicitată. Transmiteți `--fallback scan` pentru a reveni la o scanare AST nativă. Aceasta este setarea potrivită pentru instrumentele care doresc să folosească o căutare indexată când este disponibilă, dar să afișeze rezultate și când indexul nu a fost încă construit.

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

### Căutare în mai multe indexuri

Puteți căuta într-o singură comandă în mai multe indexuri AST încălzite, repetând `--index-dir`. Acest lucru este util pentru structuri precum WordPress de bază împreună cu un plugin sau o temă.

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

Când `--show-index-origin` este activată, ieșirea este prefixată cu numele intrării din indexul încălzit potrivit, astfel încât să puteți vedea ce rădăcină a produs rezultatul.

### Seturi de indexuri susținute de manifest

Pentru configurații încălzite stabile, definiți un manifest și permiteți-i lui `greph-index set` să opereze asupra indexurilor grupate:

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

Subcomenzile setului folosesc aceeași gestionare a ciclului de viață, aceleași verificări ale elementelor învechite și aceleași diagnostice ale planificatorului ca utilizarea directă a `ast-index`.

### Diagnosticarea planificatorului

`--trace-plan` arată cum a restrâns Greph interogarea înainte de rularea potrivitorului complet. Pentru `ast-index`, aceasta include de obicei:

- semnătura aproximativă a faptelor extrase din tipar
- numărul indexurilor încălzite căutate
- numărul fișierelor respinse de filtrul de fapte
- numărul fișierelor candidate analizate din nou pentru verificarea structurală exactă

## Ce stochează indexul

Pentru fiecare fișier indexat, extractorul de fapte AST înregistrează câte un rând pentru fiecare nod „interesant”. Setul de tipuri de fapte acoperă construcțiile vizate cel mai frecvent de tiparele AST:

- Apeluri de funcții și metode (după numele apelat)
- Instanțieri de clase (după numele clasei)
- Declarații de clase, interfețe, trăsături și enumuri (după nume)
- Declarații de funcții (după nume)
- Declarații de metode (după nume și vizibilitate)
- Instrucțiuni use

Când sosește o interogare, `Greph\Ast\AstFactQuery` transformă tiparul de căutare într-o semnătură aproximativă de fapte (de exemplu, „trebuie să conțină un `new` din orice clasă”) și intersectează stocarea de fapte. Fișierele care rămân după intersecție sunt apoi analizate din nou și potrivite cu tiparul complet.

Așadar, indexul de fapte este un *filtru preliminar*, nu o stocare a potrivirilor cu fidelitate completă. Etapa de potrivire analizează în continuare sursa, astfel încât corectitudinea structurală este identică cu cea a căutării AST native; doar setul de candidați este mai mic.

## Când să îl folosiți

Modul AST indexat este potrivit când:

- Rulați în mod repetat aceleași interogări structurale asupra aceleiași baze de cod.
- Tiparele vizează forme identificabile (numele apelului, numele clasei, tipul declarației) stocate de extractorul de fapte.
- Doriți o latență mai mică decât la analizarea din nou a fiecărui fișier.

Pentru tiparele a căror caracteristică distinctivă nu se găsește în setul de fapte (de exemplu, expresii imbricate complexe fără un element de început recognoscibil), [modul AST memorat în cache](https://greph.inline0.dev/ro/docs/indexed/cache) este de obicei mai potrivit, deoarece omite complet etapa de analizare fără să se bazeze pe o semnătură aproximativă.

## Utilizare programatică

```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` acceptă același `AstSearchOptions` ca și căutarea AST nativă și returnează aceeași structură `list<AstMatch>`. Pentru fluxuri cu mai multe indexuri sau susținute de manifest, folosiți `searchAstIndexedMany(...)` și `searchAstIndexedSet(...)`.
