Skip to content

Commit 56f52a8

Browse files
oleksandr-selehenenko-sonarsourceSonarTech
authored andcommitted
NET-3390 Update RSPEC before 10.22 release
GitOrigin-RevId: 8117fedb2e60c617fbc04a80523f55043d4420cf
1 parent 666647f commit 56f52a8

16 files changed

Lines changed: 238 additions & 165 deletions

File tree

analyzers/rspec/cs/S1694.html

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ <h3>Exceptions</h3>
4242
}
4343
</pre>
4444
<p>Notice that, since C# 8.0, you can also define <a
45-
href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/default-interface-methods">default implementations for
46-
interface methods</a>, which is yet another reason to prefer interfaces over abstract classes when you don’t need to provide any inheritable
47-
behavior.</p>
45+
href="https://learn.microsoft.com/en-us/dotnet/csharp/advanced-topics/interface-implementation/default-interface-methods-versions">default
46+
implementations for interface methods</a>, which is yet another reason to prefer interfaces over abstract classes when you don’t need to provide any
47+
inheritable behavior.</p>
4848
<p>However, interfaces cannot have fields (such as <code>switchLamp</code> in the example above), and that remains true even in C# 8.0 and upwards.
4949
This can be a valid reason to still prefer an abstract class over an interface.</p>
5050
<h2>How to fix it</h2>
@@ -74,9 +74,8 @@ <h3>Documentation</h3>
7474
and Sealed Classes and Class Members (C# Programming Guide)</a></li>
7575
<li>Microsoft Learn - <a href="https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/">Interfaces - define behavior for
7676
multiple types</a></li>
77-
<li>Microsoft Learn - <a
78-
href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-8.0/default-interface-methods">Default Interface
79-
Methods</a></li>
77+
<li>C# Language Design - <a href="https://github.com/dotnet/csharplang/blob/main/proposals/csharp-8.0/default-interface-methods.md">Default
78+
Interface Methods</a></li>
8079
<li>Microsoft Learn - <a
8180
href="https://learn.microsoft.com/en-us/dotnet/csharp/advanced-topics/interface-implementation/default-interface-methods-versions">Tutorial: Update
8281
interfaces with default interface methods</a></li>

analyzers/rspec/cs/S2190.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ <h3>Recursion</h3>
4343
<li><strong>Stack overflow</strong>: Recursive functions can lead to <a
4444
href="https://learn.microsoft.com/en-us/dotnet/api/system.stackoverflowexception">stack overflow</a> if the recursion is too deep, potentially
4545
causing the program to crash.</li>
46-
<li><strong>Performance overhead</strong>: Recursive function calls can lead to poor performance due to the need to push and pop <a
47-
href="https://en.citizendium.org/wiki/Stack_frame#:~:text=In%20computer%20science%2C%20a%20stack,only%20exist%20at%20run%2Dtime">stack frames</a>,
46+
<li><strong>Performance overhead</strong>: Recursive function calls can lead to poor performance due to the need to push and pop stack frames,
4847
making them potentially slower than iterative solutions.</li>
4948
<li><strong>Difficulty in debugging</strong>: Debugging recursive code can be challenging, as multiple recursive calls can make it harder to track
5049
the flow of execution and identify logical errors.</li>

analyzers/rspec/cs/S3267.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ <h2>Resources</h2>
118118
<h3>Documentation</h3>
119119
<ul>
120120
<li>Microsoft Learn - <a href="https://learn.microsoft.com/en-us/dotnet/csharp/linq">Language Integrated Query (LINQ)</a></li>
121-
<li>Microsoft Learn - <a
122-
href="https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerable-">https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerable-</a> 1[IAsyncEnumerable&lt;T&gt; Interface]</li>
121+
<li>Microsoft Learn - <a href="https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerable-1">IAsyncEnumerable&lt;T&gt;
122+
Interface</a></li>
123123
<li>Microsoft Learn - <a
124124
href="https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/10.0/asyncenumerable">System.Linq.AsyncEnumerable in .NET
125125
10</a></li>

analyzers/rspec/cs/S3416.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ <h3>Articles &amp; blog posts</h3>
111111
<ul>
112112
<li>Raygun Blog - <a href="https://raygun.com/blog/c-sharp-logging-best-practices/">C# logging: Best practices in 2023 with examples and
113113
tools</a></li>
114-
<li>Apache Logging - <a href="https://logging.apache.org/log4net/release/manual/configuration.html">Apache log4net Manual - Configuration</a></li>
114+
<li>Apache Logging - <a href="https://logging.apache.org/log4net/manual/configuration.html">Apache log4net Manual - Configuration</a></li>
115115
<li>GitHub NLog repository - <a href="https://github.com/nlog/nlog/wiki/Tutorial#best-practices-for-using-nlog">Best practices for using
116116
NLog</a></li>
117117
</ul>

analyzers/rspec/cs/S8367.html

Lines changed: 55 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,95 @@
11
<p>This rule raises an issue when code uses 'field' as an identifier in contexts where it conflicts with the new <code>field</code> contextual keyword
22
introduced in C# 14.</p>
33
<h2>Why is this an issue?</h2>
4-
<p>C# 14 introduces the <code>field</code> contextual keyword for field-backed properties. This keyword allows you to access synthesized backing
4+
<p>C# 14 introduces the <code>field</code> contextual keyword for field-backed properties. This keyword allows access to the synthesized backing
55
fields directly within property accessors, simplifying property implementations that need custom logic.</p>
6-
<p>When your code uses 'field' as an identifier, several problems can occur:</p>
6+
<p>By using 'field' as an identifier, several problems can occur:</p>
77
<ul>
8-
<li><strong>Compilation errors</strong>: Local variables or parameters named 'field' within property accessors will cause compiler error CS9272,
9-
preventing your code from compiling.</li>
10-
<li><strong>Semantic confusion</strong>: Existing class members named 'field' may be overshadowed by the synthesized backing field when referenced
11-
within property accessors, leading to unexpected behavior.</li>
12-
<li><strong>Upgrade barriers</strong>: Code that compiles in earlier C# versions may break when upgrading to C# 14.</li>
8+
<li><strong>Compilation errors</strong>: Local variable declarations or parameters named <code>field</code> within property accessors cause compiler
9+
error CS9273. References to existing members named <code>field</code> within property accessors cause compiler error CS9258. See <a
10+
href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors">Compiler errors on property
11+
declarations</a>.</li>
12+
<li><strong>Semantic confusion</strong>: Existing class members named <code>field</code> may be unexpectedly overshadowed by the synthesized backing
13+
field when referenced within property accessors, leading to logic errors and unexpected runtime behavior.</li>
14+
<li><strong>Upgrade barriers</strong>: Code that compiles successfully in C# 13 and earlier may fail to compile or change behavior when upgrading to
15+
C# 14.</li>
1316
</ul>
14-
<p>The <code>field</code> keyword specifically refers to compiler-synthesized backing fields for properties. When the compiler encounters 'field'
15-
within a property accessor, it treats it as this special keyword rather than a regular identifier, which can cause conflicts with your existing
16-
code.</p>
1717
<h3>What is the potential impact?</h3>
18-
<p>Using 'field' as an identifier can prevent successful compilation when upgrading to C# 14. In property accessors, local variables named 'field'
19-
will cause compilation errors, while class members named 'field' may be unexpectedly overshadowed by synthesized backing fields, leading to logic
20-
errors and unexpected runtime behavior.</p>
18+
<p>Using 'field' as an identifier can prevent successful compilation when upgrading to C# 14. In property accessors, local variables or parameters
19+
named 'field' will cause compilation errors, while class members named 'field' may be unexpectedly overshadowed by synthesized backing fields, leading
20+
to logic errors and unexpected runtime behavior.</p>
2121
<h2>How to fix it</h2>
22-
<p>Rename class members that use 'field' as an identifier to avoid conflicts with the contextual keyword, or escape the field identifier with "@".</p>
22+
<p>Rename the identifier, escape it by prefixing with <code>@</code>, or qualify member access with <code>this.</code> or <code>base.</code> to avoid
23+
conflicts with the contextual keyword. This rule applies only inside property <code>get</code>, <code>set</code>, and <code>init</code> accessors;
24+
indexer and event accessors are not affected.</p>
2325
<h3>Code examples</h3>
2426
<h4>Noncompliant code example</h4>
2527
<pre data-diff-id="1" data-diff-type="noncompliant">
26-
public class MyClass
28+
public class ClassFieldExample
2729
{
28-
private string field; // Noncompliant
30+
private string field;
2931

3032
public string Message
3133
{
32-
get =&gt; field;
33-
set =&gt; field = value;
34+
get =&gt; field; // Noncompliant
35+
set =&gt; field = value; // Noncompliant
3436
}
3537
}
36-
37-
public class MyClass2
38+
</pre>
39+
<pre data-diff-id="2" data-diff-type="noncompliant">
40+
public class LocalFunctionExample
3841
{
39-
private string field; // Noncompliant
40-
41-
public string Message
42+
public int Value
4243
{
43-
get =&gt; field;
44-
set =&gt; field = value;
44+
get
45+
{
46+
return LocalFunction(42);
47+
48+
int LocalFunction(int field) // Noncompliant
49+
=&gt; field;
50+
}
4551
}
4652
}
4753
</pre>
4854
<h4>Compliant solution</h4>
4955
<pre data-diff-id="1" data-diff-type="compliant">
50-
public class MyClass
56+
public class ClassFieldExample
5157
{
52-
private string _field;
58+
private string field;
5359

5460
public string Message
5561
{
56-
get =&gt; _field;
57-
set =&gt; _field = value;
62+
get =&gt; this.field; // or @field
63+
set =&gt; this.field = value; // or @field = value;
5864
}
5965
}
60-
61-
public class MyClass2
66+
</pre>
67+
<pre data-diff-id="2" data-diff-type="compliant">
68+
public class LocalFunctionExample
6269
{
63-
private string field;
64-
65-
public string Message
70+
public int Value
6671
{
67-
get =&gt; @field;
68-
set =&gt; @field = value;
72+
get
73+
{
74+
return LocalFunction(42);
75+
76+
int LocalFunction(int value) // Compliant - renamed
77+
=&gt; value;
78+
}
6979
}
7080
}
7181
</pre>
7282
<h2>Resources</h2>
7383
<h3>Documentation</h3>
7484
<ul>
75-
<li>What’s new in C# 14 - The field keyword - <a
76-
href="https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-14#the-field-keyword">Official Microsoft documentation explaining the field
77-
keyword feature in C# 14</a></li>
78-
<li>Breaking changes in Roslyn - field keyword conflicts - <a
79-
href="https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/breaking-changes/compiler%20breaking%20changes%20-%20dotnet%2010">Documentation of
80-
breaking changes related to the field keyword in C# 14</a></li>
85+
<li>Microsoft Learn - <a href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/field">The <code>field</code>
86+
keyword</a></li>
87+
<li>Microsoft Learn - <a
88+
href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/property-declaration-errors">Compiler errors on property
89+
declarations</a></li>
90+
<li>Microsoft Learn - <a
91+
href="https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/breaking-changes/compiler%20breaking%20changes%20-%20dotnet%2010#expression-field-in-a-property-accessor-refers-to-synthesized-backing-field">C# compiler breaking changes since C# 13 - Expression <code>field</code> in a property accessor refers to synthesized backing field</a></li>
92+
<li>Microsoft Learn - <a
93+
href="https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/breaking-changes/compiler%20breaking%20changes%20-%20dotnet%2010#variable-named-field-disallowed-in-a-property-accessor">C# compiler breaking changes since C# 13 - Variable named <code>field</code> disallowed in a property accessor</a> (documentation incorrectly references CS9272; the actual error code is CS9273)</li>
8194
</ul>
8295

analyzers/rspec/cs/S8367.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111
"compatibility",
1212
"upgrade"
1313
],
14-
"defaultSeverity": "Blocker",
14+
"defaultSeverity": "Critical",
1515
"ruleSpecification": "RSPEC-8367",
1616
"sqKey": "S8367",
1717
"scope": "All",
1818
"quickfix": "unknown",
1919
"code": {
2020
"impacts": {
21-
"MAINTAINABILITY": "BLOCKER"
21+
"MAINTAINABILITY": "HIGH"
2222
},
2323
"attribute": "CONVENTIONAL"
2424
}

