Skip to content

refactor: order type members, and enforce it - #176

Open
cosmin-staicu wants to merge 1 commit into
mainfrom
chore/analyzer-member-order
Open

refactor: order type members, and enforce it#176
cosmin-staicu wants to merge 1 commit into
mainfrom
chore/analyzer-member-order

Conversation

@cosmin-staicu

@cosmin-staicu cosmin-staicu commented Sep 10, 2026

Copy link
Copy Markdown
Member

Members are laid out the way the ordering rules ask, and the rules are on so it stays that way. Every SA1201, SA1202, SA1203, SA1210, SA1214 and IDE0040 in the repository is gone.

How to review this: 154 files, but the reordering is a move and nothing else — the insertion and deletion counts match, per file and overall. The parts worth actual attention are the four files at the top of the "by hand" list below, .editorconfig, stylecop.json and Directory.Build.props. The rest is mechanical.

What is now enforced

.editorconfig already carried a curated StyleCop block, so this joins it rather than replacing it — worth knowing when reading the diff. StyleCop.Analyzers is now referenced, and every one of its eight categories is none except OrderingRules, with rules named individually where a category cannot reach them. Without that the package reports about 5,000 warnings.

  • The OrderingRules category — order by kind, by access, constants first, readonly first, using directives alphabetical. The category rather than a list of ids, because it costs 28 more violations and no maintenance.
  • SA1204 (static before instance) had to be named explicitly. It was already none further up the file, and a specific id beats a category, so the category alone would not have applied it. SA1200 and SA1208, on using-directive placement, stay none as they were.
  • SA1402, scoped to src — one top-level type per file on the shipped surface. topLevelTypes in stylecop.json widens it past its default of class alone. Four files held nine extra types and are now thirteen. Tests and samples keep small helper types beside what uses them; enforcing it there would break up 12 test files and 4 sample files for no gain.
  • SA1649 was already none and stays there. It doesn't recognise the OfT suffix used for generic types, so it would ask to rename CacheOfT.cs, ICacheOfT.cs and five siblings to Cache{T}.cs.
  • SX1309 is off explicitly. The alternative to SA1309, it wants every field to begin with an underscore — the opposite of what SA1309 asks, and SA1309 is already off above. It belongs to no StyleCop category, so switching the categories off does not reach it; the SX family is named. This one caught me out: enabling the package surfaced 20 SX1309 warnings that main does not have, and my first greps were filtered to SA1*/IDE0040 and missed them. The build now reports no warnings at all.
  • IDE0040 was configured but at severity silent, so it never reported. It's a warning now, which is the rule as asked: a class member always states its accessibility, an interface member never repeats the public it already has. 25 interface members carried a redundant public; two class members had none at all. Removing public from an interface member changes no API — PublicAPI.Shipped.txt is untouched.

How the members were moved

Neither dotnet format nor the Roslynator CLI can drive StyleCop's fixer for the ordering rules — both answer that no code fix was found, and Roslynator lists the diagnostics as unfixable. Rider's own layout engine ranks constants and statics above accessibility, which pushes SA1202 up rather than down.

So a Roslyn pass did it: parse, sort each type's members by StyleCop's default elementOrder (kind → accessibility → const → static → readonly), write the tree back — which carries each member's doc comments and blank lines with it, rather than matching them by text.

Three rules kept it safe:

  1. The sort is stable, so anything the comparer calls equal keeps the order the author chose.
  2. A field whose initializer reads a sibling member, or this, is pinned where it is — C# runs field initializers in textual order, so moving one can change behaviour. A field built from literals, constants and other types moves freely.
  3. A file containing #region or #if is refused outright. Those directives are trivia on the members around them, and a sort can carry one away from its partner and change what compiles.

Settled by hand

Rule 2 and rule 3 leave work behind by design. Each of these is the safety net working, not failing:

  • MemoryCacheFactoryTests and RedisSetCacheTests — field blocks moved as units, so Before/After keep reading Deadline and the set-cache options keep reading their const.
  • GenerationDepthBehavior — an interface declared below a class, which is a file-level ordering the pass doesn't do.
  • UiPathBufferDistributedCacheTests — the whole file is one conditional block, so its directives were lifted, the members sorted, and the directives restored.
  • DistributedCacheRedisIntegrationTests — an inner block held both a public test and a private nested helper, which cannot satisfy kind order and access order as one unit. It is two blocks now.

Also here

