@@ -22,7 +22,7 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules
22
22
#endif
23
23
public class UseConsistentWhitespace : ConfigurableRule
24
24
{
25
- private enum ErrorKind { Brace , Paren , Operator , SeparatorComma , SeparatorSemi } ;
25
+ private enum ErrorKind { BeforeOpeningBrace , Paren , Operator , SeparatorComma , SeparatorSemi , AfterOpeningBrace , BeforeClosingBrace , BeforePipe , AfterPipe } ;
26
26
private const int whiteSpaceSize = 1 ;
27
27
private const string whiteSpace = " " ;
28
28
private readonly SortedSet < TokenKind > openParenKeywordWhitelist = new SortedSet < TokenKind > ( )
@@ -41,6 +41,12 @@ private List<Func<TokenOperations, IEnumerable<DiagnosticRecord>>> violationFind
41
41
[ ConfigurableRuleProperty ( defaultValue : true ) ]
42
42
public bool CheckOpenBrace { get ; protected set ; }
43
43
44
+ [ ConfigurableRuleProperty ( defaultValue : true ) ]
45
+ public bool CheckInnerBrace { get ; protected set ; }
46
+
47
+ [ ConfigurableRuleProperty ( defaultValue : true ) ]
48
+ public bool CheckPipe { get ; protected set ; }
49
+
44
50
[ ConfigurableRuleProperty ( defaultValue : true ) ]
45
51
public bool CheckOpenParen { get ; protected set ; }
46
52
@@ -58,6 +64,16 @@ public override void ConfigureRule(IDictionary<string, object> paramValueMap)
58
64
violationFinders . Add ( FindOpenBraceViolations ) ;
59
65
}
60
66
67
+ if ( CheckInnerBrace )
68
+ {
69
+ violationFinders . Add ( FindInnerBraceViolations ) ;
70
+ }
71
+
72
+ if ( CheckPipe )
73
+ {
74
+ violationFinders . Add ( FindPipeViolations ) ;
75
+ }
76
+
61
77
if ( CheckOpenParen )
62
78
{
63
79
violationFinders . Add ( FindOpenParenViolations ) ;
@@ -171,10 +187,18 @@ private string GetError(ErrorKind kind)
171
187
{
172
188
switch ( kind )
173
189
{
174
- case ErrorKind . Brace :
175
- return string . Format ( CultureInfo . CurrentCulture , Strings . UseConsistentWhitespaceErrorBeforeBrace ) ;
190
+ case ErrorKind . BeforeOpeningBrace :
191
+ return string . Format ( CultureInfo . CurrentCulture , Strings . UseConsistentWhitespaceErrorBeforeOpeningBrace ) ;
192
+ case ErrorKind . AfterOpeningBrace :
193
+ return string . Format ( CultureInfo . CurrentCulture , Strings . UseConsistentWhitespaceErrorAfterOpeningBrace ) ;
194
+ case ErrorKind . BeforeClosingBrace :
195
+ return string . Format ( CultureInfo . CurrentCulture , Strings . UseConsistentWhitespaceErrorBeforeClosingInnerBrace ) ;
176
196
case ErrorKind . Operator :
177
197
return string . Format ( CultureInfo . CurrentCulture , Strings . UseConsistentWhitespaceErrorOperator ) ;
198
+ case ErrorKind . BeforePipe :
199
+ return string . Format ( CultureInfo . CurrentCulture , Strings . UseConsistentWhitespaceErrorSpaceBeforePipe ) ;
200
+ case ErrorKind . AfterPipe :
201
+ return string . Format ( CultureInfo . CurrentCulture , Strings . UseConsistentWhitespaceErrorSpaceAfterPipe ) ;
178
202
case ErrorKind . SeparatorComma :
179
203
return string . Format ( CultureInfo . CurrentCulture , Strings . UseConsistentWhitespaceErrorSeparatorComma ) ;
180
204
case ErrorKind . SeparatorSemi :
@@ -200,7 +224,7 @@ private IEnumerable<DiagnosticRecord> FindOpenBraceViolations(TokenOperations to
200
224
if ( ! IsPreviousTokenApartByWhitespace ( lcurly ) )
201
225
{
202
226
yield return new DiagnosticRecord (
203
- GetError ( ErrorKind . Brace ) ,
227
+ GetError ( ErrorKind . BeforeOpeningBrace ) ,
204
228
lcurly . Value . Extent ,
205
229
GetName ( ) ,
206
230
GetDiagnosticSeverity ( ) ,
@@ -211,6 +235,111 @@ private IEnumerable<DiagnosticRecord> FindOpenBraceViolations(TokenOperations to
211
235
}
212
236
}
213
237
238
+ private IEnumerable < DiagnosticRecord > FindInnerBraceViolations ( TokenOperations tokenOperations )
239
+ {
240
+ foreach ( var lCurly in tokenOperations . GetTokenNodes ( TokenKind . LCurly ) )
241
+ {
242
+ if ( lCurly . Next == null
243
+ || ! IsPreviousTokenOnSameLine ( lCurly )
244
+ || lCurly . Next . Value . Kind == TokenKind . NewLine
245
+ || lCurly . Next . Value . Kind == TokenKind . LineContinuation
246
+ )
247
+ {
248
+ continue ;
249
+ }
250
+
251
+ if ( ! IsNextTokenApartByWhitespace ( lCurly ) )
252
+ {
253
+ yield return new DiagnosticRecord (
254
+ GetError ( ErrorKind . AfterOpeningBrace ) ,
255
+ lCurly . Value . Extent ,
256
+ GetName ( ) ,
257
+ GetDiagnosticSeverity ( ) ,
258
+ tokenOperations . Ast . Extent . File ,
259
+ null ,
260
+ GetCorrections ( lCurly . Previous . Value , lCurly . Value , lCurly . Next . Value , true , false ) . ToList ( ) ) ;
261
+ }
262
+ }
263
+
264
+ foreach ( var rCurly in tokenOperations . GetTokenNodes ( TokenKind . RCurly ) )
265
+ {
266
+ if ( rCurly . Previous == null
267
+ || ! IsPreviousTokenOnSameLine ( rCurly )
268
+ || rCurly . Previous . Value . Kind == TokenKind . LCurly
269
+ || rCurly . Previous . Value . Kind == TokenKind . NewLine
270
+ || rCurly . Previous . Value . Kind == TokenKind . LineContinuation
271
+ )
272
+ {
273
+ continue ;
274
+ }
275
+
276
+ if ( ! IsPreviousTokenApartByWhitespace ( rCurly ) )
277
+ {
278
+ yield return new DiagnosticRecord (
279
+ GetError ( ErrorKind . BeforeClosingBrace ) ,
280
+ rCurly . Value . Extent ,
281
+ GetName ( ) ,
282
+ GetDiagnosticSeverity ( ) ,
283
+ tokenOperations . Ast . Extent . File ,
284
+ null ,
285
+ GetCorrections ( rCurly . Previous . Value , rCurly . Value , rCurly . Next . Value , false , true ) . ToList ( ) ) ;
286
+ }
287
+ }
288
+ }
289
+
290
+ private IEnumerable < DiagnosticRecord > FindPipeViolations ( TokenOperations tokenOperations )
291
+ {
292
+ foreach ( var pipe in tokenOperations . GetTokenNodes ( TokenKind . Pipe ) )
293
+ {
294
+ if ( pipe . Next == null
295
+ || ! IsPreviousTokenOnSameLine ( pipe )
296
+ || pipe . Next . Value . Kind == TokenKind . Pipe
297
+ || pipe . Next . Value . Kind == TokenKind . NewLine
298
+ || pipe . Next . Value . Kind == TokenKind . LineContinuation
299
+ )
300
+ {
301
+ continue ;
302
+ }
303
+
304
+ if ( ! IsNextTokenApartByWhitespace ( pipe ) )
305
+ {
306
+ yield return new DiagnosticRecord (
307
+ GetError ( ErrorKind . AfterPipe ) ,
308
+ pipe . Value . Extent ,
309
+ GetName ( ) ,
310
+ GetDiagnosticSeverity ( ) ,
311
+ tokenOperations . Ast . Extent . File ,
312
+ null ,
313
+ GetCorrections ( pipe . Previous . Value , pipe . Value , pipe . Next . Value , true , false ) . ToList ( ) ) ;
314
+ }
315
+ }
316
+
317
+ foreach ( var pipe in tokenOperations . GetTokenNodes ( TokenKind . Pipe ) )
318
+ {
319
+ if ( pipe . Previous == null
320
+ || ! IsPreviousTokenOnSameLine ( pipe )
321
+ || pipe . Previous . Value . Kind == TokenKind . Pipe
322
+ || pipe . Previous . Value . Kind == TokenKind . NewLine
323
+ || pipe . Previous . Value . Kind == TokenKind . LineContinuation
324
+ )
325
+ {
326
+ continue ;
327
+ }
328
+
329
+ if ( ! IsPreviousTokenApartByWhitespace ( pipe ) )
330
+ {
331
+ yield return new DiagnosticRecord (
332
+ GetError ( ErrorKind . BeforePipe ) ,
333
+ pipe . Value . Extent ,
334
+ GetName ( ) ,
335
+ GetDiagnosticSeverity ( ) ,
336
+ tokenOperations . Ast . Extent . File ,
337
+ null ,
338
+ GetCorrections ( pipe . Previous . Value , pipe . Value , pipe . Next . Value , false , true ) . ToList ( ) ) ;
339
+ }
340
+ }
341
+ }
342
+
214
343
private IEnumerable < DiagnosticRecord > FindOpenParenViolations ( TokenOperations tokenOperations )
215
344
{
216
345
foreach ( var lparen in tokenOperations . GetTokenNodes ( TokenKind . LParen ) )
@@ -291,6 +420,12 @@ private bool IsPreviousTokenApartByWhitespace(LinkedListNode<Token> tokenNode)
291
420
( tokenNode . Value . Extent . StartColumnNumber - tokenNode . Previous . Value . Extent . EndColumnNumber ) ;
292
421
}
293
422
423
+ private bool IsNextTokenApartByWhitespace ( LinkedListNode < Token > tokenNode )
424
+ {
425
+ return whiteSpaceSize ==
426
+ ( tokenNode . Next . Value . Extent . StartColumnNumber - tokenNode . Value . Extent . EndColumnNumber ) ;
427
+ }
428
+
294
429
private bool IsPreviousTokenOnSameLineAndApartByWhitespace ( LinkedListNode < Token > tokenNode )
295
430
{
296
431
return IsPreviousTokenOnSameLine ( tokenNode ) && IsPreviousTokenApartByWhitespace ( tokenNode ) ;
@@ -342,8 +477,9 @@ private List<CorrectionExtent> GetCorrections(
342
477
Token prevToken ,
343
478
Token token ,
344
479
Token nextToken ,
345
- bool hasWhitespaceBefore ,
346
- bool hasWhitespaceAfter )
480
+ bool hasWhitespaceBefore , // if this is false, then the returned correction extent will add a whitespace before the token
481
+ bool hasWhitespaceAfter // if this is false, then the returned correction extent will add a whitespace after the token
482
+ )
347
483
{
348
484
var sb = new StringBuilder ( ) ;
349
485
IScriptExtent e1 = token . Extent ;
0 commit comments