analyzers/rspec/cs/S8368.html

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,71 @@
1-
<p>This is an issue when using 'extension' as an identifier (class name, method name, variable name, etc.) in C# 14 or later without the '@' escape
2-
prefix.</p>
1+
<p>Identifiers named <code>extension</code> should be renamed or use the <code>@</code> escape prefix to avoid breaking changes in C# 14 or later.</p>
32
<h2>Why is this an issue?</h2>
4-
<p>Starting with C# 14, 'extension' becomes a contextual keyword used for extension containers. When the compiler encounters 'extension' in certain
5-
contexts, it tries to parse it as this new language feature rather than as a regular identifier.</p>
6-
<p>This change can cause compilation errors in existing code that uses 'extension' as an identifier. For example, a class named 'extension' will be
7-
interpreted as an extension container declaration, leading to parsing failures.</p>
8-
<p>The '@' prefix tells the compiler to treat the word as a regular identifier rather than a keyword, resolving the ambiguity and allowing the code to
9-
compile correctly.</p>
3+
<p>Starting with C# 14, <code>extension</code> <a
4+
href="https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/breaking-changes/compiler%20breaking%20changes%20-%20dotnet%2010#extension-treated-as-a-contextual-keyword">is
5+
a contextual keyword</a> for declaring extension members and extension containers. This change can cause compilation errors in existing code that uses
6+
the word <code>extension</code> as an identifier. For example, a class named 'extension' will be interpreted as an extension container declaration,
7+
leading to parsing failures.</p>
8+
<p>This rule flags any unescaped <code>extension</code> identifiers used in the following cases:</p>
9+
<ul>
10+
<li>Type declaration names</li>
11+
<li>Type parameter names</li>
12+
<li>Constructor names</li>
13+
<li>Using alias names</li>
14+
<li>Return types, property types, and field types (including arrays and pointers)</li>
15+
</ul>
16+
<p>Note that method names, parameter names, and local variable names are not affected by this breaking change. For example, <code>void extension() {
17+
}</code> remains valid in C# 14.</p>
1018
<h3>What is the potential impact?</h3>
11-
<p>Code that previously compiled successfully will fail to compile with C# 14 or later. This can break builds and prevent applications from being
12-
updated to newer language versions.</p>
19+
<p>Code that currently compiles will fail to compile when the project is upgraded to C# 14.</p>
1320
<h2>How to fix it</h2>
14-
<p>Change the identifier name, or add the '@' prefix before 'extension' when using it as a class name, constructor name, or method name.</p>
21+
<p>Rename the identifier, or add the <code>@</code> prefix to it.</p>
1522
<h3>Code examples</h3>
1623
<h4>Noncompliant code example</h4>
1724
<pre data-diff-id="1" data-diff-type="noncompliant">
18-
class extension
25+
class extension { }
26+
class MyClass
1927
{
20-
extension(object o) { } // Noncompliant
21-
extension M() { } // Noncompliant
28+
extension field;
29+
extension Property { get; }
2230
}
2331
</pre>
2432
<h4>Compliant solution</h4>
33+
<p>Escape the identifier with the <code>@</code> verbatim prefix:</p>
2534
<pre data-diff-id="1" data-diff-type="compliant">
26-
class @extension
35+
class @extension { }
36+
class MyClass
2737
{
28-
@extension(object o) { }
29-
@extension M() { }
38+
@extension field;
39+
@extension Property { get; }
3040
}
3141
</pre>
32-
<p>or</p>
33-
<pre data-diff-id="1" data-diff-type="compliant">
34-
class MyExtension
42+
<h4>Noncompliant code example</h4>
43+
<pre data-diff-id="2" data-diff-type="noncompliant">
44+
class extension { }
45+
class MyClass
46+
{
47+
extension ReturnType() { return default; }
48+
}
49+
</pre>
50+
<h4>Compliant solution</h4>
51+
<p>Rename the identifier:</p>
52+
<pre data-diff-id="2" data-diff-type="compliant">
53+
class MyExtension { }
54+
class MyClass
3555
{
36-
MyExtension(object o) { }
37-
MyExtension M() { }
56+
MyExtension ReturnType() { return default; }
3857
}
3958
</pre>
4059
<h2>Resources</h2>
4160
<h3>Documentation</h3>
4261
<ul>
43-
<li>C# Breaking Changes in .NET 10 - <a
44-
href="https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/breaking-changes/compiler%20breaking%20changes%20-%20dotnet%2010">Official Microsoft
45-
documentation about breaking changes in C# 14, including the 'extension' contextual keyword</a></li>
46-
<li>C# Identifiers - <a
47-
href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/lexical-structure#643-identifiers">C# language
48-
specification section on identifiers and the '@' escape mechanism</a></li>
62+
<li>Microsoft Learn - <a
63+
href="https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/breaking-changes/compiler%20breaking%20changes%20-%20dotnet%2010#extension-treated-as-a-contextual-keyword"><code>extension</code> treated as a contextual keyword</a></li>
64+
<li>Microsoft Learn - <a href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/extension">Extension member
65+
declarations</a></li>
66+
<li>Microsoft Learn - <a href="https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/tutorials/extension-members">Explore extension members in
67+
C# 14</a></li>
68+
<li>Microsoft Learn - <a href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/verbatim">Verbatim identifiers
69+
(<code>@</code> prefix)</a></li>
4970
</ul>
5071

analyzers/rspec/cs/S8368.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"status": "ready",
55
"remediation": {
66
"func": "Constant\/Issue",
7-
"constantCost": "5 min"
7+
"constantCost": "1 min"
88
},
99
"tags": [
1010
"csharp14",

0 commit comments

Comments
 (0)