From 4f82d81ff015314552d3fe2225d06781d8c4833f Mon Sep 17 00:00:00 2001 From: "Christoph Bergmeister [MVP]" Date: Mon, 19 Aug 2019 21:56:26 +0100 Subject: [PATCH] Fix PSCloseBrace rule to not wrongly flag closing brace of one-line hashtable, which lead to incorrect formatting (#1309) * Ignore Hashtables for PlaceCloseBrace rule * suppress only single line hash tables * Add test and make fix in proper place where RCurly of hashtable gets wrongly associated to the LCurly of the one line if statement * cleanup code * revert change to minimise diff * final cleanup * Apply suggestions from code review Co-Authored-By: Robert Holt --- Engine/TokenOperations.cs | 12 +++++++++++- Tests/Rules/PlaceCloseBrace.tests.ps1 | 12 ++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Engine/TokenOperations.cs b/Engine/TokenOperations.cs index 07b8a2621..d7df01fc2 100644 --- a/Engine/TokenOperations.cs +++ b/Engine/TokenOperations.cs @@ -73,6 +73,7 @@ public IEnumerable GetCloseBracesInCommandElements() public IEnumerable> GetBracePairs() { var openBraceStack = new Stack(); + IEnumerable hashtableAsts = ast.FindAll(oneAst => oneAst is HashtableAst, searchNestedScriptBlocks: true); foreach (var token in tokens) { if (token.Kind == TokenKind.LCurly) @@ -84,7 +85,16 @@ public IEnumerable> GetBracePairs() if (token.Kind == TokenKind.RCurly && openBraceStack.Count > 0) { - yield return new Tuple(openBraceStack.Pop(), token); + bool closeBraceBelongsToHashTable = hashtableAsts.Any(hashtableAst => + { + return hashtableAst.Extent.EndLineNumber == token.Extent.EndLineNumber + && hashtableAst.Extent.EndColumnNumber == token.Extent.EndColumnNumber; + }); + + if (!closeBraceBelongsToHashTable) + { + yield return new Tuple(openBraceStack.Pop(), token); + } } } } diff --git a/Tests/Rules/PlaceCloseBrace.tests.ps1 b/Tests/Rules/PlaceCloseBrace.tests.ps1 index 22d4785f6..df1be8812 100644 --- a/Tests/Rules/PlaceCloseBrace.tests.ps1 +++ b/Tests/Rules/PlaceCloseBrace.tests.ps1 @@ -78,6 +78,18 @@ $hashtable = @{a = 1; b = 2} } } + Context "When there is a one line hashtable inside a one line statement" { + BeforeAll { + $scriptDefinition = 'if ($true) { $test = @{ } }' + $ruleConfiguration.'IgnoreOneLineBlock' = $true + } + + It "Should not find a violation" { + $violations = Invoke-ScriptAnalyzer -ScriptDefinition $scriptDefinition -Settings $settings + $violations.Count | Should -Be 0 + } + } + Context "When there is a multi-line hashtable" { BeforeAll {