@@ -23,6 +23,12 @@ import { Resources } from "../extension/resources";
2323
2424/** A tree item representing a workspace folder. */ 
2525export  class  BazelWorkspaceFolderTreeItem  implements  IBazelTreeItem  { 
26+   /** 
27+    * Stores all BazelPackageTreeItems in sorted order (by path length and in descending order). 
28+    * This is used to find the most specific match for a given file path. 
29+    */ 
30+   private  sortedPackageTreeItems : BazelPackageTreeItem [ ]  =  [ ] ; 
31+ 
2632  /** 
2733   * Initializes a new tree item with the given workspace folder. 
2834   * 
@@ -41,6 +47,10 @@ export class BazelWorkspaceFolderTreeItem implements IBazelTreeItem {
4147    return  this . getDirectoryItems ( ) ; 
4248  } 
4349
50+   public  getParent ( ) : vscode . ProviderResult < IBazelTreeItem >  { 
51+     return  undefined ; 
52+   } 
53+ 
4454  public  getLabel ( ) : string  { 
4555    return  this . workspaceInfo . workspaceFolder . name ; 
4656  } 
@@ -61,6 +71,31 @@ export class BazelWorkspaceFolderTreeItem implements IBazelTreeItem {
6171    return  "workspaceFolder" ; 
6272  } 
6373
74+   public  getWorkspaceInfo ( ) : BazelWorkspaceInfo  { 
75+     return  this . workspaceInfo ; 
76+   } 
77+ 
78+   public  getPackagePath ( ) : string  { 
79+     return  "" ; 
80+   } 
81+ 
82+   /** 
83+    * Finds the package that contains the given relative file path. 
84+    * Uses the presorted list of package items for efficient lookups. 
85+    * Find the first package that is a prefix of the relative path 
86+    * 
87+    * @param  relativeFilePath The filepath relative to the workspace folder. 
88+    * @returns  The package tree item that contains the given relative file path, 
89+    * or undefined if no such package exists. 
90+    */ 
91+   public  getClosestPackageTreeItem ( 
92+     relativeFilePath : string , 
93+   ) : BazelPackageTreeItem  |  undefined  { 
94+     return  this . sortedPackageTreeItems . find ( ( pkg )  => 
95+       relativeFilePath . startsWith ( pkg . getPackagePath ( ) ) , 
96+     ) ; 
97+   } 
98+ 
6499  /** 
65100   * Recursively creates the tree items that represent packages found in a Bazel 
66101   * query. 
@@ -73,16 +108,15 @@ export class BazelWorkspaceFolderTreeItem implements IBazelTreeItem {
73108   * common prefixes should be searched. 
74109   * @param  treeItems An array into which the tree items created at this level 
75110   * in the tree will be pushed. 
76-    * @param  parentPackagePath The parent package path of the items being created 
77-    * by this call, which is used to trim the package prefix from labels in 
78-    * the tree items. 
111+    * @param  parent The parent tree item of the items being created by this call, 
112+    * which is used to trim the package prefix from labels in the tree items. 
79113   */ 
80114  private  buildPackageTree ( 
81115    packagePaths : string [ ] , 
82116    startIndex : number , 
83117    endIndex : number , 
84118    treeItems : BazelPackageTreeItem [ ] , 
85-     parentPackagePath :  string , 
119+     parent :  IBazelTreeItem , 
86120  )  { 
87121    // We can assume that the caller has sorted the packages, so we scan them to 
88122    // find groupings into which we should traverse more deeply. For example, if 
@@ -128,16 +162,16 @@ export class BazelWorkspaceFolderTreeItem implements IBazelTreeItem {
128162      const  item  =  new  BazelPackageTreeItem ( 
129163        this . resources , 
130164        this . workspaceInfo , 
165+         parent , 
131166        packagePath , 
132-         parentPackagePath , 
133167      ) ; 
134168      treeItems . push ( item ) ; 
135169      this . buildPackageTree ( 
136170        packagePaths , 
137171        groupStart  +  1 , 
138172        groupEnd , 
139173        item . directSubpackages , 
140-         packagePath , 
174+         item , 
141175      ) ; 
142176
143177      // Move our index to start looking for more groups in the next iteration 
@@ -175,7 +209,7 @@ export class BazelWorkspaceFolderTreeItem implements IBazelTreeItem {
175209      0 , 
176210      packagePaths . length , 
177211      topLevelItems , 
178-       "" , 
212+       this , 
179213    ) ; 
180214
181215    // Now collect any targets in the directory also (this can fail since 
@@ -191,10 +225,37 @@ export class BazelWorkspaceFolderTreeItem implements IBazelTreeItem {
191225      return  new  BazelTargetTreeItem ( 
192226        this . resources , 
193227        this . workspaceInfo , 
228+         this  as  unknown  as  IBazelTreeItem , 
194229        target , 
195230      ) ; 
196231    } ) ; 
197232
233+     // Cache all packages after building the tree 
234+     this . collectAndSortPackageTreeItems ( topLevelItems ) ; 
235+ 
198236    return  Promise . resolve ( ( topLevelItems  as  IBazelTreeItem [ ] ) . concat ( targets ) ) ; 
199237  } 
238+ 
239+   /** 
240+    * Collect, sort and store packages for later lookup 
241+    */ 
242+   private  collectAndSortPackageTreeItems ( items : BazelPackageTreeItem [ ] ) : void { 
243+     this . sortedPackageTreeItems  =  [ ] ; 
244+     this . collectAllPackageTreeItems ( items ) ; 
245+     this . sortedPackageTreeItems . sort ( 
246+       ( a ,  b )  =>  b . getPackagePath ( ) . length  -  a . getPackagePath ( ) . length , 
247+     ) ; 
248+   } 
249+ 
250+   /** 
251+    * Recursively collect all children of type BazelPackageTreeItem 
252+    */ 
253+   private  collectAllPackageTreeItems ( items : BazelPackageTreeItem [ ] ) : void { 
254+     for  ( const  item  of  items )  { 
255+       this . sortedPackageTreeItems . push ( item ) ; 
256+       if  ( item . directSubpackages )  { 
257+         this . collectAllPackageTreeItems ( item . directSubpackages ) ; 
258+       } 
259+     } 
260+   } 
200261} 
0 commit comments