Skip to content

Commit b158d50

Browse files
author
Kapil Borle
committed
Add logic to detect operator violations
1 parent 7347add commit b158d50

1 file changed

Lines changed: 53 additions & 1 deletion

File tree

Rules/UseWhitespace.cs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules
2828
#endif
2929
public class UseWhitespace : ConfigurableRule
3030
{
31-
private enum ErrorKind { Brace, Paren };
31+
private enum ErrorKind { Brace, Paren, Operator };
3232
private readonly int whiteSpaceSize = 1;
3333

3434
private List<Func<TokenOperations, IEnumerable<DiagnosticRecord>>> violationFinders
@@ -40,6 +40,8 @@ private List<Func<TokenOperations, IEnumerable<DiagnosticRecord>>> violationFind
4040
[ConfigurableRuleProperty(defaultValue: true)]
4141
public bool CheckOpenParen { get; protected set; }
4242

43+
[ConfigurableRuleProperty(defaultValue: true)]
44+
public bool CheckOperator { get; protected set; }
4345

4446
public override void ConfigureRule(IDictionary<string, object> paramValueMap)
4547
{
@@ -53,6 +55,11 @@ public override void ConfigureRule(IDictionary<string, object> paramValueMap)
5355
{
5456
violationFinders.Add(FindOpenParenViolations);
5557
}
58+
59+
if (CheckOperator)
60+
{
61+
violationFinders.Add(FindOperatorViolations);
62+
}
5663
}
5764

5865
/// <summary>
@@ -84,6 +91,8 @@ private string GetError(ErrorKind kind)
8491
{
8592
case ErrorKind.Brace:
8693
return string.Format(CultureInfo.CurrentCulture, Strings.UseWhitespaceErrorBeforeBrace);
94+
case ErrorKind.Operator:
95+
return string.Format(CultureInfo.CurrentCulture, Strings.UseWhitespaceErrorOperator);
8796
default:
8897
return string.Format(CultureInfo.CurrentCulture, Strings.UseWhitespaceErrorBeforeParen);
8998
}
@@ -149,6 +158,49 @@ private bool IsPreviousTokenApartByWhitespace(LinkedListNode<Token> tokenNode)
149158
(tokenNode.Value.Extent.StartColumnNumber - tokenNode.Previous.Value.Extent.EndColumnNumber);
150159
}
151160

161+
private IEnumerable<DiagnosticRecord> FindOperatorViolations(TokenOperations tokenOperations)
162+
{
163+
foreach (var tokenNode in tokenOperations.GetTokenNodes(IsOperator))
164+
{
165+
var hasWhitespaceBefore = false;
166+
var hasWhitespaceAfter = false;
167+
if (tokenNode.Previous != null
168+
&& IsPreviousTokenOnSameLine(tokenNode)
169+
&& IsPreviousTokenApartByWhitespace(tokenNode))
170+
{
171+
hasWhitespaceBefore = true;
172+
}
173+
174+
if (tokenNode.Next != null
175+
&& IsPreviousTokenOnSameLine(tokenNode.Next)
176+
&& IsPreviousTokenApartByWhitespace(tokenNode.Next))
177+
{
178+
hasWhitespaceAfter = true;
179+
}
180+
181+
if (!hasWhitespaceAfter || !hasWhitespaceBefore)
182+
{
183+
yield return new DiagnosticRecord(
184+
GetError(ErrorKind.Operator),
185+
tokenNode.Value.Extent,
186+
GetName(),
187+
GetDiagnosticSeverity(),
188+
tokenOperations.Ast.Extent.File,
189+
null,
190+
null);
191+
}
192+
}
193+
}
194+
195+
private bool IsOperator(Token token)
196+
{
197+
return TokenTraits.HasTrait(token.Kind, TokenFlags.AssignmentOperator)
198+
|| TokenTraits.HasTrait(token.Kind, TokenFlags.BinaryPrecedenceAdd)
199+
|| TokenTraits.HasTrait(token.Kind, TokenFlags.BinaryPrecedenceMultiply)
200+
|| token.Kind == TokenKind.AndAnd
201+
|| token.Kind == TokenKind.OrOr;
202+
}
203+
152204
private bool IsPreviousTokenOnSameLine(LinkedListNode<Token> lparen)
153205
{
154206
return lparen.Previous.Value.Extent.StartLineNumber == lparen.Value.Extent.EndLineNumber;

0 commit comments

Comments
 (0)