Skip to content

Commit c9cf96f

Browse files
committed
Implement the 'elementOrder' configuration property
Fixes #1745
1 parent 3cb375e commit c9cf96f

15 files changed

Lines changed: 606 additions & 286 deletions

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/OrderingRules/ElementOrderCodeFixProvider.cs

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace StyleCop.Analyzers.OrderingRules
1515
using Microsoft.CodeAnalysis.CodeFixes;
1616
using Microsoft.CodeAnalysis.CSharp;
1717
using Microsoft.CodeAnalysis.CSharp.Syntax;
18+
using Settings.ObjectModel;
1819

1920
/// <summary>
2021
/// Implements code fixes for element ordering rules.
@@ -57,7 +58,8 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
5758

5859
private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
5960
{
60-
var orderingChecks = await GetEnabledRulesForDocumentAsync(document, cancellationToken).ConfigureAwait(false);
61+
var settings = SettingsHelper.GetStyleCopSettings(document.Project.AnalyzerOptions, cancellationToken);
62+
var elementOrder = settings.OrderingRules.ElementOrder;
6163
var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
6264
var indentationOptions = IndentationOptions.FromDocument(document);
6365

@@ -67,68 +69,57 @@ private static async Task<Document> GetTransformedDocumentAsync(Document documen
6769
return document;
6870
}
6971

70-
syntaxRoot = UpdateSyntaxRoot(memberDeclaration, orderingChecks, syntaxRoot, indentationOptions);
72+
syntaxRoot = UpdateSyntaxRoot(memberDeclaration, elementOrder, syntaxRoot, indentationOptions);
7173

7274
return document.WithSyntaxRoot(syntaxRoot);
7375
}
7476

75-
private static async Task<ElementOrderingChecks> GetEnabledRulesForDocumentAsync(Document document, CancellationToken cancellationToken)
76-
{
77-
SemanticModel semanticModel;
78-
if (!document.TryGetSemanticModel(out semanticModel))
79-
{
80-
semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
81-
}
82-
83-
return ElementOrderingChecks.GetElementOrderingChecksForSemanticModel(semanticModel);
84-
}
85-
86-
private static SyntaxNode UpdateSyntaxRoot(MemberDeclarationSyntax memberDeclaration, ElementOrderingChecks checks, SyntaxNode syntaxRoot, IndentationOptions indentationOptions)
77+
private static SyntaxNode UpdateSyntaxRoot(MemberDeclarationSyntax memberDeclaration, ImmutableArray<OrderingTrait> elementOrder, SyntaxNode syntaxRoot, IndentationOptions indentationOptions)
8778
{
8879
var parentDeclaration = memberDeclaration.Parent;
89-
var memberToMove = new MemberOrderHelper(memberDeclaration, checks);
80+
var memberToMove = new MemberOrderHelper(memberDeclaration, elementOrder);
9081

9182
if (parentDeclaration is TypeDeclarationSyntax)
9283
{
93-
return HandleTypeDeclaration(memberToMove, (TypeDeclarationSyntax)parentDeclaration, checks, syntaxRoot, indentationOptions);
84+
return HandleTypeDeclaration(memberToMove, (TypeDeclarationSyntax)parentDeclaration, elementOrder, syntaxRoot, indentationOptions);
9485
}
9586

9687
if (parentDeclaration is NamespaceDeclarationSyntax)
9788
{
98-
return HandleNamespaceDeclaration(memberToMove, (NamespaceDeclarationSyntax)parentDeclaration, checks, syntaxRoot, indentationOptions);
89+
return HandleNamespaceDeclaration(memberToMove, (NamespaceDeclarationSyntax)parentDeclaration, elementOrder, syntaxRoot, indentationOptions);
9990
}
10091

10192
if (parentDeclaration is CompilationUnitSyntax)
10293
{
103-
return HandleCompilationUnitDeclaration(memberToMove, (CompilationUnitSyntax)parentDeclaration, checks, syntaxRoot, indentationOptions);
94+
return HandleCompilationUnitDeclaration(memberToMove, (CompilationUnitSyntax)parentDeclaration, elementOrder, syntaxRoot, indentationOptions);
10495
}
10596

10697
return syntaxRoot;
10798
}
10899

109-
private static SyntaxNode HandleTypeDeclaration(MemberOrderHelper memberOrder, TypeDeclarationSyntax typeDeclarationNode, ElementOrderingChecks checks, SyntaxNode syntaxRoot, IndentationOptions indentationOptions)
100+
private static SyntaxNode HandleTypeDeclaration(MemberOrderHelper memberOrder, TypeDeclarationSyntax typeDeclarationNode, ImmutableArray<OrderingTrait> elementOrder, SyntaxNode syntaxRoot, IndentationOptions indentationOptions)
110101
{
111-
return OrderMember(memberOrder, typeDeclarationNode.Members, checks, syntaxRoot, indentationOptions);
102+
return OrderMember(memberOrder, typeDeclarationNode.Members, elementOrder, syntaxRoot, indentationOptions);
112103
}
113104

114-
private static SyntaxNode HandleCompilationUnitDeclaration(MemberOrderHelper memberOrder, CompilationUnitSyntax compilationUnitDeclaration, ElementOrderingChecks checks, SyntaxNode syntaxRoot, IndentationOptions indentationOptions)
105+
private static SyntaxNode HandleCompilationUnitDeclaration(MemberOrderHelper memberOrder, CompilationUnitSyntax compilationUnitDeclaration, ImmutableArray<OrderingTrait> elementOrder, SyntaxNode syntaxRoot, IndentationOptions indentationOptions)
115106
{
116-
return OrderMember(memberOrder, compilationUnitDeclaration.Members, checks, syntaxRoot, indentationOptions);
107+
return OrderMember(memberOrder, compilationUnitDeclaration.Members, elementOrder, syntaxRoot, indentationOptions);
117108
}
118109

