Skip to content

test(scanner): confirm --strict-types closes #16, transitive factory wrapping#29

Merged
flaglint merged 2 commits into
mainfrom
test/strict-types-transitive-factory
Jul 7, 2026
Merged

test(scanner): confirm --strict-types closes #16, transitive factory wrapping#29
flaglint merged 2 commits into
mainfrom
test/strict-types-transitive-factory

Conversation

@flaglint

@flaglint flaglint commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #16. This is a test-only PR — no new resolution logic needed.

Issue #16: a cross-package factory function (wrapper.NewClientWrapper) whose declared return type isn't *ld.LDClient directly but a wrapper struct with a client field — Phase 1 doesn't register it as a factory at all (its return type doesn't match), so w.Inner.BoolVariation(...) goes undetected even though w.Inner really is a client.

Turns out no new resolution logic was needed — found while building this regression test, not before. resolveByStaticType (added in the --strict-types Phase 2a work that closed #15, PR #28) checks any expression's real static type against the SDK client type, not just an assignment's RHS. A field selector like w.Inner is exactly such an expression: go/types reports its type the same way regardless of how the struct it's read from was constructed, so the interface-satisfaction fix already resolves this transitive-factory case as a natural consequence.

What changed

Verification

  • Full test suite green.
  • Re-verified against weaviate: same 4 real usages, no regressions, no --strict-types warnings.

…wrapping

Issue #16: a cross-package factory function (wrapper.NewClientWrapper)
whose declared return type isn't *ld.LDClient directly but a wrapper
struct with a client field — Phase 1 doesn't register it as a factory at
all (its return type doesn't match), so w.Inner.BoolVariation(...) goes
undetected even though w.Inner really is a client.

Turns out no new resolution logic was needed — found while building this
regression test, not before. resolveByStaticType (identity.go, added in
the --strict-types Phase 2a work that closed #15) checks *any*
expression's real static type against the SDK client type, not just an
assignment's RHS. A field selector like w.Inner is exactly such an
expression: go/types reports its type the same way regardless of how the
struct it's read from was constructed, so the interface-satisfaction fix
already resolves this transitive-factory case as a natural consequence.

Added a real, buildable fixture (testdata/strict/transitive_factory,
cross-package: wrapper + consumer, same local-replace-stub-SDK pattern as
the interface_satisfaction fixture) reproducing issue #16's exact repro,
and a regression test proving Phase 1 misses it while ScanStrict finds it
correctly. Re-verified against weaviate: same 4 real usages, no
regressions, no --strict-types warnings.

Fixes #16

Signed-off-by: Krishan Kant Sharma <krishansharma0327@gmail.com>
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@flaglint, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 44 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1f5e08df-3db6-4e49-a198-843bbd2bbf81

📥 Commits

Reviewing files that changed from the base of the PR and between 1540c0a and 830e564.

📒 Files selected for processing (7)
  • internal/scanner/strict_test.go
  • internal/scanner/testdata/strict/transitive_factory/consumer/.gitignore
  • internal/scanner/testdata/strict/transitive_factory/consumer/main.go
  • internal/scanner/testdata/strict/transitive_factory/go.mod
  • internal/scanner/testdata/strict/transitive_factory/stubsdk/client.go
  • internal/scanner/testdata/strict/transitive_factory/stubsdk/go.mod
  • internal/scanner/testdata/strict/transitive_factory/wrapper/wrapper.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/strict-types-transitive-factory

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Suggested by independent review of the previous commit: the one-hop
fixture (w.Inner.BoolVariation) proves resolveByStaticType resolves a
single field-selector hop, but doesn't explicitly prove the mechanism
generalizes to a deeper chain rather than happening to work by
coincidence for exactly one hop.

Added OuterWrapper (wrapper.go) — Middle *ClientWrapper, two hops removed
from the SDK client — and runTwoHop (consumer/main.go), evaluating
o.Middle.Inner.BoolVariation(...). Confirmed: resolves correctly with no
new code, exactly as expected, since resolveByStaticType queries
go/types.Info.TypeOf for the whole expression's real type directly rather
than manually walking one hop at a time (that manual walking is Phase 1's
syntax-only structFieldTypes chain resolution, never invoked once
typesInfo is populated). Phase 1 still correctly misses both call sites
(confirmed by the test, not assumed).

Signed-off-by: Krishan Kant Sharma <krishansharma0327@gmail.com>
@flaglint flaglint merged commit a645d12 into main Jul 7, 2026
13 checks passed
@flaglint flaglint deleted the test/strict-types-transitive-factory branch July 7, 2026 19:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants