Skip to content

Commit ab021bf

Browse files
committed
remove proxy usage
1 parent cee8dae commit ab021bf

3 files changed

Lines changed: 54 additions & 63 deletions

File tree

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

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import { ComposedTreeDelegate, IAbstractTreeOptions, IAbstractTreeOptionsUpdate } from 'vs/base/browser/ui/tree/abstractTree';
77
import { ObjectTree, IObjectTreeOptions, CompressibleObjectTree, ICompressibleTreeRenderer } from 'vs/base/browser/ui/tree/objectTree';
88
import { IListVirtualDelegate, IIdentityProvider, IListDragAndDrop, IListDragOverReaction } from 'vs/base/browser/ui/list/list';
9-
import { ITreeElement, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeSorter, ICollapseStateChangeEvent, IAsyncDataSource, ITreeDragAndDrop, TreeError } from 'vs/base/browser/ui/tree/tree';
9+
import { ITreeElement, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeSorter, ICollapseStateChangeEvent, IAsyncDataSource, ITreeDragAndDrop, TreeError, WeakMapper } from 'vs/base/browser/ui/tree/tree';
1010
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
1111
import { Emitter, Event } from 'vs/base/common/event';
1212
import { timeout, CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
@@ -67,24 +67,6 @@ interface IDataTreeListTemplateData<T> {
6767
templateData: T;
6868
}
6969

70-
class WeakMapper<K extends object, V> {
71-
72-
constructor(private fn: (k: K) => V) { }
73-
74-
private _map = new WeakMap<K, V>();
75-
76-
map(key: K): V {
77-
let result = this._map.get(key);
78-
79-
if (!result) {
80-
result = this.fn(key);
81-
this._map.set(key, result);
82-
}
83-
84-
return result;
85-
}
86-
}
87-
8870
type AsyncDataTreeNodeMapper<TInput, T, TFilterData> = WeakMapper<ITreeNode<IAsyncDataTreeNode<TInput, T> | null, TFilterData>, ITreeNode<TInput | T, TFilterData>>;
8971

9072
class AsyncDataTreeNodeWrapper<TInput, T, TFilterData> implements ITreeNode<TInput | T, TFilterData> {

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

Lines changed: 35 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import { ISpliceable } from 'vs/base/common/sequence';
77
import { Iterator, ISequence } from 'vs/base/common/iterator';
88
import { Event } from 'vs/base/common/event';
9-
import { ITreeModel, ITreeNode, ITreeElement, ICollapseStateChangeEvent, ITreeModelSpliceEvent, TreeError, TreeFilterResult, TreeVisibility } from 'vs/base/browser/ui/tree/tree';
9+
import { ITreeModel, ITreeNode, ITreeElement, ICollapseStateChangeEvent, ITreeModelSpliceEvent, TreeError, TreeFilterResult, TreeVisibility, WeakMapper } from 'vs/base/browser/ui/tree/tree';
1010
import { IObjectTreeModelOptions, ObjectTreeModel, IObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
1111

1212
// Exported only for test reasons, do not use directly
@@ -300,62 +300,53 @@ export class CompressedObjectTreeModel<T extends NonNullable<any>, TFilterData e
300300
// Compressible Object Tree
301301

302302
export type ElementMapper<T> = (elements: T[]) => T;
303-
export type CompressedNodeMapper<T> = (node: ICompressedTreeNode<T>) => T;
304-
export type NodeMapper<T, TFilterData> = (node: ITreeNode<ICompressedTreeNode<T> | null, TFilterData>) => ITreeNode<T | null, TFilterData>;
305-
306303
export const DefaultElementMapper: ElementMapper<any> = elements => elements[elements.length - 1];
307304

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>;
305+
export type CompressedNodeUnwrapper<T> = (node: ICompressedTreeNode<T>) => T;
306+
type CompressedNodeWeakMapper<T, TFilterData> = WeakMapper<ITreeNode<ICompressedTreeNode<T> | null, TFilterData>, ITreeNode<T | null, TFilterData>>;
325307

326-
map.set(node, result);
327-
}
308+
class CompressedTreeNodeWrapper<T, TFilterData> implements ITreeNode<T | null, TFilterData> {
328309

329-
return result;
330-
};
310+
get element(): T | null { return this.node.element === null ? null : this.unwrapper(this.node.element); }
311+
get children(): ITreeNode<T | null, TFilterData>[] { return this.node.children.map(node => new CompressedTreeNodeWrapper(this.unwrapper, node)); }
312+
get depth(): number { return this.node.depth; }
313+
get visibleChildrenCount(): number { return this.node.visibleChildrenCount; }
314+
get visibleChildIndex(): number { return this.node.visibleChildIndex; }
315+
get collapsible(): boolean { return this.node.collapsible; }
316+
get collapsed(): boolean { return this.node.collapsed; }
317+
get visible(): boolean { return this.node.visible; }
318+
get filterData(): TFilterData | undefined { return this.node.filterData; }
331319

332-
return nodeMapper;
320+
constructor(
321+
private unwrapper: CompressedNodeUnwrapper<T>,
322+
private node: ITreeNode<ICompressedTreeNode<T> | null, TFilterData>
323+
) { }
333324
}
334325

335-
function mapList<T, TFilterData>(nodeMapper: NodeMapper<T, TFilterData>, list: ISpliceable<ITreeNode<T, TFilterData>>): ISpliceable<ITreeNode<ICompressedTreeNode<T>, TFilterData>> {
326+
function mapList<T, TFilterData>(nodeMapper: CompressedNodeWeakMapper<T, TFilterData>, list: ISpliceable<ITreeNode<T, TFilterData>>): ISpliceable<ITreeNode<ICompressedTreeNode<T>, TFilterData>> {
336327
return {
337328
splice(start: number, deleteCount: number, toInsert: ITreeNode<ICompressedTreeNode<T>, TFilterData>[]): void {
338-
list.splice(start, deleteCount, toInsert.map(nodeMapper) as ITreeNode<T, TFilterData>[]);
329+
list.splice(start, deleteCount, toInsert.map(node => nodeMapper.map(node)) as ITreeNode<T, TFilterData>[]);
339330
}
340331
};
341332
}
342333

343-
function mapOptions<T, TFilterData>(compressedNodeMapper: CompressedNodeMapper<T>, options: ICompressibleObjectTreeModelOptions<T, TFilterData>): ICompressedObjectTreeModelOptions<T, TFilterData> {
334+
function mapOptions<T, TFilterData>(compressedNodeUnwrapper: CompressedNodeUnwrapper<T>, options: ICompressibleObjectTreeModelOptions<T, TFilterData>): ICompressedObjectTreeModelOptions<T, TFilterData> {
344335
return {
345336
...options,
346337
sorter: options.sorter && {
347-
compare(element: ICompressedTreeNode<T>, otherElement: ICompressedTreeNode<T>): number {
348-
return options.sorter!.compare(compressedNodeMapper(element), compressedNodeMapper(otherElement));
338+
compare(node: ICompressedTreeNode<T>, otherNode: ICompressedTreeNode<T>): number {
339+
return options.sorter!.compare(compressedNodeUnwrapper(node), compressedNodeUnwrapper(otherNode));
349340
}
350341
},
351342
identityProvider: options.identityProvider && {
352-
getId(element: ICompressedTreeNode<T>): { toString(): string; } {
353-
return options.identityProvider!.getId(compressedNodeMapper(element));
343+
getId(node: ICompressedTreeNode<T>): { toString(): string; } {
344+
return options.identityProvider!.getId(compressedNodeUnwrapper(node));
354345
}
355346
},
356347
filter: options.filter && {
357-
filter(element: ICompressedTreeNode<T>, parentVisibility: TreeVisibility): TreeFilterResult<TFilterData> {
358-
return options.filter!.filter(compressedNodeMapper(element), parentVisibility);
348+
filter(node: ICompressedTreeNode<T>, parentVisibility: TreeVisibility): TreeFilterResult<TFilterData> {
349+
return options.filter!.filter(compressedNodeUnwrapper(node), parentVisibility);
359350
}
360351
}
361352
};
@@ -371,24 +362,24 @@ export class CompressibleObjectTreeModel<T extends NonNullable<any>, TFilterData
371362

372363
get onDidSplice(): Event<ITreeModelSpliceEvent<T | null, TFilterData>> {
373364
return Event.map(this.model.onDidSplice, ({ insertedNodes, deletedNodes }) => ({
374-
insertedNodes: insertedNodes.map(this.nodeMapper),
375-
deletedNodes: deletedNodes.map(this.nodeMapper),
365+
insertedNodes: insertedNodes.map(node => this.nodeMapper.map(node)),
366+
deletedNodes: deletedNodes.map(node => this.nodeMapper.map(node)),
376367
}));
377368
}
378369

379370
get onDidChangeCollapseState(): Event<ICollapseStateChangeEvent<T | null, TFilterData>> {
380371
return Event.map(this.model.onDidChangeCollapseState, ({ node, deep }) => ({
381-
node: this.nodeMapper(node),
372+
node: this.nodeMapper.map(node),
382373
deep
383374
}));
384375
}
385376

386377
get onDidChangeRenderNodeCount(): Event<ITreeNode<T | null, TFilterData>> {
387-
return Event.map(this.model.onDidChangeRenderNodeCount, this.nodeMapper);
378+
return Event.map(this.model.onDidChangeRenderNodeCount, node => this.nodeMapper.map(node));
388379
}
389380

390381
private elementMapper: ElementMapper<T>;
391-
private nodeMapper: NodeMapper<T, TFilterData>;
382+
private nodeMapper: CompressedNodeWeakMapper<T, TFilterData>;
392383
private model: CompressedObjectTreeModel<T, TFilterData>;
393384

394385
constructor(
@@ -397,10 +388,10 @@ export class CompressibleObjectTreeModel<T extends NonNullable<any>, TFilterData
397388
options: ICompressibleObjectTreeModelOptions<T, TFilterData> = {}
398389
) {
399390
this.elementMapper = options.elementMapper || DefaultElementMapper;
400-
const compressedNodeMapper: CompressedNodeMapper<T> = node => this.elementMapper(node.elements);
401-
this.nodeMapper = createNodeMapper(compressedNodeMapper);
391+
const compressedNodeUnwrapper: CompressedNodeUnwrapper<T> = node => this.elementMapper(node.elements);
392+
this.nodeMapper = new WeakMapper(node => new CompressedTreeNodeWrapper(compressedNodeUnwrapper, node));
402393

403-
this.model = new CompressedObjectTreeModel(user, mapList(this.nodeMapper, list), mapOptions(compressedNodeMapper, options));
394+
this.model = new CompressedObjectTreeModel(user, mapList(this.nodeMapper, list), mapOptions(compressedNodeUnwrapper, options));
404395
}
405396

406397
setChildren(element: T | null, children?: ISequence<ICompressedTreeElement<T>>): void {
@@ -424,7 +415,7 @@ export class CompressibleObjectTreeModel<T extends NonNullable<any>, TFilterData
424415
}
425416

426417
getNode(location?: T | null | undefined): ITreeNode<T | null, any> {
427-
return this.nodeMapper(this.model.getNode(location));
418+
return this.nodeMapper.map(this.model.getNode(location));
428419
}
429420

430421
getNodeLocation(node: ITreeNode<T | null, any>): T | null {

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,21 @@ export class TreeError extends Error {
199199
super(`TreeError [${user}] ${message}`);
200200
}
201201
}
202+
203+
export class WeakMapper<K extends object, V> {
204+
205+
constructor(private fn: (k: K) => V) { }
206+
207+
private _map = new WeakMap<K, V>();
208+
209+
map(key: K): V {
210+
let result = this._map.get(key);
211+
212+
if (!result) {
213+
result = this.fn(key);
214+
this._map.set(key, result);
215+
}
216+
217+
return result;
218+
}
219+
}

0 commit comments

Comments
 (0)