diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/OrderingRules/SA1212CSharp9UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/OrderingRules/SA1212CSharp9UnitTests.cs index 15301157f..9c0dfe925 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/OrderingRules/SA1212CSharp9UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/OrderingRules/SA1212CSharp9UnitTests.cs @@ -3,9 +3,89 @@ namespace StyleCop.Analyzers.Test.CSharp9.OrderingRules { + using System.Threading; + using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp8.OrderingRules; + using Xunit; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.OrderingRules.SA1212PropertyAccessorsMustFollowOrder, + StyleCop.Analyzers.OrderingRules.SA1212SA1213CodeFixProvider>; public class SA1212CSharp9UnitTests : SA1212CSharp8UnitTests { + [Fact] + [WorkItem(3652, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3652")] + public async Task TestAutoPropertyDeclarationInitBeforeGetterAsync() + { + var testCode = @" +public class Foo +{ + public int Prop { [|init;|] get; } +}"; + + var fixedCode = @" +public class Foo +{ + public int Prop { get; init; } +}"; + + await new CSharpTest + { + TestCode = testCode, + FixedCode = fixedCode, + ReferenceAssemblies = ReferenceAssemblies.Net.Net50, + }.RunAsync(CancellationToken.None).ConfigureAwait(false); + } + + [Fact] + [WorkItem(3652, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3652")] + public async Task TestPropertyWithBackingFieldDeclarationInitBeforeGetterAsync() + { + var testCode = @" +public class Foo +{ + private int i = 0; + + public int Prop + { + [|init + { + i = value; + }|] + + get + { + return i; + } + } +}"; + + var fixedCode = @" +public class Foo +{ + private int i = 0; + + public int Prop + { + get + { + return i; + } + + init + { + i = value; + } + } +}"; + + await new CSharpTest + { + TestCode = testCode, + FixedCode = fixedCode, + ReferenceAssemblies = ReferenceAssemblies.Net.Net50, + }.RunAsync(CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1212UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1212UnitTests.cs index a9e7d07af..987e709b2 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1212UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1212UnitTests.cs @@ -339,7 +339,7 @@ public int Prop } [Fact] - public async Task TestAutoPropertydDeclarationSetterBeforeGetterAsync() + public async Task TestAutoPropertyDeclarationSetterBeforeGetterAsync() { var testCode = @" public class Foo diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1212PropertyAccessorsMustFollowOrder.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1212PropertyAccessorsMustFollowOrder.cs index 083f7ce6b..a2285c411 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1212PropertyAccessorsMustFollowOrder.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1212PropertyAccessorsMustFollowOrder.cs @@ -11,6 +11,7 @@ namespace StyleCop.Analyzers.OrderingRules using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; + using StyleCop.Analyzers.Lightup; /// /// A get accessor appears after a set accessor within a property or indexer. @@ -99,7 +100,7 @@ private static void AnalyzeProperty(SyntaxNodeAnalysisContext context, BasePrope return; } - if (accessors[0].Kind() == SyntaxKind.SetAccessorDeclaration && + if ((accessors[0].Kind() is SyntaxKind.SetAccessorDeclaration or SyntaxKindEx.InitAccessorDeclaration) && accessors[1].Kind() == SyntaxKind.GetAccessorDeclaration) { context.ReportDiagnostic(Diagnostic.Create(Descriptor, accessors[0].GetLocation())); diff --git a/documentation/SA1212.md b/documentation/SA1212.md index e735b0c09..2790f8ae4 100644 --- a/documentation/SA1212.md +++ b/documentation/SA1212.md @@ -17,11 +17,11 @@ ## Cause -A get accessor appears after a set accessor within a property or indexer. +A get accessor appears after a set or init accessor within a property or indexer. ## Rule description -A violation of this rule occurs when a get accessor is placed after a set accessor within a property or indexer. To comply with this rule, the get accessor should appear before the set accessor. +A violation of this rule occurs when a get accessor is placed after a set or init accessor within a property or indexer. To comply with this rule, the get accessor should appear first. For example, the following code would raise an instance of this violation: