Handbooks
リファレンス

言語サポート

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 one

full ティア

手書きのアダプタ: 型駆動の呼び出し解決、継承メンバー、属性ごとの状態追跡、ステートメントスパン。

言語拡張子レジストリキー索引される型
Python.pypythonclass
TypeScript (および JavaScript).ts .tsx .js .jsx .mjs .cjstypescriptclass interface enum alias
Go.gogostruct interface alias other
Rust.rsruststruct enum trait alias other
Java.javajavaclass interface enum record other
C#.cscsharpclass interface struct record enum other
C/C++.c .h .cpp .cc .cxx .c++ .hpp .hh .hxxcppclass struct enum alias other
Ruby.rb .rake .gemspecrubyclass other
PHP.php .phtmlphpclass interface enum trait
Swift.swiftswiftclass struct enum interface alias
Dart.dartdartclass enum trait alias other
Solidity.solsolidityclass interface struct enum other
Shell.sh .bashshell

最後の列は AdapterCapabilities.typeKinds です。各アダプタが実際に見つけられるもので、 見つけたいものではありません。Shell には型宣言が存在しないので、その行の は欠落ではなく 肯定的な主張です。定数・変数・マクロはどの言語でも索引されません。

JavaScript に専用のアダプタはありません

TypeScript のアダプタがまとめて担当します。選ぶものは何もなく、.js.jsx.mjs.cjs は 自動的に引き受けられます。

C ファミリのアダプタは 2 つではなく 1 つ

cpp のグラマーは C も扱えますが、c のグラマーは C++ をまったく扱えません。そのため 1 つの アダプタが両方を引き受けており、純粋な C のプロジェクトでも --lang cpp が正解です。

generic ティア

1 つの設定駆動エンジンと、言語ごとの宣言的スペック。ファイルと関数のインベントリは正確ですが、呼び出し関係はベストエフォートです。

言語拡張子レジストリキー
Kotlin.kt .ktskotlin
Scala.scala .scscala
Zig.zigzig
Objective-C.mobjc
OCaml.mlocaml

解析がティアをまたいでいるハンドブックは、その概要でそう明言します。何がどう劣化するのかは 解析忠実度 を参照してください。

踏み抜く前に伝えておく 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=611
jq '.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 ティアの言語を追加するのは、パーサーではなく宣言的なスペックの追加です — しかも グラマーはすでに同梱されているので、新しい依存も要りません。 言語の追加 を参照してください。

このページの内容