Skip to content

Commit 0a15552

Browse files
committed
compressed object tree model: use proxy
1 parent 7434a77 commit 0a15552

1 file changed

Lines changed: 25 additions & 6 deletions

File tree

src/vs/base/browser/ui/tree/compressedObjectTreeModel.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -305,12 +305,31 @@ export type NodeMapper<T, TFilterData> = (node: ITreeNode<ICompressedTreeNode<T>
305305

306306
export const DefaultElementMapper: ElementMapper<any> = elements => elements[elements.length - 1];
307307

308-
function mapNode<T, TFilterData>(compressedNodeMapper: CompressedNodeMapper<T>, node: ITreeNode<ICompressedTreeNode<T> | null, TFilterData>): ITreeNode<T | null, TFilterData> {
309-
return {
310-
...node,
311-
element: node.element === null ? null : compressedNodeMapper(node.element),
312-
children: node.children.map(child => mapNode(compressedNodeMapper, child))
308+
function createNodeMapper<T, TFilterData>(compressedNodeMapper: CompressedNodeMapper<T>): NodeMapper<T, TFilterData> {
309+
const map = new WeakMap<ITreeNode<ICompressedTreeNode<T> | null, TFilterData>, ITreeNode<T | null, TFilterData>>();
310+
const nodeMapper: NodeMapper<T, TFilterData> = node => {
311+
let result = map.get(node);
312+
313+
if (!result) {
314+
result = new Proxy(node, {
315+
get(obj, prop) {
316+
if (prop === 'element') {
317+
return node.element === null ? null : compressedNodeMapper(node.element);
318+
} else if (prop === 'children') {
319+
return node.children.map(nodeMapper);
320+
}
321+
322+
return (obj as any)[prop];
323+
}
324+
}) as ITreeNode<T | null, TFilterData>;
325+
326+
map.set(node, result);
327+
}
328+
329+
return result;
313330
};
331+
332+
return nodeMapper;
314333
}
315334

316335
function mapList<T, TFilterData>(nodeMapper: NodeMapper<T, TFilterData>, list: ISpliceable<ITreeNode<T, TFilterData>>): ISpliceable<ITreeNode<ICompressedTreeNode<T>, TFilterData>> {
@@ -379,7 +398,7 @@ export class CompressibleObjectTreeModel<T extends NonNullable<any>, TFilterData
379398
) {
380399
this.elementMapper = options.elementMapper || DefaultElementMapper;
381400
const compressedNodeMapper: CompressedNodeMapper<T> = node => this.elementMapper(node.elements);
382-
this.nodeMapper = node => mapNode(compressedNodeMapper, node);
401+
this.nodeMapper = createNodeMapper(compressedNodeMapper);
383402

384403
this.model = new CompressedObjectTreeModel(user, mapList(this.nodeMapper, list), mapOptions(compressedNodeMapper, options));
385404
}

0 commit comments

Comments
 (0)