S4136 had been reporting eight non-adjacent overload groups on every build, and #164 proposed switching the rule off. Measuring first said otherwise: every one of the eight groups is of uniform accessibility, five are split by a single private XCoreAsync sitting between the public overloads it serves, and moving that helper below the group is what SA1202 asks for anyway. The two rules agree rather than conflict, so the rule is satisfied instead of suppressed.

KeyMasker.IsMasking carried two <summary> tags, having absorbed ShouldMask's when it was inserted above it in #165. ShouldMask has its documentation back; it's the only place in src with that mistake.

Verification

  • Insertions equal deletions — the hallmark of a move with no edit.
  • Both suites unchanged: 1701 on net10, 1680 on net8. For the conditional files that count is the check: a [Fact] carried out of a NET9_0_OR_GREATER block would raise the net8 total, one carried in would lower it. Neither moved.
  • #if/#endif pairs balanced in both files that have them.
  • Packed nuspec unchanged.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NsPw6MZHPGmpbo6WDuLzF1

@cosmin-staicu
cosmin-staicu requested a lite review from Copilot September 10, 2026 15:47
@github-actions github-actions Bot added the needs-cla-review A maintainer should assess whether a signed CLA is required (see CONTRIBUTING.md) label Sep 10, 2026
@github-actions

Copy link
Copy Markdown

🔎 Maintainer heads-up: automated triage flagged this PR as potentially material, so it may need a signed CLA in addition to the DCO sign-off.

Strong signals

  • adds dependency: StyleCop.Analyzers

Other signals

  • large production change (+2105 lines under src/)

This is advisory only — the bot does not decide. Please judge against the CLA criteria (material, product-critical, patent-sensitive, corporate contributor, broad commercial use). Note that thresholds can be gamed by splitting PRs, so use your judgement.

  • If a CLA is needed → add the cla-required label (a contributor comment with signing steps is posted automatically).
  • If it is not needed → replace needs-cla-review with cla-not-required so later pushes don't re-flag it.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

It contains a couple of objective mismatches between documentation/PR description and the enforced analyzer/package-floor behavior that should be corrected for maintainability and accurate review context.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Refactors the repository to comply with (and enforce) consistent C# member ordering and accessibility-modifier rules, primarily by enabling specific analyzers and mechanically reordering members across types.

Changes:

  • Enable and configure StyleCop/IDE analyzer rules (OrderingRules, SA1402 under src, IDE0040 severity) and add StyleCop settings.
  • Mechanical reordering of members across src/, tests/, samples/, and benchmarks/ to eliminate ordering/accessibility diagnostics.
  • Adjust central package-version floors and add StyleCop.Analyzers as a centrally-managed dependency.
