
# Pesquisa de AST indexada

A pesquisa de AST indexada é a versão com cache aquecido de [Pesquisa de AST](https://greph.inline0.dev/pt/docs/modes/ast). Na primeira chamada, fatos no nível dos nós (nomes de chamadas, instanciações, declarações de classes e declarações de métodos) são extraídos para um armazenamento em disco; nas chamadas seguintes, o armazenamento permite ignorar arquivos que claramente não podem conter uma correspondência estrutural. Em seguida, o mecanismo de correspondência verifica novamente os candidatos usando o código-fonte.

O índice de fatos está disponível pelo subcomando `greph-index ast-index` CLI e pelos métodos de fachada `Greph::buildAstIndex()` / `Greph::searchAstIndexed()`. Ele também participa de fluxos de trabalho aquecidos com vários índices e conjuntos respaldados por manifestos.

## Criar o índice

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

Por padrão, o índice de fatos é armazenado em `<root>/.greph-ast-index/`.

Uma criação bem-sucedida exibe um resumo de uma linha:

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

Os quatro contadores registram arquivos adicionados, atualizados, excluídos e inalterados desde a última criação.

## Atualizar o índice

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

`refresh` percorre novamente a raiz indexada, analisa outra vez os arquivos alterados e regrava apenas as linhas de fatos que mudaram. A saída usa os mesmos quatro contadores do índice de texto.

Os perfis de ciclo de vida funcionam da mesma forma que nos índices de texto aquecidos:

- `static`: nunca verifica a atualidade nem modifica automaticamente
- `manual-refresh`: informa o estado obsoleto em `stats`, mas nunca atualiza durante a pesquisa
- `opportunistic-refresh`: atualiza durante a pesquisa somente quando o conjunto de alterações ainda é pequeno o bastante
- `strict-stale-check`: rejeita pesquisas obsoletas em vez de atualizar

## Consultar o índice

```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 sintaxe das metavariáveis é idêntica à da pesquisa nativa de AST. Consulte [Modos / Pesquisa de AST](https://greph.inline0.dev/pt/docs/modes/ast) para ver a gramática completa.

### Opções

| Opção | Significado |
|---|---|
| `--lang NAME` | Linguagem da AST. Padrão: `php` |
| `-j N`, `--jobs N` | Número de processos de trabalho paralelos |
| `-l`, `--files-with-matches` | Listar apenas arquivos correspondentes |
| `--glob GLOB` | Incluir apenas arquivos cujos caminhos correspondam a GLOB |
| `--type NAME` / `--type-not NAME` | Filtro de tipo de arquivo |
| `--json` | Emitir saída JSON |
| `--no-ignore` | Ignorar `.gitignore` e `.grephignore` |
| `--hidden` | Incluir arquivos ocultos |
| `--strict-parse` | Falhar em erros de análise em vez de ignorá-los |
| `--fallback MODE` | Comportamento para índice ausente: `fail` (padrão) ou `scan` |
| `--index-dir DIR` | Usar um diretório de índice diferente do padrão |
| `--trace-plan` | Emitir diagnósticos do planejador de AST aquecido em `stderr` |
| `--show-index-origin` | Prefixar a saída com o rótulo do índice correspondente no modo de vários índices ou conjuntos |

### Alternativa para índice ausente

Por padrão, `ast-index search` gera um erro quando não há índice no local solicitado. Passe `--fallback scan` para recorrer a uma varredura nativa de AST. Essa opção é adequada para ferramentas que querem usar a pesquisa indexada quando disponível, mas ainda precisam produzir resultados quando o índice não foi criado.

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

### Pesquisa em vários índices

Você pode pesquisar em vários índices aquecidos de AST com um único comando repetindo `--index-dir`. Isso é útil para configurações como o núcleo WordPress junto com um plugin ou 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()' .
```

Quando `--show-index-origin` está habilitado, a saída recebe como prefixo o nome da entrada do índice aquecido correspondente, para que você possa ver qual raiz gerou o resultado.

### Conjuntos de índices respaldados por manifesto

Para configurações estáveis com índices aquecidos, defina um manifesto e deixe `greph-index set` operar nos índices agrupados:

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

Os subcomandos de conjunto compartilham o mesmo tratamento do ciclo de vida, as mesmas verificações de obsolescência e os mesmos diagnósticos do planejador que o uso direto de `ast-index`.

### Diagnósticos do planejador

`--trace-plan` mostra como Greph reduziu a consulta antes de executar o mecanismo completo de correspondência. Para `ast-index`, isso normalmente inclui:

- a assinatura geral de fatos extraída do padrão
- quantos índices aquecidos foram pesquisados
- quantos arquivos foram rejeitados pelo filtro de fatos
- quantos arquivos candidatos foram analisados novamente para uma verificação estrutural exata

## O que o índice armazena

Para cada arquivo indexado, o extrator de fatos de AST registra uma linha por nó "interessante". O conjunto de tipos de fatos abrange as construções mais frequentemente visadas por padrões de AST:

- Chamadas de funções e métodos (pelo nome chamado)
- Instanciações de classes (pelo nome da classe)
- Declarações de classes, interfaces, traits e enums (pelo nome)
- Declarações de funções (pelo nome)
- Declarações de métodos (pelo nome e pela visibilidade)
- Instruções de importação

Quando uma consulta chega, `Greph\Ast\AstFactQuery` converte o padrão de pesquisa em uma assinatura geral de fatos (por exemplo, "deve conter um `new` de qualquer classe") e cruza os dados do armazenamento de fatos. Os arquivos que passam por esse cruzamento são analisados novamente e comparados com o padrão completo.

Isso significa que o índice de fatos é um *pré-filtro*, não um armazenamento de correspondências totalmente precisas. A etapa de correspondência ainda analisa o código-fonte, então a correção estrutural é idêntica à da pesquisa nativa de AST; apenas o conjunto de candidatos é menor.

## Quando usar

O modo de AST indexada é a ferramenta adequada quando:

- Você executa repetidamente as mesmas consultas estruturais na mesma base de código.
- Os padrões visam formas identificáveis (nome de chamada, nome de classe, tipo de declaração) armazenadas pelo extrator de fatos.
- Você quer reduzir a latência em comparação com analisar novamente todos os arquivos.

Para padrões cuja característica distintiva não está no conjunto de fatos (por exemplo, expressões aninhadas complexas sem um elemento inicial reconhecível), o [modo de AST em cache](https://greph.inline0.dev/pt/docs/indexed/cache) costuma ser mais adequado, pois ignora completamente a etapa de análise sem depender de uma assinatura geral.

## Uso programático

```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` aceita o mesmo `AstSearchOptions` da pesquisa nativa de AST e retorna o mesmo formato de `list<AstMatch>`. Para fluxos com vários índices ou respaldados por manifestos, use `searchAstIndexedMany(...)` e `searchAstIndexedSet(...)`.
