@@ -519,7 +519,9 @@ namespace ts {
519519 visitNode(cbNode, (node as JsxExpression).expression);
520520 case SyntaxKind.JsxClosingElement:
521521 return visitNode(cbNode, (node as JsxClosingElement).tagName);
522-
522+ case SyntaxKind.JsxNamespacedName:
523+ return visitNode(cbNode, (node as JsxNamespacedName).namespace) ||
524+ visitNode(cbNode, (node as JsxNamespacedName).name);
523525 case SyntaxKind.OptionalType:
524526 case SyntaxKind.RestType:
525527 case SyntaxKind.JSDocTypeExpression:
@@ -5406,20 +5408,31 @@ namespace ts {
54065408
54075409 function parseJsxElementName(): JsxTagNameExpression {
54085410 const pos = getNodePos();
5409- scanJsxIdentifier ( ) ;
54105411 // JsxElement can have name in the form of
54115412 // propertyAccessExpression
54125413 // primaryExpression in the form of an identifier and "this" keyword
54135414 // We can't just simply use parseLeftHandSideExpressionOrHigher because then we will start consider class,function etc as a keyword
54145415 // We only want to consider "this" as a primaryExpression
5415- let expression : JsxTagNameExpression = token ( ) === SyntaxKind . ThisKeyword ?
5416- parseTokenNode < ThisExpression > ( ) : parseIdentifierName ( ) ;
5416+ let expression: JsxTagNameExpression = parseJsxTagName();
54175417 while (parseOptional(SyntaxKind.DotToken)) {
54185418 expression = finishNode(factory.createPropertyAccessExpression(expression, parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ false)), pos) as JsxTagNamePropertyAccess;
54195419 }
54205420 return expression;
54215421 }
54225422
5423+ function parseJsxTagName(): Identifier | JsxNamespacedName | ThisExpression {
5424+ const pos = getNodePos();
5425+ scanJsxIdentifier();
5426+
5427+ const isThis = token() === SyntaxKind.ThisKeyword;
5428+ const tagName = parseIdentifierName();
5429+ if (parseOptional(SyntaxKind.ColonToken)) {
5430+ scanJsxIdentifier();
5431+ return finishNode(factory.createJsxNamespacedName(tagName, parseIdentifierName()), pos);
5432+ }
5433+ return isThis ? finishNode(factory.createToken(SyntaxKind.ThisKeyword), pos) : tagName;
5434+ }
5435+
54235436 function parseJsxExpression(inExpressionContext: boolean): JsxExpression | undefined {
54245437 const pos = getNodePos();
54255438 if (!parseExpected(SyntaxKind.OpenBraceToken)) {
@@ -5452,9 +5465,8 @@ namespace ts {
54525465 return parseJsxSpreadAttribute();
54535466 }
54545467
5455- scanJsxIdentifier ( ) ;
54565468 const pos = getNodePos();
5457- return finishNode ( factory . createJsxAttribute ( parseIdentifierName ( ) , parseJsxAttributeValue ( ) ) , pos ) ;
5469+ return finishNode(factory.createJsxAttribute(parseJsxAttributeName (), parseJsxAttributeValue()), pos);
54585470 }
54595471
54605472 function parseJsxAttributeValue(): JsxAttributeValue | undefined {
@@ -5473,6 +5485,18 @@ namespace ts {
54735485 return undefined;
54745486 }
54755487
5488+ function parseJsxAttributeName() {
5489+ const pos = getNodePos();
5490+ scanJsxIdentifier();
5491+
5492+ const attrName = parseIdentifierName();
5493+ if (parseOptional(SyntaxKind.ColonToken)) {
5494+ scanJsxIdentifier();
5495+ return finishNode(factory.createJsxNamespacedName(attrName, parseIdentifierName()), pos);
5496+ }
5497+ return attrName;
5498+ }
5499+
54765500 function parseJsxSpreadAttribute(): JsxSpreadAttribute {
54775501 const pos = getNodePos();
54785502 parseExpected(SyntaxKind.OpenBraceToken);
@@ -9637,6 +9661,11 @@ namespace ts {
96379661 return true;
96389662 }
96399663
9664+ if (lhs.kind === SyntaxKind.JsxNamespacedName) {
9665+ return lhs.namespace.escapedText === (rhs as JsxNamespacedName).namespace.escapedText &&
9666+ lhs.name.escapedText === (rhs as JsxNamespacedName).name.escapedText;
9667+ }
9668+
96409669 // If we are at this statement then we must have PropertyAccessExpression and because tag name in Jsx element can only
96419670 // take forms of JsxTagNameExpression which includes an identifier, "this" expression, or another propertyAccessExpression
96429671 // it is safe to case the expression property as such. See parseJsxElementName for how we parse tag name in Jsx element
0 commit comments