File summaries
File Description
.editorconfig Enables IDE0040 as warning and configures StyleCop categories/rules.
.github/dependabot.yml Updates Dependabot guidance comments for the new floor strategy.
Directory.Build.props Adds StyleCop analyzer package reference + links stylecop.json.
Directory.Packages.props Updates per-TFM floors and adds central StyleCop.Analyzers version.
stylecop.json Adds StyleCop settings (notably topLevelTypes for SA1402).
src/UiPath.Caching/CacheEntryFactory.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/CacheMemoryMonitor.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Config/CachingBuilder.cs Registers options validator and reorders members.
src/UiPath.Caching/Config/RedisCollectionExtensions.cs Reorders extension methods.
src/UiPath.Caching/Config/ServiceCollectionExtensions.cs Member reordering (also reserves Redis keyspaces).
src/UiPath.Caching/InMemoryCacheProvider.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/InMemoryRedisCacheProvider.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/IMultilayerCacheOptions.cs Removes redundant public modifiers and reorders members.
src/UiPath.Caching/ICacheOptions.cs Removes redundant public modifiers and reorders members.
src/UiPath.Caching/ICacheEntryOptions.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Logging/AlwaysMaskKeyMaskingPolicy.cs Extracted type into its own file for SA1402.
src/UiPath.Caching/Logging/IKeyMaskingPolicy.cs Extracts nested types; member ordering cleanup.
src/UiPath.Caching/Logging/KeyMasker.cs Member reordering and doc-comment cleanup.
src/UiPath.Caching/Logging/LoggedKey.cs Removes extra top-level type (moved out for SA1402).
src/UiPath.Caching/Logging/LoggedKeys.cs New dedicated file for LoggedKeys type (SA1402).
src/UiPath.Caching/Logging/MaskingContext.cs Extracted type into its own file for SA1402.
src/UiPath.Caching/Logging/NullKeyMaskingPolicy.cs Extracted type into its own file for SA1402.
src/UiPath.Caching/Metrics.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/MemoryCacheSetter.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/RehydrationCoordinator.cs Member reordering (helper methods/constants).
src/UiPath.Caching/Broadcast/ChangeToken.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Broadcast/EventDispatcher.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Broadcast/KeyedSubject.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Broadcast/Redis/RedisPubSubSubjectWriter.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Broadcast/Redis/RedisPubSubTopic.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Broadcast/Redis/RedisPubSubTopicProvider.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Broadcast/Redis/RedisStreamHealthMaintainer.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Broadcast/Redis/RedisStreamNotifyChannel.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Broadcast/Redis/RedisStreamsTopic.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Broadcast/Redis/RedisStreamsTopicProvider.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Broadcast/Redis/RedisStreamSubjectWriter.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Broadcast/Redis/RedisTopicProviderBase.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Broadcast/Redis/StreamConstants.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Locking/RedisDistributedLock.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Redis/ClusterConfigurationReader.cs Extracted type into its own file for SA1402.
src/UiPath.Caching/Redis/ClusterMembership.cs Extracted type into its own file for SA1402.
src/UiPath.Caching/Redis/ClusterTopologyReader.cs Removes extra top-level types (moved out for SA1402).
src/UiPath.Caching/Redis/ConnectionStateMonitor.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Redis/IProfiledCommandProcessor.cs Removes redundant public modifier and reorders members.
src/UiPath.Caching/Redis/IProfilingSessionCommandReader.cs Removes redundant public modifier and reorders members.
src/UiPath.Caching/Redis/IReservedRedisKeyspace.cs Adds reserved-keyspace contract used for validation.
src/UiPath.Caching/Redis/PrefixRedisKeyStrategy.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Redis/ProfiledCommandExtensions.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Redis/RedisCacheProvider.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Redis/RedisPlannedMaintenance.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Redis/RedisProfiler.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching/Redis/ReservedRedisKeyspaceExtensions.cs Adds reservation/validation helpers for keyspaces.
src/UiPath.Caching/Redis/ReservedRedisKeyspaceValidator.cs Adds early options validation for reserved keyspaces.
src/UiPath.Caching/Redis/StreamId.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Queue/InMemoryQueueCacheProvider.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Queue/InMemoryRedisQueueCacheProvider.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Queue/MemorySetCache.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Queue/MultilayerSetCache.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Queue/RedisQueueCacheProvider.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Queue/RedisSetCache.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Polly/GlobalUsings.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.CloudEvents/CacheCloudEventWrapper.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Azure/AzureEntraConnectionConfigurator.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Azure/AzureEntraCredentialFactory.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Azure/UiPath.Caching.Azure.csproj Updates Microsoft.Extensions.Options VersionOverride.
src/UiPath.Caching.Abstractions/CacheKey.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Abstractions/CacheOfT.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Abstractions/ICacheChangeToken.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Abstractions/ICacheEntry.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Abstractions/NullCache.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Abstractions/NullHashCache.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Abstractions/Config/ICachePolicyFactory.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Abstractions/Config/NullCachePolicyFactory.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Abstractions/Telemetry/ICachingTelemetryProvider.cs Removes redundant public modifier and reorders members.
src/UiPath.Caching.Abstractions/Telemetry/TelemetryOperation.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Abstractions/Broadcast/IChangeTokenFactory.cs Removes redundant public modifier and reorders members.
src/UiPath.Caching.Abstractions/Broadcast/ITopic.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Abstractions/Broadcast/NullCacheChangeToken.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Abstractions/Broadcast/NullCacheEventFactory.cs Member reordering to satisfy ordering rules.
src/UiPath.Caching.Abstractions/Broadcast/TopicKey.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Azure/AzureEntraConnectionConfiguratorTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/BatchGetOrAddTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Broadcast/ChangeTokenTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Broadcast/ConnectionStateMonitorTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Broadcast/KeyedSubjectTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Broadcast/RedisPubSubSubjectWriterTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Broadcast/RedisPubSubTopicTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Broadcast/RedisStreamSubjectWriterTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/CacheExpirationTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/CacheOfTBatchGetOrAddTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/CancelationTokenCacheTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Distributed/DistributedCacheEndToEndTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Distributed/UiPathBufferDistributedCacheTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Fakes/DictionaryCache.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/GenerationDepthBehavior.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/InMemorySetCacheTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/LegacySerializerWireCompatTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Logging/KeyMaskingTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Logging/MaskedLogSiteTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Locking/AsyncKeyedLocalLockTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Locking/CacheOptionsLockValidatorTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Locking/MultilayerCacheBatchGetOrAddLockTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Locking/MultilayerCacheGetOrAddLockTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Locking/MultilayerCacheLockCrossOptionsValidatorTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Locking/MultilayerHashCacheGetOrAddLockTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Locking/RedisDistributedLockTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/MemoryCacheFactoryTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/MultilayerCacheBatchGetOrAddTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/MultilayerCacheBatchRehydrateTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/MultilayerCachePerNameLockTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/MultilayerCacheRehydrateTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/MultilayerCacheTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/MultilayerCacheTryAddTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/MultilayerHashCacheRehydrateTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/MultilayerHashCacheTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/MultilayerSetCacheTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/OpenTelemetry/OpenTelemetryCachingTelemetryProviderTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/PackageVersionFloorTests.cs Updates tests guarding central package floors.
tests/UiPath.Caching.Tests/PropagateCacheNullValuesFromMultilayerTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/RawByteSerializerProxyTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Redis/RedisCacheTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Redis/RedisCacheTryAddTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Redis/RedisConfigurationOptionsProviderFactoryTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Redis/RedisConnectionConfiguratorTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Redis/RedisConnectionWarmupTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Redis/RedisConnectorIntegrationTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Redis/RedisConnectorTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Redis/RedisHashCacheTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Redis/RedisPlannedMaintenanceIntegrationTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/Redis/RedisSetCacheTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/RehydrationCoordinatorTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/ResiliencePipelineFactoryTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/ResiliencePipelineProviderTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/SetCacheProviderTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/SystemJsonByteSerializerProxyTests.cs Member reordering to satisfy ordering rules.
tests/UiPath.Caching.Tests/TestCacheEntry.cs Member reordering to satisfy ordering rules.
benchmarks/UiPath.Caching.Benchmarks/CacheBenchmark.cs Member reordering to satisfy ordering rules.
benchmarks/UiPath.Caching.Benchmarks/SerializerBenchmark.cs Member reordering to satisfy ordering rules.
benchmarks/UiPath.Caching.Benchmarks/StreamNotifyDoorbellHarness.cs Member reordering to satisfy ordering rules.
samples/UiPath.Caching.Sample.ServiceDefaults/Extensions.cs Member reordering to satisfy ordering rules.
Review details
  • Files reviewed: 154/154 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread Directory.Packages.props
