Skip to content

feat(visualbasic): add VB.NET structural extraction (WinForms-grade)#1179

Open
ankitsusheel wants to merge 5 commits into
DeusData:mainfrom
ankitsusheel:feat/vbnet-structural-extraction
Open

feat(visualbasic): add VB.NET structural extraction (WinForms-grade)#1179
ankitsusheel wants to merge 5 commits into
DeusData:mainfrom
ankitsusheel:feat/vbnet-structural-extraction

Conversation

@ankitsusheel

Copy link
Copy Markdown

Fixes #1178

Adds VB.NET (.vb) as a supported language, with real-world WinForms code as the acceptance bar. Before this change, .vb files were silently dropped at discovery — status:"indexed", zero nodes, zero warnings, no counter (verified on main; see the issue for the baseline evidence).

What's in here (3 commits)

  1. Grammar vendoringCodeAnt-AI/tree-sitter-vb-dotnet (MIT declared, ABI 15, no external scanner) pinned at cfca210, vendored under internal/cbm/vendored/grammars/vb_dotnet/. ⚠️ Not byte-for-byte upstream: the shipped grammar cannot parse standard next-line/colon Inherits/Implements, Handles clauses, AddHandler/RemoveHandler/RaiseEvent, As New T(), member-level #Region, nested types, or attribute _-continuations (the Designer-file shape). parser.c is regenerated (tree-sitter-cli 0.25.6) from a patched grammar.js; the full diff is vendored as grammar.js.patch, with the re-vendor procedure in MANIFEST.md. Patches to be proposed upstream. Upstream ships no LICENSE file (MIT metadata only) — vendored LICENSE carries the standard MIT text per the move/zsh convention.
  2. Registration + extractionCBM_LANG_VISUALBASIC, .vb extension mapping, lang_specs.c row, and the per-language handling the generic paths can't cover: body-wrapper-less class blocks (member routing + no double extraction), Sub New constructors (no name node → Method "New" via a small push_method_def split), inherits_clause/implements_clause base collection feeding the existing generic INHERITS-vs-IMPLEMENTS decision, Field defs from variable_declarator/property_declaration with as_clause types (incl. As New), and callee extraction from invocation's target field with Me./MyClass. receiver stripping.
  3. Tests + docs — 11 extraction tests (Designer shapes, partials, #Region, Handles/AddHandler, constructors, calls, imports, nested types), grammar-regression row, label golden, .vb detection tests, README tier entry, 158→159 language count.

Design decisions for maintainer review

  • Partial classes: one Class node per file (path-derived QNs) — same treatment C# partial gets today; no merge pass. Cross-file wiring verified working via name resolution (a Handles reference in Form1.vb resolves to the WithEvents field in Form1.Designer.vb).
  • Case-insensitivity: not implemented; registry.c untouched. Names emitted as written; mixed-case references are a documented limitation.
  • Event wiring: rides the existing USAGE machinery — no new edge type; HANDLES stays route-scoped.
  • Namespaces QN-transparent; Module/Structure → "Class" label — both matching C#.

Verification

  • Full suite: 6387 passed, 0 failed (includes the new tests). Vendored-integrity manifest updated via scripts/security-vendored.sh --update after its dangerous-code scan passed.
  • E2E on a faithful WinForms fixture (Form1.vb + Form1.Designer.vb + service class): 44 nodes / 72 edges, zero parse errors; IMPLEMENTS edge, class-scoped Method QNs, Field nodes with control types, and trace_path walking Button1_Click → CustomerService → Save → Validate.
  • Note: cppcheck/clang-format were unavailable on the dev machine — relying on CI for those two gates.

Diff-size note

The reviewable hand-written diff is ~500 lines across extract_defs.c/extract_calls.c/lang_specs.c/language.c/tests/docs. The bulk of the line count is the generated parser.c (vendored, machine-generated) — same shape as prior grammar additions (e.g. objectscript).

🤖 Generated with Claude Code

ankitsusheel and others added 3 commits July 19, 2026 21:33
Vendor CodeAnt-AI/tree-sitter-vb-dotnet (MIT, ABI 15, no external
scanner) pinned at cfca210, as internal/cbm/vendored/grammars/vb_dotnet/.

parser.c is regenerated (tree-sitter-cli 0.25.6) from a locally patched
grammar.js: upstream at the pinned commit cannot parse several core
VB.NET forms — next-line/colon Inherits/Implements clauses, Handles
clauses, AddHandler/RemoveHandler/RaiseEvent statements, As New
initializers, member-level #Region directives, nested types, and
attribute-with-line-continuation before declarations (the standard
WinForms Designer file shape). The full diff against upstream is
vendored as vb_dotnet/grammar.js.patch alongside the patched grammar.js;
MANIFEST.md documents the re-vendor procedure.

Upstream declares MIT in package.json/tree-sitter.json but ships no
LICENSE file; the vendored LICENSE carries the standard MIT text for
the declared license, per the move/zsh convention in MANIFEST.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Ankit Susheel <ankitsusheel@gmail.com>
Register CBM_LANG_VISUALBASIC (.vb, display name "VB.NET") with a
lang_specs.c row (CBM_LANG_CSHARP as template) over the vb_dotnet
grammar's node kinds, plus the per-language handling the generic
paths cannot cover:

- extract_defs.c: VB blocks have no body wrapper node — find_class_body
  returns the block itself and push_class_body_children routes through
  the nested-class scan so members are not double-extracted as top-level
  functions. interface_block/enum_block get Interface/Enum labels
  (Module/Structure stay Class, matching the C# struct labeling).
  Sub New constructors carry no name node — emitted as Method "New"
  via a new push_method_def_named split of push_method_def.
  Base classes are collected from inherits_clause/implements_clause
  type children (generic (Of T) suffixes stripped), which feeds the
  existing generic INHERITS-vs-IMPLEMENTS decision in pass_semantic.c.
  Fields/properties: field_declaration declarators and
  property_declaration emit Field defs with the as_clause type
  (including the As New shorthand), so WinForms WithEvents controls
  become graph nodes and Handles/AddHandler identifier references
  resolve to them as USAGE edges via the existing usage machinery.

- extract_calls.c: invocation carries its callee in a target field
  (identifier or member_access) and new_expression in type;
  Me./MyClass. receivers are stripped so self-calls resolve like bare
  same-class calls.

Namespaces stay QN-transparent, matching the established C# behavior.
Partial classes keep one node per file (path-derived QNs), also
matching C#.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Ankit Susheel <ankitsusheel@gmail.com>
…ADME

Eleven extraction tests (declarations incl. WinForms Designer shapes,
class-scoped method QNs, next-line Inherits/Implements, dotted external
bases, Sub New constructors, calls incl. Me-receiver stripping and
As New, #Region tolerance, Handles/AddHandler with the AddressOf
handler reference, imports, nested classes), a grammar-regression
fixture row, a label golden, and .vb detection tests. README gains
VB.NET in the "Also supported (not yet benchmarked)" tier and the
language count moves 158 -> 159.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Ankit Susheel <ankitsusheel@gmail.com>
@ankitsusheel
ankitsusheel requested a review from DeusData as a code owner July 19, 2026 13:02
cppcheck(knownConditionTrueFalse):
- extract_defs.c: remove redundant inner `if (base[0])` — base[0] is
  guaranteed non-zero inside the outer `if (base && base[0])` guard;
  the intervening *paren='\0' only truncates mid-string.
- extract_calls.c: simplify `return t[0] ? t : NULL` to `return t`
  for the same reason — t[0] is always true at that point.

license-gate(audit-license-provenance):
- Add vb_dotnet to SPECIAL_NOTICE so the byte-identity audit resolves
  it as MANUAL-VERIFIED instead of ERROR.  Upstream
  CodeAnt-AI/tree-sitter-vb-dotnet declares MIT in package metadata
  but ships no LICENSE file; the vendored LICENSE carries the standard
  MIT text (matching the move/zsh convention used for pine/ISC).

Signed-off-by: Ankit Susheel <ankitsusheel@gmail.com>
clang-format-20 requires the opening brace on its own line when the
array initializer spans multiple lines; the previous column-aligned
style triggered [-Wclang-format-violations].  Auto-corrected with
clang-format; verified lint-ci passes locally.

Signed-off-by: Ankit Susheel <ankitsusheel@gmail.com>
@DeusData DeusData added the enhancement New feature or request label Jul 19, 2026
@DeusData DeusData added this to the 0.9.2-rc milestone Jul 19, 2026
@DeusData DeusData added parsing/quality Graph extraction bugs, false positives, missing edges language-request Request for new language support priority/backlog Valuable contribution, lower scheduling urgency; review when maintainer capacity opens. security Security vulnerabilities, hardening labels Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request language-request Request for new language support parsing/quality Graph extraction bugs, false positives, missing edges priority/backlog Valuable contribution, lower scheduling urgency; review when maintainer capacity opens. security Security vulnerabilities, hardening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add VB.NET (.vb) tree-sitter structural extraction

2 participants