Skip to content

Commit b2f23f8

Browse files
ardelperalclaude
andauthored
feat(vba): record each procedure's error policy (#287)
* feat(vba): record each procedure's error policy Nothing in the graph recorded how a procedure handles errors, and neither of the two questions that matters is greppable: an ABSENCE scoped to a procedure body has no text to match, and whether an `On Error Resume Next` is ever closed depends on the whole body rather than on any one line. In this corpus that hides 816 procedures with no protection at all and 516 procedures whose suppression scope runs to the `End Sub`. Every procedure's `function` node now carries an `errorPolicy` object: `protection`, `handlerLabel`, `handlerStartLine`, `handlerEndLine`, `behavior`, `handlerCount`, `resumeNextOpen` and `danglingTarget`. Decisions taken: - ZERO new node kinds and ZERO new edge kinds. Section 4 of `docs/vba-error-handling-plan.md` rejects a `label` node plus a `handles-error` edge because 96.5% of the corpus's 3,911 line labels are the same label (`errores`) doing the same job — one bit, which belongs in a field. Measured on the corpus: 14,649 nodes / 21,361 edges / 26,613 unresolved references before and after, byte-identical. - A label defined but never targeted by an `On Error GoTo` is CONTROL FLOW, not a handler. 137 labels in the corpus are exactly that (`siguiente`, `salir`, `fin`). Reporting one as a handler would give a confidently wrong answer to "does this procedure handle errors", the worst failure mode available here, so a label only opens a handler region when an `On Error GoTo` in the SAME procedure names it. - Every rule scans the MASKED line, so `s = "On Error GoTo errores"` sets nothing (the #209 discipline), and the procedure body's END is the existing `PROCEDURE_END_RE` — the same constant the `proc-end` rule in `enums-consts.ts` dispatches — rather than a second end detector, which is what makes the colon-separated single-line procedure form (#208) work here for free. The body's START is the node the procedures pre-walk already emitted, so there is no second `PROC_RE` dispatch either. - The classifier agrees with `scripts/vba-coverage-probe.mjs` by construction: same label regex, same statement-keyword guard, and the same treatment of `On Error GoTo 0` / `-1` as resets and of every other target as a handler label. Its `protection` census reproduces the probe's exactly — 3,774 handler / 227 resume-next / 816 none over 4,817 procedures. - `On Error GoTo -1` is valid VBA (it clears the current error) and appears 0 times in the corpus. It is treated as a reset and pinned by a fixture so the zero-occurrence case cannot rot untested. - `behavior` is deliberately left null. It is derived in E3, where the handler body's calls are already being classified; guessing it here would be fabrication. The classifier's `count` stays at 0 for its whole life, so a file whose only content is an `On Error` statement is still a file with no symbols and gains no module node. Closes #259 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019gmKKUq1ng5ESk6Qhxu77d * docs(vba): correct the E2 dangling-target acceptance to the measured 0 The E2 acceptance line predicted exactly one dangling handler target in the corpus, carried over from the pre-probe hand census. E1 landed the committed probe and its reconciliation table already records the measured figure as 0; this line was the last place still asserting 1, so the implementer of E2 was being asked to find something that is not there. The corpus does contain a handler literally named `noExiste`, defined in its own procedure and therefore correctly not dangling — almost certainly what the hand census mistook for an unresolved target. The protection distribution on the same line is updated to the measured 3,774 / 227 / 816 for the same reason. Refs #259 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019gmKKUq1ng5ESk6Qhxu77d --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent e6fd728 commit b2f23f8

7 files changed

Lines changed: 1033 additions & 9 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
2121
- Every parameter a VBA procedure declares is now its own symbol in the graph, linked to the procedure that owns it and to the class it is typed as, so you can ask which procedures take a given class and follow it from there. (#257)
2222
- SQL that a form or control is bound to at runtime — assigned to `RowSource`, `RecordSource`, `ControlSource`, `Filter` or `OrderBy` — now shows the tables it reads, whether the statement is written inline or built up in a variable first. (#252)
2323
- Access domain functions such as `DLookup` and `DCount` now record the table or saved query they read, so a procedure that touches data only through them no longer looks like it touches no data at all. (#255)
24+
- Procedures now record how they handle errors — whether they have a handler, silently suppress errors, or have no protection at all — so unguarded code paths can be found without reading every module. (#259)
2425

2526
### Changed
2627

0 commit comments

Comments
 (0)