66import { memoize } from 'vs/base/common/decorators' ;
77import * as paths from 'vs/base/common/path' ;
88import { Iterator } from 'vs/base/common/iterator' ;
9- import { relativePath } from 'vs/base/common/resources' ;
9+ import { relativePath , joinPath } from 'vs/base/common/resources' ;
1010import { URI } from 'vs/base/common/uri' ;
1111
12- export interface ILeafNode < T > {
13- readonly path : string ;
12+ export interface ILeafNode < T , C = void > {
13+ readonly uri : URI ;
14+ readonly relativePath : string ;
1415 readonly name : string ;
1516 readonly element : T ;
17+ readonly context : C ;
1618}
1719
18- export interface IBranchNode < T > {
19- readonly path : string ;
20+ export interface IBranchNode < T , C = void > {
21+ readonly uri : URI ;
22+ readonly relativePath : string ;
2023 readonly name : string ;
2124 readonly size : number ;
22- readonly children : Iterator < INode < T > > ;
23- readonly parent : IBranchNode < T > | undefined ;
24- get ( childName : string ) : INode < T > | undefined ;
25+ readonly children : Iterator < INode < T , C > > ;
26+ readonly parent : IBranchNode < T , C > | undefined ;
27+ readonly context : C ;
28+ get ( childName : string ) : INode < T , C > | undefined ;
2529}
2630
27- export type INode < T > = IBranchNode < T > | ILeafNode < T > ;
31+ export type INode < T , C > = IBranchNode < T , C > | ILeafNode < T , C > ;
2832
2933// Internals
3034
31- class Node {
35+ class Node < C > {
3236
3337 @memoize
34- get name ( ) : string { return paths . posix . basename ( this . path ) ; }
38+ get name ( ) : string { return paths . posix . basename ( this . relativePath ) ; }
3539
36- constructor ( readonly path : string ) { }
40+ constructor ( readonly uri : URI , readonly relativePath : string , readonly context : C ) { }
3741}
3842
39- class BranchNode < T > extends Node implements IBranchNode < T > {
43+ class BranchNode < T , C > extends Node < C > implements IBranchNode < T , C > {
4044
41- private _children = new Map < string , BranchNode < T > | LeafNode < T > > ( ) ;
45+ private _children = new Map < string , BranchNode < T , C > | LeafNode < T , C > > ( ) ;
4246
4347 get size ( ) : number {
4448 return this . _children . size ;
4549 }
4650
47- get children ( ) : Iterator < BranchNode < T > | LeafNode < T > > {
51+ get children ( ) : Iterator < BranchNode < T , C > | LeafNode < T , C > > {
4852 return Iterator . fromIterableIterator ( this . _children . values ( ) ) ;
4953 }
5054
51- constructor ( path : string , readonly parent : IBranchNode < T > | undefined = undefined ) {
52- super ( path ) ;
55+ constructor ( uri : URI , relativePath : string , context : C , readonly parent : IBranchNode < T , C > | undefined = undefined ) {
56+ super ( uri , relativePath , context ) ;
5357 }
5458
55- get ( path : string ) : BranchNode < T > | LeafNode < T > | undefined {
59+ get ( path : string ) : BranchNode < T , C > | LeafNode < T , C > | undefined {
5660 return this . _children . get ( path ) ;
5761 }
5862
59- set ( path : string , child : BranchNode < T > | LeafNode < T > ) : void {
63+ set ( path : string , child : BranchNode < T , C > | LeafNode < T , C > ) : void {
6064 this . _children . set ( path , child ) ;
6165 }
6266
@@ -65,36 +69,52 @@ class BranchNode<T> extends Node implements IBranchNode<T> {
6569 }
6670}
6771
68- class LeafNode < T > extends Node implements ILeafNode < T > {
72+ class LeafNode < T , C > extends Node < C > implements ILeafNode < T , C > {
6973
70- constructor ( path : string , readonly element : T ) {
71- super ( path ) ;
74+ constructor ( uri : URI , path : string , context : C , readonly element : T ) {
75+ super ( uri , path , context ) ;
7276 }
7377}
7478
75- export class ResourceTree < T extends NonNullable < any > > {
79+ function collect < T , C > ( node : INode < T , C > , result : T [ ] ) : T [ ] {
80+ if ( ResourceTree . isBranchNode ( node ) ) {
81+ Iterator . forEach ( node . children , child => collect ( child , result ) ) ;
82+ } else {
83+ result . push ( node . element ) ;
84+ }
85+
86+ return result ;
87+ }
88+
89+ export class ResourceTree < T extends NonNullable < any > , C > {
7690
77- readonly root = new BranchNode < T > ( '' ) ;
91+ readonly root : BranchNode < T , C > ;
7892
79- static isBranchNode < T > ( obj : any ) : obj is IBranchNode < T > {
93+ static isBranchNode < T , C > ( obj : any ) : obj is IBranchNode < T , C > {
8094 return obj instanceof BranchNode ;
8195 }
8296
83- static getRoot < T > ( node : IBranchNode < T > ) : IBranchNode < T > {
97+ static getRoot < T , C > ( node : IBranchNode < T , C > ) : IBranchNode < T , C > {
8498 while ( node . parent ) {
8599 node = node . parent ;
86100 }
87101
88102 return node ;
89103 }
90104
91- constructor ( private rootURI : URI = URI . file ( '/' ) ) { }
105+ static collect < T , C > ( node : INode < T , C > ) : T [ ] {
106+ return collect ( node , [ ] ) ;
107+ }
108+
109+ constructor ( context : C , rootURI : URI = URI . file ( '/' ) ) {
110+ this . root = new BranchNode ( rootURI , '' , context ) ;
111+ }
92112
93113 add ( uri : URI , element : T ) : void {
94- const key = relativePath ( this . rootURI , uri ) || uri . fsPath ;
114+ const key = relativePath ( this . root . uri , uri ) || uri . fsPath ;
95115 const parts = key . split ( / [ \\ \/ ] / ) . filter ( p => ! ! p ) ;
96116 let node = this . root ;
97- let path = this . root . path ;
117+ let path = '' ;
98118
99119 for ( let i = 0 ; i < parts . length ; i ++ ) {
100120 const name = parts [ i ] ;
@@ -104,10 +124,10 @@ export class ResourceTree<T extends NonNullable<any>> {
104124
105125 if ( ! child ) {
106126 if ( i < parts . length - 1 ) {
107- child = new BranchNode ( path , node ) ;
127+ child = new BranchNode ( joinPath ( this . root . uri , path ) , path , this . root . context , node ) ;
108128 node . set ( name , child ) ;
109129 } else {
110- child = new LeafNode ( path , element ) ;
130+ child = new LeafNode ( uri , path , this . root . context , element ) ;
111131 node . set ( name , child ) ;
112132 return ;
113133 }
@@ -119,7 +139,7 @@ export class ResourceTree<T extends NonNullable<any>> {
119139 }
120140
121141 // replace
122- node . set ( name , new LeafNode ( path , element ) ) ;
142+ node . set ( name , new LeafNode ( uri , path , this . root . context , element ) ) ;
123143 return ;
124144 } else if ( i === parts . length - 1 ) {
125145 throw new Error ( 'Inconsistent tree: can\'t override branch with leaf.' ) ;
@@ -130,12 +150,12 @@ export class ResourceTree<T extends NonNullable<any>> {
130150 }
131151
132152 delete ( uri : URI ) : T | undefined {
133- const key = relativePath ( this . rootURI , uri ) || uri . fsPath ;
153+ const key = relativePath ( this . root . uri , uri ) || uri . fsPath ;
134154 const parts = key . split ( / [ \\ \/ ] / ) . filter ( p => ! ! p ) ;
135155 return this . _delete ( this . root , parts , 0 ) ;
136156 }
137157
138- private _delete ( node : BranchNode < T > , parts : string [ ] , index : number ) : T | undefined {
158+ private _delete ( node : BranchNode < T , C > , parts : string [ ] , index : number ) : T | undefined {
139159 const name = parts [ index ] ;
140160 const child = node . get ( name ) ;
141161
0 commit comments