@@ -272,7 +272,7 @@ namespace ts.Completions {
272
272
}
273
273
274
274
for ( const literal of literals ) {
275
- entries . push ( createCompletionEntryForLiteral ( literal ) ) ;
275
+ entries . push ( createCompletionEntryForLiteral ( literal , preferences ) ) ;
276
276
}
277
277
278
278
return { isGlobalCompletion : isInSnippetScope , isMemberCompletion : isMemberCompletionKind ( completionKind ) , isNewIdentifierLocation, entries } ;
@@ -317,10 +317,13 @@ namespace ts.Completions {
317
317
} ) ;
318
318
}
319
319
320
- const completionNameForLiteral = ( literal : string | number | PseudoBigInt ) =>
321
- typeof literal === "object" ? pseudoBigIntToString ( literal ) + "n" : JSON . stringify ( literal ) ;
322
- function createCompletionEntryForLiteral ( literal : string | number | PseudoBigInt ) : CompletionEntry {
323
- return { name : completionNameForLiteral ( literal ) , kind : ScriptElementKind . string , kindModifiers : ScriptElementKindModifier . none , sortText : SortText . LocationPriority } ;
320
+ function completionNameForLiteral ( literal : string | number | PseudoBigInt , preferences : UserPreferences ) : string {
321
+ return typeof literal === "object" ? pseudoBigIntToString ( literal ) + "n" :
322
+ isString ( literal ) ? quote ( literal , preferences ) : JSON . stringify ( literal ) ;
323
+ }
324
+
325
+ function createCompletionEntryForLiteral ( literal : string | number | PseudoBigInt , preferences : UserPreferences ) : CompletionEntry {
326
+ return { name : completionNameForLiteral ( literal , preferences ) , kind : ScriptElementKind . string , kindModifiers : ScriptElementKindModifier . none , sortText : SortText . LocationPriority } ;
324
327
}
325
328
326
329
function createCompletionEntry (
@@ -344,13 +347,13 @@ namespace ts.Completions {
344
347
const useBraces = origin && originIsSymbolMember ( origin ) || needsConvertPropertyAccess ;
345
348
if ( origin && originIsThisType ( origin ) ) {
346
349
insertText = needsConvertPropertyAccess
347
- ? `this${ insertQuestionDot ? "?." : "" } [${ quote ( name , preferences ) } ]`
350
+ ? `this${ insertQuestionDot ? "?." : "" } [${ quotePropertyName ( name , preferences ) } ]`
348
351
: `this${ insertQuestionDot ? "?." : "." } ${ name } ` ;
349
352
}
350
353
// We should only have needsConvertPropertyAccess if there's a property access to convert. But see #21790.
351
354
// Somehow there was a global with a non-identifier name. Hopefully someone will complain about getting a "foo bar" global completion and provide a repro.
352
355
else if ( ( useBraces || insertQuestionDot ) && propertyAccessToConvert ) {
353
- insertText = useBraces ? needsConvertPropertyAccess ? `[${ quote ( name , preferences ) } ]` : `[${ name } ]` : name ;
356
+ insertText = useBraces ? needsConvertPropertyAccess ? `[${ quotePropertyName ( name , preferences ) } ]` : `[${ name } ]` : name ;
354
357
if ( insertQuestionDot || propertyAccessToConvert . questionDotToken ) {
355
358
insertText = `?.${ insertText } ` ;
356
359
}
@@ -410,6 +413,14 @@ namespace ts.Completions {
410
413
} ;
411
414
}
412
415
416
+ function quotePropertyName ( name : string , preferences : UserPreferences ) : string {
417
+ if ( / ^ \d + $ / . test ( name ) ) {
418
+ return name ;
419
+ }
420
+
421
+ return quote ( name , preferences ) ;
422
+ }
423
+
413
424
function isRecommendedCompletionMatch ( localSymbol : Symbol , recommendedCompletion : Symbol | undefined , checker : TypeChecker ) : boolean {
414
425
return localSymbol === recommendedCompletion ||
415
426
! ! ( localSymbol . flags & SymbolFlags . ExportValue ) && checker . getExportSymbolOfSymbol ( localSymbol ) === recommendedCompletion ;
@@ -531,6 +542,7 @@ namespace ts.Completions {
531
542
position : number ,
532
543
entryId : CompletionEntryIdentifier ,
533
544
host : LanguageServiceHost ,
545
+ preferences : UserPreferences ,
534
546
) : SymbolCompletion | { type : "request" , request : Request } | { type : "literal" , literal : string | number | PseudoBigInt } | { type : "none" } {
535
547
const compilerOptions = program . getCompilerOptions ( ) ;
536
548
const completionData = getCompletionData ( program , log , sourceFile , isUncheckedFile ( sourceFile , compilerOptions ) , position , { includeCompletionsForModuleExports : true , includeCompletionsWithInsertText : true } , entryId , host ) ;
@@ -543,7 +555,7 @@ namespace ts.Completions {
543
555
544
556
const { symbols, literals, location, completionKind, symbolToOriginInfoMap, previousToken, isJsxInitializer, isTypeOnlyLocation } = completionData ;
545
557
546
- const literal = find ( literals , l => completionNameForLiteral ( l ) === entryId . name ) ;
558
+ const literal = find ( literals , l => completionNameForLiteral ( l , preferences ) === entryId . name ) ;
547
559
if ( literal !== undefined ) return { type : "literal" , literal } ;
548
560
549
561
// Find the symbol with the matching entry name.
@@ -585,7 +597,7 @@ namespace ts.Completions {
585
597
}
586
598
587
599
// Compute all the completion symbols again.
588
- const symbolCompletion = getSymbolCompletionFromEntryId ( program , log , sourceFile , position , entryId , host ) ;
600
+ const symbolCompletion = getSymbolCompletionFromEntryId ( program , log , sourceFile , position , entryId , host , preferences ) ;
589
601
switch ( symbolCompletion . type ) {
590
602
case "request" : {
591
603
const { request } = symbolCompletion ;
@@ -607,7 +619,7 @@ namespace ts.Completions {
607
619
}
608
620
case "literal" : {
609
621
const { literal } = symbolCompletion ;
610
- return createSimpleDetails ( completionNameForLiteral ( literal ) , ScriptElementKind . string , typeof literal === "string" ? SymbolDisplayPartKind . stringLiteral : SymbolDisplayPartKind . numericLiteral ) ;
622
+ return createSimpleDetails ( completionNameForLiteral ( literal , preferences ) , ScriptElementKind . string , typeof literal === "string" ? SymbolDisplayPartKind . stringLiteral : SymbolDisplayPartKind . numericLiteral ) ;
611
623
}
612
624
case "none" :
613
625
// Didn't find a symbol with this name. See if we can find a keyword instead.
@@ -677,8 +689,9 @@ namespace ts.Completions {
677
689
position : number ,
678
690
entryId : CompletionEntryIdentifier ,
679
691
host : LanguageServiceHost ,
692
+ preferences : UserPreferences ,
680
693
) : Symbol | undefined {
681
- const completion = getSymbolCompletionFromEntryId ( program , log , sourceFile , position , entryId , host ) ;
694
+ const completion = getSymbolCompletionFromEntryId ( program , log , sourceFile , position , entryId , host , preferences ) ;
682
695
return completion . type === "symbol" ? completion . symbol : undefined ;
683
696
}
684
697
0 commit comments