@@ -483,7 +483,9 @@ namespace ts {
483483 visitNode ( cbNode , ( node as JsxExpression ) . expression ) ;
484484 case SyntaxKind . JsxClosingElement :
485485 return visitNode ( cbNode , ( node as JsxClosingElement ) . tagName ) ;
486-
486+ case SyntaxKind . JsxNamespacedName :
487+ return visitNode ( cbNode , ( node as JsxNamespacedName ) . namespace ) ||
488+ visitNode ( cbNode , ( node as JsxNamespacedName ) . name ) ;
487489 case SyntaxKind . OptionalType :
488490 case SyntaxKind . RestType :
489491 case SyntaxKind . JSDocTypeExpression :
@@ -5270,20 +5272,31 @@ namespace ts {
52705272
52715273 function parseJsxElementName ( ) : JsxTagNameExpression {
52725274 const pos = getNodePos ( ) ;
5273- scanJsxIdentifier ( ) ;
52745275 // JsxElement can have name in the form of
52755276 // propertyAccessExpression
52765277 // primaryExpression in the form of an identifier and "this" keyword
52775278 // We can't just simply use parseLeftHandSideExpressionOrHigher because then we will start consider class,function etc as a keyword
52785279 // We only want to consider "this" as a primaryExpression
5279- let expression : JsxTagNameExpression = token ( ) === SyntaxKind . ThisKeyword ?
5280- parseTokenNode < ThisExpression > ( ) : parseIdentifierName ( ) ;
5280+ let expression : JsxTagNameExpression = parseJsxTagName ( ) ;
52815281 while ( parseOptional ( SyntaxKind . DotToken ) ) {
52825282 expression = finishNode ( factory . createPropertyAccessExpression ( expression , parseRightSideOfDot ( /*allowIdentifierNames*/ true , /*allowPrivateIdentifiers*/ false ) ) , pos ) as JsxTagNamePropertyAccess ;
52835283 }
52845284 return expression ;
52855285 }
52865286
5287+ function parseJsxTagName ( ) : Identifier | JsxNamespacedName | ThisExpression {
5288+ const pos = getNodePos ( ) ;
5289+ scanJsxIdentifier ( ) ;
5290+
5291+ const isThis = token ( ) === SyntaxKind . ThisKeyword ;
5292+ const tagName = parseIdentifierName ( ) ;
5293+ if ( parseOptional ( SyntaxKind . ColonToken ) ) {
5294+ scanJsxIdentifier ( ) ;
5295+ return finishNode ( factory . createJsxNamespacedName ( tagName , parseIdentifierName ( ) ) , pos ) ;
5296+ }
5297+ return isThis ? finishNode ( factory . createToken ( SyntaxKind . ThisKeyword ) , pos ) : tagName ;
5298+ }
5299+
52875300 function parseJsxExpression ( inExpressionContext : boolean ) : JsxExpression | undefined {
52885301 const pos = getNodePos ( ) ;
52895302 if ( ! parseExpected ( SyntaxKind . OpenBraceToken ) ) {
@@ -5316,11 +5329,10 @@ namespace ts {
53165329 return parseJsxSpreadAttribute ( ) ;
53175330 }
53185331
5319- scanJsxIdentifier ( ) ;
53205332 const pos = getNodePos ( ) ;
53215333 return finishNode (
53225334 factory . createJsxAttribute (
5323- parseIdentifierName ( ) ,
5335+ parseJsxAttributeName ( ) ,
53245336 token ( ) !== SyntaxKind . EqualsToken ? undefined :
53255337 scanJsxAttributeValue ( ) === SyntaxKind . StringLiteral ? parseLiteralNode ( ) as StringLiteral :
53265338 parseJsxExpression ( /*inExpressionContext*/ true )
@@ -5329,6 +5341,18 @@ namespace ts {
53295341 ) ;
53305342 }
53315343
5344+ function parseJsxAttributeName ( ) {
5345+ const pos = getNodePos ( ) ;
5346+ scanJsxIdentifier ( ) ;
5347+
5348+ const attrName = parseIdentifierName ( ) ;
5349+ if ( parseOptional ( SyntaxKind . ColonToken ) ) {
5350+ scanJsxIdentifier ( ) ;
5351+ return finishNode ( factory . createJsxNamespacedName ( attrName , parseIdentifierName ( ) ) , pos ) ;
5352+ }
5353+ return attrName ;
5354+ }
5355+
53325356 function parseJsxSpreadAttribute ( ) : JsxSpreadAttribute {
53335357 const pos = getNodePos ( ) ;
53345358 parseExpected ( SyntaxKind . OpenBraceToken ) ;
@@ -9565,6 +9589,11 @@ namespace ts {
95659589 return true ;
95669590 }
95679591
9592+ if ( lhs . kind === SyntaxKind . JsxNamespacedName ) {
9593+ return lhs . namespace . escapedText === ( rhs as JsxNamespacedName ) . namespace . escapedText &&
9594+ lhs . name . escapedText === ( rhs as JsxNamespacedName ) . name . escapedText ;
9595+ }
9596+
95689597 // If we are at this statement then we must have PropertyAccessExpression and because tag name in Jsx element can only
95699598 // take forms of JsxTagNameExpression which includes an identifier, "this" expression, or another propertyAccessExpression
95709599 // it is safe to case the expression property as such. See parseJsxElementName for how we parse tag name in Jsx element
0 commit comments