fix(scanner): detect same-scope method values, closing #6#25
Conversation
f := client.BoolVariation; f("flag", nil, false) was not detected —
detection required the method to be called directly through a selector
expression at the call site itself, not via an intermediate variable
holding just the method value.
Added a new binding kind, methodValueBinding (identifier -> SDK version +
method name), tracked by walkScoped with the exact same block-scoped
lexical-shadowing semantics as regular client bindings (issue #5's fix) —
scopeBindings now bundles both kinds together in one struct so a single
push/pop always moves them in lockstep, since they share the same scoping
rules. bindLocalValue recognizes `f := client.BoolVariation` (a bare
selector, no call parens, receiver already a proven client, method name a
recognized SDK method) and binds f as a method value; anything else
continues to unbind both kinds for that name, exactly as before for plain
client bindings.
fileDetector.detect now resolves a call's version+method name via either
path: the existing selector-expression receiver resolution, or (new) a
bare-identifier call resolving through methodValues.
Deliberately narrow, matching the issue's own repro: only a plain
identifier receiver is recognized (`client.BoolVariation`), not a
struct-field chain (`obj.field.BoolVariation`). A method value passed
*across a function boundary* — captured in one function, called from
inside a different one it was passed into, which is the shape a real
e2b-dev/infra field-testing repro actually needed (see the comment on
#6) — is NOT resolved by this fix; that's a meaningfully larger
interprocedural-propagation problem, filed separately rather than
silently left unaddressed.
Verified: new fixtures prove the same-scope repro is detected, a
false-positive guard proves an unrelated same-named method value isn't,
and a combined fixture proves method-value bindings correctly follow the
same block-scoped shadowing rules as client bindings. Full test suite
green. Re-verified against weaviate (unchanged, 4 real usages, no
regression) and e2b-dev/infra (still correctly 0 — its cross-function
case remains open, as scoped above).
Fixes #6
Signed-off-by: Krishan Kant Sharma <krishansharma0327@gmail.com>
|
Warning Review limit reached
Next review available in: 25 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Closes #6 (the issue's own literal repro).
f := client.BoolVariation; f("flag", nil, false)was not detected — detection required the method to be called directly through a selector expression at the call site itself, not via an intermediate variable holding just the method value.What changed
methodValueBinding(identifier → SDK version + method name), tracked bywalkScopedwith the exact same block-scoped lexical-shadowing semantics as regular client bindings (scanner: block-scoped variable shadowing within a single function can cause a false positive #5's fix) —scopeBindingsnow bundles both kinds together so a single push/pop always moves them in lockstep, since they share the same scoping rules.bindLocalValuerecognizesf := client.BoolVariation(bare selector, no call parens, receiver already a proven client, method name a recognized SDK method) and bindsfas a method value; anything else continues to unbind both kinds for that name, exactly as before.fileDetector.detectnow resolves a call's version+method name via either path: the existing selector-expression receiver resolution, or (new) a bare-identifier call resolving throughmethodValues.Scope boundary (important)
Deliberately narrow, matching the issue's own repro: only a plain identifier receiver is recognized (
client.BoolVariation), not a struct-field chain. A method value passed across a function boundary — captured in one function, called from inside a different one it was passed into, which is the shape a real e2b-dev/infra field-testing repro actually needed (see the comment on #6) — is not resolved by this fix. That's a meaningfully larger interprocedural-propagation problem; I'll file it as a separate, precisely-scoped issue after this merges rather than leave it silently unaddressed under #6's now-closed title.Verification