@@ -1991,6 +1991,13 @@ namespace ts {
1991
1991
return createIdentifier(tokenIsIdentifierOrKeyword(token()), diagnosticMessage);
1992
1992
}
1993
1993
1994
+ function parseIdentifierNameErrorOnUnicodeEscapeSequence(): Identifier {
1995
+ if (scanner.hasUnicodeEscape() || scanner.hasExtendedUnicodeEscape()) {
1996
+ parseErrorAtCurrentToken(Diagnostics.Unicode_escape_sequence_cannot_appear_here);
1997
+ }
1998
+ return createIdentifier(tokenIsIdentifierOrKeyword(token()));
1999
+ }
2000
+
1994
2001
function isLiteralPropertyName(): boolean {
1995
2002
return tokenIsIdentifierOrKeyword(token()) ||
1996
2003
token() === SyntaxKind.StringLiteral ||
@@ -2843,7 +2850,7 @@ namespace ts {
2843
2850
entity = finishNode(
2844
2851
factory.createQualifiedName(
2845
2852
entity,
2846
- parseRightSideOfDot(allowReservedWords, allowPrivateIdentifiers) as Identifier
2853
+ parseRightSideOfDot(allowReservedWords, allowPrivateIdentifiers, /** allowUnicodeEscapeSequenceInIdentifierName */ false ) as Identifier
2847
2854
),
2848
2855
pos
2849
2856
);
@@ -2855,7 +2862,7 @@ namespace ts {
2855
2862
return finishNode(factory.createQualifiedName(entity, name), entity.pos);
2856
2863
}
2857
2864
2858
- function parseRightSideOfDot(allowIdentifierNames: boolean, allowPrivateIdentifiers: boolean): Identifier | PrivateIdentifier {
2865
+ function parseRightSideOfDot(allowIdentifierNames: boolean, allowPrivateIdentifiers: boolean, allowUnicodeEscapeSequenceInIdentifierName: boolean ): Identifier | PrivateIdentifier {
2859
2866
// Technically a keyword is valid here as all identifiers and keywords are identifier names.
2860
2867
// However, often we'll encounter this in error situations when the identifier or keyword
2861
2868
// is actually starting another valid construct.
@@ -2891,7 +2898,11 @@ namespace ts {
2891
2898
return allowPrivateIdentifiers ? node : createMissingNode<Identifier>(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected);
2892
2899
}
2893
2900
2894
- return allowIdentifierNames ? parseIdentifierName() : parseIdentifier();
2901
+ if (allowIdentifierNames) {
2902
+ return allowUnicodeEscapeSequenceInIdentifierName ? parseIdentifierName() : parseIdentifierNameErrorOnUnicodeEscapeSequence();
2903
+ }
2904
+
2905
+ return parseIdentifier();
2895
2906
}
2896
2907
2897
2908
function parseTemplateSpans(isTaggedTemplate: boolean) {
@@ -5237,7 +5248,7 @@ namespace ts {
5237
5248
// If it wasn't then just try to parse out a '.' and report an error.
5238
5249
parseExpectedToken(SyntaxKind.DotToken, Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access);
5239
5250
// private names will never work with `super` (`super.#foo`), but that's a semantic error, not syntactic
5240
- return finishNode(factory.createPropertyAccessExpression(expression, parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true)), pos);
5251
+ return finishNode(factory.createPropertyAccessExpression(expression, parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true, /** allowUnicodeEscapeSequenceInIdentifierName */ false )), pos);
5241
5252
}
5242
5253
5243
5254
function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext: boolean, topInvalidNodePosition?: number, openingTag?: JsxOpeningElement | JsxOpeningFragment): JsxElement | JsxSelfClosingElement | JsxFragment {
@@ -5426,9 +5437,9 @@ namespace ts {
5426
5437
// We can't just simply use parseLeftHandSideExpressionOrHigher because then we will start consider class,function etc as a keyword
5427
5438
// We only want to consider "this" as a primaryExpression
5428
5439
let expression: JsxTagNameExpression = token() === SyntaxKind.ThisKeyword ?
5429
- parseTokenNode<ThisExpression>() : parseIdentifierName ();
5440
+ parseTokenNode<ThisExpression>() : parseIdentifierNameErrorOnUnicodeEscapeSequence ();
5430
5441
while (parseOptional(SyntaxKind.DotToken)) {
5431
- expression = finishNode(factory.createPropertyAccessExpression(expression, parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ false)), pos) as JsxTagNamePropertyAccess;
5442
+ expression = finishNode(factory.createPropertyAccessExpression(expression, parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ false, /** allowUnicodeEscapeSequenceInIdentifierName */ false )), pos) as JsxTagNamePropertyAccess;
5432
5443
}
5433
5444
return expression;
5434
5445
}
@@ -5469,7 +5480,7 @@ namespace ts {
5469
5480
const pos = getNodePos();
5470
5481
return finishNode(
5471
5482
factory.createJsxAttribute(
5472
- parseIdentifierName (),
5483
+ parseIdentifierNameErrorOnUnicodeEscapeSequence (),
5473
5484
token() !== SyntaxKind.EqualsToken ? undefined :
5474
5485
scanJsxAttributeValue() === SyntaxKind.StringLiteral ? parseLiteralNode() as StringLiteral :
5475
5486
parseJsxExpression(/*inExpressionContext*/ true)
@@ -5565,7 +5576,7 @@ namespace ts {
5565
5576
}
5566
5577
5567
5578
function parsePropertyAccessExpressionRest(pos: number, expression: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined) {
5568
- const name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true);
5579
+ const name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true, /** allowUnicodeEscapeSequenceInIdentifierName */ false );
5569
5580
const isOptionalChain = questionDotToken || tryReparseOptionalChain(expression);
5570
5581
const propertyAccess = isOptionalChain ?
5571
5582
factory.createPropertyAccessChain(expression, questionDotToken, name) :
0 commit comments