言語サポート
2 つの解析ティアにまたがる 18 言語 — それぞれがどの拡張子を引き受けるのか、generic ティアが何を諦めているのか、そして踏み抜く前に知っておく価値のある 2 つの注意点。
--lang auto(デフォルト)は、1 回のパスですべての言語を検出してマージします。言語を名指しする必要は、ほとんどありません。
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 onefull ティア
手書きのアダプタ: 型駆動の呼び出し解決、継承メンバー、属性ごとの状態追跡、ステートメントスパン。
| 言語 | 拡張子 | レジストリキー | 索引される型 |
|---|---|---|---|
| Python | .py | python | class |
| TypeScript (および 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 | — |
最後の列は AdapterCapabilities.typeKinds です。各アダプタが実際に見つけられるもので、
見つけたいものではありません。Shell には型宣言が存在しないので、その行の — は欠落ではなく
肯定的な主張です。定数・変数・マクロはどの言語でも索引されません。
JavaScript に専用のアダプタはありません
TypeScript のアダプタがまとめて担当します。選ぶものは何もなく、.js、.jsx、.mjs、.cjs は
自動的に引き受けられます。
C ファミリのアダプタは 2 つではなく 1 つ
cpp のグラマーは C も扱えますが、c のグラマーは C++ をまったく扱えません。そのため 1 つの
アダプタが両方を引き受けており、純粋な C のプロジェクトでも --lang cpp が正解です。
generic ティア
1 つの設定駆動エンジンと、言語ごとの宣言的スペック。ファイルと関数のインベントリは正確ですが、呼び出し関係はベストエフォートです。
| 言語 | 拡張子 | レジストリキー |
|---|---|---|
| Kotlin | .kt .kts | kotlin |
| Scala | .scala .sc | scala |
| Zig | .zig | zig |
| Objective-C | .m | objc |
| OCaml | .ml | ocaml |
解析がティアをまたいでいるハンドブックは、その概要でそう明言します。何がどう劣化するのかは 解析忠実度 を参照してください。
踏み抜く前に伝えておく 2 つの注意点
V8 ≥ 13 では Swift がプロセスを中断させます
同梱の Swift グラマーは、V8 が WASM モジュールをティアアップした時点で、致命的なメモリ枯渇による 中断を引き起こします — Node 24 では 5 回中 5 回が致命的、Node 21 では問題なし、そして 19 個の グラマーのうちこれだけに固有の現象です。
そのようなランタイムでは、アダプタは検出の時点で拒否し、実行全体を道連れにする代わりに対処法を 示します:
node --liftoff-only $(which handbook) analyze --source ~/code/ios-app --work work/ios--liftoff-only は、これを引き起こすティアアップコンパイルをスキップします。このリポジトリ自身の
テストスイートが同じフラグを渡しているのも、まさに同じ理由です。
case を含むシェルスクリプトはスキップされます
固定された bash グラマーの外部スキャナは env.isalpha をインポートしますが、
web-tree-sitter@0.25.10 の動的リンカはそれを提供しません。そのため case 文があると parse() が
例外を投げ、しかもパーサーが汚染されたまま残るので、アダプタはそれを破棄して先へ進みます。
これは聞こえるより大ごとです
case はシェルに遍在します。nvm で実測したところ、6 ファイル
すべてと 122 関数すべてがスキップされました。アダプタが full ティアなので Shell は full ティア
として掲載されていますが、そのグラマーが上流で直るまでは、シェルのカバレッジは部分的だと考えて
ください。
スキャンログはそれを明示し、理由も名指しします:
[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, …それらのファイルは 1 つずつ phase1/scan-coverage.json にも reason: "unparsable" 付きで
名指しされ、グラフの scannedFiles からは外されます — つまり、沈黙した欠落ではなく目に
見える欠落になります。
どこでもスキップされるもの
すべてのアダプタは、共有された 1 つのスキップリストを尊重します:
.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-patchesビルド出力が別の場所にあるなら、リポジトリのルートではなく本当のソースルートを --source に
指定してください。
1 つのファイルが 2 つの言語に属しうるとき
検出は決まった順序でアダプタを実行し、最初にそのファイルを引き受けたアダプタが保持します。
拡張子のマッチングは最長一致を優先します。実際にこれが効いてくるのは .h(C/C++ アダプタが引き
受ける)と .m(Objective-C)だけです。
実際に何がスキャンされたのかを読む
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 all言語の追加
generic ティアの言語を追加するのは、パーサーではなく宣言的なスペックの追加です — しかも グラマーはすでに同梱されているので、新しい依存も要りません。 言語の追加 を参照してください。