Skip to content

feat(lang): add Visual Basic 6 / VBA grammar (harumiWeb/tree-sitter-vba) - #2086

Open
Tokarzewski wants to merge 1 commit into
DeusData:mainfrom
Tokarzewski:feat/721-vb6-grammar
Open

feat(lang): add Visual Basic 6 / VBA grammar (harumiWeb/tree-sitter-vba)#2086
Tokarzewski wants to merge 1 commit into
DeusData:mainfrom
Tokarzewski:feat/721-vb6-grammar

Conversation

@Tokarzewski

@Tokarzewski Tokarzewski commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds Visual Basic 6 / VBA as a language (CBM_LANG_VB6) — part two of #721, following the merged short-term disambiguation in #2074. The VB6 .frm/.cls files that #2074 routed to "unsupported" now parse with a real grammar; .bas/.ctl/.dsr/.pag are mapped directly.

Refs #721.

Grammar: harumiWeb/tree-sitter-vba @ 63b2f8d0d65c (v0.13.0, MIT, ABI 15, lexer-only — no external scanner). It parses the module export headers natively (VERSION, Begin … End, BeginProperty … EndProperty, GUID blocks, Attribute lines), so the .frm designer block flagged in #721 as the main technical risk needs no preprocessing step — it becomes ordinary frm_begin_block nodes and the code below parses normally. VB6-specific statements are covered (Declare, Implements, Event/RaiseEvent, WithEvents, Property Get|Let|Set). Rejected alternatives: arrmee-wt/tree-sitter-vba (GPL-3.0 — outside scripts/license-policy.json), joannefan/tree-sitter-vb6 (no licence file, no generated parser, .frm metadata "poorly parsed" per its README), CodeAnt-AI/tree-sitter-vb-dotnet (VB.NET — that is #1073).