119-
private static SyntaxNode HandleNamespaceDeclaration(MemberOrderHelper memberOrder, NamespaceDeclarationSyntax namespaceDeclaration, ElementOrderingChecks checks, SyntaxNode syntaxRoot, IndentationOptions indentationOptions)
110+
private static SyntaxNode HandleNamespaceDeclaration(MemberOrderHelper memberOrder, NamespaceDeclarationSyntax namespaceDeclaration, ImmutableArray<OrderingTrait> elementOrder, SyntaxNode syntaxRoot, IndentationOptions indentationOptions)
120111
{
121-
return OrderMember(memberOrder, namespaceDeclaration.Members, checks, syntaxRoot, indentationOptions);
112+
return OrderMember(memberOrder, namespaceDeclaration.Members, elementOrder, syntaxRoot, indentationOptions);
122113
}
123114

124-
private static SyntaxNode OrderMember(MemberOrderHelper memberOrder, SyntaxList<MemberDeclarationSyntax> members, ElementOrderingChecks checks, SyntaxNode syntaxRoot, IndentationOptions indentationOptions)
115+
private static SyntaxNode OrderMember(MemberOrderHelper memberOrder, SyntaxList<MemberDeclarationSyntax> members, ImmutableArray<OrderingTrait> elementOrder, SyntaxNode syntaxRoot, IndentationOptions indentationOptions)
125116
{
126117
var memberIndex = members.IndexOf(memberOrder.Member);
127118
MemberOrderHelper target = default(MemberOrderHelper);
128119

129120
for (var i = memberIndex - 1; i >= 0; --i)
130121
{
131-
var orderHelper = new MemberOrderHelper(members[i], checks);
122+
var orderHelper = new MemberOrderHelper(members[i], elementOrder);
132123
if (orderHelper.Priority < memberOrder.Priority)
133124
{
134125
target = orderHelper;
@@ -276,7 +267,8 @@ protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fi
276267
}
277268

278269
var indentationOptions = IndentationOptions.FromDocument(document);
279-
var orderingChecks = await GetEnabledRulesForDocumentAsync(document, fixAllContext.CancellationToken).ConfigureAwait(false);
270+
var settings = SettingsHelper.GetStyleCopSettings(document.Project.AnalyzerOptions, fixAllContext.CancellationToken);
271+
var elementOrder = settings.OrderingRules.ElementOrder;
280272
var syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);
281273

282274
var trackedDiagnosticMembers = new List<MemberDeclarationSyntax>();
@@ -296,7 +288,7 @@ protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fi
296288
foreach (var member in trackedDiagnosticMembers)
297289
{
298290
var memberDeclaration = syntaxRoot.GetCurrentNode(member);
299-
syntaxRoot = UpdateSyntaxRoot(memberDeclaration, orderingChecks, syntaxRoot, indentationOptions);
291+
syntaxRoot = UpdateSyntaxRoot(memberDeclaration, elementOrder, syntaxRoot, indentationOptions);
300292
}
301293

302294
return syntaxRoot;

StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1203UnitTests.cs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace StyleCop.Analyzers.Test.OrderingRules
1414

1515
public class SA1203UnitTests : CodeFixVerifier
1616
{
17-
private bool suppressSA1202 = false;
17+
private bool orderByAccess = true;
1818

1919
[Fact]
2020
public async Task TestNoDiagnosticAsync()
@@ -385,13 +385,14 @@ public async Task TestOnlyLeadingWhitespaceIsMovedAsync()
385385
}
386386

387387
/// <summary>
388-
/// Verifies that the code fix will move the non constant fields before the constant ones with SA1202 suppressed.
388+
/// Verifies that the code fix will move the non-constant fields before the constant ones when element access is
389+
/// not considered for ordering.
389390
/// </summary>
390391
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
391392
[Fact]
392-
public async Task TestCodeFixWithSA1202SuppressedAsync()
393+
public async Task TestCodeFixWithoutOrderByAccessAsync()
393394
{
394-
this.suppressSA1202 = true;
395+
this.orderByAccess = false;
395396

396397
var testCode = @"public class Foo
397398
{
@@ -435,6 +436,29 @@ public async Task TestCodeFixWithSA1202SuppressedAsync()
435436
await this.VerifyCSharpFixAsync(testCode, fixedTestCode).ConfigureAwait(false);
436437
}
437438

439+
protected override string GetSettings()
440+
{
441+
if (!this.orderByAccess)
442+
{
443+
return @"
444+
{
445+
""settings"": {
446+
""orderingRules"": {
447+
""elementOrder"": [
448+
""kind"",
449+
""constant"",
450+
""static"",
451+
""readonly"",
452+
]
453+
}
454+
}
455+
}
456+
";
457+
}
458+
459+
return base.GetSettings();
460+
}
461+
438462
protected override IEnumerable<DiagnosticAnalyzer> GetCSharpDiagnosticAnalyzers()
439463
{
440464
yield return new SA1203ConstantsMustAppearBeforeFields();
@@ -444,13 +468,5 @@ protected override CodeFixProvider GetCSharpCodeFixProvider()
444468
{
445469
return new ElementOrderCodeFixProvider();
446470
}
447-
448-
protected override IEnumerable<string> GetDisabledDiagnostics()
449-
{
450-
if (this.suppressSA1202)
451-
{
452-
yield return SA1202ElementsMustBeOrderedByAccess.DiagnosticId;
453-
}
454-
}
455471
}
456472
}

StyleCop.Analyzers/StyleCop.Analyzers/Helpers/ElementOrderingChecks.cs

Lines changed: 0 additions & 78 deletions
This file was deleted.

0 commit comments

Comments
 (0)