@@ -89,7 +89,7 @@ namespace ts.Completions {
8989 return { isGlobalCompletion : false , isMemberCompletion : true , isNewIdentifierLocation : true , entries } ;
9090 }
9191 case StringLiteralCompletionKind . Types : {
92- const entries = completion . types . map ( type => ( { name : type . value , kindModifiers : ScriptElementKindModifier . none , kind : ScriptElementKind . variableElement , sortText : "0" } ) ) ;
92+ const entries = completion . types . map ( type => ( { name : type . value , kindModifiers : ScriptElementKindModifier . none , kind : ScriptElementKind . typeElement , sortText : "0" } ) ) ;
9393 return { isGlobalCompletion : false , isMemberCompletion : false , isNewIdentifierLocation : true , entries } ;
9494 }
9595 default :
@@ -531,6 +531,15 @@ namespace ts.Completions {
531531 ) : CompletionEntryDetails {
532532 const typeChecker = program . getTypeChecker ( ) ;
533533 const { name } = entryId ;
534+
535+ const contextToken = findPrecedingToken ( position , sourceFile ) ;
536+ if ( isInString ( sourceFile , position , contextToken ) ) {
537+ const stringLiteralCompletions = ! contextToken || ! isStringLiteralLike ( contextToken )
538+ ? undefined
539+ : getStringLiteralCompletionEntries ( sourceFile , contextToken , position , typeChecker , compilerOptions , host ) ;
540+ return stringLiteralCompletions && stringLiteralCompletionDetails ( name , contextToken , stringLiteralCompletions , sourceFile , typeChecker ) ;
541+ }
542+
534543 // Compute all the completion symbols again.
535544 const symbolCompletion = getSymbolCompletionFromEntryId ( typeChecker , log , compilerOptions , sourceFile , position , entryId , allSourceFiles ) ;
536545 switch ( symbolCompletion . type ) {
@@ -550,29 +559,40 @@ namespace ts.Completions {
550559 case "symbol" : {
551560 const { symbol, location, symbolToOriginInfoMap, previousToken } = symbolCompletion ;
552561 const { codeActions, sourceDisplay } = getCompletionEntryCodeActionsAndSourceDisplay ( symbolToOriginInfoMap , symbol , program , typeChecker , host , compilerOptions , sourceFile , previousToken , formatContext , getCanonicalFileName , allSourceFiles , preferences ) ;
553- const kindModifiers = SymbolDisplay . getSymbolModifiers ( symbol ) ;
554- const { displayParts, documentation, symbolKind, tags } = SymbolDisplay . getSymbolDisplayPartsDocumentationAndSymbolKind ( typeChecker , symbol , sourceFile , location , location , SemanticMeaning . All ) ;
555- return { name, kindModifiers, kind : symbolKind , displayParts, documentation, tags, codeActions, source : sourceDisplay } ;
562+ return createCompletionDetailsForSymbol ( symbol , typeChecker , sourceFile , location , codeActions , sourceDisplay ) ;
556563 }
557- case "none" : {
564+ case "none" :
558565 // Didn't find a symbol with this name. See if we can find a keyword instead.
559- if ( allKeywordsCompletions ( ) . some ( c => c . name === name ) ) {
560- return {
561- name,
562- kind : ScriptElementKind . keyword ,
563- kindModifiers : ScriptElementKindModifier . none ,
564- displayParts : [ displayPart ( name , SymbolDisplayPartKind . keyword ) ] ,
565- documentation : undefined ,
566- tags : undefined ,
567- codeActions : undefined ,
568- source : undefined ,
569- } ;
570- }
571- return undefined ;
566+ return allKeywordsCompletions ( ) . some ( c => c . name === name ) ? createCompletionDetails ( name , ScriptElementKindModifier . none , ScriptElementKind . keyword , [ displayPart ( name , SymbolDisplayPartKind . keyword ) ] ) : undefined ;
567+ }
568+ }
569+
570+ function createCompletionDetailsForSymbol ( symbol : Symbol , checker : TypeChecker , sourceFile : SourceFile , location : Node , codeActions ?: CodeAction [ ] , sourceDisplay ?: SymbolDisplayPart [ ] ) : CompletionEntryDetails {
571+ const { displayParts, documentation, symbolKind, tags } = SymbolDisplay . getSymbolDisplayPartsDocumentationAndSymbolKind ( checker , symbol , sourceFile , location , location , SemanticMeaning . All ) ;
572+ return createCompletionDetails ( symbol . name , SymbolDisplay . getSymbolModifiers ( symbol ) , symbolKind , displayParts , documentation , tags , codeActions , sourceDisplay ) ;
573+ }
574+
575+ function stringLiteralCompletionDetails ( name : string , location : Node , completion : StringLiteralCompletion , sourceFile : SourceFile , checker : TypeChecker ) : CompletionEntryDetails | undefined {
576+ switch ( completion . kind ) {
577+ case StringLiteralCompletionKind . Paths : {
578+ const match = find ( completion . paths , p => p . name === name ) ;
579+ return match && createCompletionDetails ( name , ScriptElementKindModifier . none , match . kind , [ textPart ( name ) ] ) ;
572580 }
581+ case StringLiteralCompletionKind . Properties : {
582+ const match = find ( completion . symbols , s => s . name === name ) ;
583+ return match && createCompletionDetailsForSymbol ( match , checker , sourceFile , location ) ;
584+ }
585+ case StringLiteralCompletionKind . Types :
586+ return find ( completion . types , t => t . value === name ) ? createCompletionDetails ( name , ScriptElementKindModifier . none , ScriptElementKind . typeElement , [ textPart ( name ) ] ) : undefined ;
587+ default :
588+ return Debug . assertNever ( completion ) ;
573589 }
574590 }
575591
592+ function createCompletionDetails ( name : string , kindModifiers : string , kind : ScriptElementKind , displayParts : SymbolDisplayPart [ ] , documentation ?: SymbolDisplayPart [ ] , tags ?: JSDocTagInfo [ ] , codeActions ?: CodeAction [ ] , source ?: SymbolDisplayPart [ ] ) : CompletionEntryDetails {
593+ return { name, kindModifiers, kind, displayParts, documentation, tags, codeActions, source } ;
594+ }
595+
576596 interface CodeActionsAndSourceDisplay {
577597 readonly codeActions : CodeAction [ ] | undefined ;
578598 readonly sourceDisplay : SymbolDisplayPart [ ] | undefined ;
0 commit comments