@@ -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