@@ -29,7 +29,7 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules
2929#endif
3030 public class UseWhitespace : ConfigurableRule
3131 {
32- private enum ErrorKind { Brace , Paren , Operator } ;
32+ private enum ErrorKind { Brace , Paren , Operator , SeparatorComma , SeparatorSemi } ;
3333 private const int whiteSpaceSize = 1 ;
3434 private const string whiteSpace = " " ;
3535
@@ -45,6 +45,9 @@ private List<Func<TokenOperations, IEnumerable<DiagnosticRecord>>> violationFind
4545 [ ConfigurableRuleProperty ( defaultValue : true ) ]
4646 public bool CheckOperator { get ; protected set ; }
4747
48+ [ ConfigurableRuleProperty ( defaultValue : true ) ]
49+ public bool CheckSeparator { get ; protected set ; }
50+
4851 public override void ConfigureRule ( IDictionary < string , object > paramValueMap )
4952 {
5053 base . ConfigureRule ( paramValueMap ) ;
@@ -62,6 +65,11 @@ public override void ConfigureRule(IDictionary<string, object> paramValueMap)
6265 {
6366 violationFinders . Add ( FindOperatorViolations ) ;
6467 }
68+
69+ if ( CheckSeparator )
70+ {
71+ violationFinders . Add ( FindSeparatorViolations ) ;
72+ }
6573 }
6674
6775 /// <summary>
@@ -95,6 +103,10 @@ private string GetError(ErrorKind kind)
95103 return string . Format ( CultureInfo . CurrentCulture , Strings . UseWhitespaceErrorBeforeBrace ) ;
96104 case ErrorKind . Operator :
97105 return string . Format ( CultureInfo . CurrentCulture , Strings . UseWhitespaceErrorOperator ) ;
106+ case ErrorKind . SeparatorComma :
107+ return string . Format ( CultureInfo . CurrentCulture , Strings . UseWhitespaceErrorSeparatorComma ) ;
108+ case ErrorKind . SeparatorSemi :
109+ return string . Format ( CultureInfo . CurrentCulture , Strings . UseWhitespaceErrorSeparatorSemi ) ;
98110 default :
99111 return string . Format ( CultureInfo . CurrentCulture , Strings . UseWhitespaceErrorBeforeParen ) ;
100112 }
@@ -147,6 +159,45 @@ private IEnumerable<DiagnosticRecord> FindOpenParenViolations(TokenOperations to
147159 }
148160 }
149161
162+ private IEnumerable < DiagnosticRecord > FindSeparatorViolations ( TokenOperations tokenOperations )
163+ {
164+ Func < LinkedListNode < Token > , bool > predicate = node =>
165+ {
166+ return node . Next != null
167+ && ! IsPreviousTokenApartByWhitespace ( node . Next ) ;
168+ } ;
169+
170+ Func < Token , ErrorKind , DiagnosticRecord > getDiagnosticRecord = ( token , errKind ) =>
171+ {
172+ return new DiagnosticRecord (
173+ GetError ( errKind ) ,
174+ token . Extent ,
175+ GetName ( ) ,
176+ GetDiagnosticSeverity ( ) ,
177+ token . Extent . File ,
178+ null ,
179+ null ) ;
180+ } ;
181+
182+ foreach ( var tokenNode in tokenOperations . GetTokenNodes ( TokenKind . Comma ) . Where ( predicate ) )
183+ {
184+ yield return getDiagnosticRecord ( tokenNode . Value , ErrorKind . SeparatorComma ) ;
185+ }
186+
187+ foreach ( var tokenNode in tokenOperations . GetTokenNodes ( TokenKind . Semi ) . Where ( predicate ) )
188+ {
189+ // semi-colon can be followed by newline or end of input
190+ if ( tokenNode . Next . Value . Kind == TokenKind . EndOfInput
191+ || tokenNode . Next . Value . Kind == TokenKind . NewLine )
192+ {
193+ continue ;
194+ }
195+
196+ yield return getDiagnosticRecord ( tokenNode . Value , ErrorKind . SeparatorSemi ) ;
197+ }
198+ }
199+
200+
150201 private bool IsKeyword ( Token token )
151202 {
152203 switch ( token . Kind )
0 commit comments