Suporte a linguagens
18 linguagens em dois níveis de análise — quais extensões cada uma reivindica, do que o nível generic abre mão e as duas ressalvas que vale conhecer antes de esbarrar nelas.
--lang auto (o padrão) detecta e mescla todas as linguagens em uma única passada.
Você quase nunca precisa nomear uma.
handbook analyze --source ~/code/polyglot-repo --work work/poly # one pass, all languages
handbook analyze --source ~/code/repo --work work/x --lang python # or pin oneNível full
Adaptadores escritos à mão: resolução de chamadas guiada por tipos, membros herdados, rastreamento de estado por atributo, spans de instruções.
| Linguagem | Extensões | Chave no registro | Tipos indexados |
|---|---|---|---|
| Python | .py | python | class |
| TypeScript (e JavaScript) | .ts .tsx .js .jsx .mjs .cjs | typescript | class interface enum alias |
| Go | .go | go | struct interface alias other |
| Rust | .rs | rust | struct enum trait alias other |
| Java | .java | java | class interface enum record other |
| C# | .cs | csharp | class interface struct record enum other |
| C/C++ | .c .h .cpp .cc .cxx .c++ .hpp .hh .hxx | cpp | class struct enum alias other |
| Ruby | .rb .rake .gemspec | ruby | class other |
| PHP | .php .phtml | php | class interface enum trait |
| Swift | .swift | swift | class struct enum interface alias |
| Dart | .dart | dart | class enum trait alias other |
| Solidity | .sol | solidity | class interface struct enum other |
| Shell | .sh .bash | shell | — |
A última coluna é AdapterCapabilities.typeKinds: o que cada adaptador realmente encontra,
não o que ele aspira encontrar. O Shell não tem declarações de tipo, então o — daquela linha
é uma afirmação positiva e não uma lacuna. Constantes, variáveis e macros não são indexadas em
nenhuma linguagem.
JavaScript não tem um adaptador separado
Ele é coberto pelo do TypeScript. Não há nada a escolher — .js, .jsx, .mjs e .cjs são reivindicados
automaticamente.
Um adaptador para a família C, não dois
A gramática cpp também dá conta de C; a gramática c não dá conta de C++ de jeito nenhum. Então um único
adaptador reivindica as duas, e --lang cpp é o correto para um projeto puramente em C.
Nível generic
Um único motor guiado por configuração, uma especificação declarativa por linguagem. O inventário de arquivos e funções é exato; as relações de chamada são de melhor esforço.
| Linguagem | Extensões | Chave no registro |
|---|---|---|
| Kotlin | .kt .kts | kotlin |
| Scala | .scala .sc | scala |
| Zig | .zig | zig |
| Objective-C | .m | objc |
| OCaml | .ml | ocaml |
Um handbook cuja análise mistura níveis diz isso na sua visão geral. Veja Fidelidade da análise para saber exatamente o que degrada.
Duas ressalvas, declaradas antes que você esbarre nelas
O Swift aborta o processo em V8 ≥ 13
A gramática Swift embutida causa um abort fatal por falta de memória assim que a V8 sobe o módulo WASM de nível — medida como fatal 5 vezes em 5 no Node 24, funcionando bem no Node 21, e exclusiva dessa única gramática entre dezenove.
O adaptador recusa na descoberta em um runtime desses e nomeia o remédio, em vez de derrubar a sua execução inteira junto:
node --liftoff-only $(which handbook) analyze --source ~/code/ios-app --work work/iosO --liftoff-only pula a compilação de subida de nível que dispara isso. A própria suíte
de testes do repositório passa a mesma flag exatamente por esse motivo.
Scripts shell que contêm case são pulados
O scanner externo da gramática bash travada importa env.isalpha, que o linker dinâmico do
web-tree-sitter@0.25.10 não fornece, então parse() lança uma exceção em qualquer
instrução case — e deixa o parser envenenado, então o adaptador o descarta e segue em frente.
Isso é maior do que parece
case é onipresente em shell. Medido no nvm: todos
os 6 arquivos e todas as 122 funções foram pulados. Shell está listado como nível full
porque o adaptador é de nível full, mas trate a cobertura de shell como parcial até
que essa gramática seja corrigida no upstream.
O log de varredura diz isso explicitamente, e nomeia o motivo:
[scan] shell: 5 file(s) the grammar could not parse — the pinned bash grammar throws on
`case`, which most real scripts use; their functions are absent from this graph, not
merely unresolved — install.sh, nvm.sh, …Cada um desses arquivos também é nomeado individualmente em phase1/scan-coverage.json
com reason: "unparsable", e mantido fora do scannedFiles do grafo — de modo que eles
são uma lacuna visível, não uma lacuna silenciosa.
O que é pulado em todo lugar
Todo adaptador respeita uma mesma lista de exclusão compartilhada:
.git .hg .svn node_modules vendor target build dist out
__pycache__ .mypy_cache .pytest_cache .ruff_cache .tox
venv .venv env .env site-packages .idea .vscode .handbook-patchesSe a saída da sua build fica em outro lugar, aponte --source para a raiz real do
código-fonte, e não para a raiz do repositório.
Quando um arquivo poderia pertencer a duas linguagens
A descoberta roda os adaptadores em uma ordem fixa e o primeiro a reivindicar um arquivo
fica com ele; a correspondência de extensão prefere a mais longa. Na prática isso só
importa para .h (reivindicado pelo adaptador C/C++) e .m (Objective-C).
Lendo o que de fato foi varrido
handbook analyze --source ~/code/repo --work work/x -v
# [scan] auto root=/Users/me/code/repo
# [scan] typescript: 284 files
# [scan] python: 96 files
# [scan] shell: 12 files
# [build] functions=3187 kept=9042 dropped=611jq '.metadata.languages | keys' work/x/phase1/graph.json # which tiers are in play
jq '.metadata.byCategory' work/x/phase1/dropped-calls.json # what could not be resolved
jq '.metadata.byReason, .files' work/x/phase1/scan-coverage.json # what could not be parsed at allAdicionando uma linguagem
Adicionar uma linguagem de nível generic é uma especificação declarativa, não um parser — e não exige nenhuma dependência nova, porque as gramáticas já vêm junto. Veja Adicionando uma linguagem.