33
44namespace StyleCop . Analyzers . ReadabilityRules
55{
6+ using System ;
67 using System . Collections . Generic ;
78 using System . Collections . Immutable ;
89 using System . Composition ;
@@ -27,23 +28,23 @@ namespace StyleCop.Analyzers.ReadabilityRules
2728 [ Shared ]
2829 internal class SA1121CodeFixProvider : CodeFixProvider
2930 {
30- private static readonly Dictionary < SpecialType , SyntaxKind > PredefinedSpecialTypes = new Dictionary < SpecialType , SyntaxKind >
31+ private static readonly Dictionary < SpecialType , PredefinedTypeSyntax > PredefinedSpecialTypes = new Dictionary < SpecialType , PredefinedTypeSyntax >
3132 {
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
33+ [ SpecialType . System_Boolean ] = SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . BoolKeyword ) ) ,
34+ [ SpecialType . System_Byte ] = SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . ByteKeyword ) ) ,
35+ [ SpecialType . System_Char ] = SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . CharKeyword ) ) ,
36+ [ SpecialType . System_Decimal ] = SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . DecimalKeyword ) ) ,
37+ [ SpecialType . System_Double ] = SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . DoubleKeyword ) ) ,
38+ [ SpecialType . System_Int16 ] = SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . ShortKeyword ) ) ,
39+ [ SpecialType . System_Int32 ] = SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . IntKeyword ) ) ,
40+ [ SpecialType . System_Int64 ] = SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . LongKeyword ) ) ,
41+ [ SpecialType . System_Object ] = SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . ObjectKeyword ) ) ,
42+ [ SpecialType . System_SByte ] = SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . SByteKeyword ) ) ,
43+ [ SpecialType . System_Single ] = SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . FloatKeyword ) ) ,
44+ [ SpecialType . System_String ] = SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . StringKeyword ) ) ,
45+ [ SpecialType . System_UInt16 ] = SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . UShortKeyword ) ) ,
46+ [ SpecialType . System_UInt32 ] = SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . UIntKeyword ) ) ,
47+ [ SpecialType . System_UInt64 ] = SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( SyntaxKind . ULongKeyword ) )
4748 } ;
4849
4950 private static readonly ImmutableArray < string > FixableDiagnostics =
@@ -55,7 +56,7 @@ internal class SA1121CodeFixProvider : CodeFixProvider
5556 /// <inheritdoc/>
5657 public override FixAllProvider GetFixAllProvider ( )
5758 {
58- return CustomFixAllProviders . BatchFixer ;
59+ return FixAll . Instance ;
5960 }
6061
6162 /// <inheritdoc/>
@@ -74,17 +75,8 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
7475 return SpecializedTasks . CompletedTask ;
7576 }
7677
77- private static async Task < Document > GetTransformedDocumentAsync ( Document document , Diagnostic diagnostic , CancellationToken cancellationToken )
78+ private static SyntaxNode ComputeReplacement ( SemanticModel semanticModel , SyntaxNode node , CancellationToken cancellationToken )
7879 {
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-
8880 var memberAccess = node . Parent as MemberAccessExpressionSyntax ;
8981 if ( memberAccess != null )
9082 {
@@ -96,14 +88,13 @@ private static async Task<Document> GetTransformedDocumentAsync(Document documen
9688
9789 var type = semanticModel . GetSymbolInfo ( node , cancellationToken ) . Symbol as INamedTypeSymbol ;
9890
99- SyntaxKind specialKind ;
100- if ( ! PredefinedSpecialTypes . TryGetValue ( type . SpecialType , out specialKind ) )
91+ PredefinedTypeSyntax typeSyntax ;
92+ if ( ! PredefinedSpecialTypes . TryGetValue ( type . SpecialType , out typeSyntax ) )
10193 {
102- return document ;
94+ return node ;
10395 }
10496
10597 SyntaxNode newNode ;
106- PredefinedTypeSyntax typeSyntax = SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( specialKind ) ) ;
10798 if ( node is CrefSyntax )
10899 {
109100 newNode = SyntaxFactory . TypeCref ( typeSyntax ) ;
@@ -113,12 +104,55 @@ private static async Task<Document> GetTransformedDocumentAsync(Document documen
113104 newNode = typeSyntax ;
114105 }
115106
116- newNode = newNode
117- . WithTriviaFrom ( node )
118- . WithoutFormatting ( ) ;
107+ return newNode . WithTriviaFrom ( node ) . WithoutFormatting ( ) ;
108+ }
109+
110+ private static async Task < Document > GetTransformedDocumentAsync ( Document document , Diagnostic diagnostic , CancellationToken cancellationToken )
111+ {
112+ var root = await document . GetSyntaxRootAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
113+ var semanticModel = await document . GetSemanticModelAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
114+ if ( semanticModel == null )
115+ {
116+ return document ;
117+ }
118+
119+ var node = root . FindNode ( diagnostic . Location . SourceSpan , findInsideTrivia : true , getInnermostNodeForTie : true ) ;
120+
121+ var newNode = ComputeReplacement ( semanticModel , node , cancellationToken ) ;
119122
120123 var newRoot = root . ReplaceNode ( node , newNode ) ;
121124 return document . WithSyntaxRoot ( newRoot ) ;
122125 }
126+
127+ private class FixAll : DocumentBasedFixAllProvider
128+ {
129+ public static FixAllProvider Instance { get ; }
130+ = new FixAll ( ) ;
131+
132+ protected override string CodeActionTitle
133+ => ReadabilityResources . SA1121CodeFix ;
134+
135+ protected override async Task < SyntaxNode > FixAllInDocumentAsync ( FixAllContext fixAllContext , Document document )
136+ {
137+ var diagnostics = await fixAllContext . GetDocumentDiagnosticsAsync ( document ) . ConfigureAwait ( false ) ;
138+ if ( diagnostics . IsEmpty )
139+ {
140+ return null ;
141+ }
142+
143+ var syntaxRoot = await document . GetSyntaxRootAsync ( ) . ConfigureAwait ( false ) ;
144+ var semanticModel = await document . GetSemanticModelAsync ( fixAllContext . CancellationToken ) . ConfigureAwait ( false ) ;
145+
146+ List < SyntaxNode > nodesToReplace = new List < SyntaxNode > ( diagnostics . Length ) ;
147+ foreach ( var diagnostic in diagnostics )
148+ {
149+ var node = syntaxRoot . FindNode ( diagnostic . Location . SourceSpan , findInsideTrivia : true , getInnermostNodeForTie : true ) ;
150+
151+ nodesToReplace . Add ( node ) ;
152+ }
153+
154+ return syntaxRoot . ReplaceNodes ( nodesToReplace , ( originalNode , rewrittenNode ) => ComputeReplacement ( semanticModel , originalNode , fixAllContext . CancellationToken ) ) ;
155+ }
156+ }
123157 }
124158}
0 commit comments