Skip to content

Commit

Permalink
Update SA1212 to also trigger for an init accessor before a getter
Browse files Browse the repository at this point in the history
  • Loading branch information
bjornhellander committed May 23, 2023
1 parent b80f0c2 commit c5aab58
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,91 @@

namespace StyleCop.Analyzers.Test.CSharp9.OrderingRules
{
using System.Threading;
using System.Threading.Tasks;
using StyleCop.Analyzers.Test.CSharp8.OrderingRules;
using StyleCop.Analyzers.Test.Verifiers;
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; }
}";

var test = new CSharpTest
{
TestCode = testCode,
FixedCode = fixedCode,
ReferenceAssemblies = GenericAnalyzerTest.ReferenceAssembliesNet50,
};
await test.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;
}
}
}";

var test = new CSharpTest
{
TestCode = testCode,
FixedCode = fixedCode,
ReferenceAssemblies = GenericAnalyzerTest.ReferenceAssembliesNet50,
};
await test.RunAsync(CancellationToken.None).ConfigureAwait(false);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ public int Prop
}

[Fact]
public async Task TestAutoPropertydDeclarationSetterBeforeGetterAsync()
public async Task TestAutoPropertyDeclarationSetterBeforeGetterAsync()
{
var testCode = @"
public class Foo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ internal static class SyntaxKindEx
public const SyntaxKind NullableDirectiveTrivia = (SyntaxKind)9055;
public const SyntaxKind FunctionPointerType = (SyntaxKind)9056;
public const SyntaxKind FunctionPointerParameter = (SyntaxKind)9057;
public const SyntaxKind InitAccessorDeclaration = (SyntaxKind)9060;
public const SyntaxKind WithExpression = (SyntaxKind)9061;
public const SyntaxKind WithInitializerExpression = (SyntaxKind)9062;
public const SyntaxKind RecordDeclaration = (SyntaxKind)9063;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/// <summary>
/// A get accessor appears after a set accessor within a property or indexer.
Expand Down Expand Up @@ -99,7 +100,7 @@ private static void AnalyzeProperty(SyntaxNodeAnalysisContext context, BasePrope
return;
}

if (accessors[0].Kind() == SyntaxKind.SetAccessorDeclaration &&
if ((accessors[0].Kind() == SyntaxKind.SetAccessorDeclaration || accessors[0].Kind() == SyntaxKindEx.InitAccessorDeclaration) &&
accessors[1].Kind() == SyntaxKind.GetAccessorDeclaration)
{
context.ReportDiagnostic(Diagnostic.Create(Descriptor, accessors[0].GetLocation()));
Expand Down
4 changes: 2 additions & 2 deletions documentation/SA1212.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down

0 comments on commit c5aab58

Please sign in to comment.