mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-11 03:38:07 +00:00
hedging on registrations the analyzer already followed Five findings from the review bot on #3219; four valid, all addressed. 1. QUALIFIED VALUE REFERENCES RESOLVED BY TAIL NAME (the serious one). `bridge.accessor(Element.getNamespaceUri, …)` was resolved with `findCallableBindingInScope(site.inScope, site.name, …)`, which never sees the receiver and gives LOCAL bindings precedence. Reproduced: const Element = @This(); pub fn getThing(...) // main.getThing pub const JsApi = struct { fn getThing(...) // JsApi.getThing pub const thing = bridge.accessor(Element.getThing, null, .{}); }; emitted `USES JsApi → JsApi.getThing` — a WRONG edge, which is worse than the missing edge this PR set out to fix. `resolveValueRefTarget` now resolves a site carrying an explicit receiver through `findClassBindingInScope` → `findOwnedMember` (the machinery `receiver-bound-calls` already uses), gated on `CALL_TARGET_TYPES` because `findOwnedMember` also answers with fields. A bare site keeps the lexical walk, which is what an unqualified name means. When the owner cannot be resolved the site is DECLINED rather than falling back: declining costs a reference, falling back mints a confident edge to the wrong function, and the missing reference is now reported as `lower-bound` anyway. Cost on lightpanda-io/browser: value-ref edges 3,169 → 2,799 (−12%). Those 370 were tail-name coincidences, not registrations — all 94 `Element.zig` `JsApi` entries survive, the cross-container case resolves and is correctly attributed (`IntersectionObserverEntry.JsApi` → `IntersectionObserverEntry. getTarget#0`, not the enclosing observer), and both acceptance probes are unchanged: `getNamespaceUri` 7/3/LOW/lower-bound, `getTagNameLower` 31/10/HIGH/exact. 2. A FAILED PROBE READ AS "NO BOUNDARY". `.catch(() => [])` turned an unanswerable query into count 0 and no note, so `exact` could be published on the strength of a question that was never asked. It now returns `null` and emits a boundary note. This file's own `loadMeta` comment states the rule: a probe failing must never read as certainty. 3. NOT EVERY VALUE REFERENCE IS AN UNMODELLED INVOCATION. Where `emitPropertyDispatchCalls` sweep 2 synthesized the dispatch (reason `property-dispatch`), the walk did NOT provably miss the caller, so hedging was noise over an answer that was computed — and a signal that fires on every JS/TS hook table stops carrying information. A second probe excludes those targets. Zig never sets a property key, so the motivating case is untouched. The exclusion is symbol-level, not per-edge, because the graph does not record which registration produced which synthesized call; that residual is documented at the call site. 4. `LIMIT 50` SILENTLY UNDERSTATED THE COUNT. `rows.length` over a capped row set published a ceiling as the documented symbol count. Replaced with `COUNT(DISTINCT other.id)` — bounded work without a bounded answer, the shape `countByType` in the same file already uses. 5. THE TEST DID NOT PIN THE CALLER COUNT its own comment promised. Added `expect(result.impactedCount).toBe(2)`. New regression tests: qualified references bind the written owner and not the nearer lexical match; an unresolvable receiver emits nothing rather than a wrong edge; a dispatch-modelled registration stays `exact`; a probe that cannot run hedges instead of claiming certainty. Known limitation, pinned by a test rather than left implicit: when a `@This()` alias's NAME differs from its container's (`const Element = @This();` inside `main.zig`), the receiver does not resolve and the reference is declined. The provider has `rewriteZigThisAlias` for this, but it is applied to type nodes and extending it to reference receivers would change existing CALL-site behaviour. Lightpanda's `const Foo = @This();` in `Foo.zig` convention makes the names coincide, which is why the corpus is unaffected. |
||
|---|---|---|
| .. | ||
| fixtures | ||
| helpers | ||
| integration | ||
| unit | ||
| utils | ||