1e4f1d0da7
Walker now dispatches through a `languageKindMap` keyed on language name before falling back to the conventional `*_definition` / `*_declaration` suffix matcher. Covers grammar rule names that don't match the standard convention: Erlang `fun_decl`, Haskell `function` / `signature` / `data_type` / `type_synomym` (upstream typo preserved), Crystal `class_def` / `method_def`, Nim `proc_declaration` / `func_declaration`, Ada `function_specification` / `procedure_specification`, Odin `procedure_declaration`, Apex `class_declaration` / `method_declaration` / `trigger_declaration`, Solidity `contract_declaration` / `interface_declaration` / `modifier_definition`, F# `function_or_value_defn` / `named_module` / `record_type_defn`, ReScript `let_declaration` / `module_declaration`, ObjC `class_interface` / `class_implementation`, AL `codeunit_declaration` / `table_declaration` / `page_declaration`, GDScript `class_name_statement`, Jinja / Twig `macro_statement`. `nodeName` recurses three levels deep so wrappers like `fun_decl ▶ function_clause ▶ atom` resolve to the inner identifier; `isIdentifierKind` recognises `constant` / `atom` / `variable` in addition to the conventional `*identifier*` patterns. 17 regex extractors migrated to forest+regex hybrid — forest covers structural definitions via the walker, regex stays for idiom-specific edges (imports, framework-specific metadata): R, Gleam, Erlang, Crystal, Haskell, Nim, Hare, Vala, Zig, Groovy, Ada, D, Matlab, Odin, F#, Jinja, ReScript. Net change: −469 lines across 22 files; each migration deletes ~50–200 lines of bespoke regex and delegates definition extraction to the forest grammar. Adds `internal/parser/forest/dump_kinds_test.go` — a parameterised research helper. Future contributors map a new grammar's node-kind landscape in ~5 minutes by adding a fixture to its table and running `go test -run TestDumpGrammarKinds/<lang>`. Lifts `lineAt` / `findBlockEnd` out of `zig.go` into a shared `helpers_lines.go` so other hybrid extractors don't import them from a language-specific file. Lisp-family and uniform-grammar languages (Clojure, Tcl, Pascal, Cobol, Liquid, Blade, Pug, Nix) stay regex-only — their grammars don't encode definitions as distinct AST node kinds, so the walker can't distinguish `(defn foo …)` from `(println …)` without symbol-text matching (which is what tags.scm `(#match? …)` predicates do; forest's packages for these languages don't ship one). Languages attempted and reverted: Vim (special function-name chars), Julia (short-form `name() = body`), CMake (deeply-nested name), Perl, PowerShell, GDScript, Twig, ObjC, AL, Apex.