
# PHP API

## `Greph\Greph`

De klasse `Greph\Greph` is het statische toegangspunt. Deze biedt elke zoek-, herschrijf- en indexbewerking. Alle methoden accepteren één pad of een lijst met paden.

```php
use Greph\Greph;
```

### `walk`

```php
public static function walk(string|array $paths, ?WalkOptions $options = null): FileList
```

Los `$paths` op naar een platte `FileList` met absolute bestandspaden. Houdt rekening met gitignore, `.grephignore`, bestandstypefilters, globpatronen, het opnemen van verborgen bestanden, het volgen van symlinks, binaire detectie en de maximale bestandsgroottelimiet.

```php
use Greph\Walker\WalkOptions;
use Greph\Walker\FileTypeFilter;

$files = Greph::walk('src', new WalkOptions(
    fileTypeFilter: new FileTypeFilter(['php']),
));

foreach ($files->paths() as $path) {
    echo "$path\n";
}
```

---

### `searchText`

```php
public static function searchText(
    string $pattern,
    string|array $paths,
    ?TextSearchOptions $options = null,
): array
```

Voer een tekstzoekopdracht uit en geef een `list<TextFileResult>` terug. Elk `TextFileResult` bevat het bestandspad en een lijst met `TextMatch`-objecten (regel, kolom, inhoud, captures, optionele context).

```php
use Greph\Greph;
use Greph\Text\TextSearchOptions;

$results = Greph::searchText(
    'function',
    'src',
    new TextSearchOptions(
        fixedString: true,
        caseInsensitive: true,
        beforeContext: 1,
        afterContext: 1,
        jobs: 4,
    ),
);

foreach ($results as $file) {
    foreach ($file->matches as $match) {
        echo "{$file->file}:{$match->line}:{$match->content}\n";
    }
}
```

Wanneer `jobs > 1` is ingeschakeld en het aantal bestanden de workergrens overschrijdt, stuurt `searchText` de scan automatisch naar een `WorkerPool`. Anders wordt deze binnen hetzelfde proces uitgevoerd.

---

### `searchAst`

```php
public static function searchAst(
    string $pattern,
    string|array $paths,
    ?AstSearchOptions $options = null,
): array
```

Voer een structurele AST-zoekopdracht uit en geef een `list<AstMatch>` terug. Patronen worden geschreven als broncode in PHP, met metavariabelen `$VAR` en `$$$VARIADIC`. Elke `AstMatch` bevat het bestand, de vastgelegde `PhpParser\Node`, de captures, de begin- en eindregel en byte-offsets, en het overeenkomende bronfragment.

```php
use Greph\Greph;
use Greph\Ast\AstSearchOptions;

$matches = Greph::searchAst(
    'new $CLASS()',
    'src',
    new AstSearchOptions(),
);

foreach ($matches as $match) {
    echo "{$match->file}:{$match->startLine}:{$match->code}\n";
}
```

---

### `rewriteAst`

```php
public static function rewriteAst(
    string $searchPattern,
    string $rewritePattern,
    string|array $paths,
    ?AstSearchOptions $options = null,
): array
```

Voer een structurele herschrijving uit en geef een `list<RewriteResult>` terug. Elk `RewriteResult` bevat het bestandspad, de oorspronkelijke inhoud, de herschreven inhoud en het aantal vervangingen. Bij herschrijvingen blijft de opmaak behouden: alleen de bereiken van overeenkomende knooppunten worden vervangen; de rest van het bestand blijft onaangeroerd.

```php
$rewrites = Greph::rewriteAst(
    'array($$$ITEMS)',
    '[$$$ITEMS]',
    'src',
);

foreach ($rewrites as $result) {
    if ($result->changed()) {
        file_put_contents($result->file, $result->rewrittenContents);
    }
}
```

De facade schrijft niet naar schijf; de aanroeper bepaalt of de wijzigingen worden toegepast. CLI voert ze uit, tenzij `--dry-run` of `--interactive` is ingesteld.

---

### Geïndexeerd tekstzoeken

#### `buildTextIndex`

```php
public static function buildTextIndex(
    string $rootPath = '.',
    ?string $indexPath = null,
    IndexLifecycle|IndexLifecycleProfile|string|null $lifecycle = null,
): IndexBuildResult
```