Provenance caveat — please decide: upstream gitignores src/parser.c, so the vendored 46 MB parser.c was generated from the pinned grammar.js with tree-sitter-cli 0.26.9 (tree-sitter generate --abi 15, the project's own pnpm generate). Byte-identity with an upstream artefact therefore cannot be claimed; MANIFEST.md records the exact regeneration command (the vba row is marked NOT-IN-REGISTRIES (see note)). The size comes from per-keyword case-insensitive expansion; lean's parser is 102 MB, so it is within precedent.

Extraction (generic paths plus small language hooks):

  • Sub/Function/Property Get|Let|Set/conditional_*_declaration/Declare Sub|Function/Event → callables (every kind exposes a name field). Type … End Type → Class with typed Fields (As clause unwrapped, so a Field is Long, not As Long); Enum → Enum with members; module-level Dim/Const → one Variable per declarator; Implements → import.
  • Calls: call_statement (callee field — Foo 1, Call Foo(1), obj.Bar x), call_expression (function field — y = Foo(1); VB6 syntax cannot distinguish this from array indexing, unresolved callees just produce no edge), raise_event_statement (event). Dotted obj.Method is kept dotted; With-block .Method yields the bare member name; nested a(1)(2) is unwrapped.
  • VB6 reserved words/intrinsic types for cbm_is_keyword; source_file as module parent.

Everything a new grammar needs here (modelled on #1888): enum, lang_specs.c row, language table (the #2074 sniffers now return CBM_LANG_VB6; discover.h docs updated), userconfig.c names (vb6, vba, vb, visualbasic), tests (test_language.c, grammar regression case + label golden, lang_contract CALL case, test_extraction.c), the four repro registries, the seven language-count surfaces 162→163 (README.md, docs/index.html, docs/llms.txt, pkg/npm/README.md, chocolatey nuspec, scripts/package-release.sh, server.json) with tests/test_language_count_contract.sh passing, MANIFEST.md (row, ABI tally recounted from the tree, re-vendor note, custom-extraction-handling entry), THIRD_PARTY.md, scripts/vendored-checksums.txt (sha256 of the LF index blobs), scripts/new-languages.json. .gitattributes already covers grammars/**/parser.c.

Deliberately not in this PR: treating .cls/.frm/.ctl files as classes (Class node + Methods) — that is the separate draft #2087, stacked on this one so it can be reviewed or declined independently. Also out of scope: .vbs (no header markers), .vbp/.vbg project files, VB.NET (#1073).

Known grammar gaps (lines reported as parse_partial; the files still index): a call with a leading omitted argument (.Add , x), Print #f, …, graphics Line (x, y)-(x2, y2), _-continued comments, and the .frm header Object = "{GUID}…" lines.

With the grammar in place VB6 files no longer "vanish silently" (the note on #2074), which largely dissolves that follow-up.

Checklist

  • Every commit is signed off (git commit -s)
  • Tests pass locally — run on Windows with a zig/clang toolchain without ASan/UBSan (no sanitiser runtime on this host): language discover extraction grammar_regression grammar_labels lang_contract → 737 passed, 0 failed, 2 Windows platform skips; repro_language_registry repro_call_node_manifest repro_call_argument_matrix_b → 58 passed; repro_invariant_breadth → PASS (vb6 calls=1 callable=1 module=0); bash tests/test_language_count_contract.sh → 163 grammars, 7 surfaces OK. CI's sanitised runs are the authoritative check.
  • Lint: clang-format-20 --dry-run --Werror clean on every touched src/ and internal/cbm file; cppcheck not run locally (not installed) — relying on CI
  • New behaviour is covered by tests (listed above); all fixtures are synthetic

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown

Thanks for opening this — it has been seen, and it is queued.

This note is automated, but it is not a brush-off: it exists so you know where your PR stands instead of having to guess from silence.

Current review status: working through a backlog. 0.9.1-rc.1 is out, so the release freeze that held reviews is over — but it left a large queue of open pull requests behind it, and we are reading through them oldest-first. The background is in discussion #1144.

What that means for this PR, concretely:

  • It will not be closed for inactivity. No stale bot touches pull requests here.
  • It may still sit a while before a human reads it. That is on us, not on you.
  • Older PRs are read first, so a recent one is not being skipped — it is behind a queue.

Things that will genuinely speed it up whenever review does happen:

  • Keep it rebased on main — the tree is moving quickly right now, and a conflicting branch cannot be reviewed as the diff you intended.
  • Get CI green, or say which failures you believe are pre-existing.
  • Keep the change to one claim. Bundled features and refactors get split before they get merged, which costs you a round trip.
  • Every commit needs a sign-off (git commit -s) — CI enforces DCO.

If this fixes a bug, a reproduction we can run is worth more than a description of the symptom.

Thanks for contributing, and sorry in advance for the wait.

Vendors tree-sitter-vba @ 63b2f8d0d65c (v0.13.0, MIT, ABI 15, lexer-only,
no external scanner) as CBM_LANG_VB6 and wires it end to end:

- discover: .bas/.ctl/.dsr/.pag map directly; .cls (Apex/ObjectScript)
  and .frm (FORM) keep their table owners and the DeusData#2074 content sniffers
  now route VB6 modules to CBM_LANG_VB6 instead of CBM_LANG_COUNT.
- lang_specs: Sub/Function/Property Get|Let|Set/Declare/Event as
  callables; Type -> Class with typed Fields (As clause unwrapped);
  Enum -> Enum with members; module-level Dim/Const -> one Variable per
  declarator; call_statement/call_expression/raise_event_statement
  callees; Implements as import; VB6 keyword set; source_file module
  parents.
- release surfaces: MANIFEST (163 grammars, 75x ABI-15, vba row + note
  on the locally generated parser.c), THIRD_PARTY, vendored checksums,
  new-languages.json, and the 162 -> 163 language-count claims on all
  seven contract surfaces.
- tests: extension/sniff mapping, grammar regression + label golden,
  calls contract, extraction block, and the four repro registries
  (capability ledger, call-node manifest, invariant breadth, argument
  matrix B).

Class-module synthesis (.cls/.frm as a Class with Methods) is a
separate follow-up change.

Refs DeusData#721.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Tokarzewski <bartlomiej.tokarzewski@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant