diff --git a/Rules/Strings.resx b/Rules/Strings.resx index 120ead158..07f825ae9 100644 --- a/Rules/Strings.resx +++ b/Rules/Strings.resx @@ -988,7 +988,7 @@ Use space before open parenthesis. - Use space before and after binary and assignment operators. + Use space around binary, assignment and unary operators that start with a dash. Use space after a comma. diff --git a/Rules/UseConsistentWhitespace.cs b/Rules/UseConsistentWhitespace.cs index 6112c43f9..4262e1ee7 100644 --- a/Rules/UseConsistentWhitespace.cs +++ b/Rules/UseConsistentWhitespace.cs @@ -194,6 +194,7 @@ private bool IsOperator(Token token) return TokenTraits.HasTrait(token.Kind, TokenFlags.AssignmentOperator) || TokenTraits.HasTrait(token.Kind, TokenFlags.BinaryPrecedenceAdd) || TokenTraits.HasTrait(token.Kind, TokenFlags.BinaryPrecedenceMultiply) + || TokenTraits.HasTrait(token.Kind, TokenFlags.UnaryOperator) && token.Text.StartsWith("-") || token.Kind == TokenKind.AndAnd || token.Kind == TokenKind.OrOr; } @@ -529,6 +530,35 @@ private IEnumerable FindOperatorViolations(TokenOperations tok || tokenNode.Next == null || tokenNode.Value.Kind == TokenKind.DotDot) { + // for cases like '-split$a' as the other checks below in this function assume a preceding token + if (TokenTraits.HasTrait(tokenNode.Value.Kind, TokenFlags.UnaryOperator) + && tokenNode.Value.Text.StartsWith("-") + && tokenNode.Value.Text.Length > 1 + && Char.IsLetter(tokenNode.Value.Text[1])) + { + bool hasWhitespaceAfterOperator = tokenNode.Next.Value.Kind == TokenKind.NewLine + || IsPreviousTokenOnSameLineAndApartByWhitespace(tokenNode.Next); + if (!hasWhitespaceAfterOperator) + { + yield return new DiagnosticRecord( + GetError(ErrorKind.Operator), + tokenNode.Value.Extent, + GetName(), + GetDiagnosticSeverity(), + tokenOperations.Ast.Extent.File, + null, + new List() + { + new CorrectionExtent( + tokenNode.Value.Extent.StartLineNumber, + tokenNode.Value.Extent.EndLineNumber, + tokenNode.Value.Extent.StartColumnNumber, + tokenNode.Value.Extent.EndColumnNumber, + $"{tokenNode.Value.Text} ", + tokenNode.Value.Extent.File) + }); + } + } continue; } diff --git a/Tests/Rules/UseConsistentWhitespace.tests.ps1 b/Tests/Rules/UseConsistentWhitespace.tests.ps1 index 27e17e74e..c88776b43 100644 --- a/Tests/Rules/UseConsistentWhitespace.tests.ps1 +++ b/Tests/Rules/UseConsistentWhitespace.tests.ps1 @@ -185,6 +185,40 @@ $x = $true -and Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null } + It 'Should not find violation if there are whitespaces of size 1 around a unary operator starting with a dash' { + Invoke-ScriptAnalyzer -ScriptDefinition '$x -join $y' -Settings $settings | Should -BeNullOrEmpty + } + + It 'Should find a violation if no whitespace around a unary operator starting with a dash' { + $def = '$x=1' + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + Test-CorrectionExtentFromContent $def $violations 1 '=' ' = ' + } + + It 'Should find a violation if no whitespace before a unary operator starting with a dash' { + $def = '$x-join $Y' + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + Test-CorrectionExtentFromContent $def $violations 1 '' ' ' + } + + It 'Should find a violation if no whitespace after a unary operator starting with a dash' { + $def = '$x -join$y' + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + Test-CorrectionExtentFromContent $def $violations 1 '' ' ' + } + + It 'Should find a violation if there is a whitespaces not of size 1 around a unary operator starting with a dash' { + $def = '$x -join $y' + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + Test-CorrectionExtentFromContent $def $violations 1 ' -join ' ' -join ' + } + + It 'Should find a violation if there is no whitespace after a unary operator with a dash but nothing that preceds it' { + $def = '-join$x' + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings + Test-CorrectionExtentFromContent $def $violations 1 '-join' '-join ' + } + It "Should find violation if not asked to ignore assignment operator in hash table" { $def = @' $ht = @{ @@ -207,6 +241,7 @@ $ht = @{ $ruleConfiguration.CheckSeparator = $false $ruleConfiguration.IgnoreAssignmentOperatorInsideHashTable = $true } + It "Should not find violation if assignment operator is in multi-line hash table" { $def = @' $ht = @{