Skip to content

feat(generator): intercept calls whose types generated code cannot name - #167

Merged
glennawatson merged 1 commit into
mainfrom
fix/generate-calls-with-unnameable-types
Oct 4, 2026
Merged

glennawatson merged 1 commit into
mainfrom
fix/generate-calls-with-unnameable-types

Conversation

@glennawatson

Copy link
Copy Markdown
Contributor

Summary

The generator now intercepts calls whose types it could not name before, and fails the build at any call it still cannot generate.

  • Calls whose selector result is an anonymous type or a private nested type are intercepted. The result type becomes a generic parameter.
  • Calls on private or protected types and members are intercepted from inside the caller's partial class, which hosts the generated code in a private nested class.
  • Calls made through the caller's type parameters, such as a generic view base or a receiver typed T, are intercepted with code that is generic over them.
  • A call that cannot be intercepted, on the Roslyn 4.8 build or with interceptors off, is now a build error at the call instead of a warning followed by a throw at run time.
  • Anonymous result types, file-local types and BindCommand with a stored parameter expression no longer produce broken generated code.

Why

A call naming a type the generated code could not reach was skipped with a warning, and the call then threw InvalidOperationException at run time. An anonymous result type was not skipped at all, and the generator wrote the anonymous type's display name into the generated source, which then failed to compile.

Breaking changes

RXUIBIND001, 003, 006, 009, 012, 013, 015, 016 and 021 are now errors. Every call they report already threw at run time, so only code that was already broken stops compiling. To fix such a call, make the types or members it uses reachable (internal, or inside a partial class), or call the matching *Unsafe method. RXUIBIND021 stays a warning when the member is declared only by another source generator. This ships as a minor release.

How this was verified

New generator, analyzer and runtime tests cover each intercepted shape with real values for every generated API, the error path on the Roslyn 4.8 build and with interceptors off, and the shapes that still cannot be intercepted. The AOT example could not be linked locally without clang.

Notes for the reviewer

Start with Helpers/CallSiteHosting.cs and InvocationPipeline.cs, which decide whether a call is intercepted with a generic result, hosted in the caller's partial class, or reported. CodeGeneration/HostedCallSiteEmitter.cs and HostedSourceReader.cs emit the hosted code. The per-API emitters are unchanged. The analyzer changes skip any call the generator intercepts, and the AnalyzerReleases files record the severity changes. The test and snapshot files are mechanical.

Checklist

  • I have read the Contribute guide
  • The PR title follows Conventional Commits
  • Tests cover this change, or the summary says why they do not
  • New or changed public API has XML documentation

- Intercept calls whose selector result is an anonymous or private type, by taking the result type as a generic parameter.
- Intercept calls on private or protected types and members from inside the caller's partial class, by placing the generated code in a private nested class of that class.
- Intercept calls made through the caller's type parameters, by generating code that is generic over them.
- Fail the build at the call when it cannot be intercepted. RXUIBIND001, 003, 006, 009, 012, 013, 015, 016 and 021 are errors. Every call they report throws at run time.
- Keep RXUIBIND021 a warning for a member that only another source generator declares.
- Stop emitting broken code for anonymous result types, file-local types and BindCommand with a stored parameter expression.
@glennawatson
glennawatson enabled auto-merge (squash) October 4, 2026 01:57
@codecov

codecov Bot commented Oct 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.84917% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 99.28%. Comparing base (cbb8e3c) to head (ab95a7b).

Files with missing lines Patch % Lines
...g.SourceGenerators/Helpers/InteractionExtractor.cs 93.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #167      +/-   ##
==========================================
+ Coverage   99.23%   99.28%   +0.04%     
==========================================
  Files         396      403       +7     
  Lines       14469    15028     +559     
  Branches     2065     2227     +162     
==========================================
+ Hits        14359    14920     +561     
+ Misses        110      108       -2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@sonarqubecloud

sonarqubecloud Bot commented Oct 4, 2026

Copy link
Copy Markdown

@glennawatson
glennawatson merged commit 6609f8e into main Oct 4, 2026
23 checks passed
@glennawatson
glennawatson deleted the fix/generate-calls-with-unnameable-types branch October 4, 2026 02:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant