Skip to content

Commit 47fd199

Browse files
Gate ES2025 regex syntax (duplicate named groups, pattern modifiers) behind target check
Fixes #63682
1 parent b465fdb commit 47fd199

12 files changed

Lines changed: 123 additions & 2 deletions

src/compiler/diagnosticMessages.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,6 +1724,14 @@
17241724
"category": "Error",
17251725
"code": 1515
17261726
},
1727+
"Regular expression pattern modifiers are only available when targeting '{0}' or later.": {
1728+
"category": "Error",
1729+
"code": 18062
1730+
},
1731+
"Duplicate named capturing groups are only available when targeting '{0}' or later.": {
1732+
"category": "Error",
1733+
"code": 18063
1734+
},
17271735
"A character class range must not be bounded by another character class.": {
17281736
"category": "Error",
17291737
"code": 1516

src/compiler/scanner.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2750,6 +2750,9 @@ export function createScanner(
27502750
error(Diagnostics.Subpattern_flags_must_be_present_when_there_is_a_minus_sign, start, pos - start);
27512751
}
27522752
}
2753+
if (pos !== start && languageVersion < ScriptTarget.ES2025) {
2754+
error(Diagnostics.Regular_expression_pattern_modifiers_are_only_available_when_targeting_0_or_later, start, pos - start, getNameOfScriptTarget(ScriptTarget.ES2025));
2755+
}
27532756
scanExpectedChar(CharacterCodes.colon);
27542757
isPreviousTermQuantifiable = true;
27552758
break;
@@ -3008,6 +3011,9 @@ export function createScanner(
30083011
error(Diagnostics.Named_capturing_groups_with_the_same_name_must_be_mutually_exclusive_to_each_other, tokenStart, pos - tokenStart);
30093012
}
30103013
else {
3014+
if (groupSpecifiers?.has(tokenValue) && languageVersion < ScriptTarget.ES2025) {
3015+
error(Diagnostics.Duplicate_named_capturing_groups_are_only_available_when_targeting_0_or_later, tokenStart, pos - tokenStart, getNameOfScriptTarget(ScriptTarget.ES2025));
3016+
}
30113017
topNamedCapturingGroupsScope ??= new Set();
30123018
topNamedCapturingGroupsScope.add(tokenValue);
30133019
groupSpecifiers ??= new Set();
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
regexPatternModifiersAndDuplicateNamedGroups.ts(1,47): error TS18063: Duplicate named capturing groups are only available when targeting 'es2025' or later.
2+
regexPatternModifiersAndDuplicateNamedGroups.ts(2,22): error TS18062: Regular expression pattern modifiers are only available when targeting 'es2025' or later.
3+
4+
5+
==== regexPatternModifiersAndDuplicateNamedGroups.ts (2 errors) ====
6+
const dupNames = /(?<y>\d{4})-\d{2}|\d{2}\/(?<y>\d{4})/;
7+
~
8+
!!! error TS18063: Duplicate named capturing groups are only available when targeting 'es2025' or later.
9+
const modifiers = /(?i:abc)/;
10+
~
11+
!!! error TS18062: Regular expression pattern modifiers are only available when targeting 'es2025' or later.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//// [tests/cases/conformance/es2025/regexPatternModifiersAndDuplicateNamedGroups.ts] ////
2+
3+
//// [regexPatternModifiersAndDuplicateNamedGroups.ts]
4+
const dupNames = /(?<y>\d{4})-\d{2}|\d{2}\/(?<y>\d{4})/;
5+
const modifiers = /(?i:abc)/;
6+
7+
//// [regexPatternModifiersAndDuplicateNamedGroups.js]
8+
"use strict";
9+
const dupNames = /(?<y>\d{4})-\d{2}|\d{2}\/(?<y>\d{4})/;
10+
const modifiers = /(?i:abc)/;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//// [tests/cases/conformance/es2025/regexPatternModifiersAndDuplicateNamedGroups.ts] ////
2+
3+
=== regexPatternModifiersAndDuplicateNamedGroups.ts ===
4+
const dupNames = /(?<y>\d{4})-\d{2}|\d{2}\/(?<y>\d{4})/;
5+
>dupNames : Symbol(dupNames, Decl(regexPatternModifiersAndDuplicateNamedGroups.ts, 0, 5))
6+
7+
const modifiers = /(?i:abc)/;
8+
>modifiers : Symbol(modifiers, Decl(regexPatternModifiersAndDuplicateNamedGroups.ts, 1, 5))
9+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//// [tests/cases/conformance/es2025/regexPatternModifiersAndDuplicateNamedGroups.ts] ////
2+
3+
=== regexPatternModifiersAndDuplicateNamedGroups.ts ===
4+
const dupNames = /(?<y>\d{4})-\d{2}|\d{2}\/(?<y>\d{4})/;
5+
>dupNames : RegExp
6+
> : ^^^^^^
7+
>/(?<y>\d{4})-\d{2}|\d{2}\/(?<y>\d{4})/ : RegExp
8+
> : ^^^^^^
9+
10+
const modifiers = /(?i:abc)/;
11+
>modifiers : RegExp
12+
> : ^^^^^^
13+
>/(?i:abc)/ : RegExp
14+
> : ^^^^^^
15+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//// [tests/cases/conformance/es2025/regexPatternModifiersAndDuplicateNamedGroups.ts] ////
2+
3+
//// [regexPatternModifiersAndDuplicateNamedGroups.ts]
4+
const dupNames = /(?<y>\d{4})-\d{2}|\d{2}\/(?<y>\d{4})/;
5+
const modifiers = /(?i:abc)/;
6+
7+
//// [regexPatternModifiersAndDuplicateNamedGroups.js]
8+
"use strict";
9+
const dupNames = /(?<y>\d{4})-\d{2}|\d{2}\/(?<y>\d{4})/;
10+
const modifiers = /(?i:abc)/;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//// [tests/cases/conformance/es2025/regexPatternModifiersAndDuplicateNamedGroups.ts] ////
2+
3+
=== regexPatternModifiersAndDuplicateNamedGroups.ts ===
4+
const dupNames = /(?<y>\d{4})-\d{2}|\d{2}\/(?<y>\d{4})/;
5+
>dupNames : Symbol(dupNames, Decl(regexPatternModifiersAndDuplicateNamedGroups.ts, 0, 5))
6+
7+
const modifiers = /(?i:abc)/;
8+
>modifiers : Symbol(modifiers, Decl(regexPatternModifiersAndDuplicateNamedGroups.ts, 1, 5))
9+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//// [tests/cases/conformance/es2025/regexPatternModifiersAndDuplicateNamedGroups.ts] ////
2+
3+
=== regexPatternModifiersAndDuplicateNamedGroups.ts ===
4+
const dupNames = /(?<y>\d{4})-\d{2}|\d{2}\/(?<y>\d{4})/;
5+
>dupNames : RegExp
6+
> : ^^^^^^
7+
>/(?<y>\d{4})-\d{2}|\d{2}\/(?<y>\d{4})/ : RegExp
8+
> : ^^^^^^
9+
10+
const modifiers = /(?i:abc)/;
11+
>modifiers : RegExp
12+
> : ^^^^^^
13+
>/(?i:abc)/ : RegExp
14+
> : ^^^^^^
15+

tests/baselines/reference/regularExpressionScanning(target=es2015).errors.txt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ regularExpressionScanning.ts(3,19): error TS1499: Unknown regular expression fla
1313
regularExpressionScanning.ts(3,20): error TS1499: Unknown regular expression flag.
1414
regularExpressionScanning.ts(3,21): error TS1500: Duplicate regular expression flag.
1515
regularExpressionScanning.ts(3,22): error TS1499: Unknown regular expression flag.
16+
regularExpressionScanning.ts(5,5): error TS18062: Regular expression pattern modifiers are only available when targeting 'es2025' or later.
1617
regularExpressionScanning.ts(5,6): error TS1499: Unknown regular expression flag.
1718
regularExpressionScanning.ts(5,7): error TS1509: This regular expression flag cannot be toggled within a subpattern.
1819
regularExpressionScanning.ts(5,10): error TS1509: This regular expression flag cannot be toggled within a subpattern.
@@ -45,11 +46,14 @@ regularExpressionScanning.ts(14,5): error TS1503: Named capturing groups are onl
4546
regularExpressionScanning.ts(14,14): error TS1503: Named capturing groups are only available when targeting 'ES2018' or later.
4647
regularExpressionScanning.ts(14,29): error TS1503: Named capturing groups are only available when targeting 'ES2018' or later.
4748
regularExpressionScanning.ts(14,45): error TS1503: Named capturing groups are only available when targeting 'ES2018' or later.
49+
regularExpressionScanning.ts(14,46): error TS18063: Duplicate named capturing groups are only available when targeting 'es2025' or later.
4850
regularExpressionScanning.ts(14,57): error TS1503: Named capturing groups are only available when targeting 'ES2018' or later.
51+
regularExpressionScanning.ts(14,58): error TS18063: Duplicate named capturing groups are only available when targeting 'es2025' or later.
4952
regularExpressionScanning.ts(15,15): error TS1532: There is no capturing group named 'absent' in this regular expression.
5053
regularExpressionScanning.ts(15,24): error TS1503: Named capturing groups are only available when targeting 'ES2018' or later.
5154
regularExpressionScanning.ts(15,36): error TS1503: Named capturing groups are only available when targeting 'ES2018' or later.
5255
regularExpressionScanning.ts(15,45): error TS1503: Named capturing groups are only available when targeting 'ES2018' or later.
56+
regularExpressionScanning.ts(15,46): error TS18063: Duplicate named capturing groups are only available when targeting 'es2025' or later.
5357
regularExpressionScanning.ts(15,58): error TS1503: Named capturing groups are only available when targeting 'ES2018' or later.
5458
regularExpressionScanning.ts(15,59): error TS1515: Named capturing groups with the same name must be mutually exclusive to each other.
5559
regularExpressionScanning.ts(17,31): error TS1507: There is nothing available for repetition.
@@ -219,7 +223,7 @@ regularExpressionScanning.ts(47,89): error TS1518: Anything that would possibly
219223
regularExpressionScanning.ts(47,101): error TS1501: This regular expression flag is only available when targeting 'es2024' or later.
220224

221225

222-
==== regularExpressionScanning.ts (219 errors) ====
226+
==== regularExpressionScanning.ts (223 errors) ====
223227
const regexes: RegExp[] = [
224228
// Flags
225229
/foo/visualstudiocode,
@@ -255,6 +259,8 @@ regularExpressionScanning.ts(47,101): error TS1501: This regular expression flag
255259
!!! error TS1499: Unknown regular expression flag.
256260
// Pattern modifiers
257261
/(?med-ium:bar)/,
262+
~~~~~~~
263+
!!! error TS18062: Regular expression pattern modifiers are only available when targeting 'es2025' or later.
258264
~
259265
!!! error TS1499: Unknown regular expression flag.
260266
~
@@ -328,8 +334,12 @@ regularExpressionScanning.ts(47,101): error TS1501: This regular expression flag
328334
!!! error TS1503: Named capturing groups are only available when targeting 'ES2018' or later.
329335
~~~~~
330336
!!! error TS1503: Named capturing groups are only available when targeting 'ES2018' or later.
337+
~~~
338+
!!! error TS18063: Duplicate named capturing groups are only available when targeting 'es2025' or later.
331339
~~~~~
332340
!!! error TS1503: Named capturing groups are only available when targeting 'ES2018' or later.
341+
~~~
342+
!!! error TS18063: Duplicate named capturing groups are only available when targeting 'es2025' or later.
333343
/(\k<bar>)\k<absent>(?<foo>foo)|(?<bar>)((?<foo>)|(bar(?<bar>bar)))/,
334344
~~~~~~
335345
!!! error TS1532: There is no capturing group named 'absent' in this regular expression.
@@ -339,6 +349,8 @@ regularExpressionScanning.ts(47,101): error TS1501: This regular expression flag
339349
!!! error TS1503: Named capturing groups are only available when targeting 'ES2018' or later.
340350
~~~~~
341351
!!! error TS1503: Named capturing groups are only available when targeting 'ES2018' or later.
352+
~~~
353+
!!! error TS18063: Duplicate named capturing groups are only available when targeting 'es2025' or later.
342354
~~~~~
343355
!!! error TS1503: Named capturing groups are only available when targeting 'ES2018' or later.
344356
~~~

0 commit comments

Comments
 (0)