Skip to content

Commit 165350d

Browse files
Provide User-Friendly Message for Extended Unicode Escapes in Regular Expressions in Non-Unicode Modes (#58981)
Co-authored-by: Ron Buckton <ron.buckton@microsoft.com>
1 parent afa03f0 commit 165350d

8 files changed

+102
-19
lines changed

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1805,6 +1805,10 @@
18051805
"category": "Error",
18061806
"code": 1537
18071807
},
1808+
"Unicode escape sequences are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.": {
1809+
"category": "Error",
1810+
"code": 1538
1811+
},
18081812

18091813
"The types of '{0}' are incompatible between these types.": {
18101814
"category": "Error",

src/compiler/scanner.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,7 +1006,7 @@ const enum EscapeSequenceScanningFlags {
10061006
AtomEscape = 1 << 5,
10071007

10081008
ReportInvalidEscapeErrors = RegularExpression | ReportErrors,
1009-
ScanExtendedUnicodeEscape = String | AnyUnicodeMode,
1009+
AllowExtendedUnicodeEscape = String | AnyUnicodeMode,
10101010
}
10111011

10121012
const enum ClassSetExpressionType {
@@ -1609,13 +1609,17 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
16091609
case CharacterCodes.doubleQuote:
16101610
return '"';
16111611
case CharacterCodes.u:
1612-
if (
1613-
flags & EscapeSequenceScanningFlags.ScanExtendedUnicodeEscape &&
1614-
pos < end && charCodeUnchecked(pos) === CharacterCodes.openBrace
1615-
) {
1612+
if (pos < end && charCodeUnchecked(pos) === CharacterCodes.openBrace) {
16161613
// '\u{DDDDDD}'
16171614
pos -= 2;
1618-
return scanExtendedUnicodeEscape(!!(flags & EscapeSequenceScanningFlags.ReportInvalidEscapeErrors));
1615+
const result = scanExtendedUnicodeEscape(!!(flags & EscapeSequenceScanningFlags.ReportInvalidEscapeErrors));
1616+
if (!(flags & EscapeSequenceScanningFlags.AllowExtendedUnicodeEscape)) {
1617+
tokenFlags |= TokenFlags.ContainsInvalidEscape;
1618+
if (flags & EscapeSequenceScanningFlags.ReportInvalidEscapeErrors) {
1619+
error(Diagnostics.Unicode_escape_sequences_are_only_available_when_the_Unicode_u_flag_or_the_Unicode_Sets_v_flag_is_set, start, pos - start);
1620+
}
1621+
}
1622+
return result;
16191623
}
16201624
// '\uDDDD'
16211625
for (; pos < start + 6; pos++) {

tests/baselines/reference/regularExpressionCharacterClassRangeOrder.errors.txt

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ regularExpressionCharacterClassRangeOrder.ts(7,5): error TS1517: Range out of or
22
regularExpressionCharacterClassRangeOrder.ts(7,12): error TS1517: Range out of order in character class.
33
regularExpressionCharacterClassRangeOrder.ts(8,11): error TS1517: Range out of order in character class.
44
regularExpressionCharacterClassRangeOrder.ts(9,11): error TS1517: Range out of order in character class.
5-
regularExpressionCharacterClassRangeOrder.ts(11,6): error TS1125: Hexadecimal digit expected.
6-
regularExpressionCharacterClassRangeOrder.ts(11,16): error TS1125: Hexadecimal digit expected.
7-
regularExpressionCharacterClassRangeOrder.ts(11,27): error TS1125: Hexadecimal digit expected.
8-
regularExpressionCharacterClassRangeOrder.ts(11,37): error TS1125: Hexadecimal digit expected.
5+
regularExpressionCharacterClassRangeOrder.ts(11,4): error TS1538: Unicode escape sequences are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.
6+
regularExpressionCharacterClassRangeOrder.ts(11,14): error TS1538: Unicode escape sequences are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.
7+
regularExpressionCharacterClassRangeOrder.ts(11,25): error TS1538: Unicode escape sequences are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.
8+
regularExpressionCharacterClassRangeOrder.ts(11,25): error TS1517: Range out of order in character class.
9+
regularExpressionCharacterClassRangeOrder.ts(11,35): error TS1538: Unicode escape sequences are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.
910
regularExpressionCharacterClassRangeOrder.ts(12,25): error TS1517: Range out of order in character class.
1011
regularExpressionCharacterClassRangeOrder.ts(13,25): error TS1517: Range out of order in character class.
1112
regularExpressionCharacterClassRangeOrder.ts(15,10): error TS1517: Range out of order in character class.
@@ -14,7 +15,7 @@ regularExpressionCharacterClassRangeOrder.ts(16,31): error TS1517: Range out of
1415
regularExpressionCharacterClassRangeOrder.ts(17,31): error TS1517: Range out of order in character class.
1516

1617

17-
==== regularExpressionCharacterClassRangeOrder.ts (14 errors) ====
18+
==== regularExpressionCharacterClassRangeOrder.ts (15 errors) ====
1819
// The characters in the following regular expressions are ASCII-lookalike characters found in Unicode, including:
1920
// - 𝘈 (U+1D608 Mathematical Sans-Serif Italic Capital A)
2021
// - 𝘡 (U+1D621 Mathematical Sans-Serif Italic Capital Z)
@@ -34,14 +35,16 @@ regularExpressionCharacterClassRangeOrder.ts(17,31): error TS1517: Range out of
3435
!!! error TS1517: Range out of order in character class.
3536

3637
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/,
37-
38-
!!! error TS1125: Hexadecimal digit expected.
39-
40-
!!! error TS1125: Hexadecimal digit expected.
41-
42-
!!! error TS1125: Hexadecimal digit expected.
43-
44-
!!! error TS1125: Hexadecimal digit expected.
38+
~~~~~~~~~
39+
!!! error TS1538: Unicode escape sequences are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.
40+
~~~~~~~~~
41+
!!! error TS1538: Unicode escape sequences are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.
42+
~~~~~~~~~
43+
!!! error TS1538: Unicode escape sequences are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.
44+
~~~~~~~~~~~~~~~~~~~
45+
!!! error TS1517: Range out of order in character class.
46+
~~~~~~~~~
47+
!!! error TS1538: Unicode escape sequences are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.
4548
/[\u{1D608}-\u{1D621}][\u{1D621}-\u{1D608}]/u,
4649
~~~~~~~~~~~~~~~~~~~
4750
!!! error TS1517: Range out of order in character class.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
regularExpressionExtendedUnicodeEscapes.ts(2,3): error TS1538: Unicode escape sequences are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.
2+
regularExpressionExtendedUnicodeEscapes.ts(2,13): error TS1538: Unicode escape sequences are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.
3+
4+
5+
==== regularExpressionExtendedUnicodeEscapes.ts (2 errors) ====
6+
const regexes: RegExp[] = [
7+
/\u{10000}[\u{10000}]/,
8+
~~~~~~~~~
9+
!!! error TS1538: Unicode escape sequences are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.
10+
~~~~~~~~~
11+
!!! error TS1538: Unicode escape sequences are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.
12+
/\u{10000}[\u{10000}]/u,
13+
/\u{10000}[\u{10000}]/v,
14+
];
15+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//// [tests/cases/compiler/regularExpressionExtendedUnicodeEscapes.ts] ////
2+
3+
//// [regularExpressionExtendedUnicodeEscapes.ts]
4+
const regexes: RegExp[] = [
5+
/\u{10000}[\u{10000}]/,
6+
/\u{10000}[\u{10000}]/u,
7+
/\u{10000}[\u{10000}]/v,
8+
];
9+
10+
11+
//// [regularExpressionExtendedUnicodeEscapes.js]
12+
const regexes = [
13+
/\u{10000}[\u{10000}]/,
14+
/\u{10000}[\u{10000}]/u,
15+
/\u{10000}[\u{10000}]/v,
16+
];
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//// [tests/cases/compiler/regularExpressionExtendedUnicodeEscapes.ts] ////
2+
3+
=== regularExpressionExtendedUnicodeEscapes.ts ===
4+
const regexes: RegExp[] = [
5+
>regexes : Symbol(regexes, Decl(regularExpressionExtendedUnicodeEscapes.ts, 0, 5))
6+
>RegExp : Symbol(RegExp, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.regexp.d.ts, --, --) ... and 3 more)
7+
8+
/\u{10000}[\u{10000}]/,
9+
/\u{10000}[\u{10000}]/u,
10+
/\u{10000}[\u{10000}]/v,
11+
];
12+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//// [tests/cases/compiler/regularExpressionExtendedUnicodeEscapes.ts] ////
2+
3+
=== regularExpressionExtendedUnicodeEscapes.ts ===
4+
const regexes: RegExp[] = [
5+
>regexes : RegExp[]
6+
> : ^^^^^^^^
7+
>[ /\u{10000}[\u{10000}]/, /\u{10000}[\u{10000}]/u, /\u{10000}[\u{10000}]/v,] : RegExp[]
8+
> : ^^^^^^^^
9+
10+
/\u{10000}[\u{10000}]/,
11+
>/\u{10000}[\u{10000}]/ : RegExp
12+
> : ^^^^^^
13+
14+
/\u{10000}[\u{10000}]/u,
15+
>/\u{10000}[\u{10000}]/u : RegExp
16+
> : ^^^^^^
17+
18+
/\u{10000}[\u{10000}]/v,
19+
>/\u{10000}[\u{10000}]/v : RegExp
20+
> : ^^^^^^
21+
22+
];
23+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// @target: esnext
2+
const regexes: RegExp[] = [
3+
/\u{10000}[\u{10000}]/,
4+
/\u{10000}[\u{10000}]/u,
5+
/\u{10000}[\u{10000}]/v,
6+
];

0 commit comments

Comments
 (0)