@@ -399,7 +399,7 @@ namespace FourSlash {
399
399
}
400
400
const memo = Utils . memoize (
401
401
( _version : number , _active : string , _caret : number , _selectEnd : number , _marker : string , ...args : any [ ] ) => ( ls [ key ] as Function ) ( ...args ) ,
402
- ( ...args ) => args . join ( "|,|" )
402
+ ( ...args ) => args . map ( a => a && typeof a === "object" ? JSON . stringify ( a ) : a ) . join ( "|,|" )
403
403
) ;
404
404
proxy [ key ] = ( ...args : any [ ] ) => memo (
405
405
target . languageServiceAdapterHost . getScriptInfo ( target . activeFile . fileName ) ! . version ,
@@ -867,7 +867,7 @@ namespace FourSlash {
867
867
nameToEntries . set ( entry . name , [ entry ] ) ;
868
868
}
869
869
else {
870
- if ( entries . some ( e => e . source === entry . source ) ) {
870
+ if ( entries . some ( e => e . source === entry . source && this . deepEqual ( e . data , entry . data ) ) ) {
871
871
this . raiseError ( `Duplicate completions for ${ entry . name } ` ) ;
872
872
}
873
873
entries . push ( entry ) ;
@@ -885,8 +885,8 @@ namespace FourSlash {
885
885
const name = typeof include === "string" ? include : include . name ;
886
886
const found = nameToEntries . get ( name ) ;
887
887
if ( ! found ) throw this . raiseError ( `Includes: completion '${ name } ' not found.` ) ;
888
- assert ( found . length === 1 , `Must use 'exact' for multiple completions with same name: '${ name } '`) ;
889
- this . verifyCompletionEntry ( ts . first ( found ) , include ) ;
888
+ if ( ! found . length ) throw this . raiseError ( `Includes: no completions with name '${ name } ' remain unmatched. `) ;
889
+ this . verifyCompletionEntry ( found . shift ( ) ! , include ) ;
890
890
}
891
891
}
892
892
if ( options . excludes ) {
@@ -933,7 +933,7 @@ namespace FourSlash {
933
933
assert . equal ( actual . sortText , expected . sortText || ts . Completions . SortText . LocationPriority , this . messageAtLastKnownMarker ( `Actual entry: ${ JSON . stringify ( actual ) } ` ) ) ;
934
934
935
935
if ( expected . text !== undefined ) {
936
- const actualDetails = ts . Debug . checkDefined ( this . getCompletionEntryDetails ( actual . name , actual . source ) , `No completion details available for name '${ actual . name } ' and source '${ actual . source } '` ) ;
936
+ const actualDetails = ts . Debug . checkDefined ( this . getCompletionEntryDetails ( actual . name , actual . source , actual . data ) , `No completion details available for name '${ actual . name } ' and source '${ actual . source } '` ) ;
937
937
assert . equal ( ts . displayPartsToString ( actualDetails . displayParts ) , expected . text , "Expected 'text' property to match 'displayParts' string" ) ;
938
938
assert . equal ( ts . displayPartsToString ( actualDetails . documentation ) , expected . documentation || "" , "Expected 'documentation' property to match 'documentation' display parts string" ) ;
939
939
// TODO: GH#23587
@@ -1003,8 +1003,8 @@ namespace FourSlash {
1003
1003
1004
1004
private verifySymbol ( symbol : ts . Symbol , declarationRanges : Range [ ] ) {
1005
1005
const { declarations } = symbol ;
1006
- if ( declarations . length !== declarationRanges . length ) {
1007
- this . raiseError ( `Expected to get ${ declarationRanges . length } declarations, got ${ declarations . length } ` ) ;
1006
+ if ( declarations ? .length !== declarationRanges . length ) {
1007
+ this . raiseError ( `Expected to get ${ declarationRanges . length } declarations, got ${ declarations ? .length } ` ) ;
1008
1008
}
1009
1009
1010
1010
ts . zipWith ( declarations , declarationRanges , ( decl , range ) => {
@@ -1254,6 +1254,16 @@ namespace FourSlash {
1254
1254
1255
1255
}
1256
1256
1257
+ private deepEqual ( a : unknown , b : unknown ) {
1258
+ try {
1259
+ this . assertObjectsEqual ( a , b ) ;
1260
+ return true ;
1261
+ }
1262
+ catch {
1263
+ return false ;
1264
+ }
1265
+ }
1266
+
1257
1267
public verifyDisplayPartsOfReferencedSymbol ( expected : ts . SymbolDisplayPart [ ] ) {
1258
1268
const referencedSymbols = this . findReferencesAtCaret ( ) ! ;
1259
1269
@@ -1281,11 +1291,11 @@ namespace FourSlash {
1281
1291
return this . languageService . getCompletionsAtPosition ( this . activeFile . fileName , this . currentCaretPosition , options ) ;
1282
1292
}
1283
1293
1284
- private getCompletionEntryDetails ( entryName : string , source ? : string , preferences ?: ts . UserPreferences ) : ts . CompletionEntryDetails | undefined {
1294
+ private getCompletionEntryDetails ( entryName : string , source : string | undefined , data : ts . CompletionEntryData | undefined , preferences ?: ts . UserPreferences ) : ts . CompletionEntryDetails | undefined {
1285
1295
if ( preferences ) {
1286
1296
this . configure ( preferences ) ;
1287
1297
}
1288
- return this . languageService . getCompletionEntryDetails ( this . activeFile . fileName , this . currentCaretPosition , entryName , this . formatCodeSettings , source , preferences ) ;
1298
+ return this . languageService . getCompletionEntryDetails ( this . activeFile . fileName , this . currentCaretPosition , entryName , this . formatCodeSettings , source , preferences , data ) ;
1289
1299
}
1290
1300
1291
1301
private getReferencesAtCaret ( ) {
@@ -2796,14 +2806,14 @@ namespace FourSlash {
2796
2806
public applyCodeActionFromCompletion ( markerName : string , options : FourSlashInterface . VerifyCompletionActionOptions ) {
2797
2807
this . goToMarker ( markerName ) ;
2798
2808
2799
- const details = this . getCompletionEntryDetails ( options . name , options . source , options . preferences ) ;
2809
+ const details = this . getCompletionEntryDetails ( options . name , options . source , options . data , options . preferences ) ;
2800
2810
if ( ! details ) {
2801
2811
const completions = this . getCompletionListAtCaret ( options . preferences ) ?. entries ;
2802
2812
const matchingName = completions ?. filter ( e => e . name === options . name ) ;
2803
2813
const detailMessage = matchingName ?. length
2804
2814
? `\n Found ${ matchingName . length } with name '${ options . name } ' from source(s) ${ matchingName . map ( e => `'${ e . source } '` ) . join ( ", " ) } .`
2805
2815
: ` (In fact, there were no completions with name '${ options . name } ' at all.)` ;
2806
- return this . raiseError ( `No completions were found for the given name, source, and preferences.` + detailMessage ) ;
2816
+ return this . raiseError ( `No completions were found for the given name, source/data , and preferences.` + detailMessage ) ;
2807
2817
}
2808
2818
const codeActions = details . codeActions ;
2809
2819
if ( codeActions ?. length !== 1 ) {
0 commit comments