@@ -77,6 +77,11 @@ class DebugTestsCodeLens extends TestCodeLens {
7777 }
7878}
7979
80+ interface Test {
81+ framework : string ;
82+ methodName : string ;
83+ }
84+
8085export default class OmniSharpCodeLensProvider extends AbstractProvider implements vscode . CodeLensProvider {
8186
8287 constructor ( server : OmniSharpServer , testManager : TestManager , private optionProvider : OptionProvider , languageMiddlewareFeature : LanguageMiddlewareFeature ) {
@@ -100,7 +105,7 @@ export default class OmniSharpCodeLensProvider extends AbstractProvider implemen
100105 return [ ] ;
101106 }
102107
103- async resolveCodeLens ( codeLens : vscode . CodeLens , token : vscode . CancellationToken ) : Promise < vscode . CodeLens > {
108+ async resolveCodeLens ( codeLens : vscode . CodeLens , token : vscode . CancellationToken ) : Promise < vscode . CodeLens | undefined > {
104109 if ( codeLens instanceof ReferencesCodeLens ) {
105110 return this . resolveReferencesCodeLens ( codeLens , token ) ;
106111 }
@@ -110,9 +115,11 @@ export default class OmniSharpCodeLensProvider extends AbstractProvider implemen
110115 else if ( codeLens instanceof DebugTestsCodeLens ) {
111116 return this . resolveTestCodeLens ( codeLens , 'Debug Test' , 'dotnet.test.debug' , 'Debug All Tests' , 'dotnet.classTests.debug' ) ;
112117 }
118+
119+ return undefined ;
113120 }
114121
115- private async resolveReferencesCodeLens ( codeLens : ReferencesCodeLens , token : vscode . CancellationToken ) : Promise < vscode . CodeLens > {
122+ private async resolveReferencesCodeLens ( codeLens : ReferencesCodeLens , token : vscode . CancellationToken ) : Promise < vscode . CodeLens | undefined > {
116123 const request : protocol . FindUsagesRequest = {
117124 FileName : codeLens . fileName ,
118125 Line : codeLens . range . start . line ,
@@ -137,7 +144,7 @@ export default class OmniSharpCodeLensProvider extends AbstractProvider implemen
137144 codeLens . command = {
138145 title : count === 1 ? '1 reference' : `${ count } references` ,
139146 command : 'editor.action.showReferences' ,
140- arguments : [ vscode . Uri . file ( request . FileName ) , codeLens . range . start , remappedLocations ]
147+ arguments : [ vscode . Uri . file ( codeLens . fileName ) , codeLens . range . start , remappedLocations ]
141148 } ;
142149
143150 return codeLens ;
@@ -147,7 +154,7 @@ export default class OmniSharpCodeLensProvider extends AbstractProvider implemen
147154 }
148155 }
149156
150- private async resolveTestCodeLens ( codeLens : TestCodeLens , singularTitle : string , singularCommandName : string , pluralTitle : string , pluralCommandName : string ) : Promise < vscode . CodeLens > {
157+ private async resolveTestCodeLens ( codeLens : TestCodeLens , singularTitle : string , singularCommandName : string , pluralTitle : string , pluralCommandName : string ) : Promise < vscode . CodeLens | undefined > {
151158 if ( ! codeLens . isTestContainer ) {
152159 // This is just a single test method, not a container.
153160 codeLens . command = {
@@ -202,35 +209,33 @@ function createCodeLensesForElement(element: Structure.CodeElement, fileName: st
202209 }
203210
204211 if ( options . showTestsCodeLens ) {
205- if ( isValidMethodForTestCodeLens ( element ) ) {
206- let [ testFramework , testMethodName ] = getTestFrameworkAndMethodName ( element ) ;
207- let range = element . Ranges [ SymbolRangeNames . Name ] ;
208-
209- if ( range && testFramework && testMethodName ) {
210- results . push ( new RunTestsCodeLens ( range , fileName , element . DisplayName , /*isTestContainer*/ false , testFramework , [ testMethodName ] ) ) ;
211- results . push ( new DebugTestsCodeLens ( range , fileName , element . DisplayName , /*isTestContainer*/ false , testFramework , [ testMethodName ] ) ) ;
212+ if ( element . Kind === SymbolKinds . Method ) {
213+ const test = getTest ( element ) ;
214+ if ( test !== undefined ) {
215+ let range = element . Ranges [ SymbolRangeNames . Name ] ;
216+ if ( range !== undefined ) {
217+ results . push ( new RunTestsCodeLens ( range , fileName , element . DisplayName , /*isTestContainer*/ false , test . framework , [ test . methodName ] ) ) ;
218+ results . push ( new DebugTestsCodeLens ( range , fileName , element . DisplayName , /*isTestContainer*/ false , test . framework , [ test . methodName ] ) ) ;
219+ }
212220 }
213- }
214- else if ( isValidClassForTestCodeLens ( element ) ) {
215- // Note: We don't handle multiple test frameworks in the same class. The first test framework wins.
216- let testFramework : string = null ;
217- let testMethodNames : string [ ] = [ ] ;
218- let range = element . Ranges [ SymbolRangeNames . Name ] ;
221+ } else if ( element . Kind === SymbolKinds . Class && element . Children !== undefined ) {
222+ const methods = element . Children . filter ( child => child . Kind === SymbolKinds . Method ) ;
219223
220- for ( let childElement of element . Children ) {
221- let [ childTestFramework , childTestMethodName ] = getTestFrameworkAndMethodName ( childElement ) ;
224+ const tests = methods
225+ . map ( method => getTest ( method ) )
226+ . filter ( ( test ) : test is NonNullable < typeof test > => test !== undefined ) ;
222227
223- if ( ! testFramework && childTestFramework ) {
224- testFramework = childTestFramework ;
225- testMethodNames . push ( childTestMethodName ) ;
226- }
227- else if ( testFramework && childTestFramework === testFramework ) {
228- testMethodNames . push ( childTestMethodName ) ;
229- }
228+ // Note: We don't handle multiple test frameworks in the same class. The first test framework wins.
229+ const testFramework = tests . length > 0 ? tests [ 0 ] . framework : undefined ;
230+ if ( testFramework !== undefined ) {
231+ const testMethodNames = tests
232+ . filter ( test => test . framework === testFramework )
233+ . map ( test => test . methodName ) ;
234+
235+ let range = element . Ranges [ SymbolRangeNames . Name ] ;
236+ results . push ( new RunTestsCodeLens ( range , fileName , element . DisplayName , /*isTestContainer*/ true , testFramework , testMethodNames ) ) ;
237+ results . push ( new DebugTestsCodeLens ( range , fileName , element . DisplayName , /*isTestContainer*/ true , testFramework , testMethodNames ) ) ;
230238 }
231-
232- results . push ( new RunTestsCodeLens ( range , fileName , element . DisplayName , /*isTestContainer*/ true , testFramework , testMethodNames ) ) ;
233- results . push ( new DebugTestsCodeLens ( range , fileName , element . DisplayName , /*isTestContainer*/ true , testFramework , testMethodNames ) ) ;
234239 }
235240 }
236241
@@ -262,40 +267,19 @@ function isValidElementForReferencesCodeLens(element: Structure.CodeElement, opt
262267 return true ;
263268}
264269
265-
266- function isValidClassForTestCodeLens ( element : Structure . CodeElement ) : boolean {
267- if ( element . Kind != SymbolKinds . Class ) {
268- return false ;
270+ function getTest ( element : Structure . CodeElement ) : Test | undefined {
271+ if ( element . Properties === undefined ) {
272+ return undefined ;
269273 }
270274
271- if ( ! element . Children ) {
272- return false ;
275+ const framework = element . Properties [ SymbolPropertyNames . TestFramework ] ;
276+ const methodName = element . Properties [ SymbolPropertyNames . TestMethodName ] ;
277+ if ( framework === undefined || methodName === undefined ) {
278+ return undefined ;
273279 }
274280
275- return element . Children . find ( isValidMethodForTestCodeLens ) !== undefined ;
276- }
277-
278- function isValidMethodForTestCodeLens ( element : Structure . CodeElement ) : boolean {
279- if ( element . Kind != SymbolKinds . Method ) {
280- return false ;
281+ return {
282+ framework,
283+ methodName,
281284 }
282-
283- if ( ! element . Properties ||
284- ! element . Properties [ SymbolPropertyNames . TestFramework ] ||
285- ! element . Properties [ SymbolPropertyNames . TestMethodName ] ) {
286- return false ;
287- }
288-
289- return true ;
290- }
291-
292- function getTestFrameworkAndMethodName ( element : Structure . CodeElement ) : [ string , string ] {
293- if ( ! element . Properties ) {
294- return [ null , null ] ;
295- }
296-
297- const testFramework = element . Properties [ SymbolPropertyNames . TestFramework ] ;
298- const testMethodName = element . Properties [ SymbolPropertyNames . TestMethodName ] ;
299-
300- return [ testFramework , testMethodName ] ;
301285}
0 commit comments