Handbooks
Referenz

Sprachunterstützung

18 Sprachen in zwei Analysestufen — welche Endungen jede beansprucht, worauf die generische Stufe verzichtet, und die zwei Vorbehalte, die man kennen sollte, bevor man auf sie stößt.

--lang auto (der Standard) erkennt und verschmilzt jede Sprache in einem Durchgang. Man muss fast nie eine benennen.

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

Volle Stufe

Handgeschriebene Adapter: typgetriebene Aufrufauflösung, geerbte Member, Zustandsverfolgung pro Attribut, Anweisungsbereiche.

SpracheEndungenRegistry-SchlüsselIndexierte Typen
Python.pypythonclass
TypeScript (und 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

Die letzte Spalte ist AdapterCapabilities.typeKinds — was jeder Adapter wirklich findet, nicht was er anstrebt. Shell hat überhaupt keine Typdeklarationen, das dort ist also eine positive Aussage und keine Lücke. Konstanten, Variablen und Makros werden in keiner Sprache indexiert.

JavaScript hat keinen eigenen Adapter

Es wird vom TypeScript-Adapter abgedeckt. Es gibt nichts zu wählen — .js, .jsx, .mjs und .cjs werden automatisch beansprucht.

Ein Adapter für die C-Familie, nicht zwei

Die cpp-Grammatik verarbeitet auch C; die c-Grammatik verarbeitet C++ überhaupt nicht. Also beansprucht ein Adapter beide, und --lang cpp ist für ein reines C-Projekt korrekt.

Generische Stufe

Eine konfigurationsgetriebene Engine, eine deklarative Spezifikation pro Sprache. Das Inventar an Dateien und Funktionen ist exakt; Aufrufbeziehungen sind nach bestem Wissen.

SpracheEndungenRegistry-Schlüssel
Kotlin.kt .ktskotlin
Scala.scala .scscala
Zig.zigzig
Objective-C.mobjc
OCaml.mlocaml

Ein Handbuch, dessen Analyse Stufen mischt, sagt das in seiner Übersicht. Was genau schlechter wird, steht unter Analysetreue.

Zwei Vorbehalte, genannt, bevor du auf sie stößt

Swift bricht den Prozess auf V8 ≥ 13 ab

Die mitgelieferte Swift-Grammatik verursacht einen fatalen Out-of-Memory-Abbruch, sobald V8 das WASM-Modul eine Stufe höher kompiliert — gemessen 5 von 5 Mal fatal auf Node 24, in Ordnung auf Node 21, und unter neunzehn Grammatiken einzigartig.

Auf einer solchen Laufzeit verweigert der Adapter bereits bei der Erkennung und nennt die Abhilfe, statt deinen ganzen Lauf zu reißen:

node --liftoff-only $(which handbook) analyze --source ~/code/ios-app --work work/ios

--liftoff-only überspringt genau die Höherstufungs-Kompilierung, die das auslöst. Die Testsuite des Repositorys übergibt dasselbe Flag aus exakt diesem Grund.

Shell-Skripte mit case werden übersprungen

Der externe Scanner der festgepinnten bash-Grammatik importiert env.isalpha, das der dynamische Linker von web-tree-sitter@0.25.10 nicht bereitstellt, sodass parse() bei jeder case-Anweisung wirft — und den Parser vergiftet zurücklässt, weshalb der Adapter ihn verwirft und weitergeht.

Das ist größer, als es klingt

case ist in Shell allgegenwärtig. Gemessen an nvm: alle 6 Dateien und alle 122 Funktionen wurden übersprungen. Shell ist als volle Stufe gelistet, weil der Adapter volle Stufe ist, aber behandle die Shell-Abdeckung als unvollständig, bis diese Grammatik stromaufwärts repariert ist.

Das Scan-Log sagt das ausdrücklich und nennt den Grund:

[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, …

Jede dieser Dateien wird zusätzlich einzeln in phase1/scan-coverage.json mit reason: "unparsable" benannt und aus scannedFiles im Graphen herausgehalten — die Lücke ist damit sichtbar statt still.

Was überall übersprungen wird

Jeder Adapter beachtet eine gemeinsame Ausschlussliste:

.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

Wenn deine Build-Ausgabe woanders liegt, richte --source auf die echte Quell-Wurzel statt auf die Repository-Wurzel.

Wenn eine Datei zu zwei Sprachen gehören könnte

Die Erkennung führt die Adapter in fester Reihenfolge aus, und wer eine Datei zuerst beansprucht, behält sie; beim Abgleich der Endungen gewinnt die längste Übereinstimmung. In der Praxis zählt das nur bei .h (beansprucht vom C/C++-Adapter) und .m (Objective-C).

Lesen, was tatsächlich gescannt wurde

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

Eine Sprache hinzufügen

Eine Sprache der generischen Stufe hinzuzufügen ist eine deklarative Spezifikation, kein Parser — und braucht keine neue Abhängigkeit, weil die Grammatiken bereits mitgeliefert werden. Siehe Eine Sprache hinzufügen.

Auf dieser Seite