@@ -11,6 +11,7 @@ let inputFileSet: Set<string> | undefined;
11
11
const failingTestsPath = path . join ( import . meta. dirname , "failingTests.txt" ) ;
12
12
const failingTestsList = fs . readFileSync ( failingTestsPath , "utf-8" ) . split ( "\n" ) . map ( line => line . trim ( ) . substring ( 4 ) ) . filter ( line => line . length > 0 ) ;
13
13
const failingTests = new Set ( failingTestsList ) ;
14
+ const helperFilePath = path . join ( import . meta. dirname , "../" , "tests" , "util_test.go" ) ;
14
15
15
16
const outputDir = path . join ( import . meta. dirname , "../" , "tests" , "gen" ) ;
16
17
@@ -183,6 +184,28 @@ function parseVerifyCompletionsArgs(args: readonly ts.Expression[]): VerifyCompl
183
184
return cmds ;
184
185
}
185
186
187
+ const completionConstants = new Map ( [
188
+ [ "completion.globals" , "completionGlobals" ] ,
189
+ [ "completion.globalTypes" , "completionGlobalTypes" ] ,
190
+ [ "completion.classElementKeywords" , "completionClassElementKeywords" ] ,
191
+ [ "completion.classElementInJsKeywords" , "completionClassElementInJSKeywords" ] ,
192
+ [ "completion.constructorParameterKeywords" , "completionConstructorParameterKeywords" ] ,
193
+ [ "completion.functionMembersWithPrototype" , "completionFunctionMembersWithPrototype" ] ,
194
+ [ "completion.functionMembers" , "completionFunctionMembers" ] ,
195
+ [ "completion.typeKeywords" , "completionTypeKeywords" ] ,
196
+ [ "completion.undefinedVarEntry" , "completionUndefinedVarItem" ] ,
197
+ [ "completion.typeAssertionKeywords" , "completionTypeAssertionKeywords" ] ,
198
+ ] ) ;
199
+
200
+ const completionPlus = new Map ( [
201
+ [ "completion.globalsPlus" , "completionGlobalsPlus" ] ,
202
+ [ "completion.globalTypesPlus" , "completionGlobalTypesPlus" ] ,
203
+ [ "completion.functionMembersPlus" , "completionFunctionMembersPlus" ] ,
204
+ [ "completion.functionMembersWithPrototypePlus" , "completionFunctionMembersWithPrototypePlus" ] ,
205
+ [ "completion.globalsInJsPlus" , "completionGlobalsInJSPlus" ] ,
206
+ [ "completion.typeKeywordsPlus" , "completionTypeKeywordsPlus" ] ,
207
+ ] ) ;
208
+
186
209
function parseVerifyCompletionArg ( arg : ts . Expression ) : VerifyCompletionsCmd | undefined {
187
210
let marker : string | undefined ;
188
211
let goArgs : VerifyCompletionsArgs | undefined ;
@@ -236,31 +259,84 @@ function parseVerifyCompletionArg(arg: ts.Expression): VerifyCompletionsCmd | un
236
259
args : undefined ,
237
260
} ;
238
261
}
239
- let expected = "[]fourslash.ExpectedCompletionItem{" ;
240
- if ( ts . isArrayLiteralExpression ( init ) ) {
241
- for ( const elem of init . elements ) {
262
+ let expected : string ;
263
+ const initText = init . getText ( ) ;
264
+ if ( completionConstants . has ( initText ) ) {
265
+ expected = completionConstants . get ( initText ) ! ;
266
+ }
267
+ else if ( completionPlus . keys ( ) . some ( funcName => initText . startsWith ( funcName ) ) ) {
268
+ const tsFunc = completionPlus . keys ( ) . find ( funcName => initText . startsWith ( funcName ) ) ;
269
+ const funcName = completionPlus . get ( tsFunc ! ) ! ;
270
+ const items = ( init as ts . CallExpression ) . arguments [ 0 ] ;
271
+ const opts = ( init as ts . CallExpression ) . arguments [ 1 ] ;
272
+ if ( ! ts . isArrayLiteralExpression ( items ) ) {
273
+ console . error ( `Expected array literal expression for completion.globalsPlus items, got ${ items . getText ( ) } ` ) ;
274
+ return undefined ;
275
+ }
276
+ expected = `${ funcName } ([]fourslash.CompletionsExpectedItem{` ;
277
+ for ( const elem of items . elements ) {
242
278
const result = parseExpectedCompletionItem ( elem ) ;
243
279
if ( ! result ) {
244
280
return undefined ;
245
281
}
246
282
expected += result + ", " ;
247
283
}
284
+ expected += "}" ;
285
+ if ( opts ) {
286
+ if ( ! ts . isObjectLiteralExpression ( opts ) ) {
287
+ console . error ( `Expected object literal expression for completion.globalsPlus options, got ${ opts . getText ( ) } ` ) ;
288
+ return undefined ;
289
+ }
290
+ const noLib = opts . properties [ 0 ] ;
291
+ if ( noLib && ts . isPropertyAssignment ( noLib ) && noLib . name . getText ( ) === "noLib" ) {
292
+ if ( noLib . initializer . kind === ts . SyntaxKind . TrueKeyword ) {
293
+ expected += ", true" ;
294
+ }
295
+ else if ( noLib . initializer . kind === ts . SyntaxKind . FalseKeyword ) {
296
+ expected += ", false" ;
297
+ }
298
+ else {
299
+ console . error ( `Expected boolean literal for noLib, got ${ noLib . initializer . getText ( ) } ` ) ;
300
+ return undefined ;
301
+ }
302
+ }
303
+ else {
304
+ console . error ( `Expected noLib property in completion.globalsPlus options, got ${ opts . getText ( ) } ` ) ;
305
+ return undefined ;
306
+ }
307
+ }
308
+ else if ( tsFunc === "completion.globalsPlus" || tsFunc === "completion.globalsInJsPlus" ) {
309
+ expected += ", false" ; // Default for noLib
310
+ }
311
+ expected += ")" ;
248
312
}
249
313
else {
250
- const result = parseExpectedCompletionItem ( init ) ;
251
- if ( ! result ) {
252
- return undefined ;
314
+ expected = "[]fourslash.CompletionsExpectedItem{" ;
315
+ if ( ts . isArrayLiteralExpression ( init ) ) {
316
+ for ( const elem of init . elements ) {
317
+ const result = parseExpectedCompletionItem ( elem ) ;
318
+ if ( ! result ) {
319
+ return undefined ;
320
+ }
321
+ expected += result + ", " ;
322
+ }
323
+ }
324
+ else {
325
+ const result = parseExpectedCompletionItem ( init ) ;
326
+ if ( ! result ) {
327
+ return undefined ;
328
+ }
329
+ expected += result ;
253
330
}
254
- expected += result ;
331
+ expected += "}" ;
255
332
}
256
- expected += "}" ;
257
333
if ( propName === "includes" ) {
258
334
( goArgs ??= { } ) . includes = expected ;
259
335
}
260
336
else {
261
337
( goArgs ??= { } ) . exact = expected ;
262
338
}
263
- break ; // !!! parse these args
339
+ break ;
264
340
case "excludes" :
265
341
let excludes = "[]string{" ;
266
342
if ( ts . isStringLiteral ( init ) ) {
@@ -286,7 +362,7 @@ function parseVerifyCompletionArg(arg: ts.Expression): VerifyCompletionsCmd | un
286
362
case "triggerCharacter" :
287
363
case "defaultCommitCharacters" :
288
364
break ; // !!! parse once they're supported in fourslash
289
- case "optionalReplacementSpan" :
365
+ case "optionalReplacementSpan" : // the only two tests that use this will require manual conversion
290
366
case "isGlobalCompletion" :
291
367
break ; // Ignored, unused
292
368
default :
@@ -303,6 +379,9 @@ function parseVerifyCompletionArg(arg: ts.Expression): VerifyCompletionsCmd | un
303
379
}
304
380
305
381
function parseExpectedCompletionItem ( expr : ts . Expression ) : string | undefined {
382
+ if ( completionConstants . has ( expr . getText ( ) ) ) {
383
+ return completionConstants . get ( expr . getText ( ) ) ! ;
384
+ }
306
385
if ( ts . isStringLiteral ( expr ) ) {
307
386
return getGoStringLiteral ( expr . text ) ;
308
387
}
@@ -501,16 +580,16 @@ function parseSortText(expr: ts.Expression): string | undefined {
501
580
return "ls.SortTextOptionalMember" ;
502
581
case "completion.SortText.MemberDeclaredBySpreadAssignment" :
503
582
return "ls.SortTextMemberDeclaredBySpreadAssignment" ;
504
- case "completion.SortText.SuggestedClassMember " :
505
- return "ls.SortTextSuggestedClassMember " ;
583
+ case "completion.SortText.SuggestedClassMembers " :
584
+ return "ls.SortTextSuggestedClassMembers " ;
506
585
case "completion.SortText.GlobalsOrKeywords" :
507
586
return "ls.SortTextGlobalsOrKeywords" ;
508
587
case "completion.SortText.AutoImportSuggestions" :
509
588
return "ls.SortTextAutoImportSuggestions" ;
510
589
case "completion.SortText.ClassMemberSnippets" :
511
590
return "ls.SortTextClassMemberSnippets" ;
512
- case "completion.SortText.JavaScriptIdentifiers " :
513
- return "ls.SortTextJavaScriptIdentifiers " ;
591
+ case "completion.SortText.JavascriptIdentifiers " :
592
+ return "ls.SortTextJavascriptIdentifiers " ;
514
593
default :
515
594
console . error ( `Unrecognized sort text: ${ text } ` ) ;
516
595
return undefined ; // !!! support deprecated/obj literal prop/etc
@@ -545,14 +624,14 @@ function generateVerifyCompletions({ marker, args, isNewIdentifierLocation }: Ve
545
624
if ( args . excludes ) expected . push ( `Excludes: ${ args . excludes } ,` ) ;
546
625
if ( args . exact ) expected . push ( `Exact: ${ args . exact } ,` ) ;
547
626
// !!! isIncomplete
548
- // !!! itemDefaults/commitCharacters from `isNewIdentifierLocation`
549
627
const commitCharacters = isNewIdentifierLocation ? "[]string{}" : "defaultCommitCharacters" ;
550
- expectedList = `&fourslash.VerifyCompletionsExpectedList {
628
+ expectedList = `&fourslash.CompletionsExpectedList {
551
629
IsIncomplete: false,
552
- ItemDefaults: &lsproto.CompletionItemDefaults {
630
+ ItemDefaults: &fourslash.CompletionsExpectedItemDefaults {
553
631
CommitCharacters: &${ commitCharacters } ,
632
+ EditRange: ignored,
554
633
},
555
- Items: &fourslash.VerifyCompletionsExpectedItems {
634
+ Items: &fourslash.CompletionsExpectedItems {
556
635
${ expected . join ( "\n" ) }
557
636
},
558
637
}` ;
@@ -614,14 +693,7 @@ func Test${testName}(t *testing.T) {
614
693
}
615
694
616
695
function generateHelperFile ( ) {
617
- const helper = `package fourslash_test
618
-
619
- func ptrTo[T any](v T) *T {
620
- return &v
621
- }
622
-
623
- var defaultCommitCharacters = []string{".", ",", ";"}` ;
624
- fs . writeFileSync ( path . join ( outputDir , "util_test.go" ) , helper , "utf-8" ) ;
696
+ fs . copyFileSync ( helperFilePath , path . join ( outputDir , "util_test.go" ) ) ;
625
697
}
626
698
627
699
main ( ) ;
0 commit comments