Comment on lines 12 to +28
@@ -46,19 +23,27 @@
<PackageVersion Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="8.0.30" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net10.0'">
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.11" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="10.0.11" />
Comment thread Directory.Build.props
Comment on lines +47 to +48
<!-- StyleCop is here for two rules only: the file-per-type pair. Everything else it ships,
including the ordering rules, is switched off by category in .editorconfig. -->

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Core ordering rules remain disabled, while unrelated dependency downgrades and removed floor safeguards introduce operational regressions.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (2)

Directory.Build.props:48

  • This comment contradicts the configuration it documents: .editorconfig:495 enables the OrderingRules category, while SA1402 is the single file-per-type rule enabled under src. Please describe the analyzer scope accurately so future maintainers do not disable a rule set that is intentionally active.
  <!-- StyleCop is here for two rules only: the file-per-type pair. Everything else it ships,
       including the ordering rules, is switched off by category in .editorconfig. -->

Directory.Packages.props:26

  • Placing the net8 floor before the net10 floor reintroduces the Dependabot failure this file previously guarded against: for duplicate package IDs, its patch update can target the first (now net8) declaration. The PR also removes TheNet10FloorIsDeclaredFirst, so CI no longer detects this. Keep the net10 group first and retain the order test.
  <ItemGroup Condition="'$(TargetFramework)' == 'net10.0'">
  • Files reviewed: 154/154 changed files
  • Comments generated: 3
  • Review effort level: Balanced

