11import * as vscode from 'vscode' ;
22import { Settings } from './settings' ;
3- import { DocumentInfoProvider , MethodInfo } from './services/documentInfoProvider' ;
3+ import { DocumentInfo , DocumentInfoProvider , MethodInfo } from './services/documentInfoProvider' ;
44import { CodeAnalyticsView } from './views/codeAnalytics/codeAnalyticsView' ;
55import { WorkspaceState } from './state' ;
66import { CodeObjectInsight , InsightImportance } from './views/codeAnalytics/InsightListView/IInsightListViewItemsCreator' ;
77import { CodeObjectLocationInfo } from './services/languages/extractors' ;
88import { UsageStatusResults } from './services/analyticsProvider' ;
9+ import { CodeInspector } from './services/codeInspector' ;
10+ import { Token } from './services/languages/tokens' ;
911
12+ export interface CodeLensData {
13+
14+ methodInfo : MethodInfo ;
15+ insights : CodeObjectInsight [ ] ;
16+
17+ }
1018export class AnalyticsCodeLens implements vscode . Disposable
1119{
1220
1321 private _provider : CodelensProvider ;
1422 private _disposables : vscode . Disposable [ ] = [ ] ;
1523
1624 constructor ( documentInfoProvider : DocumentInfoProvider ,
17- state : WorkspaceState )
25+ state : WorkspaceState , condeInspector : CodeInspector )
1826 {
19- this . _provider = new CodelensProvider ( documentInfoProvider , state ) ;
27+ this . _provider = new CodelensProvider ( documentInfoProvider , state , condeInspector ) ;
2028
2129 this . _disposables . push ( vscode . commands . registerCommand ( CodelensProvider . clickCommand , async ( methodInfo : MethodInfo , environment :string ) => {
30+
2231 if ( vscode . window . activeTextEditor ) {
32+ if ( methodInfo . documentUri !== vscode . window . activeTextEditor . document . uri ) {
33+
34+ const doc = await vscode . workspace . openTextDocument ( methodInfo . documentUri ) ;
35+ if ( doc ) {
36+ await vscode . window . showTextDocument ( doc , { preview : true } ) ;
37+
38+ }
39+
40+ }
41+
2342 vscode . window . activeTextEditor . selection = new vscode . Selection ( methodInfo . range . start , methodInfo . range . start ) ;
2443 }
2544
@@ -55,7 +74,7 @@ class CodelensProvider implements vscode.CodeLensProvider<vscode.CodeLens>
5574 public readonly onDidChangeCodeLenses : vscode . Event < void > = this . _onDidChangeCodeLenses . event ;
5675
5776 constructor ( private _documentInfoProvider : DocumentInfoProvider ,
58- private _state : WorkspaceState )
77+ private _state : WorkspaceState , private _codeInspector : CodeInspector )
5978 {
6079 }
6180
@@ -92,7 +111,6 @@ class CodelensProvider implements vscode.CodeLensProvider<vscode.CodeLens>
92111 private async getCodeLens ( methodInfo : MethodInfo ,
93112 codeObjectInfo :CodeObjectLocationInfo ,
94113 insights : CodeObjectInsight [ ] ,
95- state : UsageStatusResults ,
96114 environmentPrefix : boolean ) : Promise < vscode . CodeLens [ ] > {
97115
98116 const lens : vscode . CodeLens [ ] = [ ] ;
@@ -165,7 +183,7 @@ class CodelensProvider implements vscode.CodeLensProvider<vscode.CodeLens>
165183 = insights
166184 . filter ( x => x . environment == this . _state . environment ) ;
167185
168- const lenses = await this . getCodeLens ( methodInfo , codeObject , currentEnvInsights , usageStatus , false ) ;
186+ const lenses = await this . getCodeLens ( methodInfo , codeObject , currentEnvInsights , false ) ;
169187 for ( const lens of lenses ) {
170188 codelens . push ( lens ) ;
171189 }
@@ -176,7 +194,7 @@ class CodelensProvider implements vscode.CodeLensProvider<vscode.CodeLens>
176194 . filter ( x => x . decorators && x . importance < InsightImportance . important )
177195 . filter ( x => ! currentEnvInsights . some ( i => i . type == x . type && i . importance == x . importance ) ) ;
178196
179- const otherEnvLenses = await this . getCodeLens ( methodInfo , codeObject , otherEnvsInsightsToShow , usageStatus , true ) ;
197+ const otherEnvLenses = await this . getCodeLens ( methodInfo , codeObject , otherEnvsInsightsToShow , true ) ;
180198 for ( const lens of otherEnvLenses ) {
181199 codelens . push ( lens ) ;
182200 }
@@ -185,7 +203,67 @@ class CodelensProvider implements vscode.CodeLensProvider<vscode.CodeLens>
185203 return codelens ;
186204
187205 }
206+
207+ public async getCodeLensesForFunctions ( document : vscode . TextDocument , documentInfo : DocumentInfo , token : vscode . CancellationToken ) : Promise < vscode . CodeLens [ ] > {
208+
209+
210+ const memoised : { [ token :string ] : CodeLensData } = { } ;
211+ const functions = documentInfo . tokens . filter ( x => x . type === 'function' ) ;
212+ const lens : vscode . CodeLens [ ] = [ ] ;
213+ for ( const methodInfo of documentInfo . methods ) {
214+
215+ for ( const func of functions . filter ( x => x . range . intersection ( methodInfo . range ) ) ) {
216+
217+ const funcKey = tokenKey ( func . text , document . uri ) ;
218+ if ( funcKey in memoised ) {
219+ const data = memoised [ funcKey ] ;
220+ const newLens = await this . getCodeLens ( data . methodInfo , getFakeCodeLocation ( func ) ,
221+ data . insights , false ) ;
222+ lens . push ( ...newLens ) ;
223+ }
188224
225+ else {
226+
227+ if ( func . text === methodInfo . name && func . range === methodInfo . nameRange ) {
228+ continue ;
229+ }
230+ const remoteMethodInfo =
231+ await this . _codeInspector . getExecuteDefinitionMethodInfo ( document , func . range . start , this . _documentInfoProvider ) ;
232+
233+ if ( ! remoteMethodInfo ) {
234+ continue ;
235+ }
236+
237+ const remoteDoc = await this . _codeInspector . getDocumentInfo ( document , func . range . start , this . _documentInfoProvider ) ;
238+ if ( ! remoteDoc ) {
239+ continue ;
240+ }
241+
242+ const insights = remoteDoc . insights . forMethod ( remoteMethodInfo , this . _state . environment ) ;
243+ const funcLens = await this . getCodeLens ( remoteMethodInfo ,
244+ getFakeCodeLocation ( func ) , insights , false ) ;
245+
246+ lens . push ( ...funcLens ) ;
247+ memoised [ funcKey ] = { insights : insights , methodInfo : remoteMethodInfo } ;
248+ }
249+
250+ }
251+ }
252+
253+ return lens ;
254+
255+
256+ function getFakeCodeLocation ( func : Token ) : CodeObjectLocationInfo {
257+ return {
258+ range : func . range , documentUri : documentInfo . uri , ids : [ ] , displayName : func . text ,
259+ id : func . text , idsWithType : [ func . text ]
260+ } ;
261+ }
262+
263+ function tokenKey ( token :string , uri : vscode . Uri ) {
264+ return `${ uri } $$${ token } `
265+ }
266+ }
189267 public async provideCodeLenses ( document : vscode . TextDocument , token : vscode . CancellationToken ) : Promise < vscode . CodeLens [ ] >
190268 {
191269 if ( ! Settings . enableCodeLens . value )
@@ -209,7 +287,7 @@ class CodelensProvider implements vscode.CodeLensProvider<vscode.CodeLens>
209287
210288 const lenses = await this . getCodeLens ( methodInfo , methodInfo ,
211289 thisEnvInsights . filter ( x => x . scope == "Function" ) ,
212- documentInfo . usageData . getAll ( ) , false ) ;
290+ false ) ;
213291
214292 for ( const lens of lenses ) {
215293 methodCodeLens . push ( lens ) ;
@@ -272,7 +350,7 @@ class CodelensProvider implements vscode.CodeLensProvider<vscode.CodeLens>
272350 . filter ( x => x . decorators && x . importance < InsightImportance . important ) ;
273351
274352 const otherEnvLenses = await this . getCodeLens ( methodInfo , methodInfo , otherEnvsInsights ,
275- documentInfo . usageData . getAll ( ) , true ) ;
353+ true ) ;
276354 for ( const lens of otherEnvLenses ) {
277355 methodCodeLens . push ( lens ) ;
278356 }
@@ -287,7 +365,8 @@ class CodelensProvider implements vscode.CodeLensProvider<vscode.CodeLens>
287365
288366 }
289367
290-
368+ const funcLenses = await this . getCodeLensesForFunctions ( document , documentInfo , token ) ;
369+ codelens . push ( ...funcLenses ) ;
291370
292371 return codelens ;
293372 }
0 commit comments