@@ -232,6 +232,7 @@ namespace ts.Completions {
232232 completionKind ,
233233 preferences ,
234234 propertyAccessToConvert ,
235+ completionData . isJsxIdentifierExpected ,
235236 isJsxInitializer ,
236237 recommendedCompletion ,
237238 symbolToOriginInfoMap ,
@@ -255,6 +256,7 @@ namespace ts.Completions {
255256 completionKind ,
256257 preferences ,
257258 propertyAccessToConvert ,
259+ completionData . isJsxIdentifierExpected ,
258260 isJsxInitializer ,
259261 recommendedCompletion ,
260262 symbolToOriginInfoMap ,
@@ -441,6 +443,7 @@ namespace ts.Completions {
441443 kind : CompletionKind ,
442444 preferences : UserPreferences ,
443445 propertyAccessToConvert ?: PropertyAccessExpression ,
446+ jsxIdentifierExpected ?: boolean ,
444447 isJsxInitializer ?: IsJsxInitializer ,
445448 recommendedCompletion ?: Symbol ,
446449 symbolToOriginInfoMap ?: SymbolOriginInfoMap ,
@@ -454,7 +457,7 @@ namespace ts.Completions {
454457 const uniques = createMap < true > ( ) ;
455458 for ( const symbol of symbols ) {
456459 const origin = symbolToOriginInfoMap ? symbolToOriginInfoMap [ getSymbolId ( symbol ) ] : undefined ;
457- const info = getCompletionEntryDisplayNameForSymbol ( symbol , target , origin , kind ) ;
460+ const info = getCompletionEntryDisplayNameForSymbol ( symbol , target , origin , kind , ! ! jsxIdentifierExpected ) ;
458461 if ( ! info ) {
459462 continue ;
460463 }
@@ -564,7 +567,7 @@ namespace ts.Completions {
564567 // completion entry.
565568 return firstDefined ( symbols , ( symbol ) : SymbolCompletion | undefined => {
566569 const origin = symbolToOriginInfoMap [ getSymbolId ( symbol ) ] ;
567- const info = getCompletionEntryDisplayNameForSymbol ( symbol , compilerOptions . target ! , origin , completionKind ) ;
570+ const info = getCompletionEntryDisplayNameForSymbol ( symbol , compilerOptions . target ! , origin , completionKind , completionData . isJsxIdentifierExpected ) ;
568571 return info && info . name === entryId . name && getSourceFromOrigin ( origin ) === entryId . source
569572 ? { type : "symbol" as const , symbol, location, symbolToOriginInfoMap, previousToken, isJsxInitializer, isTypeOnlyLocation }
570573 : undefined ;
@@ -716,6 +719,8 @@ namespace ts.Completions {
716719 readonly insideJsDocTagTypeExpression : boolean ;
717720 readonly symbolToSortTextMap : SymbolSortTextMap ;
718721 readonly isTypeOnlyLocation : boolean ;
722+ /** In JSX tag name and attribute names, identifiers like "my-tag" or "aria-name" is valid identifier. */
723+ readonly isJsxIdentifierExpected : boolean ;
719724 }
720725 type Request = { readonly kind : CompletionDataKind . JsDocTagName | CompletionDataKind . JsDocTag } | { readonly kind : CompletionDataKind . JsDocParameterName , tag : JSDocParameterTag } ;
721726
@@ -895,6 +900,7 @@ namespace ts.Completions {
895900 let isRightOfOpenTag = false ;
896901 let isStartingCloseTag = false ;
897902 let isJsxInitializer : IsJsxInitializer = false ;
903+ let isJsxIdentifierExpected = false ;
898904
899905 let location = getTouchingPropertyName ( sourceFile , position ) ;
900906 if ( contextToken ) {
@@ -975,11 +981,12 @@ namespace ts.Completions {
975981 if ( ! binaryExpressionMayBeOpenTag ( parent as BinaryExpression ) ) {
976982 break ;
977983 }
978- // falls through
984+ // falls through
979985
980986 case SyntaxKind . JsxSelfClosingElement :
981987 case SyntaxKind . JsxElement :
982988 case SyntaxKind . JsxOpeningElement :
989+ isJsxIdentifierExpected = true ;
983990 if ( contextToken . kind === SyntaxKind . LessThanToken ) {
984991 isRightOfOpenTag = true ;
985992 location = contextToken ;
@@ -992,6 +999,7 @@ namespace ts.Completions {
992999 isJsxInitializer = true ;
9931000 break ;
9941001 case SyntaxKind . Identifier :
1002+ isJsxIdentifierExpected = true ;
9951003 // For `<div x=[|f/**/|]`, `parent` will be `x` and `previousToken.parent` will be `f` (which is its own JsxAttribute)
9961004 // Note for `<div someBool f>` we don't want to treat this as a jsx inializer, instead it's the attribute name.
9971005 if ( parent !== previousToken . parent &&
@@ -1066,7 +1074,8 @@ namespace ts.Completions {
10661074 isJsxInitializer,
10671075 insideJsDocTagTypeExpression,
10681076 symbolToSortTextMap,
1069- isTypeOnlyLocation : isTypeOnly
1077+ isTypeOnlyLocation : isTypeOnly ,
1078+ isJsxIdentifierExpected,
10701079 } ;
10711080
10721081 type JSDocTagWithTypeExpression = JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag ;
@@ -1130,9 +1139,9 @@ namespace ts.Completions {
11301139 let insertQuestionDot = false ;
11311140 if ( type . isNullableType ( ) ) {
11321141 const canCorrectToQuestionDot =
1133- isRightOfDot &&
1134- ! isRightOfQuestionDot &&
1135- preferences . includeAutomaticOptionalChainCompletions !== false ;
1142+ isRightOfDot &&
1143+ ! isRightOfQuestionDot &&
1144+ preferences . includeAutomaticOptionalChainCompletions !== false ;
11361145
11371146 if ( canCorrectToQuestionDot || isRightOfQuestionDot ) {
11381147 type = type . getNonNullableType ( ) ;
@@ -1447,8 +1456,8 @@ namespace ts.Completions {
14471456 return insideJsDocTagTypeExpression
14481457 || ! isContextTokenValueLocation ( contextToken ) &&
14491458 ( isPossiblyTypeArgumentPosition ( contextToken , sourceFile , typeChecker )
1450- || isPartOfTypeNode ( location )
1451- || isContextTokenTypeLocation ( contextToken ) ) ;
1459+ || isPartOfTypeNode ( location )
1460+ || isContextTokenTypeLocation ( contextToken ) ) ;
14521461 }
14531462
14541463 function isContextTokenValueLocation ( contextToken : Node ) {
@@ -2399,6 +2408,7 @@ namespace ts.Completions {
23992408 target : ScriptTarget ,
24002409 origin : SymbolOriginInfo | undefined ,
24012410 kind : CompletionKind ,
2411+ jsxIdentifierExpected : boolean ,
24022412 ) : CompletionEntryDisplayNameForSymbol | undefined {
24032413 const name = originIsExport ( origin ) ? getNameForExportedSymbol ( symbol , target ) : symbol . name ;
24042414 if ( name === undefined
@@ -2411,7 +2421,7 @@ namespace ts.Completions {
24112421 }
24122422
24132423 const validNameResult : CompletionEntryDisplayNameForSymbol = { name, needsConvertPropertyAccess : false } ;
2414- if ( isIdentifierText ( name , target ) || symbol . valueDeclaration && isPrivateIdentifierPropertyDeclaration ( symbol . valueDeclaration ) ) {
2424+ if ( isIdentifierText ( name , target , jsxIdentifierExpected ? LanguageVariant . JSX : LanguageVariant . Standard ) || symbol . valueDeclaration && isPrivateIdentifierPropertyDeclaration ( symbol . valueDeclaration ) ) {
24152425 return validNameResult ;
24162426 }
24172427 switch ( kind ) {
0 commit comments