Skip to content

Commit 02273eb

Browse files
committed
(GH-811) Fix folding for regions with same end token
Previously the token matching was broken; ``` foreach ($1 in $2) { <----- STARTS MATCH HERE (1) $x = @{ <----- STARTS MATCH HERE (2) 'abc' = 'def' } <----- ENDS MATCH HERE (1) (2) } ``` This was caused by two or more different token pairs sharing the same end token. This commit modifies the token pair matching to take an array of Start Tokens instead of a single. This has the added benefit of performance increase too. This commit also adds tests for this scenario.
1 parent bb65b2a commit 02273eb

File tree

2 files changed

+39
-17
lines changed

2 files changed

+39
-17
lines changed

src/PowerShellEditorServices/Language/TokenOperations.cs

+11-17
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
44
//
55

6+
using System;
67
using System.Collections.Generic;
78
using System.Management.Automation.Language;
89
using System.Text.RegularExpressions;
@@ -28,24 +29,17 @@ internal static FoldingReference[] FoldableRegions(
2829
{
2930
List<FoldingReference> foldableRegions = new List<FoldingReference>();
3031

31-
// Find matching braces { -> }
32-
foldableRegions.AddRange(
33-
MatchTokenElements(tokens, TokenKind.LCurly, TokenKind.RCurly, RegionKindNone)
34-
);
35-
36-
// Find matching braces ( -> )
37-
foldableRegions.AddRange(
38-
MatchTokenElements(tokens, TokenKind.LParen, TokenKind.RParen, RegionKindNone)
39-
);
40-
41-
// Find matching arrays @( -> )
32+
// Find matching braces { -> }
33+
// Find matching hashes @{ -> }
4234
foldableRegions.AddRange(
43-
MatchTokenElements(tokens, TokenKind.AtParen, TokenKind.RParen, RegionKindNone)
35+
MatchTokenElements(tokens, new TokenKind[] { TokenKind.LCurly, TokenKind.AtCurly }, TokenKind.RCurly, RegionKindNone)
4436
);
4537

46-
// Find matching hashes @{ -> }
38+
// Find matching parentheses ( -> )
39+
// Find matching array literals @( -> )
40+
// Find matching subexpressions $( -> )
4741
foldableRegions.AddRange(
48-
MatchTokenElements(tokens, TokenKind.AtCurly, TokenKind.RParen, RegionKindNone)
42+
MatchTokenElements(tokens, new TokenKind[] { TokenKind.LParen, TokenKind.AtParen, TokenKind.DollarParen }, TokenKind.RParen, RegionKindNone)
4943
);
5044

5145
// Find contiguous here strings @' -> '@
@@ -146,19 +140,19 @@ static private FoldingReference CreateFoldingReference(
146140
}
147141

148142
/// <summary>
149-
/// Given an array of tokens, find matching regions which start and end with a different TokenKind
143+
/// Given an array of tokens, find matching regions which start (array of tokens) and end with a different TokenKind
150144
/// </summary>
151145
static private List<FoldingReference> MatchTokenElements(
152146
Token[] tokens,
153-
TokenKind startTokenKind,
147+
TokenKind[] startTokenKind,
154148
TokenKind endTokenKind,
155149
string matchKind)
156150
{
157151
List<FoldingReference> result = new List<FoldingReference>();
158152
Stack<Token> tokenStack = new Stack<Token>();
159153
foreach (Token token in tokens)
160154
{
161-
if (token.Kind == startTokenKind) {
155+
if (Array.IndexOf(startTokenKind, token.Kind) != -1) {
162156
tokenStack.Push(token);
163157
}
164158
if ((tokenStack.Count > 0) && (token.Kind == endTokenKind)) {

test/PowerShellEditorServices.Test/Language/TokenOperationsTests.cs

+28
Original file line numberDiff line numberDiff line change
@@ -217,5 +217,33 @@ public void LaguageServiceFindsFoldablRegionsWithDuplicateRegions() {
217217
FoldingReference[] result = GetRegions(testString);
218218
AssertFoldingReferenceArrays(expectedFolds, result);
219219
}
220+
221+
// This tests that token matching { -> }, @{ -> } and
222+
// ( -> ), @( -> ) and $( -> ) does not confuse the folder
223+
[Fact]
224+
public void LaguageServiceFindsFoldablRegionsWithSameEndToken() {
225+
string testString =
226+
@"foreach ($1 in $2) {
227+
228+
$x = @{
229+
'abc' = 'def'
230+
}
231+
}
232+
233+
$y = $(
234+
$arr = @('1', '2'); Write-Host ($arr)
235+
)
236+
";
237+
FoldingReference[] expectedFolds = {
238+
CreateFoldingReference(0, 19, 4, 1, null),
239+
CreateFoldingReference(2, 9, 3, 5, null),
240+
CreateFoldingReference(7, 5, 8, 1, null)
241+
};
242+
243+
FoldingReference[] result = GetRegions(testString);
244+
245+
AssertFoldingReferenceArrays(expectedFolds, result);
246+
}
247+
220248
}
221249
}

0 commit comments

Comments
 (0)