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 oneVolle Stufe
Handgeschriebene Adapter: typgetriebene Aufrufauflösung, geerbte Member, Zustandsverfolgung pro Attribut, Anweisungsbereiche.
| Sprache | Endungen | Registry-Schlüssel | Indexierte Typen |
|---|---|---|---|
| Python | .py | python | class |
| TypeScript (und 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 | — |
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.
| Sprache | Endungen | Registry-Schlüssel |
|---|---|---|
| Kotlin | .kt .kts | kotlin |
| Scala | .scala .sc | scala |
| Zig | .zig | zig |
| Objective-C | .m | objc |
| OCaml | .ml | ocaml |
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-patchesWenn 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=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 allEine 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.