Skip to content

Commit 2b5b96a

Browse files
committed
Merge pull request #1519 from pdelvo/SA1121FA
2 parents c312743 + d545b84 commit 2b5b96a

1 file changed

Lines changed: 67 additions & 34 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1121CodeFixProvider.cs

Lines changed: 67 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,23 @@ namespace StyleCop.Analyzers.ReadabilityRules
2727
[Shared]
2828
internal class SA1121CodeFixProvider : CodeFixProvider
2929
{
30-
private static readonly Dictionary<SpecialType, SyntaxKind> PredefinedSpecialTypes = new Dictionary<SpecialType, SyntaxKind>
30+
private static readonly Dictionary<SpecialType, PredefinedTypeSyntax> PredefinedSpecialTypes = new Dictionary<SpecialType, PredefinedTypeSyntax>
3131
{
32-
[SpecialType.System_Boolean] = SyntaxKind.BoolKeyword,
33-
[SpecialType.System_Byte] = SyntaxKind.ByteKeyword,
34-
[SpecialType.System_Char] = SyntaxKind.CharKeyword,
35-
[SpecialType.System_Decimal] = SyntaxKind.DecimalKeyword,
36-
[SpecialType.System_Double] = SyntaxKind.DoubleKeyword,
37-
[SpecialType.System_Int16] = SyntaxKind.ShortKeyword,
38-
[SpecialType.System_Int32] = SyntaxKind.IntKeyword,
39-
[SpecialType.System_Int64] = SyntaxKind.LongKeyword,
40-
[SpecialType.System_Object] = SyntaxKind.ObjectKeyword,
41-
[SpecialType.System_SByte] = SyntaxKind.SByteKeyword,
42-
[SpecialType.System_Single] = SyntaxKind.FloatKeyword,
43-
[SpecialType.System_String] = SyntaxKind.StringKeyword,
44-
[SpecialType.System_UInt16] = SyntaxKind.UShortKeyword,
45-
[SpecialType.System_UInt32] = SyntaxKind.UIntKeyword,
46-
[SpecialType.System_UInt64] = SyntaxKind.ULongKeyword
32+
[SpecialType.System_Boolean] = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.BoolKeyword)),
33+
[SpecialType.System_Byte] = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ByteKeyword)),
34+
[SpecialType.System_Char] = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.CharKeyword)),
35+
[SpecialType.System_Decimal] = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.DecimalKeyword)),
36+
[SpecialType.System_Double] = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.DoubleKeyword)),
37+
[SpecialType.System_Int16] = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ShortKeyword)),
38+
[SpecialType.System_Int32] = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)),
39+
[SpecialType.System_Int64] = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.LongKeyword)),
40+
[SpecialType.System_Object] = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ObjectKeyword)),
41+
[SpecialType.System_SByte] = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.SByteKeyword)),
42+
[SpecialType.System_Single] = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.FloatKeyword)),
43+
[SpecialType.System_String] = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.StringKeyword)),
44+
[SpecialType.System_UInt16] = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.UShortKeyword)),
45+
[SpecialType.System_UInt32] = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.UIntKeyword)),
46+
[SpecialType.System_UInt64] = SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ULongKeyword))
4747
};
4848

4949
private static readonly ImmutableArray<string> FixableDiagnostics =
@@ -55,7 +55,7 @@ internal class SA1121CodeFixProvider : CodeFixProvider
5555
/// <inheritdoc/>
5656
public override FixAllProvider GetFixAllProvider()
5757
{
58-
return CustomFixAllProviders.BatchFixer;
58+
return FixAll.Instance;
5959
}
6060

6161
/// <inheritdoc/>
@@ -74,17 +74,8 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
7474
return SpecializedTasks.CompletedTask;
7575
}
7676

77-
private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
77+
private static SyntaxNode ComputeReplacement(SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken)
7878
{
79-
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
80-
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
81-
if (semanticModel == null)
82-
{
83-
return document;
84-
}
85-
86-
var node = root.FindNode(diagnostic.Location.SourceSpan, findInsideTrivia: true, getInnermostNodeForTie: true);
87-
8879
var memberAccess = node.Parent as MemberAccessExpressionSyntax;
8980
if (memberAccess != null)
9081
{
@@ -96,14 +87,13 @@ private static async Task<Document> GetTransformedDocumentAsync(Document documen
9687

9788
var type = semanticModel.GetSymbolInfo(node, cancellationToken).Symbol as INamedTypeSymbol;
9889

99-
SyntaxKind specialKind;
100-
if (!PredefinedSpecialTypes.TryGetValue(type.SpecialType, out specialKind))
90+
PredefinedTypeSyntax typeSyntax;
91+
if (!PredefinedSpecialTypes.TryGetValue(type.SpecialType, out typeSyntax))
10192
{
102-
return document;
93+
return node;
10394
}
10495

10596
SyntaxNode newNode;
106-
PredefinedTypeSyntax typeSyntax = SyntaxFactory.PredefinedType(SyntaxFactory.Token(specialKind));
10797
if (node is CrefSyntax)
10898
{
10999
newNode = SyntaxFactory.TypeCref(typeSyntax);
@@ -113,12 +103,55 @@ private static async Task<Document> GetTransformedDocumentAsync(Document documen
113103
newNode = typeSyntax;
114104
}
115105

116-
newNode = newNode
117-
.WithTriviaFrom(node)
118-
.WithoutFormatting();
106+
return newNode.WithTriviaFrom(node).WithoutFormatting();
107+
}
108+
109+
private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
110+
{
111+
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
112+
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
113+
if (semanticModel == null)
114+
{
115+
return document;
116+
}
117+
118+
var node = root.FindNode(diagnostic.Location.SourceSpan, findInsideTrivia: true, getInnermostNodeForTie: true);
119+
120+
var newNode = ComputeReplacement(semanticModel, node, cancellationToken);
119121

120122
var newRoot = root.ReplaceNode(node, newNode);
121123
return document.WithSyntaxRoot(newRoot);
122124
}
125+
126+
private class FixAll : DocumentBasedFixAllProvider
127+
{
128+
public static FixAllProvider Instance { get; }
129+
= new FixAll();
130+
131+
protected override string CodeActionTitle
132+
=> ReadabilityResources.SA1121CodeFix;
133+
134+
protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
135+
{
136+
var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
137+
if (diagnostics.IsEmpty)
138+
{
139+
return null;
140+
}
141+
142+
var syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);
143+
var semanticModel = await document.GetSemanticModelAsync(fixAllContext.CancellationToken).ConfigureAwait(false);
144+
145+
List<SyntaxNode> nodesToReplace = new List<SyntaxNode>(diagnostics.Length);
146+
foreach (var diagnostic in diagnostics)
147+
{
148+
var node = syntaxRoot.FindNode(diagnostic.Location.SourceSpan, findInsideTrivia: true, getInnermostNodeForTie: true);
149+
150+
nodesToReplace.Add(node);
151+
}
152+
153+
return syntaxRoot.ReplaceNodes(nodesToReplace, (originalNode, rewrittenNode) => ComputeReplacement(semanticModel, originalNode, fixAllContext.CancellationToken));
154+
}
155+
}
123156
}
124157
}

0 commit comments

Comments
 (0)