Skip to content

Use extension-member polyfills across libraries - #136221

Merged
eiriktsarpalis merged 10 commits into
dotnet:mainfrom
eiriktsarpalis:eiriktsarpalis-stj-extension-polyfills
Oct 22, 2026
Merged

eiriktsarpalis merged 10 commits into
dotnet:mainfrom
eiriktsarpalis:eiriktsarpalis-stj-extension-polyfills

Conversation

@eiriktsarpalis

@eiriktsarpalis eiriktsarpalis commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Use C# extension-member polyfills to consolidate framework-compatibility code across src/libraries, following #136156. Call sites use framework API names while downlevel implementations remain in internal polyfill containers. Targets that already provide a member continue to bind to the framework implementation.

The cleanup extends beyond System.Text.Json and its source generator to CBOR, Metadata/NRBF, xxHash, Packaging, Dataflow, MEF2, DiagnosticSource, Server-Sent Events, and several Microsoft.Extensions libraries. It includes:

  • Shared static-member and property polyfills for type and enum inspection, bit and endian conversions, multiplication, array limits, elapsed time, Unix epoch, and platform checks.
  • Reuse of existing span, collection, stack, string, decimal, and uninitialized-object polyfills instead of local compatibility helpers and conditional branches.
  • Standard argument guards in place of equivalent manual checks, preserving validation order and parameter names.
  • The same consolidation in existing CBOR tests and shared assertion utilities, removing the paired CBOR test-helper files without adding test coverage.

The source generator's IsClosed helper is expressed as an extension property while retaining its existing Roslyn light-up and syntax-fallback behavior. There are no public API changes or new test cases.

Initial Release validation passed .\build.cmd libs -rc Release -lc Release /p:RunAnalyzersInBuild=true /p:RunILLinkInBuild=true, followed by targeted compatibility builds and existing test-suite runs on CoreCLR and .NET Framework. Subsequent review adjustments were covered by targeted rebuilds and tests.

Note

This pull request was generated with GitHub Copilot.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3c692d8a-03a2-4ed9-b337-2066c25a3cb6
@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 and others added 3 commits October 21, 2026 16:55
Retain VolatilePolyfills alongside the STJ compatibility polyfills.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3c692d8a-03a2-4ed9-b337-2066c25a3cb6
Remove the unused nDigits temporary from AreEqualJsonNumbers while retaining the length comparison. This fixes IDE0059 in analyzer-enabled builds.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3c692d8a-03a2-4ed9-b337-2066c25a3cb6
Replace five manual null guards and remove the unused shared ThrowHelper. Preserve exception parameter names and writer disposal-check precedence, with public API coverage.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3c692d8a-03a2-4ed9-b337-2066c25a3cb6
@eiriktsarpalis eiriktsarpalis changed the title Use extension-member polyfills in System.Text.Json Use extension-member polyfills across libraries Oct 21, 2026
Comment thread src/libraries/System.Text.Json/gen/Helpers/RoslynExtensions.cs
Replace duplicated compatibility helpers and conditional branches with framework-shaped calls. Reuse the polyfills in existing CBOR tests and shared assertions without adding test coverage.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3c692d8a-03a2-4ed9-b337-2066c25a3cb6
@dotnet-policy-service dotnet-policy-service Bot added the linkable-framework Issues associated with delivering a linker friendly framework label Oct 21, 2026
Comment thread src/libraries/Common/src/Polyfills/ArrayPolyfills.cs Outdated
eiriktsarpalis and others added 2 commits October 21, 2026 23:10
The only caller, ImmutableArray<T>.Builder.Reverse, supplies a valid range.
Keep the null check and let AsSpan perform any range validation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3c692d8a-03a2-4ed9-b337-2066c25a3cb6
Restore ImmutableArray<T>.Builder.Reverse and ArrayPolyfills to their original
implementations. The span-based shim changes behavior for covariant arrays,
so leave this migration out of the compatibility cleanup.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3c692d8a-03a2-4ed9-b337-2066c25a3cb6
Comment thread src/libraries/Common/src/Polyfills/DateTimeOffsetPolyfills.cs
@eiriktsarpalis

Copy link
Copy Markdown
Member Author

/ba-g test failure is unrelated.

Move the existing array-swap loop into the downlevel Array.Reverse<T> polyfill.
Preserve covariant arrays and delegate invalid inputs to the existing BCL
overload. Use the generic API spelling in ImmutableArray<T>.Builder.Reverse.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3c692d8a-03a2-4ed9-b337-2066c25a3cb6
@eiriktsarpalis
eiriktsarpalis requested a review from jkotas October 22, 2026 07:25
eiriktsarpalis and others added 2 commits October 22, 2026 10:48
Remove the extra validation and non-generic Array.Reverse delegation.
The reversal polyfill now contains only the original array-swap loop.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3c692d8a-03a2-4ed9-b337-2066c25a3cb6
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 3c692d8a-03a2-4ed9-b337-2066c25a3cb6
@eiriktsarpalis

Copy link
Copy Markdown
Member Author

/ba-g test failure is unrelated

@eiriktsarpalis
eiriktsarpalis merged commit 132d071 into dotnet:main Oct 22, 2026
113 of 115 checks passed
@eiriktsarpalis
eiriktsarpalis deleted the eiriktsarpalis-stj-extension-polyfills branch October 22, 2026 12:12
@drieseng

drieseng commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

@eiriktsarpalis: I only had a very brief look at the changes, but it seems you're not conditionally including the polyfilld for those target(framework)s where they are effectively necessary. Does Roslyn automatically "filter" these out (hereby reducing code size)?

@jkotas

jkotas commented Oct 23, 2026

Copy link
Copy Markdown
Member

@drieseng We minimize the maintenance burden for packages targeting .NET Framework and other older runtimes. As a result, these packages may include some unreachable polyfills. This is by design.

@eiriktsarpalis

Copy link
Copy Markdown
Member Author

it seems you're not conditionally including the polyfilld for those target(framework)s where they are effectively necessary. Does Roslyn automatically "filter" these out (hereby reducing code size)?

Not sure what you mean by this, the polyfill source files are included conditionally.

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

Labels

area-System.Text.Json linkable-framework Issues associated with delivering a linker friendly framework

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants