Skip to content

Extract STJ UnsafeAccessor emitter into a shared SourceGenerators helper - #133360

Draft
svick wants to merge 1 commit into
mainfrom
svick/stj-shared-unsafeaccessor-emitter
Draft

Extract STJ UnsafeAccessor emitter into a shared SourceGenerators helper#133360
svick wants to merge 1 commit into
mainfrom
svick/stj-shared-unsafeaccessor-emitter

Conversation

@svick

@svick svick commented Sep 7, 2026

Copy link
Copy Markdown
Member

Summary

Extracts the System.Text.Json source generator's accessor-emission machinery into a new shared helper, src/libraries/Common/src/SourceGenerators/UnsafeAccessorEmitter.cs, so that other source generators can reuse it.

This is a pure refactoring with no behavior change — it is a preparatory step for giving the Microsoft.Extensions.Configuration.Binder source generator the same [UnsafeAccessor]-based accessor support (including generic-type support), which will come in a follow-up PR stacked on top of this one.

What moved

The shared helper now owns:

  • UnsafeAccessor-based property/field get/set accessors and the generic wrapper-class accessors used for members on generic types (.NET 9+).
  • The inaccessible-constructor accessor (UnsafeAccessor + reflection fallback).
  • The reflection fallback for older TFMs (net462), including the cached MemberInfo/ConstructorInfo wrappers.
  • Accessor naming, using STJ's existing scheme, parameterized by a "type-friendly name" so a different generator can supply its own identifier source.

The helper works over neutral, primitive-only spec types (UnsafeAccessorMemberSpec, UnsafeAccessorConstructorSpec, UnsafeAccessorParameterSpec) rather than STJ's own model types.

STJ's GenerateMemberAccessors and GenerateConstructorAccessor are now thin adapters that build the neutral specs and delegate to the helper. The value-type-setter/reflection-fallback contract (the ValueTypeSetter<,> delegate and BindingFlags const the emitted code references) is documented on the helper and remains emitted by the consuming generator, exactly as STJ already does.

Note

This PR description was generated by GitHub Copilot.

Move the System.Text.Json source generator's accessor-emission machinery
(UnsafeAccessor-based get/set/field accessors, constructor accessors, generic
wrappers, and the reflection fallback) into a new shared helper,
Common/src/SourceGenerators/UnsafeAccessorEmitter.cs, so other source
generators (e.g. the Microsoft.Extensions.Configuration.Binder generator) can
reuse it.

The helper works over neutral, primitive-only spec types
(UnsafeAccessorMemberSpec, UnsafeAccessorConstructorSpec,
UnsafeAccessorParameterSpec) and owns accessor naming using STJ's existing
scheme, parameterized by a type-friendly name. STJ's GenerateMemberAccessors
and GenerateConstructorAccessor become thin adapters that build the neutral
specs and delegate to the helper.

This is a pure refactoring with no behavior change: the generated output is
byte-identical, as verified by the SourceGeneratedOutputTests baselines for
both the netcoreapp (UnsafeAccessor) and net462 (reflection) code paths.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1a0d7ac2-f2a3-4526-93ab-36bf1a23933f
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-system-text-json
See info in area-owners.md if you want to be subscribed.

@eiriktsarpalis

Copy link
Copy Markdown
Member

Is this change a precondition for a #133369 fix? If the answer is yes, it may complicate the backporting process to .NET 11. I would suggest making a minimal fix for the regression first that can be backported to 11 before branching off to new infra.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants