Skip to content

Commit f886a29

Browse files
author
Kapil Borle
committed
Detect comma and semicolon violations
1 parent dca518b commit f886a29

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

Rules/Strings.resx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,4 +933,10 @@
933933
<data name="UseWhitespaceErrorOperator" xml:space="preserve">
934934
<value>Use space before and after binary and assignment operators.</value>
935935
</data>
936+
<data name="UseWhitespaceErrorSeparatorComma" xml:space="preserve">
937+
<value>Use space before a comma.</value>
938+
</data>
939+
<data name="UseWhitespaceErrorSeparatorSemi" xml:space="preserve">
940+
<value>Use space before a semi-colon.</value>
941+
</data>
936942
</root>

Rules/UseWhitespace.cs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)