From d1a1bcb16adc51aae5aba911758a4b2fe0d57a87 Mon Sep 17 00:00:00 2001 From: Liam Peters Date: Tue, 16 Jul 2024 21:16:41 +0100 Subject: [PATCH] PSUseConsistentWhitespace: Handle redirect operators which are not in stream order (#2001) --- Rules/UseConsistentWhitespace.cs | 11 ++++++++++- Tests/Rules/UseConsistentWhitespace.tests.ps1 | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Rules/UseConsistentWhitespace.cs b/Rules/UseConsistentWhitespace.cs index 13613ae74..a062e5d3f 100644 --- a/Rules/UseConsistentWhitespace.cs +++ b/Rules/UseConsistentWhitespace.cs @@ -396,8 +396,17 @@ private IEnumerable FindParameterViolations(Ast ast) testAst => testAst is CommandAst, true); foreach (CommandAst commandAst in commandAsts) { + /// When finding all the command parameter elements, there is no guarantee that + /// we will read them from the AST in the order they appear in the script (in token + /// order). So we first sort the tokens by their starting line number, followed by + /// their starting column number. List commandParameterAstElements = commandAst.FindAll( - testAst => testAst.Parent == commandAst, searchNestedScriptBlocks: false).ToList(); + testAst => testAst.Parent == commandAst, searchNestedScriptBlocks: false + ).OrderBy( + e => e.Extent.StartLineNumber + ).ThenBy( + e => e.Extent.StartColumnNumber + ).ToList(); for (int i = 0; i < commandParameterAstElements.Count - 1; i++) { IScriptExtent leftExtent = commandParameterAstElements[i].Extent; diff --git a/Tests/Rules/UseConsistentWhitespace.tests.ps1 b/Tests/Rules/UseConsistentWhitespace.tests.ps1 index 31442ad77..30d8cce57 100644 --- a/Tests/Rules/UseConsistentWhitespace.tests.ps1 +++ b/Tests/Rules/UseConsistentWhitespace.tests.ps1 @@ -540,6 +540,12 @@ bar -h i ` Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null } + It "Should not find a violation when redirect operators, spearated by 1 space, are used and not in stream order" { + # Related to Issue #2000 + $def = 'foo 3>&1 1>$null 2>&1' + Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings | Should -Be $null + } + It "Should find 1 violation if there is 1 space too much before a parameter" { $def = 'foo -bar' $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings @@ -578,5 +584,13 @@ bar -h i ` Invoke-Formatter -ScriptDefinition "$def" -Settings $settings | Should -Be "$expected" } + + It "Should fix script when redirects are involved and whitespace is not consistent" { + # Related to Issue #2000 + $def = 'foo 3>&1 1>$null 2>&1' + $expected = 'foo 3>&1 1>$null 2>&1' + Invoke-Formatter -ScriptDefinition $def -Settings $settings | + Should -Be $expected + } } }