Skip to content

Commit 0d0a793

Browse files
authoredSep 30, 2022
Allow Unicode extended escapes in ES5 and earlier (#50918)
* Remove language version check for extended escapes. * Accepted baselines. * Record whether nodes have extended Unicode escapes. Replace them in the es2015 transform. * Accepted baselines. * Move file to better-reflect generality of tests. * Added tests for variables at the top level. * Accepted baselines. * Added test for extended astral character. * Accepted baseline. * Enable sourcemaps in tests. * Accepted baselines. * Call `setOriginalNode` on identifiers with extended escapes.
1 parent 58bae8d commit 0d0a793

File tree

36 files changed

+7010
-497
lines changed

36 files changed

+7010
-497
lines changed
 

‎src/compiler/factory/nodeFactory.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,7 @@ namespace ts {
874874
}
875875

876876
// @api
877-
function createIdentifier(text: string, typeArguments?: readonly (TypeNode | TypeParameterDeclaration)[], originalKeywordKind?: SyntaxKind): Identifier {
877+
function createIdentifier(text: string, typeArguments?: readonly (TypeNode | TypeParameterDeclaration)[], originalKeywordKind?: SyntaxKind, hasExtendedUnicodeEscape?: boolean): Identifier {
878878
const node = createBaseIdentifier(text, originalKeywordKind);
879879
if (typeArguments) {
880880
// NOTE: we do not use `setChildren` here because typeArguments in an identifier do not contribute to transformations
@@ -883,6 +883,10 @@ namespace ts {
883883
if (node.originalKeywordKind === SyntaxKind.AwaitKeyword) {
884884
node.transformFlags |= TransformFlags.ContainsPossibleTopLevelAwait;
885885
}
886+
if (hasExtendedUnicodeEscape) {
887+
node.hasExtendedUnicodeEscape = hasExtendedUnicodeEscape;
888+
node.transformFlags |= TransformFlags.ContainsES2015;
889+
}
886890
return node;
887891
}
888892

‎src/compiler/parser.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -2187,8 +2187,9 @@ namespace ts {
21872187
// Store original token kind if it is not just an Identifier so we can report appropriate error later in type checker
21882188
const originalKeywordKind = token();
21892189
const text = internIdentifier(scanner.getTokenValue());
2190+
const hasExtendedUnicodeEscape = scanner.hasExtendedUnicodeEscape();
21902191
nextTokenWithoutCheck();
2191-
return finishNode(factory.createIdentifier(text, /*typeArguments*/ undefined, originalKeywordKind), pos);
2192+
return finishNode(factory.createIdentifier(text, /*typeArguments*/ undefined, originalKeywordKind, hasExtendedUnicodeEscape), pos);
21922193
}
21932194

21942195
if (token() === SyntaxKind.PrivateIdentifier) {

‎src/compiler/scanner.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1486,7 +1486,7 @@ namespace ts {
14861486

14871487

14881488
function peekExtendedUnicodeEscape(): number {
1489-
if (languageVersion >= ScriptTarget.ES2015 && codePointAt(text, pos + 1) === CharacterCodes.u && codePointAt(text, pos + 2) === CharacterCodes.openBrace) {
1489+
if (codePointAt(text, pos + 1) === CharacterCodes.u && codePointAt(text, pos + 2) === CharacterCodes.openBrace) {
14901490
const start = pos;
14911491
pos += 3;
14921492
const escapedValueString = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false);

‎src/compiler/transformers/es2015.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -643,11 +643,16 @@ namespace ts {
643643
}
644644

645645
function visitIdentifier(node: Identifier): Identifier {
646-
if (!convertedLoopState) {
647-
return node;
646+
if (convertedLoopState) {
647+
if (resolver.isArgumentsLocalBinding(node)) {
648+
return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = factory.createUniqueName("arguments"));
649+
}
648650
}
649-
if (resolver.isArgumentsLocalBinding(node)) {
650-
return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = factory.createUniqueName("arguments"));
651+
if (node.hasExtendedUnicodeEscape) {
652+
return setOriginalNode(setTextRange(
653+
factory.createIdentifier(unescapeLeadingUnderscores(node.escapedText)),
654+
node
655+
), node);
651656
}
652657
return node;
653658
}

‎src/compiler/types.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1427,6 +1427,7 @@ namespace ts {
14271427
isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace
14281428
/*@internal*/ typeArguments?: NodeArray<TypeNode | TypeParameterDeclaration>; // Only defined on synthesized nodes. Though not syntactically valid, used in emitting diagnostics, quickinfo, and signature help.
14291429
/*@internal*/ jsdocDotPos?: number; // Identifier occurs in JSDoc-style generic: Id.<T>
1430+
/*@internal*/ hasExtendedUnicodeEscape?: boolean;
14301431
}
14311432

14321433
// Transient identifier node (marked by id === -1)
@@ -7653,7 +7654,7 @@ namespace ts {
76537654
//
76547655

76557656
createIdentifier(text: string): Identifier;
7656-
/* @internal */ createIdentifier(text: string, typeArguments?: readonly (TypeNode | TypeParameterDeclaration)[], originalKeywordKind?: SyntaxKind): Identifier; // eslint-disable-line @typescript-eslint/unified-signatures
7657+
/* @internal */ createIdentifier(text: string, typeArguments?: readonly (TypeNode | TypeParameterDeclaration)[], originalKeywordKind?: SyntaxKind, hasExtendedUnicodeEscape?: boolean): Identifier; // eslint-disable-line @typescript-eslint/unified-signatures
76577658
/* @internal */ updateIdentifier(node: Identifier, typeArguments: NodeArray<TypeNode | TypeParameterDeclaration> | undefined): Identifier;
76587659

76597660
/**

0 commit comments

Comments
 (0)