Comment thread .editorconfig
# StyleCop's fixer for these — both answer that no code fix was found — so the outstanding
# violations are cleared with Fix All in the IDE. TreatWarningsAsErrors is false, so they report
# without failing the build while that happens.
dotnet_analyzer_diagnostic.category-StyleCop.CSharp.OrderingRules.severity = warning
Comment thread Directory.Packages.props
Comment on lines +27 to +31
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.11" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="10.0.11" />
<PackageVersion Include="Microsoft.Extensions.Primitives" Version="10.0.11" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.11" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="10.0.11" />
<!-- Tracks $(MEVersion10) rather than repeating it: this override has to move with the net10
floor or restore fails NU1605 against it, and hand-aligning it is what broke in #134. -->
<PackageReference Include="Microsoft.Extensions.Options" VersionOverride="$(MEVersion10)" />
<PackageReference Include="Microsoft.Extensions.Options" VersionOverride="10.0.11" />
alinahornet
alinahornet previously approved these changes Sep 10, 2026
@cosmin-staicu
cosmin-staicu force-pushed the chore/analyzer-member-order branch 3 times, most recently from 99cae08 to 1cc3253 Compare September 10, 2026 23:30
Members are laid out the way the ordering rules ask, and the rules are
on so it stays that way. The build reports no warnings at all: every
SA1201, SA1202, SA1203, SA1204, SA1210, SA1214 and IDE0040 is gone, and
S4136 with them.

What is enforced

.editorconfig already carried a curated StyleCop block, so this joins it
rather than replacing it. StyleCop.Analyzers is now referenced, and every
one of its eight categories is none except OrderingRules, with the rules
we want named individually where a category cannot reach them. Without
that the package reports around five thousand warnings.

- The OrderingRules category: order by kind, by access, constants first,
  readonly first, using directives alphabetical. The category rather
  than a list of ids, because it costs 28 more violations and no
  maintenance.
- SA1204, static before instance, was already none further up the file.
  A specific id beats a category, so the category alone would not have
  applied it; it is named explicitly. SA1200 and SA1208, on using
  directive placement, stay none as they were.
- SA1402, scoped to src: one top-level type per file on the shipped
  surface. topLevelTypes in stylecop.json widens it past its default of
  class alone. Four files held nine extra types and are now thirteen.
  Tests and samples keep small helper types next to what uses them.
- SA1649 was already none and stays there: it does not recognise the OfT
  suffix this repo uses for generic types, so it would rename
  CacheOfT.cs and six siblings to Cache{T}.cs.
- SX1309, the alternative to SA1309, wants every field to begin with an
  underscore. It belongs to no StyleCop category, so switching the
  categories off does not reach it; the SX family is named off
  explicitly. SA1309 is already off above for the opposite reason.
- IDE0040 was configured but silent. It is a warning now: a class member
  always states its accessibility, an interface member never repeats the
  public it already has. 25 interface members carried a redundant public
  and two class members had none.

How the members were moved

Neither dotnet format nor the Roslynator CLI can drive StyleCop's fixer
for the ordering rules — both answer that no code fix was found — and
Rider's layout engine ranks constants and statics above accessibility,
which pushes SA1202 up rather than down. So a Roslyn pass did it: parse,
sort each type's members by StyleCop's default elementOrder, write the
tree back, which carries each member's doc comments and blank lines with
it.

Three rules kept it safe. The sort is stable, so anything the comparer
calls equal keeps the order the author chose. A field whose initializer
reads a sibling member, or this, is pinned where it is, because C# runs
field initializers in textual order. And a file containing #region or
#if is refused outright, since those directives are trivia on the
members around them and a sort can carry one away from its partner.

That left seven conditional-compilation files and six other places to
settle by hand: three field blocks moved as units so their initializers
keep reading what they read, an interface that sat below a class in its
file, and the two buffer tests whose nested helper lives beside the
tests that use it.

Also here

S4136 had been reporting eight non-adjacent overload groups on every
build, and #164 proposed turning the rule off. Measuring first said
otherwise: every group is of uniform accessibility, five are split by a
single private Core helper sitting between the public overloads it
serves, and moving that helper below the group is what SA1202 asks for
anyway. The two rules agree rather than conflict.

KeyMasker.IsMasking carried two summary tags, having taken ShouldMask's
when it was inserted above it. ShouldMask has its documentation back.

Verification

The reordering is a move and nothing else, which the diff shows: the
insertions and deletions match. Both suites are unchanged at 1701 on
net10 and 1680 on net8 — the count is the check that matters for the
conditional files, because a test carried out of a NET9_0_OR_GREATER
block would raise the net8 total and one carried in would lower it. #if
pairs stay balanced. The packed nuspec is untouched.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NsPw6MZHPGmpbo6WDuLzF1
Signed-off-by: Cosmin Staicu <cosmin.staicu@uipath.com>
@cosmin-staicu
cosmin-staicu force-pushed the chore/analyzer-member-order branch from 1cc3253 to a31e1e0 Compare September 10, 2026 23:40
@sonarqubecloud

Copy link
Copy Markdown

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

Labels

needs-cla-review A maintainer should assess whether a signed CLA is required (see CONTRIBUTING.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants