@@ -167,7 +167,6 @@ namespace ts.Completions {
167
167
return undefined ;
168
168
}
169
169
const { name, needsConvertPropertyAccess } = info ;
170
- Debug . assert ( ! ( needsConvertPropertyAccess && ! propertyAccessToConvert ) ) ;
171
170
if ( needsConvertPropertyAccess && ! includeInsertTextCompletions ) {
172
171
return undefined ;
173
172
}
@@ -186,14 +185,24 @@ namespace ts.Completions {
186
185
kindModifiers : SymbolDisplay . getSymbolModifiers ( symbol ) ,
187
186
sortText : "0" ,
188
187
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 ) ,
195
189
isRecommended : trueOrUndefined ( isRecommendedCompletionMatch ( symbol , recommendedCompletion , typeChecker ) ) ,
190
+ ...getInsertTextAndReplacementSpan ( ) ,
196
191
} ;
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
+ }
197
206
}
198
207
199
208
@@ -1097,6 +1106,15 @@ namespace ts.Completions {
1097
1106
const symbolMeanings = SymbolFlags . Type | SymbolFlags . Value | SymbolFlags . Namespace | SymbolFlags . Alias ;
1098
1107
1099
1108
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
+
1100
1118
if ( options . includeExternalModuleExports ) {
1101
1119
getSymbolsFromOtherSourceFileExports ( symbols , previousToken && isIdentifier ( previousToken ) ? previousToken . text : "" , target ) ;
1102
1120
}
@@ -2052,13 +2070,13 @@ namespace ts.Completions {
2052
2070
if ( isIdentifierText ( name , target ) ) return validIdentiferResult ;
2053
2071
switch ( kind ) {
2054
2072
case CompletionKind . None :
2055
- case CompletionKind . Global :
2056
2073
case CompletionKind . MemberLike :
2057
2074
return undefined ;
2058
2075
case CompletionKind . ObjectPropertyDeclaration :
2059
2076
// TODO: GH#18169
2060
2077
return { name : JSON . stringify ( name ) , needsConvertPropertyAccess : false } ;
2061
2078
case CompletionKind . PropertyAccess :
2079
+ case CompletionKind . Global :
2062
2080
// Don't add a completion for a name starting with a space. See https://github.com/Microsoft/TypeScript/pull/20547
2063
2081
return name . charCodeAt ( 0 ) === CharacterCodes . space ? undefined : { name, needsConvertPropertyAccess : true } ;
2064
2082
case CompletionKind . String :
0 commit comments