mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-30 06:42:43 +00:00
U10. Wires the fold into resolution. Three TypeScript receiver spellings that
emitted no CALLS edge now resolve:
svc?.getUser().save()
svc!.getUser().save()
svc.getTyped<User>().save()
WIRED IN ONE PLACE, not four. The fold runs at the top of
`resolveCompoundReceiverClass`, ahead of the text cascade, so every caller
inherits it — Case 0, the Case 4 fallback, and the duplicate walk alike — rather
than four call sites each having to remember. Only at `depth === 0`: the chain
describes THIS site's receiver, not the inner expressions the cascade recurses
into. A failed fold falls THROUGH rather than returning, so structure is an
additional route to an answer and never a veto on the existing one.
Group A only, which settles U11 by construction. The two sites that consume
`typeRef.rawName` cannot be routed: they have no reference site in scope, so
there is no `receiverChain` to pass. That is not a decision deferred, it is the
shape of the code — Group B needs the type-binding capture layer to carry
structure, which is a separate piece of work. U12 needs no code either: the
`gitnexus-shared` registry `lookupReceiverType` is a name-keyed map miss, not a
text-sniff site, and threading the fold into `RegistryContext` would be a shared
contract change across `LookupParams` and both registry option types.
`extractMixedChain` also needed a transparent-wrapper unwrap. For `svc!` the walk
reached `non_null_expression`, which is not a chain node, so the wrapper's own
TEXT became the base — `"svc!"`, matching no binding, silently costing the chain
its base. `non_null_expression` and `parenthesized_expression` denote exactly
their operand and are now read through. A cast is deliberately NOT unwrapped:
`x as T` changes the type an expression denotes, so reading through one would
type the receiver as the operand instead of the cast target.
`INCREMENTAL_SCHEMA_VERSION` 25→26 lands HERE, at the first commit where edge
semantics change. A changed-files top-up against a pre-v26 index keeps the
pre-fix graph for every unchanged file — and worse than merely incomplete, the
drop summary is a whole-repo recompute while the edges are a changed-files
write, so the two would actively disagree. The reuse-gate ladder test is updated
with that rationale; it is the guard that caught the missing bump.
MEASURED, and the result is the argument for how this was measured. The three
shapes flipped to RESOLVES while the call-drop count did not move at all: 99
before, 99 after. The committed fixture corpus contains none of those three
spellings, so a gate reading only the drop count would have scored this as "no
improvement" and stopped the series. No edge was lost and no new drop appeared.
Two shapes remain unresolved, both genuinely and both recorded rather than
glossed: `(await svc.getUserAsync()).save()` (the walk reaches `await …`, not a
chain node) and `repos[0].save()` (Case 0's punctuation gate never fires for a
subscript receiver).
One test changed meaning rather than breaking. The #2744 drop-recorder test used
`svc!.getUser().save()` as its call-kind example; that shape now resolves, so
there is no drop to record. It moves to the await-parenthesized shape, which
still drops. The write case is untouched — a write receiver mints no chain at
all, since the emitter gates on CALL_TAGS — so calls and writes stay separable,
which was the point of the test.
334 tests green across all six touched suites.
|
||
|---|---|---|
| .. | ||
| fixtures | ||
| helpers | ||
| integration | ||
| unit | ||
| utils | ||