Skip to content

Commit ad639a8

Browse files
committed
Updated SA1516
1 parent 1a0eaae commit ad639a8

12 files changed

Lines changed: 832 additions & 35 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/LayoutRules/SA1516CodeFixProvider.cs

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
namespace StyleCop.Analyzers.LayoutRules
55
{
6+
using System;
67
using System.Collections.Generic;
78
using System.Collections.Immutable;
89
using System.Composition;
@@ -39,16 +40,44 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
3940

4041
foreach (Diagnostic diagnostic in context.Diagnostics)
4142
{
43+
var insertBlankLine = DetermineCodeFixAction(diagnostic);
44+
if (insertBlankLine == null)
45+
{
46+
continue;
47+
}
48+
4249
context.RegisterCodeFix(
4350
CodeAction.Create(
44-
LayoutResources.SA1516CodeFix,
45-
cancellationToken => GetTransformedDocumentAsync(context.Document, syntaxRoot, diagnostic, context.CancellationToken),
51+
insertBlankLine.Value ? LayoutResources.SA1516CodeFixInsert : LayoutResources.SA1516CodeFixRemove,
52+
cancellationToken => GetTransformedDocumentAsync(context.Document, syntaxRoot, diagnostic, insertBlankLine.Value, context.CancellationToken),
4653
nameof(SA1516CodeFixProvider)),
4754
diagnostic);
4855
}
4956
}
5057

51-
private static Task<Document> GetTransformedDocumentAsync(Document document, SyntaxNode syntaxRoot, Diagnostic diagnostic, CancellationToken cancellationToken)
58+
private static bool? DetermineCodeFixAction(Diagnostic diagnostic)
59+
{
60+
string codeFixAction;
61+
62+
if (!diagnostic.Properties.TryGetValue(SA1516ElementsMustBeSeparatedByBlankLine.CodeFixActionKey, out codeFixAction))
63+
{
64+
return null;
65+
}
66+
67+
switch (codeFixAction)
68+
{
69+
case SA1516ElementsMustBeSeparatedByBlankLine.InsertBlankLineValue:
70+
return true;
71+
72+
case SA1516ElementsMustBeSeparatedByBlankLine.RemoveBlankLinesValue:
73+
return false;
74+
75+
default:
76+
return null;
77+
}
78+
}
79+
80+
private static Task<Document> GetTransformedDocumentAsync(Document document, SyntaxNode syntaxRoot, Diagnostic diagnostic, bool insertBlankLine, CancellationToken cancellationToken)
5281
{
5382
var node = syntaxRoot.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true);
5483
node = GetRelevantNode(node);
@@ -58,18 +87,30 @@ private static Task<Document> GetTransformedDocumentAsync(Document document, Syn
5887
return Task.FromResult(document);
5988
}
6089

61-
var leadingTrivia = node.GetLeadingTrivia();
62-
63-
var newTriviaList = leadingTrivia;
64-
newTriviaList = newTriviaList.Insert(0, SyntaxFactory.CarriageReturnLineFeed);
65-
66-
var newNode = node.WithLeadingTrivia(newTriviaList);
90+
SyntaxNode newNode = ProcessNode(node, insertBlankLine);
6791
var newSyntaxRoot = syntaxRoot.ReplaceNode(node, newNode);
6892
var newDocument = document.WithSyntaxRoot(newSyntaxRoot);
6993

7094
return Task.FromResult(newDocument);
7195
}
7296

97+
private static SyntaxNode ProcessNode(SyntaxNode node, bool insertBlankLine)
98+
{
99+
var leadingTrivia = node.GetLeadingTrivia();
100+
SyntaxTriviaList newLeadingTrivia;
101+
102+
if (insertBlankLine)
103+
{
104+
newLeadingTrivia = leadingTrivia.Insert(0, SyntaxFactory.CarriageReturnLineFeed);
105+
}
106+
else
107+
{
108+
newLeadingTrivia = leadingTrivia.WithoutBlankLines();
109+
}
110+
111+
return node.WithLeadingTrivia(newLeadingTrivia);
112+
}
113+
73114
private static SyntaxNode GetRelevantNode(SyntaxNode innerNode)
74115
{
75116
SyntaxNode currentNode = innerNode;
@@ -112,7 +153,7 @@ private class FixAll : DocumentBasedFixAllProvider
112153
new FixAll();
113154

114155
protected override string CodeActionTitle =>
115-
LayoutResources.SA1516CodeFix;
156+
LayoutResources.SA1516CodeFixAll;
116157

117158
protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document, ImmutableArray<Diagnostic> diagnostics)
118159
{
@@ -123,26 +164,26 @@ protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fi
123164

124165
var syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);
125166

126-
List<SyntaxNode> nodes = new List<SyntaxNode>();
167+
Dictionary<SyntaxNode, SyntaxNode> replaceMap = new Dictionary<SyntaxNode, SyntaxNode>();
127168

128169
foreach (var diagnostic in diagnostics)
129170
{
171+
var insertBlankLine = DetermineCodeFixAction(diagnostic);
172+
if (insertBlankLine == null)
173+
{
174+
continue;
175+
}
176+
130177
var node = syntaxRoot.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true);
131178
node = GetRelevantNode(node);
132179

133180
if (node != null)
134181
{
135-
nodes.Add(node);
182+
replaceMap[node] = ProcessNode(node, insertBlankLine.Value);
136183
}
137184
}
138185

139-
return syntaxRoot.ReplaceNodes(nodes, (oldNode, newNode) =>
140-
{
141-
var newTriviaList = newNode.GetLeadingTrivia();
142-
newTriviaList = newTriviaList.Insert(0, SyntaxFactory.CarriageReturnLineFeed);
143-
144-
return newNode.WithLeadingTrivia(newTriviaList);
145-
});
186+
return syntaxRoot.ReplaceNodes(replaceMap.Keys, (original, rewritten) => replaceMap[original]);
146187
}
147188
}
148189
}

0 commit comments

Comments
 (0)