33
44namespace StyleCop . Analyzers . SpacingRules
55{
6+ using System ;
67 using System . Collections . Generic ;
78 using System . Collections . Immutable ;
89 using System . Composition ;
@@ -122,7 +123,7 @@ private static void UpdateReplaceMap(Dictionary<SyntaxToken, SyntaxToken> replac
122123 case TokenSpacingProperties . ActionInsert :
123124 if ( ! replaceMap . ContainsKey ( prevToken ) )
124125 {
125- replaceMap [ token ] = token . WithLeadingTrivia ( token . LeadingTrivia . Add ( SyntaxFactory . Space ) ) ;
126+ UpdateReplaceMap ( replaceMap , token , t => t . WithLeadingTrivia ( token . LeadingTrivia . Add ( SyntaxFactory . Space ) ) ) ;
126127 }
127128
128129 break ;
@@ -136,11 +137,12 @@ private static void UpdateReplaceMap(Dictionary<SyntaxToken, SyntaxToken> replac
136137 break ;
137138 }
138139
139- replaceMap [ prevToken ] = prevToken . WithTrailingTrivia ( ) ;
140+ UpdateReplaceMap ( replaceMap , prevToken , t => t . WithTrailingTrivia ( ) ) ;
141+
140142 if ( ( ! preserveLayout || ! tokenIsFirstInLine )
141143 && triviaList . All ( i => i . IsKind ( SyntaxKind . WhitespaceTrivia ) || i . IsKind ( SyntaxKind . EndOfLineTrivia ) ) )
142144 {
143- replaceMap [ token ] = token . WithLeadingTrivia ( ) ;
145+ UpdateReplaceMap ( replaceMap , token , t => token . WithLeadingTrivia ( ) ) ;
144146 }
145147 else if ( tokenIsFirstInLine && token . IsLastInLine ( ) )
146148 {
@@ -176,41 +178,29 @@ private static void UpdateReplaceMap(Dictionary<SyntaxToken, SyntaxToken> replac
176178 // firstNewLineFollowing was adjusted above to account for the missing case.
177179 trailingTrivia = trailingTrivia . AddRange ( token . TrailingTrivia . Take ( firstNewLineFollowing ) ) ;
178180
179- replaceMap [ token ] = token . WithLeadingTrivia ( ) . WithTrailingTrivia ( trailingTrivia ) ;
181+ UpdateReplaceMap ( replaceMap , token , t => t . WithLeadingTrivia ( ) . WithTrailingTrivia ( trailingTrivia ) ) ;
180182 }
181183 else
182184 {
183185 // Just move the token and keep all surrounding trivia.
184186 SyntaxTriviaList trailingTrivia = triviaList . AddRange ( token . TrailingTrivia ) ;
185- replaceMap [ token ] = token . WithLeadingTrivia ( ) . WithTrailingTrivia ( trailingTrivia ) ;
187+ UpdateReplaceMap ( replaceMap , token , t => t . WithLeadingTrivia ( ) . WithTrailingTrivia ( trailingTrivia ) ) ;
186188 }
187189 }
188190 else
189191 {
190192 SyntaxTriviaList trailingTrivia = triviaList . AddRange ( token . TrailingTrivia . WithoutLeadingWhitespace ( endOfLineIsWhitespace : false ) ) ;
191- replaceMap [ token ] = token . WithLeadingTrivia ( ) . WithTrailingTrivia ( trailingTrivia ) ;
193+ UpdateReplaceMap ( replaceMap , token , t => t . WithLeadingTrivia ( ) . WithTrailingTrivia ( trailingTrivia ) ) ;
192194 }
193195
194196 break ;
195197
196198 case TokenSpacingProperties . ActionRemoveImmediate :
197- SyntaxTriviaList tokenLeadingTrivia = token . LeadingTrivia ;
198- while ( tokenLeadingTrivia . Any ( ) && tokenLeadingTrivia . Last ( ) . IsKind ( SyntaxKind . WhitespaceTrivia ) )
199- {
200- tokenLeadingTrivia = tokenLeadingTrivia . RemoveAt ( tokenLeadingTrivia . Count - 1 ) ;
201- }
202-
203- replaceMap [ token ] = token . WithLeadingTrivia ( tokenLeadingTrivia ) ;
199+ UpdateReplaceMap ( replaceMap , token , t => t . WithLeadingTrivia ( token . LeadingTrivia . WithoutTrailingWhitespace ( endOfLineIsWhitespace : false ) ) ) ;
204200
205- if ( ! tokenLeadingTrivia . Any ( ) )
201+ if ( ! replaceMap [ token ] . LeadingTrivia . Any ( ) )
206202 {
207- SyntaxTriviaList previousTrailingTrivia = prevToken . TrailingTrivia ;
208- while ( previousTrailingTrivia . Any ( ) && previousTrailingTrivia . Last ( ) . IsKind ( SyntaxKind . WhitespaceTrivia ) )
209- {
210- previousTrailingTrivia = previousTrailingTrivia . RemoveAt ( previousTrailingTrivia . Count - 1 ) ;
211- }
212-
213- replaceMap [ prevToken ] = prevToken . WithTrailingTrivia ( previousTrailingTrivia ) ;
203+ UpdateReplaceMap ( replaceMap , prevToken , t => t . WithTrailingTrivia ( t . TrailingTrivia . WithoutTrailingWhitespace ( endOfLineIsWhitespace : false ) ) ) ;
214204 }
215205
216206 break ;
@@ -225,23 +215,40 @@ private static void UpdateReplaceMap(Dictionary<SyntaxToken, SyntaxToken> replac
225215 case TokenSpacingProperties . ActionInsert :
226216 if ( ! replaceMap . ContainsKey ( nextToken ) )
227217 {
228- replaceMap [ token ] = token . WithTrailingTrivia ( token . TrailingTrivia . Insert ( 0 , SyntaxFactory . Space ) ) ;
218+ UpdateReplaceMap ( replaceMap , token , t => t . WithTrailingTrivia ( t . TrailingTrivia . Insert ( 0 , SyntaxFactory . Space ) ) ) ;
229219 }
230220
231221 break ;
232222
233223 case TokenSpacingProperties . ActionRemove :
234224 triviaList = token . TrailingTrivia . AddRange ( nextToken . LeadingTrivia ) ;
235225
236- replaceMap [ token ] = token . WithTrailingTrivia ( ) ;
237- replaceMap [ nextToken ] = nextToken . WithLeadingTrivia ( triviaList . WithoutLeadingWhitespace ( true ) ) ;
226+ UpdateReplaceMap ( replaceMap , token , t => t . WithTrailingTrivia ( ) ) ;
227+ UpdateReplaceMap ( replaceMap , nextToken , t => t . WithLeadingTrivia ( triviaList . WithoutLeadingWhitespace ( true ) ) ) ;
238228 break ;
239229 }
240230
241231 break ;
242232 }
243233 }
244234
235+ private static void UpdateReplaceMap ( Dictionary < SyntaxToken , SyntaxToken > replaceMap , SyntaxToken token , Func < SyntaxToken , SyntaxToken > action )
236+ {
237+ SyntaxToken existingReplacement ;
238+ SyntaxToken newReplacement ;
239+
240+ if ( replaceMap . TryGetValue ( token , out existingReplacement ) )
241+ {
242+ newReplacement = action ( existingReplacement ) ;
243+ }
244+ else
245+ {
246+ newReplacement = action ( token ) ;
247+ }
248+
249+ replaceMap [ token ] = newReplacement ;
250+ }
251+
245252 private class FixAll : DocumentBasedFixAllProvider
246253 {
247254 public static FixAllProvider Instance { get ; } = new FixAll ( ) ;
0 commit comments