@@ -3009,6 +3009,7 @@ namespace ts {
3009
3009
3010
3010
function tryGetGlobalSymbols ( ) : boolean {
3011
3011
let objectLikeContainer = tryGetObjectLikeCompletionContainer ( contextToken ) ;
3012
+ let jsxContainer = tryGetContainingJsxElement ( contextToken ) ;
3012
3013
if ( objectLikeContainer ) {
3013
3014
// Object literal expression, look up possible property names from contextual type
3014
3015
isMemberCompletion = true ;
@@ -3059,30 +3060,22 @@ namespace ts {
3059
3060
}
3060
3061
return true ;
3061
3062
}
3062
- else if ( getAncestor ( contextToken , SyntaxKind . JsxElement ) || getAncestor ( contextToken , SyntaxKind . JsxSelfClosingElement ) ) {
3063
- // Go up until we hit either the element or expression
3064
- let jsxNode = contextToken ;
3063
+ else if ( jsxContainer ) {
3064
+ let attrsType : Type ;
3065
+ if ( jsxContainer . kind === SyntaxKind . JsxSelfClosingElement ) {
3066
+ // Cursor is inside a JSX self-closing element
3067
+ attrsType = typeChecker . getJsxElementAttributesType ( < JsxSelfClosingElement > jsxContainer ) ;
3068
+ }
3069
+ else if ( jsxContainer . kind === SyntaxKind . JsxOpeningElement ) {
3070
+ // Cursor is inside a JSX element
3071
+ attrsType = typeChecker . getJsxElementAttributesType ( < JsxOpeningElement > jsxContainer ) ;
3072
+ }
3065
3073
3066
- while ( jsxNode ) {
3067
- if ( jsxNode . kind === SyntaxKind . JsxExpression ) {
3068
- // Defer to global completion if we're inside an {expression}
3069
- break ;
3070
- } else if ( jsxNode . kind === SyntaxKind . JsxSelfClosingElement || jsxNode . kind === SyntaxKind . JsxElement ) {
3071
- let attrsType : Type ;
3072
- if ( jsxNode . kind === SyntaxKind . JsxSelfClosingElement ) {
3073
- // Cursor is inside a JSX self-closing element
3074
- attrsType = typeChecker . getJsxElementAttributesType ( < JsxSelfClosingElement > jsxNode ) ;
3075
- }
3076
- else {
3077
- Debug . assert ( jsxNode . kind === SyntaxKind . JsxElement ) ;
3078
- // Cursor is inside a JSX element
3079
- attrsType = typeChecker . getJsxElementAttributesType ( ( < JsxElement > jsxNode ) . openingElement ) ;
3080
- }
3081
- symbols = typeChecker . getPropertiesOfType ( attrsType ) ;
3082
- isMemberCompletion = true ;
3083
- return true ;
3084
- }
3085
- jsxNode = jsxNode . parent ;
3074
+ if ( attrsType ) {
3075
+ symbols = typeChecker . getPropertiesOfType ( attrsType ) ;
3076
+ isMemberCompletion = true ;
3077
+ isNewIdentifierLocation = false ;
3078
+ return true ;
3086
3079
}
3087
3080
}
3088
3081
@@ -3268,6 +3261,36 @@ namespace ts {
3268
3261
return undefined ;
3269
3262
}
3270
3263
3264
+ function tryGetContainingJsxElement ( contextToken : Node ) : JsxOpeningLikeElement {
3265
+ if ( contextToken ) {
3266
+ let parent = contextToken . parent ;
3267
+ switch ( contextToken . kind ) {
3268
+ case SyntaxKind . LessThanSlashToken :
3269
+ case SyntaxKind . SlashToken :
3270
+ case SyntaxKind . Identifier :
3271
+ if ( parent && ( parent . kind === SyntaxKind . JsxSelfClosingElement || parent . kind === SyntaxKind . JsxOpeningElement ) ) {
3272
+ return < JsxOpeningLikeElement > parent ;
3273
+ }
3274
+ break ;
3275
+
3276
+ case SyntaxKind . CloseBraceToken :
3277
+ // The context token is the closing } of an attribute, which means
3278
+ // its parent is a JsxExpression, whose parent is a JsxAttribute,
3279
+ // whose parent is a JsxOpeningLikeElement
3280
+ if ( parent &&
3281
+ parent . kind === SyntaxKind . JsxExpression &&
3282
+ parent . parent &&
3283
+ parent . parent . kind === SyntaxKind . JsxAttribute ) {
3284
+
3285
+ return < JsxOpeningLikeElement > parent . parent . parent ;
3286
+ }
3287
+
3288
+ break ;
3289
+ }
3290
+ }
3291
+ return undefined ;
3292
+ }
3293
+
3271
3294
function isFunction ( kind : SyntaxKind ) : boolean {
3272
3295
switch ( kind ) {
3273
3296
case SyntaxKind . FunctionExpression :
0 commit comments