fix(resolver-vba): decline runtime-object call stubs; preserve shadow user classes (#110) - #113
Merged
Merged
Conversation
… user classes (#110) The post-extraction VBA call-stub resolver pointed every `Receiver.Member` call that lacked a same-file declaration at itself (via the synthetic stub's own qualifiedName). For runtime objects (DAO, FileSystemObject, ListBox, Collection, err, DoCmd, VBA, ...) the "stub target" was never user code, so consumer SQL filters like `WHERE stub=true` returned self-referential noise (issue #109/110: gestion_riesgos PR #117 was rolled back for exactly this). This change runs the two-step name resolution FIRST so a user class or module that happens to share a runtime-object name (a "shadow" user class named, e.g., `DAO`) is still repointed like any other real symbol (FR-2.1). When no real target exists, the resolver now classifies the decline: - `declined-runtime` — receiver is a runtime object, kept stub:true - `declined-ambiguous` — 2+ real candidates, kept stub:true - `declined-not-found` — genuine miss, kept stub:true - `reponted-to-real` — edge repointed, stub:false The decision is recorded on every stub edge as `metadata.repointDecision` for observability (FR-3.1/3.2). Scope: - NEW: src/resolution/vba-runtime-objects.ts — canonical lowercase list of runtime receivers + `isRuntimeObject()` helper. - MOD: src/resolution/index.ts — `resolveVbaCallStubTarget` now returns a `StubResolution { decision, target? }`; the orchestrating `resolveVbaCallStubs` stamps `repointDecision` on every stub edge (repointed: `reponted-to-real`; declined: keeps `stub:true` + the matching decline label) and exports the `RepointDecision` type. - NEW: __tests__/extraction-vba-stub-resolver.test.ts — 6 RED-then- GREEN tests (1, 4, 5 fail before the resolver change; 2, 3 mirror tests 6.1/6.2 to keep the existing real-fixture contract; 6 is the meta-classification case). - MOD: CHANGELOG.md — `[Unreleased] → Fixes` entry referencing #110. FR checklist: - FR-1.1 Runtime-object list in canonical file (18 seeds). - FR-1.2 Two-step first; runtime skip only when no real target. - FR-1.3 Single source of truth (canonical file); the VBA extractor's own RUNTIME_RECEIVER_BLACKLIST in src/extraction/vba/constants.ts is intentionally NOT wired to the canonical file because AC-4 requires `src/extraction/vba/*` to have 0 diff. The two lists coexist: the extractor suppresses stub SYNTHESIS (PascalCase, short pre-filter), the resolver suppresses stub REPOINTING (lowercase, post-extraction safety net). Documented in the canonical file's header. - FR-2.1 Shadow user class preserved: `DAO.Execute` on a user `.cls` named `DAO` -> repointed-to-real (verified by Test 4). - FR-3.1, FR-3.2 `repointDecision` + exported `RepointDecision` type. - FR-4.1 0 diff in src/extraction/vba/*, src/db/schema.sql, package.json. - FR-5.1 Tests 6.1-6.6 in extraction-vba-realfixtures.test.ts stay green. - FR-7.1 Genuinely-missing callee preserved (Test 5): edge keeps stub:true, decision = 'declined-not-found', exactly one row. Tests (npm test, 2824 total): - baseline (pre-change): 2764 passed, 2 failed, 52 skipped (npm-sdk.test.ts requires a packaged npm bundle; pre-existing, unrelated). - post-change: 2770 passed, 2 failed, 52 skipped (same 2 npm-sdk failures, unchanged; +6 new tests, all green). - npx tsc --noEmit: clean. Supersedes #109 (the original runtime-object hypothesis, which proposed a NEW resolver pass that already exists at src/resolution/index.ts:1867). Closes #110.
This was referenced Jul 13, 2026
fix(extractor-vba): post-extraction resolver repoints stub:false synthetic call edges (round-4)
#109
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #110 (supersedes #109). The post-extraction VBA call-stub resolver in codegraph-vba was emitting
stub:truefor ALLReceiver.Membercalls whose target didn't match an existing function node by qualified_name — including runtime-object calls likeDAO.Execute,fso.GetFileName,ListBox.AddItem,Collection.Add,err.Raise,VBA.DoEvents. These are NEVER user code, so the consumer'sWHERE stub=truefilter returned self-referential noise (the synthetic stub's own qualified_name matches itself). gestion_riesgos PR #117 was rolled back for exactly this.This change runs the existing two-step name resolution FIRST and only classifies the receiver as a runtime object when no real target was found. A user class or module that happens to share a runtime-object name (e.g. a user
.clsactually namedDAO) is still repointed like any other real declaration. Every stub edge now carries ametadata.repointDecisionfield so consumers can tell a runtime-object decline apart from a genuinely-missing callee.What's in
src/resolution/vba-runtime-objects.tswith the lowercased runtime-object list andisRuntimeObject()helper.src/resolution/index.ts—resolveVbaCallStubTarget()returns aStubResolution { decision, target? }; the orchestratingresolveVbaCallStubs()stampsrepointDecisionon every stub edge (repointed:reponted-to-real, stub:false; declined: keepsstub:true+ the matching decline label). NewRepointDecisiontype is exported.__tests__/extraction-vba-stub-resolver.test.ts— 6 tests (5 active + 1 meta-classification). RED→GREEN documented in commit body.What's deferred
Acceptance
npm test— 2770 green (2764 pre-existing + 6 new), 2 failed (pre-existingnpm-sdk.test.tsbundle packaging failures, unchanged from baseline; requirenpm run build+scripts/pack-npm.shflow), 52 skipped.npx tsc --noEmitclean.src/db/schema.sql0 diff).src/extraction/vba/*0 diff). The new file lives insrc/resolution/, not in the extractor.[Unreleased] → Fixes. No pre-staged[X.Y.Z]block. Nopackage.jsonbump (maintainer handles).Closes #110. Supersedes #109.