66import { ISpliceable } from 'vs/base/common/sequence' ;
77import { Iterator , ISequence } from 'vs/base/common/iterator' ;
88import { 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' ;
1010import { 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
302302export 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-
306303export 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 {
0 commit comments