
# Indexerad AST-sökning

Indexerad AST-sökning är den cacheuppvärmda versionen av [AST-sökning](https://greph.inline0.dev/sv/docs/modes/ast). Det första anropet extraherar fakta på nodnivå (anropsnamn, instansieringar, klassdeklarationer och metoddeklarationer) till ett lager på disk. Efterföljande anrop använder lagret för att hoppa över filer som uppenbart inte kan innehålla någon strukturell träff. Matcharen verifierar sedan kandidaterna på nytt mot källkoden.

Faktindexet exponeras via underkommandot `greph-index ast-index` CLI och fasadmetoderna `Greph::buildAstIndex()` / `Greph::searchAstIndexed()`. Det ingår även i arbetsflöden med flera uppvärmda index och manifestbaserade uppsättningar.

## Bygga indexet

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

Som standard lagras faktindexet i `<root>/.greph-ast-index/`.

Ett lyckat bygge skriver ut en sammanfattning på en rad:

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

De fyra räknarna visar antalet tillagda, uppdaterade, borttagna och oförändrade filer sedan föregående bygge.

## Uppdatera indexet

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

`refresh` går igenom den indexerade roten på nytt, tolkar ändrade filer igen och skriver endast om de faktarader som har ändrats. Utdata använder samma fyra räknare som textindexet.

Livscykelprofilerna fungerar likadant som för uppvärmda textindex:

- `static`: kontrollera aldrig aktualiteten eller ändra automatiskt
- `manual-refresh`: rapportera inaktuellt tillstånd i `stats`, men uppdatera aldrig under sökning
- `opportunistic-refresh`: uppdatera vid sökning endast om den ändrade mängden fortfarande är tillräckligt liten
- `strict-stale-check`: avvisa inaktuella sökningar i stället för att uppdatera

## Söka i indexet

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

Syntaxen för metavariabler är identisk med den inbyggda AST-sökningen. Se [Lägen / AST-sökning](https://greph.inline0.dev/sv/docs/modes/ast) för hela grammatiken.

### Alternativ

| Flagga | Betydelse |
|---|---|
| `--lang NAME` | AST-språk. Standard: `php` |
| `-j N`, `--jobs N` | Antal parallella arbetsprocesser |
| `-l`, `--files-with-matches` | Visa endast matchande filer |
| `--glob GLOB` | Inkludera endast filer vars sökvägar matchar GLOB |
| `--type NAME` / `--type-not NAME` | Filter för filtyp |
| `--json` | Skriv utdata i formatet JSON |
| `--no-ignore` | Ignorera `.gitignore` och `.grephignore` |
| `--hidden` | Inkludera dolda filer |
| `--strict-parse` | Misslyckas vid tolkningsfel i stället för att hoppa över dem |
| `--fallback MODE` | Beteende när index saknas: `fail` (standard) eller `scan` |
| `--index-dir DIR` | Använd en annan indexkatalog än standardkatalogen |
| `--trace-plan` | Skriv ut diagnostik från den uppvärmda AST-planeraren till `stderr` |
| `--show-index-origin` | Lägg till etiketten för matchande index före utdata i lägen med flera index eller uppsättningar |

### Återgång när index saknas

Som standard ger `ast-index search` ett fel om det saknas ett index på den begärda platsen. Ange `--fallback scan` för att i stället använda en inbyggd AST-genomsökning. Det passar verktyg som vill använda indexerad sökning när den är tillgänglig, men som ändå ska ge resultat innan indexet har byggts.

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

### Sökning i flera index

Du kan söka i flera uppvärmda AST-index med ett enda kommando genom att upprepa `--index-dir`. Detta är användbart för upplägg som WordPress-kärnan plus ett tillägg eller ett 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()' .
```

När `--show-index-origin` är aktiverat får utdata prefix med namnet på den matchande posten i det uppvärmda indexet, så att du ser vilken rot som gav träffen.

### Manifestbaserade indexuppsättningar

För stabila uppvärmda konfigurationer kan du definiera ett manifest och låta `greph-index set` arbeta med de grupperade indexen:

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

Underkommandona för uppsättningar använder samma livscykelhantering, inaktualitetskontroller och planeringsdiagnostik som direkt användning av `ast-index`.

### Planeringsdiagnostik

`--trace-plan` visar hur Greph begränsade frågan innan den fullständiga matcharen kördes. För `ast-index` innefattar det vanligtvis:

- den grova faktasignaturen som extraherats från mönstret
- antalet uppvärmda index som genomsöktes
- antalet filer som sorterades bort av faktorfiltret
- antalet kandidater som tolkades på nytt för exakt strukturell verifiering

## Vad indexet lagrar

För varje indexerad fil registrerar AST-faktaextraktorn en rad för varje ”intressant” nod. Faktatyperna omfattar de konstruktioner som AST-mönster oftast riktar in sig på:

- Funktions- och metodanrop (efter anropsnamn)
- Klassinstansieringar (efter klassnamn)
- Klass-, gränssnitts-, trait- och enumdeklarationer (efter namn)
- Funktionsdeklarationer (efter namn)
- Metoddeklarationer (efter namn och synlighet)
- Use-satser

När en fråga kommer översätter `Greph\Ast\AstFactQuery` sökmönstret till en grov faktasignatur (till exempel ”måste innehålla en `new` av valfri klass”) och söker i faktalagret. Filerna som återstår tolkas sedan på nytt och matchas mot hela mönstret.

Det betyder att faktindexet är ett *förfilter*, inte ett matchningslager med fullständig återgivning. Matchningssteget tolkar fortfarande källkoden, så den strukturella korrektheten är densamma som vid inbyggd AST-sökning; endast mängden kandidater är mindre.

## När du ska använda det

Indexerad AST-sökning passar bäst när:

- Du upprepar samma strukturella frågor mot samma kodbas.
- Mönstren riktar in sig på identifierbara former (anropsnamn, klassnamn, deklarationstyp) som faktaxtraktorn lagrar.
- Du vill minska svarstiden jämfört med att tolka varje fil på nytt.

För mönster vars särskiljande egenskap inte finns i faktamängden (till exempel komplexa nästlade uttryck utan ett igenkännbart huvud) passar det [cachade AST-läget](https://greph.inline0.dev/sv/docs/indexed/cache) oftast bättre, eftersom det hoppar över tolkningssteget helt utan att förlita sig på en grov signatur.

## Programmatisk användning

```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` accepterar samma `AstSearchOptions` som inbyggd AST-sökning och returnerar samma form på `list<AstMatch>`. För flöden med flera index eller manifest använder du `searchAstIndexedMany(...)` och `searchAstIndexedSet(...)`.