Bouw een nieuwe trigram- en identifier-postingsindex voor `$rootPath`. De index wordt opgeslagen in `$indexPath` (standaard `$rootPath/.greph-index`). `$lifecycle` kan `static`, `manual-refresh`, `opportunistic-refresh` of `strict-stale-check` zijn. Geeft een `IndexBuildResult` terug met het aantal bestanden, het aantal trigrams en de aantallen toegevoegde, bijgewerkte, verwijderde en ongewijzigde bestanden.

#### `refreshTextIndex`

```php
public static function refreshTextIndex(
    string $rootPath = '.',
    ?string $indexPath = null,
    IndexLifecycle|IndexLifecycleProfile|string|null $lifecycle = null,
): IndexBuildResult
```

Vernieuw een bestaande tekstindex incrementeel. Bestanden worden opnieuw gehasht en alleen gewijzigde vermeldingen worden herschreven.

#### `searchTextIndexed`

```php
public static function searchTextIndexed(
    string $pattern,
    string|array $paths,
    ?TextSearchOptions $options = null,
    ?string $indexPath = null,
): array
```

Voer een tekstzoekopdracht uit op de opgewarmde index. Geeft een runtimefout als de index niet bestaat (roep eerst `buildTextIndex` aan). Geeft een `list<TextFileResult>` terug met precies dezelfde structuur als `searchText`.

```php
Greph::buildTextIndex('.');
$results = Greph::searchTextIndexed('function', 'src');
```

#### `searchTextIndexedMany`

```php
public static function searchTextIndexedMany(
    string $pattern,
    string|array $paths,
    array $indexPaths,
    ?TextSearchOptions $options = null,
): array
```

Voer een tekstzoekopdracht uit op opgewarmde tekstindexen in meerdere directories. Greph doorzoekt elke toepasselijke index, verwijdert duplicaten op basis van het absolute bestandspad en voert alleen een native scan uit voor paden buiten alle opgegeven indexroots.

#### `loadIndexSet`

```php
public static function loadIndexSet(?string $manifestPath = null): IndexSet
```

Laad een manifest voor een indexset, standaard `.greph-index-set.json` in de huidige werkdirectory.

#### `searchTextIndexedSet`

```php
public static function searchTextIndexedSet(
    string $pattern,
    string|array $paths,
    ?TextSearchOptions $options = null,
    ?string $manifestPath = null,
    array $entryNames = [],
): array
```

Los de geselecteerde vermeldingen van `text` op vanuit een manifest voor een indexset en voer het equivalent van `searchTextIndexedMany` uit.

---

### Geïndexeerd AST-zoeken

#### `buildAstIndex` / `refreshAstIndex`

```php
public static function buildAstIndex(
    string $rootPath = '.',
    ?string $indexPath = null,
    IndexLifecycle|IndexLifecycleProfile|string|null $lifecycle = null,
): AstIndexBuildResult
public static function refreshAstIndex(
    string $rootPath = '.',
    ?string $indexPath = null,
    IndexLifecycle|IndexLifecycleProfile|string|null $lifecycle = null,
): AstIndexBuildResult
```

Bouw de feitenindex voor AST's of vernieuw deze incrementeel. Opgeslagen feiten staan standaard in `$rootPath/.greph-ast-index`.

#### `searchAstIndexed`

```php
public static function searchAstIndexed(
    string $pattern,
    string|array $paths,
    ?AstSearchOptions $options = null,
    ?string $indexPath = null,
): array
```

Gebruik de feitenindex om kandidaten te beperken voordat overeenkomsten opnieuw worden gecontroleerd aan de hand van de broncode. Geeft dezelfde `list<AstMatch>`-structuur terug als `searchAst`.

#### `searchAstIndexedMany`

```php
public static function searchAstIndexedMany(
    string $pattern,
    string|array $paths,
    array $indexPaths,
    ?AstSearchOptions $options = null,
): array
```

Voer een AST-feitenzoekopdracht uit op opgewarmde indexen in meerdere AST-indexdirectories.

#### `searchAstIndexedSet`

```php
public static function searchAstIndexedSet(
    string $pattern,
    string|array $paths,
    ?AstSearchOptions $options = null,
    ?string $manifestPath = null,
    array $entryNames = [],
): array
```

