Skip to content

Commit 3caa580

Browse files
committed
fix perf excludedLines lookup
1 parent 1ba721c commit 3caa580

File tree

3 files changed

+47
-19
lines changed

3 files changed

+47
-19
lines changed

src/documentParser.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export class DocumentParser {
55
// Used to avoid calling symbol provider for the same document on every stopped location
66
private readonly functionCache: Map<string, vscode.DocumentSymbol[]> = new Map<string, vscode.DocumentSymbol[]>();
77

8+
// Clear cache between debugsessions to get updated symbols
89
clearFunctionCache(): void {
910
this.functionCache.clear();
1011
}
@@ -54,23 +55,21 @@ export class DocumentParser {
5455
return Math.max(0, ...functions.map(fn => fn.range.start.line));
5556
}
5657

57-
async getExcludedLines(document: vscode.TextDocument, stoppedLocation: vscode.Range, startLine: number): Promise<number[]> {
58+
async getExcludedLines(document: vscode.TextDocument, stoppedLocation: vscode.Range, startLine: number): Promise<Set<number>> {
5859
const functions = await this.getFunctionsInDocument(document);
5960
const stoppedEnd = stoppedLocation.end.line;
6061
const excludedLines = [];
6162

6263
for (var i = 0, length = functions.length; i < length; ++i) {
6364
const func = functions[i];
6465
// startLine (either document start or closest function start) are provided, so functions necessary to exclude
65-
// will always start >= documentStart or after currentFunction start if nested function.
66+
// will always start >= documentStart or same as currentFunction start if nested function.
6667
// Don't bother checking functions before startLine or after stoppedLocation
67-
if (func.range.start.line >= startLine && func.range.start.line < stoppedEnd && !func.range.contains(stoppedLocation)) {
68+
if (func.range.start.line >= startLine && func.range.start.line <= stoppedEnd && !func.range.contains(stoppedLocation)) {
6869
const functionRange = utils.range(func.range.start.line, func.range.end.line);
69-
excludedLines.push(...functionRange.filter(line => line < stoppedLocation.start.line || line > stoppedEnd));
70+
excludedLines.push(...functionRange);
7071
}
7172
}
72-
73-
return excludedLines;
73+
return new Set(excludedLines.filter(line => line < stoppedLocation.start.line || line > stoppedEnd));
7474
}
75-
7675
}

src/powerShellVariableInlineValuesProvider.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ export class PowerShellVariableInlineValuesProvider implements vscode.InlineValu
1717
`(?:\\$(?:[a-zA-Z]+:)?${this.alphanumChars}+)`, // Scoped or normal variables
1818
].join('|'), 'giu'); // u flag to support unicode char classes
1919

20-
// Cache for symbols per document in the current debugsessions
21-
private documentParser: DocumentParser;
20+
private readonly documentParser: DocumentParser;
2221

2322
constructor(documentParser: DocumentParser) {
2423
this.documentParser = documentParser;
@@ -35,7 +34,7 @@ export class PowerShellVariableInlineValuesProvider implements vscode.InlineValu
3534

3635
for (let l = startLine; l <= endLine; l++) {
3736
// Exclude lines out of scope (other functions)
38-
if (excludedLines.includes(l)) {
37+
if (excludedLines.has(l)) {
3938
continue;
4039
}
4140

src/test/suite/documentParser.test.ts

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,14 @@ test1
137137
});
138138

139139
const result = await parser.getExcludedLines(doc, new vscode.Range(11, 0, 11, 3), 0);
140-
assert.strictEqual(result.length, 7);
141-
assert.strictEqual(result[0], 2);
142-
assert.strictEqual(result[1], 3);
143-
assert.strictEqual(result[2], 4);
144-
assert.strictEqual(result[3], 5);
145-
assert.strictEqual(result[4], 7);
146-
assert.strictEqual(result[5], 8);
147-
assert.strictEqual(result[6], 9);
140+
assert.strictEqual(result.size, 7);
141+
assert.strictEqual(result.has(2), true);
142+
assert.strictEqual(result.has(3), true);
143+
assert.strictEqual(result.has(4), true);
144+
assert.strictEqual(result.has(5), true);
145+
assert.strictEqual(result.has(7), true);
146+
assert.strictEqual(result.has(8), true);
147+
assert.strictEqual(result.has(9), true);
148148
});
149149

150150
test('returns empty array when no functions out of scope are present in range', async () => {
@@ -168,7 +168,37 @@ test2
168168
});
169169

170170
const result = await parser.getExcludedLines(doc, new vscode.Range(8, 4, 8, 7), 7);
171-
assert.strictEqual(result.length, 0);
171+
assert.strictEqual(result.size, 0);
172+
});
173+
174+
test('does not exclude stoppedLocation multi-range', async () => {
175+
const doc = await vscode.workspace.openTextDocument({
176+
language: 'powershell',
177+
content: `
178+
function test2 {
179+
$b # Stopped location
180+
}; $param = @{ # Stopped location
181+
Abc = 123 # Stopped location
182+
} # Stopped location
183+
`,
184+
});
185+
186+
const result = await parser.getExcludedLines(doc, new vscode.Range(3, 3, 5, 1), 0);
187+
assert.strictEqual(result.size, 2);
188+
assert.strictEqual(result.has(1), true);
189+
assert.strictEqual(result.has(2), true);
190+
});
191+
192+
test('does not exclude stoppedLocation line when same as out of scope function', async () => {
193+
const doc = await vscode.workspace.openTextDocument({
194+
language: 'powershell',
195+
content: `
196+
function test1 { }; $b; function test2 { }; #$b is stoppedLocation
197+
`,
198+
});
199+
200+
const result = await parser.getExcludedLines(doc, new vscode.Range(1, 20, 1, 25), 0);
201+
assert.strictEqual(result.size, 0);
172202
});
173203
});
174204
});

0 commit comments

Comments
 (0)