Pesquisa de AST indexada
A pesquisa de AST indexada é a versão com cache aquecido de Pesquisa de 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
# 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:
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
./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 automaticamentemanual-refresh: informa o estado obsoleto emstats, mas nunca atualiza durante a pesquisaopportunistic-refresh: atualiza durante a pesquisa somente quando o conjunto de alterações ainda é pequeno o bastantestrict-stale-check: rejeita pesquisas obsoletas em vez de atualizar
Consultar o índice
./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 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.
./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.
./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:
./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 costuma ser mais adequado, pois ignora completamente a etapa de análise sem depender de uma assinatura geral.
Uso programático
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(...).