Los de geselecteerde vermeldingen van `ast-index` op vanuit een manifest voor een indexset en voer het equivalent van `searchAstIndexedMany` uit.

#### `buildAstCache` / `refreshAstCache`

```php
public static function buildAstCache(
    string $rootPath = '.',
    ?string $indexPath = null,
    IndexLifecycle|IndexLifecycleProfile|string|null $lifecycle = null,
): AstCacheBuildResult
public static function refreshAstCache(
    string $rootPath = '.',
    ?string $indexPath = null,
    IndexLifecycle|IndexLifecycleProfile|string|null $lifecycle = null,
): AstCacheBuildResult
```

Bouw de cache voor geparste bomen of vernieuw deze incrementeel. Geserialiseerde bomen worden standaard opgeslagen in `$rootPath/.greph-ast-cache`.

#### `searchAstCached`

```php
public static function searchAstCached(
    string $pattern,
    string|array $paths,
    ?AstSearchOptions $options = null,
    ?string $indexPath = null,
): array
```

Zoek in de gecachte geparste bomen naar AST's en sla de parser volledig over. Geeft dezelfde `list<AstMatch>`-structuur terug als `searchAst`.

#### `searchAstCachedMany`

```php
public static function searchAstCachedMany(
    string $pattern,
    string|array $paths,
    array $indexPaths,
    ?AstSearchOptions $options = null,
): array
```

Voer een zoekopdracht uit op de opgewarmde gecachte AST's in meerdere cachdirectories.

#### `searchAstCachedSet`

```php
public static function searchAstCachedSet(
    string $pattern,
    string|array $paths,
    ?AstSearchOptions $options = null,
    ?string $manifestPath = null,
    array $entryNames = [],
): array
```

Los de geselecteerde vermeldingen van `ast-cache` op vanuit een manifest voor een indexset en voer het equivalent van `searchAstCachedMany` uit.

---

## `Greph\Text\TextSearchOptions`

Alleen-lezenoptiesobject voor tekstzoeken.

```php
new TextSearchOptions(
    bool $fixedString = false,
    bool $caseInsensitive = false,
    bool $wholeWord = false,
    bool $invertMatch = false,
    ?int $maxCount = null,
    int $beforeContext = 0,
    int $afterContext = 0,
    bool $countOnly = false,
    bool $filesWithMatches = false,
    bool $filesWithoutMatches = false,
    bool $jsonOutput = false,
    bool $tracePlan = false,
    int $jobs = 1,
    bool $respectIgnore = true,
    bool $includeHidden = false,
    bool $followSymlinks = false,
    bool $skipBinaryFiles = true,
    bool $includeGitDirectory = false,
    ?FileTypeFilter $fileTypeFilter = null,
    int $maxFileSizeBytes = 10485760,
    array $globPatterns = [],
    bool $showLineNumbers = true,
    bool $showFileNames = true,
)
```

Validatie:

- `jobs >= 1`
- `beforeContext, afterContext >= 0`
- `maxCount === null || maxCount >= 1`

Gebruik `walkOptions()` om de bijbehorende `WalkOptions` af te leiden als u de bestandsstructuur afzonderlijk wilt doorlopen.

`tracePlan` wordt gebruikt door opgewarmde geïndexeerde zoekers en `greph-index` CLI-stromen om plannerdiagnostiek naar `stderr` uit te voeren. Native `searchText` gebruikt dit zelf niet.

---

## `Greph\Ast\AstSearchOptions`

Alleen-lezenoptiesobject voor AST-zoeken en herschrijven.

```php
new AstSearchOptions(
    string $language = 'php',
    int $jobs = 1,
    bool $respectIgnore = true,
    bool $includeHidden = false,
    bool $followSymlinks = false,
    bool $skipBinaryFiles = true,
    bool $includeGitDirectory = false,
    ?FileTypeFilter $fileTypeFilter = null,
    int $maxFileSizeBytes = 10485760,
    array $globPatterns = [],
    bool $skipParseErrors = true,
    bool $dryRun = false,
    bool $interactive = false,
    bool $jsonOutput = false,
    bool $tracePlan = false,
)
```

