Skip to content

Commit

Permalink
Fix max call stack error when closing large outline
Browse files Browse the repository at this point in the history
Fixes microsoft#235889

Implement an iterative approach to manage the outline in the `OutlineModel` class.

* Add a stack to handle the children of the outline elements iteratively in the `_makeOutlineElement` method.
* Replace the recursive call with a loop that processes the stack in the `_makeOutlineElement` method.
* Add a stack to handle the children of the document symbols iteratively in the `_flattenDocumentSymbols` method.
* Replace the recursive call with a loop that processes the stack in the `_flattenDocumentSymbols` method.

---

For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/microsoft/vscode/issues/235889?shareId=XXXX-XXXX-XXXX-XXXX).
  • Loading branch information
faraon-bot committed Dec 12, 2024
1 parent 2c7408d commit ed20c11
Showing 1 changed file with 21 additions and 4 deletions.
25 changes: 21 additions & 4 deletions src/vs/editor/contrib/documentSymbols/browser/outlineModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,8 +244,20 @@ export class OutlineModel extends TreeElement {
const id = TreeElement.findId(info, container);
const res = new OutlineElement(id, container, info);
if (info.children) {
const stack: { info: DocumentSymbol, container: OutlineElement }[] = [];
for (const childInfo of info.children) {
OutlineModel._makeOutlineElement(childInfo, res);
stack.push({ info: childInfo, container: res });
}
while (stack.length > 0) {
const { info, container } = stack.pop()!;
const id = TreeElement.findId(info, container);
const res = new OutlineElement(id, container, info);
container.children.set(res.id, res);
if (info.children) {
for (const childInfo of info.children) {
stack.push({ info: childInfo, container: res });
}
}
}
}
container.children.set(res.id, res);
Expand Down Expand Up @@ -368,7 +380,12 @@ export class OutlineModel extends TreeElement {
}

private static _flattenDocumentSymbols(bucket: DocumentSymbol[], entries: DocumentSymbol[], overrideContainerLabel: string): void {
const stack: { entry: DocumentSymbol, overrideContainerLabel: string }[] = [];
for (const entry of entries) {
stack.push({ entry, overrideContainerLabel });
}
while (stack.length > 0) {
const { entry, overrideContainerLabel } = stack.pop()!;
bucket.push({
kind: entry.kind,
tags: entry.tags,
Expand All @@ -379,10 +396,10 @@ export class OutlineModel extends TreeElement {
selectionRange: entry.selectionRange,
children: undefined, // we flatten it...
});

// Recurse over children
if (entry.children) {
OutlineModel._flattenDocumentSymbols(bucket, entry.children, entry.name);
for (const child of entry.children) {
stack.push({ entry: child, overrideContainerLabel: entry.name });
}
}
}
}
Expand Down

0 comments on commit ed20c11

Please sign in to comment.