@@ -167,7 +167,6 @@ namespace ts.Completions {
167167 return undefined ;
168168 }
169169 const { name, needsConvertPropertyAccess } = info ;
170- Debug . assert ( ! ( needsConvertPropertyAccess && ! propertyAccessToConvert ) ) ;
171170 if ( needsConvertPropertyAccess && ! includeInsertTextCompletions ) {
172171 return undefined ;
173172 }
@@ -186,14 +185,24 @@ namespace ts.Completions {
186185 kindModifiers : SymbolDisplay . getSymbolModifiers ( symbol ) ,
187186 sortText : "0" ,
188187 source : getSourceFromOrigin ( origin ) ,
189- // TODO: GH#20619 Use configured quote style
190- insertText : needsConvertPropertyAccess ? `["${ name } "]` : undefined ,
191- replacementSpan : needsConvertPropertyAccess
192- ? createTextSpanFromBounds ( findChildOfKind ( propertyAccessToConvert , SyntaxKind . DotToken , sourceFile ) ! . getStart ( sourceFile ) , propertyAccessToConvert . name . end )
193- : undefined ,
194- hasAction : trueOrUndefined ( needsConvertPropertyAccess || origin !== undefined ) ,
188+ hasAction : trueOrUndefined ( origin !== undefined ) ,
195189 isRecommended : trueOrUndefined ( isRecommendedCompletionMatch ( symbol , recommendedCompletion , typeChecker ) ) ,
190+ ...getInsertTextAndReplacementSpan ( ) ,
196191 } ;
192+
193+ function getInsertTextAndReplacementSpan ( ) : { insertText ?: string , replacementSpan ?: TextSpan } {
194+ if ( kind === CompletionKind . Global ) {
195+ if ( typeChecker . isMemberSymbol ( symbol ) ) {
196+ return { insertText : needsConvertPropertyAccess ? `this["${ name } "]` : `this.${ name } ` } ;
197+ }
198+ }
199+ if ( needsConvertPropertyAccess ) {
200+ // TODO: GH#20619 Use configured quote style
201+ const replacementSpan = createTextSpanFromBounds ( findChildOfKind ( propertyAccessToConvert ! , SyntaxKind . DotToken , sourceFile ) ! . getStart ( sourceFile ) , propertyAccessToConvert ! . name . end ) ;
202+ return { insertText : `["${ name } "]` , replacementSpan } ;
203+ }
204+ return { } ;
205+ }
197206 }
198207
199208
@@ -1097,6 +1106,15 @@ namespace ts.Completions {
10971106 const symbolMeanings = SymbolFlags . Type | SymbolFlags . Value | SymbolFlags . Namespace | SymbolFlags . Alias ;
10981107
10991108 symbols = typeChecker . getSymbolsInScope ( scopeNode , symbolMeanings ) ;
1109+
1110+ // Need to insert 'this.' before properties of `this` type, so only do that if `includeInsertTextCompletions`
1111+ if ( options . includeInsertTextCompletions && scopeNode . kind !== SyntaxKind . SourceFile ) {
1112+ const thisType = typeChecker . tryGetThisTypeAt ( scopeNode ) ;
1113+ if ( thisType ) {
1114+ symbols . push ( ...getPropertiesForCompletion ( thisType , typeChecker , /*isForAccess*/ true ) ) ;
1115+ }
1116+ }
1117+
11001118 if ( options . includeExternalModuleExports ) {
11011119 getSymbolsFromOtherSourceFileExports ( symbols , previousToken && isIdentifier ( previousToken ) ? previousToken . text : "" , target ) ;
11021120 }
@@ -2052,13 +2070,13 @@ namespace ts.Completions {
20522070 if ( isIdentifierText ( name , target ) ) return validIdentiferResult ;
20532071 switch ( kind ) {
20542072 case CompletionKind . None :
2055- case CompletionKind . Global :
20562073 case CompletionKind . MemberLike :
20572074 return undefined ;
20582075 case CompletionKind . ObjectPropertyDeclaration :
20592076 // TODO: GH#18169
20602077 return { name : JSON . stringify ( name ) , needsConvertPropertyAccess : false } ;
20612078 case CompletionKind . PropertyAccess :
2079+ case CompletionKind . Global :
20622080 // Don't add a completion for a name starting with a space. See https://github.com/Microsoft/TypeScript/pull/20547
20632081 return name . charCodeAt ( 0 ) === CharacterCodes . space ? undefined : { name, needsConvertPropertyAccess : true } ;
20642082 case CompletionKind . String :
0 commit comments