Het standaardfilter voor bestandstypen in de AST-modus is `php`. Als `skipParseErrors` `true` is (standaard), worden bestanden die niet kunnen worden geparst stilzwijgend overgeslagen; stel deze in op `false` om parsefouten als uitzonderingen weer te geven. `tracePlan` wordt gebruikt door opgewarmde AST-zoekers en `greph-index ast-index|ast-cache search` om diagnostiek over het beperken van kandidaten uit te voeren.

---

## `Greph\Walker\WalkOptions`

Alleen-lezenoptiesobject voor de bestandswalker.

```php
new WalkOptions(
    bool $respectIgnore = true,
    bool $includeHidden = false,
    bool $followSymlinks = false,
    bool $skipBinaryFiles = false,
    bool $includeGitDirectory = false,
    ?FileTypeFilter $fileTypeFilter = null,
    int $maxFileSizeBytes = 10485760,
    array $globPatterns = [],
)
```

---

## `Greph\Walker\FileTypeFilter`

Zet benoemde bestandstypen om in extensielijsten. Ingebouwde aliassen:

| Alias | Extensies |
|---|---|
| `css` | `css`, `sass`, `scss` |
| `html` | `htm`, `html`, `phtml` |
| `js` | `cjs`, `js`, `mjs` |
| `json` | `json` |
| `md` | `markdown`, `md` |
| `php` | `inc`, `php`, `php3`, `php4`, `php5`, `php7`, `php8`, `phpt`, `phtml` |
| `txt` | `txt` |
| `ts` | `ts`, `tsx` |
| `xml` | `xml` |
| `yaml` | `yaml`, `yml` |

```php
new FileTypeFilter(includeTypes: ['php'], excludeTypes: ['md']);
```

---

## Resultaatobjecten

### `Greph\Text\TextFileResult`

```php
final readonly class TextFileResult
{
    public string $file;
    /** @var list<TextMatch> */
    public array $matches;

    public function matchCount(): int;
    public function hasMatches(): bool;
}
```

### `Greph\Text\TextMatch`

```php
final readonly class TextMatch
{
    public string $file;
    public int $line;
    public int $column;
    public string $content;
    public string $matchedText;
    /** @var array<int|string, string> */
    public array $captures;
    /** @var list<array{line: int, content: string}> */
    public array $beforeContext;
    /** @var list<array{line: int, content: string}> */
    public array $afterContext;
}
```

### `Greph\Ast\AstMatch`

```php
final readonly class AstMatch
{
    public string $file;
    public PhpParser\Node $node;
    /** @var array<string, mixed> */
    public array $captures;
    public int $startLine;
    public int $endLine;
    public int $startFilePos;
    public int $endFilePos;
    public string $code;
}
```

### `Greph\Ast\RewriteResult`

```php
final readonly class RewriteResult
{
    public string $file;
    public string $originalContents;
    public string $rewrittenContents;
    public int $replacementCount;

    public function changed(): bool;
}
```

### `Greph\Index\IndexBuildResult`

```php
final readonly class IndexBuildResult
{
    public string $rootPath;
    public string $indexPath;
    public int $fileCount;
    public int $trigramCount;
    public int $addedFiles;
    public int $updatedFiles;
    public int $deletedFiles;
    public int $unchangedFiles;
}
```

`AstIndexBuildResult` en `AstCacheBuildResult` volgen dezelfde vorm, waarbij respectievelijk `factCount` en `cachedTreeCount` zijn ingevuld.

---

## Uitzonderingen

Greph werpt drie getypeerde uitzonderingen op, allemaal in `Greph\Exceptions`:

| Uitzondering | Wanneer deze wordt opgeworpen |
|---|---|
| `WalkerException` | Bestandssysteemfouten tijdens het doorlopen (ontbrekend pad, onleesbare map) |
| `PatternException` | Ongeldige regex of AST-patroon |
| `ParseException` | De PHP-bron kon niet worden geparseerd (alleen wanneer `skipParseErrors: false`) |

Geïndexeerde zoekmethoden werpen `\RuntimeException` op wanneer er op de gevraagde locatie geen index aanwezig is. De `greph-index` CLI biedt een optie `--fallback scan` die deze fouten opvangt en in plaats daarvan terugvalt op een scan zonder index.
