@@ -27,7 +27,7 @@ export class MethodsUsageDataProvider
2727 private methods : readonly Method [ ] = [ ] ;
2828 // sortedMethods is a separate field so we can check if the methods have changed
2929 // by reference, which is faster than checking if the methods have changed by value.
30- private sortedMethods : readonly Method [ ] = [ ] ;
30+ private sortedTreeItems : readonly MethodTreeViewItem [ ] = [ ] ;
3131 private databaseItem : DatabaseItem | undefined = undefined ;
3232 private sourceLocationPrefix : string | undefined = undefined ;
3333 private hideModeledMethods : boolean = INITIAL_HIDE_MODELED_METHODS_VALUE ;
@@ -72,7 +72,9 @@ export class MethodsUsageDataProvider
7272 this . modifiedMethodSignatures !== modifiedMethodSignatures
7373 ) {
7474 this . methods = methods ;
75- this . sortedMethods = sortMethodsInGroups ( methods , mode ) ;
75+ this . sortedTreeItems = createTreeItems (
76+ sortMethodsInGroups ( methods , mode ) ,
77+ ) ;
7678 this . databaseItem = databaseItem ;
7779 this . sourceLocationPrefix =
7880 await this . databaseItem . getSourceLocationPrefix ( this . cliServer ) ;
@@ -86,15 +88,15 @@ export class MethodsUsageDataProvider
8688 }
8789
8890 getTreeItem ( item : MethodsUsageTreeViewItem ) : TreeItem {
89- if ( isExternalApiUsage ( item ) ) {
91+ if ( isMethodTreeViewItem ( item ) ) {
9092 return {
9193 label : `${ item . packageName } .${ item . typeName } .${ item . methodName } ${ item . methodParameters } ` ,
9294 collapsibleState : TreeItemCollapsibleState . Collapsed ,
9395 iconPath : this . getModelingStatusIcon ( item ) ,
9496 } ;
9597 } else {
9698 const method = this . getParent ( item ) ;
97- if ( ! method || ! isExternalApiUsage ( method ) ) {
99+ if ( ! method || ! isMethodTreeViewItem ( method ) ) {
98100 throw new Error ( "Parent not found for tree item" ) ;
99101 }
100102 return {
@@ -144,12 +146,12 @@ export class MethodsUsageDataProvider
144146 getChildren ( item ?: MethodsUsageTreeViewItem ) : MethodsUsageTreeViewItem [ ] {
145147 if ( item === undefined ) {
146148 if ( this . hideModeledMethods ) {
147- return this . sortedMethods . filter ( ( api ) => ! api . supported ) ;
149+ return this . sortedTreeItems . filter ( ( api ) => ! api . supported ) ;
148150 } else {
149- return [ ...this . sortedMethods ] ;
151+ return [ ...this . sortedTreeItems ] ;
150152 }
151- } else if ( isExternalApiUsage ( item ) ) {
152- return [ ... item . usages ] ;
153+ } else if ( isMethodTreeViewItem ( item ) ) {
154+ return item . children ;
153155 } else {
154156 return [ ] ;
155157 }
@@ -158,29 +160,42 @@ export class MethodsUsageDataProvider
158160 getParent (
159161 item : MethodsUsageTreeViewItem ,
160162 ) : MethodsUsageTreeViewItem | undefined {
161- if ( isExternalApiUsage ( item ) ) {
163+ if ( isMethodTreeViewItem ( item ) ) {
162164 return undefined ;
163165 } else {
164- return this . methods . find ( ( e ) => e . usages . includes ( item ) ) ;
166+ return item . parent ;
165167 }
166168 }
167169
168- public resolveCanonicalUsage ( usage : Usage ) : Usage | undefined {
169- for ( const method of this . methods ) {
170- for ( const u of method . usages ) {
171- if ( usagesAreEqual ( u , usage ) ) {
172- return u ;
173- }
174- }
170+ public resolveUsageTreeViewItem (
171+ methodSignature : string ,
172+ usage : Usage ,
173+ ) : UsageTreeViewItem | undefined {
174+ const method = this . sortedTreeItems . find (
175+ ( m ) => m . signature === methodSignature ,
176+ ) ;
177+ if ( ! method ) {
178+ return undefined ;
175179 }
176- return undefined ;
180+
181+ return method . children . find ( ( u ) => usagesAreEqual ( u , usage ) ) ;
177182 }
178183}
179184
180- export type MethodsUsageTreeViewItem = Method | Usage ;
185+ type MethodTreeViewItem = Method & {
186+ children : UsageTreeViewItem [ ] ;
187+ } ;
188+
189+ type UsageTreeViewItem = Usage & {
190+ parent : MethodTreeViewItem ;
191+ } ;
192+
193+ export type MethodsUsageTreeViewItem = MethodTreeViewItem | UsageTreeViewItem ;
181194
182- function isExternalApiUsage ( item : MethodsUsageTreeViewItem ) : item is Method {
183- return ( item as any ) . usages !== undefined ;
195+ function isMethodTreeViewItem (
196+ item : MethodsUsageTreeViewItem ,
197+ ) : item is MethodTreeViewItem {
198+ return "children" in item && "usages" in item ;
184199}
185200
186201function usagesAreEqual ( u1 : Usage , u2 : Usage ) : boolean {
@@ -206,3 +221,20 @@ function sortMethodsInGroups(methods: readonly Method[], mode: Mode): Method[] {
206221 return sortMethods ( group ) ;
207222 } ) ;
208223}
224+
225+ function createTreeItems ( methods : readonly Method [ ] ) : MethodTreeViewItem [ ] {
226+ return methods . map ( ( method ) => {
227+ const newMethod : MethodTreeViewItem = {
228+ ...method ,
229+ children : [ ] ,
230+ } ;
231+
232+ newMethod . children = method . usages . map ( ( usage ) => ( {
233+ ...usage ,
234+ // This needs to be a reference to the parent method, not a copy of it.
235+ parent : newMethod ,
236+ } ) ) ;
237+
238+ return newMethod ;
239+ } ) ;
240+ }
0 commit comments