-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat!: explicit record class declarations (#94)
add analyzer for reference records without class keyword add fixer adding optional class keyword to records that are reference types add support for Visual Studio 2022 to the VSIX add link to NuGet Package Explorer to README fix null-check analyzer reporting on static bool Equals(object) methods update Roslyn from 3.8 to 4.0 BREAKING CHANGE: drop support for .NET 5.0 SDK and Visual Studio 2019
- Loading branch information
Showing
35 changed files
with
765 additions
and
193 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Avoid implicit reference type records | ||
|
||
DiagnosticAnalyzer: [F02001ImplicitRecordClassDeclaration.cs](../../source/production/F0.Analyzers/CodeAnalysis/Diagnostics/F02001ImplicitRecordClassDeclaration.cs) | ||
|
||
| | | | ||
|------------|--------------------| | ||
| ID | F02001 | | ||
| Category | CleanCode | | ||
| Language | C# 10.0 or greater | | ||
| Applies to | `[vNext,)` | | ||
|
||
## Summary | ||
|
||
Clarify that a `record` is a _reference type_ with the `record class` declaration. | ||
|
||
## Remarks | ||
|
||
_Record types_, introduced in _C# 9.0_, define _reference types_ with _value equality_. | ||
In _C# 10_ and later, you can explicitly declare a `record class`, which is semantically identical to a `record`. | ||
|
||
## Example | ||
|
||
```cs | ||
public record Record(int Number, string Text); // F02001 | ||
public record class RecordClass(int Number, string Text); | ||
public record struct RecordStruct(int Number, string Text); | ||
public readonly record struct ReadonlyRecordStruct(int Number, string Text); | ||
``` | ||
|
||
## See also | ||
|
||
- [What's new in C# 9.0](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9) | ||
- [What's new in C# 10](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-10) | ||
- [Records](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record) | ||
- [Reference types](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/reference-types) | ||
|
||
## History | ||
|
||
- [vNext](../../CHANGELOG.md#vNext) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Prefer explicit reference type records | ||
|
||
CodeFixProvider: [DeclareRecordClassExplicitly.cs](../../source/production/F0.Analyzers/CodeAnalysis/CodeFixes/DeclareRecordClassExplicitly.cs) | ||
|
||
| | | | ||
|------------|--------------------------------------------------------------| | ||
| Title | Explicitly add class keyword to reference record declaration | | ||
| Fixes | [F02001][F02001] | | ||
| Language | C# 10.0 or greater | | ||
| Applies to | `[vNext,)` | | ||
|
||
## Summary | ||
|
||
Adds the optional `class` keyword to _reference record_ declarations to add clarity for readers. | ||
|
||
## Remarks | ||
|
||
Both a `record` and a `record class` declare a _reference type_ and are semantically equal. | ||
The `class` keyword is optional, distinguishing these types from `record struct` and `readonly record struct` declarations, both value types with the semantic difference of immutability. | ||
|
||
## Example | ||
|
||
Before: | ||
```cs | ||
public record Record(int Number, string Text); | ||
``` | ||
|
||
After: | ||
```cs | ||
public record class Record(int Number, string Text); | ||
``` | ||
|
||
## See also | ||
|
||
- [What's new in C# 10 - Record structs](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-10#record-structs) | ||
|
||
## History | ||
|
||
- [vNext](../../CHANGELOG.md#vNext) | ||
|
||
|
||
[F02001]: ../diagnostics/F02001.md |
2 changes: 1 addition & 1 deletion
2
documentation/fixes/UsePatternMatchingNullCheckInsteadOfComparisonWithNull.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
...Analyzers.Example.CSharp10/CodeAnalysis/CodeFixes/DeclareRecordClassExplicitlyExamples.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace F0.Analyzers.Example.CSharp10.CodeAnalysis.CodeFixes | ||
{ | ||
internal sealed class DeclareRecordClassExplicitlyExamples | ||
{ | ||
public record Record(int Number, string Text); | ||
|
||
public record class RecordClass(int Number, string Text); | ||
|
||
public record struct RecordStruct(int Number, string Text); | ||
|
||
public readonly record struct ReadonlyRecordStruct(int Number, string Text); | ||
|
||
public class Class { } | ||
|
||
public static class StaticClass { } | ||
|
||
public struct Struct { } | ||
|
||
public readonly struct ReadonlyStruct { } | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
source/example/F0.Analyzers.Example.CSharp10/F0.Analyzers.Example.CSharp10.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<LangVersion>10.0</LangVersion> | ||
</PropertyGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
.../F0.Analyzers.Benchmarks/CodeAnalysis/CodeFixes/DeclareRecordClassExplicitlyBenchmarks.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
using F0.Benchmarking.CodeAnalysis; | ||
using F0.Benchmarking.CodeAnalysis.CodeFixes; | ||
using F0.CodeAnalysis.CodeFixes; | ||
using F0.CodeAnalysis.Diagnostics; | ||
|
||
namespace F0.Benchmarks.CodeAnalysis.CodeFixes; | ||
|
||
public class DeclareRecordClassExplicitlyBenchmarks | ||
{ | ||
private readonly CodeFixBenchmark<F02001ImplicitRecordClassDeclaration, DeclareRecordClassExplicitly> benchmark; | ||
|
||
public DeclareRecordClassExplicitlyBenchmarks() | ||
{ | ||
benchmark = Measure.CodeFix<F02001ImplicitRecordClassDeclaration, DeclareRecordClassExplicitly>(); | ||
} | ||
|
||
[GlobalSetup] | ||
public void Setup() | ||
{ | ||
var code = | ||
@"using System; | ||
record Record; | ||
"; | ||
|
||
benchmark.Initialize(code, LanguageVersion.Latest); | ||
} | ||
|
||
[Benchmark] | ||
public Task UseConstantNullPattern() | ||
=> benchmark.InvokeAsync(); | ||
|
||
[GlobalCleanup] | ||
public void Cleanup() | ||
{ | ||
var code = | ||
@"using System; | ||
record class Record; | ||
"; | ||
|
||
benchmark.Inspect(code); | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
...ers.Benchmarks/CodeAnalysis/Diagnostics/F02001ImplicitRecordClassDeclarationBenchmarks.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
using F0.Benchmarking.CodeAnalysis; | ||
using F0.Benchmarking.CodeAnalysis.Diagnostics; | ||
using F0.CodeAnalysis.Diagnostics; | ||
|
||
namespace F0.Benchmarks.CodeAnalysis.Diagnostics; | ||
|
||
public class F02001ImplicitRecordClassDeclarationBenchmarks | ||
{ | ||
private readonly DiagnosticAnalyzerBenchmark<F02001ImplicitRecordClassDeclaration> benchmark; | ||
|
||
public F02001ImplicitRecordClassDeclarationBenchmarks() | ||
{ | ||
benchmark = Measure.DiagnosticAnalyzer<F02001ImplicitRecordClassDeclaration>(); | ||
} | ||
|
||
[GlobalSetup] | ||
public void Setup() | ||
{ | ||
var code = | ||
@"using System; | ||
record Record(int Number, string Text); | ||
record class RecordClass(int Number, string Text); | ||
record struct RecordStruct(int Number, string Text); | ||
readonly record struct ReadonlyRecordStruct(int Number, string Text); | ||
[Obsolete] | ||
sealed record @record<T> : IDisposable where T : notnull | ||
{ | ||
public T Property { get; init; } | ||
public void Dispose() => throw new NotImplementedException(); | ||
} | ||
"; | ||
|
||
benchmark.Initialize(code, LanguageVersion.Latest); | ||
} | ||
|
||
[Benchmark] | ||
public Task GoToStatementConsideredHarmful() | ||
=> benchmark.InvokeAsync(); | ||
|
||
[GlobalCleanup] | ||
public void Cleanup() | ||
{ | ||
var diagnostics = benchmark.CreateDiagnostics( | ||
d => d.WithLocation(3, 8, 3, 14).WithArguments("Record"), | ||
d => d.WithLocation(9, 15, 9, 22).WithArguments("record") | ||
); | ||
|
||
benchmark.Inspect(diagnostics); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.