@@ -573,7 +573,9 @@ namespace ts {
573573 visitNode(cbNode, (node as JsxExpression).expression);
574574 case SyntaxKind.JsxClosingElement:
575575 return visitNode(cbNode, (node as JsxClosingElement).tagName);
576-
576+ case SyntaxKind.JsxNamespacedName:
577+ return visitNode(cbNode, (node as JsxNamespacedName).namespace) ||
578+ visitNode(cbNode, (node as JsxNamespacedName).name);
577579 case SyntaxKind.OptionalType:
578580 case SyntaxKind.RestType:
579581 case SyntaxKind.JSDocTypeExpression:
@@ -5484,20 +5486,31 @@ namespace ts {
54845486
54855487 function parseJsxElementName(): JsxTagNameExpression {
54865488 const pos = getNodePos();
5487- scanJsxIdentifier();
54885489 // JsxElement can have name in the form of
54895490 // propertyAccessExpression
54905491 // primaryExpression in the form of an identifier and "this" keyword
54915492 // We can't just simply use parseLeftHandSideExpressionOrHigher because then we will start consider class,function etc as a keyword
54925493 // We only want to consider "this" as a primaryExpression
5493- let expression: JsxTagNameExpression = token() === SyntaxKind.ThisKeyword ?
5494- parseTokenNode<ThisExpression>() : parseIdentifierName();
5494+ let expression: JsxTagNameExpression = parseJsxTagName();
54955495 while (parseOptional(SyntaxKind.DotToken)) {
54965496 expression = finishNode(factory.createPropertyAccessExpression(expression, parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ false)), pos) as JsxTagNamePropertyAccess;
54975497 }
54985498 return expression;
54995499 }
55005500
5501+ function parseJsxTagName(): Identifier | JsxNamespacedName | ThisExpression {
5502+ const pos = getNodePos();
5503+ scanJsxIdentifier();
5504+
5505+ const isThis = token() === SyntaxKind.ThisKeyword;
5506+ const tagName = parseIdentifierName();
5507+ if (parseOptional(SyntaxKind.ColonToken)) {
5508+ scanJsxIdentifier();
5509+ return finishNode(factory.createJsxNamespacedName(tagName, parseIdentifierName()), pos);
5510+ }
5511+ return isThis ? finishNode(factory.createToken(SyntaxKind.ThisKeyword), pos) : tagName;
5512+ }
5513+
55015514 function parseJsxExpression(inExpressionContext: boolean): JsxExpression | undefined {
55025515 const pos = getNodePos();
55035516 if (!parseExpected(SyntaxKind.OpenBraceToken)) {
@@ -5530,9 +5543,8 @@ namespace ts {
55305543 return parseJsxSpreadAttribute();
55315544 }
55325545
5533- scanJsxIdentifier();
55345546 const pos = getNodePos();
5535- return finishNode(factory.createJsxAttribute(parseIdentifierName (), parseJsxAttributeValue()), pos);
5547+ return finishNode(factory.createJsxAttribute(parseJsxAttributeName (), parseJsxAttributeValue()), pos);
55365548 }
55375549
55385550 function parseJsxAttributeValue(): JsxAttributeValue | undefined {
@@ -5551,6 +5563,18 @@ namespace ts {
55515563 return undefined;
55525564 }
55535565
5566+ function parseJsxAttributeName() {
5567+ const pos = getNodePos();
5568+ scanJsxIdentifier();
5569+
5570+ const attrName = parseIdentifierName();
5571+ if (parseOptional(SyntaxKind.ColonToken)) {
5572+ scanJsxIdentifier();
5573+ return finishNode(factory.createJsxNamespacedName(attrName, parseIdentifierName()), pos);
5574+ }
5575+ return attrName;
5576+ }
5577+
55545578 function parseJsxSpreadAttribute(): JsxSpreadAttribute {
55555579 const pos = getNodePos();
55565580 parseExpected(SyntaxKind.OpenBraceToken);
@@ -9755,6 +9779,11 @@ namespace ts {
97559779 return true;
97569780 }
97579781
9782+ if (lhs.kind === SyntaxKind.JsxNamespacedName) {
9783+ return lhs.namespace.escapedText === (rhs as JsxNamespacedName).namespace.escapedText &&
9784+ lhs.name.escapedText === (rhs as JsxNamespacedName).name.escapedText;
9785+ }
9786+
97589787 // If we are at this statement then we must have PropertyAccessExpression and because tag name in Jsx element can only
97599788 // take forms of JsxTagNameExpression which includes an identifier, "this" expression, or another propertyAccessExpression
97609789 // it is safe to case the expression property as such. See parseJsxElementName for how we parse tag name in Jsx element
0 commit comments