Skip to content

chore: turn off the overload-adjacency rule the caches deliberately break - #164

Closed
cosmin-staicu wants to merge 1 commit into
mainfrom
chore/overload-adjacency-rule
Closed

chore: turn off the overload-adjacency rule the caches deliberately break#164
cosmin-staicu wants to merge 1 commit into
mainfrom
chore/overload-adjacency-rule

Conversation

@cosmin-staicu

Copy link
Copy Markdown
Member

Why

S4136 ("All X method overloads should be adjacent") fires six times, in MultilayerCache, MultilayerHashCache, RedisCache and RedisHashCache. None of them is new. Because GitHub annotates warnings on changed files, every pull request that touches one of those files carries them, which is where this came from: PR #160 shows all six and introduced none.

Why not reorder instead

The layout the rule objects to is deliberate. Each group of overloads is followed by the private Core helper it delegates to:

public ValueTask<T?> GetOrAddAsync<T>(...);            // single-key group
public ValueTask<T?> GetOrAddAsync<T>(..., TimeSpan);
private ValueTask<T?> GetOrAddCoreAsync<T>(...);       // the helper those three share
public ValueTask<...[]> GetOrAddAsync<T, TState>(...); // batch group

Making the two groups adjacent means either moving the helpers away from the overloads they serve, or interleaving single-key and batch code. Both read worse than the warning, so the rule is switched off with that reason recorded next to it, in the same style as the other rules the repository already disables.

Verification

Solution builds clean. Behavior unchanged: this is one .editorconfig entry. CI on this pull request is the check that the six annotations are gone.

🤖 Generated with Claude Code

https://claude.ai/code/session_017fwLrS3Sbcen8v6iRkUaFB

…reak

S4136 fires six times across MultilayerCache, MultilayerHashCache,
RedisCache and RedisHashCache, and it annotates every pull request that
touches those files even though none of them introduced it.

The layout it objects to is deliberate: each group of overloads sits
next to the private Core helper it delegates to, so the single-key and
batch groups of one name are separated by the helper that serves the
first. Satisfying the rule would either move those helpers away from the
overloads they support or interleave the two groups. Either reads worse
than the warning.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017fwLrS3Sbcen8v6iRkUaFB
Signed-off-by: Cosmin Staicu <cosmin.staicu@uipath.com>
@sonarqubecloud

sonarqubecloud Bot commented Sep 9, 2026

Copy link
Copy Markdown

@cosmin-staicu
cosmin-staicu deleted the chore/overload-adjacency-rule branch September 10, 2026 03:55
cosmin-staicu added a commit that referenced this pull request Sep 10, 2026
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 added a commit that referenced this pull request Sep 10, 2026
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 added a commit that referenced this pull request Sep 10, 2026
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 added a commit that referenced this pull request Sep 10, 2026
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 added a commit that referenced this pull request Sep 11, 2026
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 added a commit that referenced this pull request Sep 11, 2026
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 added a commit that referenced this pull request Sep 11, 2026
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 added a commit that referenced this pull request Sep 11, 2026
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 added a commit that referenced this pull request Sep 11, 2026
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 added a commit that referenced this pull request Sep 11, 2026
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 added a commit that referenced this pull request Sep 11, 2026
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 added a commit that referenced this pull request Sep 11, 2026
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.


Claude-Session: https://claude.ai/code/session_01NsPw6MZHPGmpbo6WDuLzF1

Signed-off-by: Cosmin Staicu <cosmin.staicu@uipath.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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