Skip to content

chore(analyzers): update the Sharp analyzers to 3.45.0 and adopt PublicApiSharp - #164

Merged
glennawatson merged 1 commit into
mainfrom
chore/analyzers-3.45-publicapisharp
Aug 15, 2026
Merged

glennawatson merged 1 commit into
mainfrom
chore/analyzers-3.45-publicapisharp

Conversation

@glennawatson

Copy link
Copy Markdown
Contributor

What kind of change does this PR introduce?

Build / chore - analyzer package updates, a public-API tracking swap, and the code changes the newly enabled rules require.

What is the new behavior?

The Sharp analyzers move to 3.45.0, public-API tracking moves to PublicApiSharp, and the code satisfies the rules the repo already had switched on.

  • Public API baselines are now one file per target framework. Each project keeps PublicAPI/<tfm>/PublicAPI.txt, written in a C#-like declaration form, and the analyzer resolves that path itself - the AdditionalFiles wiring in Directory.Build.props is gone, replaced by EnablePublicApiBaseline.
  • Analyzer packages are current. StyleSharp / PerformanceSharp / SecuritySharp .Analyzers 3.45.0, SonarAnalyzer 10.32.0, Roslynator 4.16.0, TUnit 1.65.0, Microsoft.NET.Test.Sdk 18.9.0, Testing.Extensions.CodeCoverage 18.10.0, SourceLink 10.0.400, WindowsAppSDK 2.4.0, and the net11 AspNetCore.Components preview leg. Microsoft.CodeAnalysis.CSharp stays pinned on 4.14 for the reason recorded in Directory.Packages.props.
  • Code changes the enabled rules require, across the runtime library, the platform adapters, the tests and the benchmarks:
    • Aggressive-inlining hints on trivial forwarders, and [DebuggerDisplay] on publicly visible types.
    • <exception> elements for exceptions a member throws directly, and XML doc elements put back in conventional order.
    • One-shot bool latches converted to int + Interlocked.Exchange, so two threads can no longer both pass a check-then-set guard.
    • Trailing if bodies inverted into early-exit guards, explicit enum member values, PascalCase tuple elements, and UnsafeRegister for cancellation callbacks that do not depend on ambient context.

What is the current behavior?

  • Analyzer packages sat on 3.38.1, and a set of rules the repo's .editorconfig marks as errors had no corresponding fixes in the source.
  • Public API tracking used Microsoft.CodeAnalysis.PublicApiAnalyzers, with a PublicAPI.Shipped.txt / PublicAPI.Unshipped.txt pair per target framework and explicit AdditionalFiles items to point at them.

What might this PR break?

  • Two tuple element names in the public surface change case. Continuation.Lock<T> and Continuation.LockValueTask<T> take IObserver<(T Value, IDisposable Sync)>; the first element was value. Binary compatible, source-breaking only for code naming that element.
  • SyncTimer, Start and While on ReactiveExtensions become extension-block members, as do FromAsync and Start on SignalAsyncReactiveExtensions and DelayAsync on SignalAsyncExtensions. Instance-form and static-form calls both still bind; the emitted implementation signatures are unchanged.
  • Benchmark methods now carry an aggressive-inlining hint. Allocation figures are unaffected, but timings may shift slightly against previously recorded runs, since the harness-to-method call can now fold away.
  • Nothing else: no runtime behavior change is intended anywhere, and the interlocked-latch conversions preserve the winner-does-the-work semantics exactly.

Checklist

  • I have read the Contribute guide
  • Tests have been added or updated (for bug fixes / features)
  • Docs have been added or updated (for bug fixes / features)
  • Changes target the main branch
  • PR title follows Conventional Commits

Additional information

Most of the diff is generated. Every PublicAPI/<tfm>/PublicAPI.txt is tool output - regenerated from scratch, not hand-edited - and the bulk of the remaining files gain only an attribute, a using directive, or a doc element. The hand-written parts worth reviewing are:

  • src/Directory.Build.props and src/Directory.Packages.props - the package swap and the baseline wiring.
  • The interlocked-latch conversions, which are the only changes with concurrency semantics.
  • src/Primitives.Shared/SignalOperatorParityMixins.RxNames.SubscribeSafe.cs - carries two scoped [SuppressMessage] attributes for PAS0003. The two SubscribeSafe overloads there differ only by generic constraint (where T : class / where T : struct); the baseline records both, but an entry is resolved by the constraint-erased signature and compared against the first match, so exactly one of the pair can ever match.

The Apple target-framework baselines (ios, tvos, macos, maccatalyst) were generated on a host carrying those workloads, since Linux cannot enumerate or build them.

@codecov

codecov Bot commented Aug 15, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.18033% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 98.10%. Comparing base (420830d) to head (bacf76a).

Files with missing lines Patch % Lines
src/Primitives.Async.Shared/Operators/WitnessOn.cs 87.50% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #164      +/-   ##
==========================================
- Coverage   98.14%   98.10%   -0.05%     
==========================================
  Files         680      680              
  Lines       21432    21359      -73     
  Branches     2619     2622       +3     
==========================================
- Hits        21035    20954      -81     
- Misses        197      199       +2     
- Partials      200      206       +6     

☔ 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.

…icApiSharp

- Update StyleSharp/PerformanceSharp/SecuritySharp.Analyzers to 3.45.0, plus
  SonarAnalyzer 10.32.0, Roslynator 4.16.0, TUnit 1.65.0, Test.Sdk 18.9.0,
  CodeCoverage 18.10.0, SourceLink 10.0.400, WindowsAppSDK 2.4.0 and the net11
  AspNetCore preview leg.
- Replace Microsoft.CodeAnalysis.PublicApiAnalyzers with PublicApiSharp.Analyzers,
  collapsing the per-TFM Shipped/Unshipped baseline pair into a single
  PublicAPI/<tfm>/PublicAPI.txt the analyzer resolves itself.
- Regenerate all 136 (project, TFM) baselines; the 16 Apple legs were generated
  on a real Windows guest, which is the only host carrying those workloads.
- Fix the analyzer fallout the newly enabled rules report: aggressive-inlining
  hints, debugger displays, exception docs, doc-element ordering, interlocked
  one-shot latches, guard-clause inversions, explicit enum values and tuple
  casing.
- Unify the extension-block receiver name per receiver type, which the baseline
  generator records once per type.
@glennawatson
glennawatson force-pushed the chore/analyzers-3.45-publicapisharp branch from 24a483d to bacf76a Compare August 15, 2026 12:42
@sonarqubecloud

Copy link
Copy Markdown

@glennawatson
glennawatson merged commit 63b579f into main Aug 15, 2026
12 of 13 checks passed
@glennawatson
glennawatson deleted the chore/analyzers-3.45-publicapisharp branch August 15, 2026 13:15
@github-actions

Copy link
Copy Markdown

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Aug 30, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

⌂ 换网址