Skip to content

Commit 1a75d52

Browse files
saschanazRyanCavanaugh
authored andcommitted
add ES2020 matchAll APIs (#30936)
1 parent 58898f4 commit 1a75d52

20 files changed

+172
-9
lines changed

src/compiler/commandLineParser.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ namespace ts {
1616
["es2017", "lib.es2017.d.ts"],
1717
["es2018", "lib.es2018.d.ts"],
1818
["es2019", "lib.es2019.d.ts"],
19+
["es2020", "lib.es2020.d.ts"],
1920
["esnext", "lib.esnext.d.ts"],
2021
// Host only
2122
["dom", "lib.dom.d.ts"],
@@ -46,6 +47,8 @@ namespace ts {
4647
["es2019.array", "lib.es2019.array.d.ts"],
4748
["es2019.string", "lib.es2019.string.d.ts"],
4849
["es2019.symbol", "lib.es2019.symbol.d.ts"],
50+
["es2020.string", "lib.es2020.string.d.ts"],
51+
["es2020.symbol.wellknown", "lib.es2020.symbol.wellknown.d.ts"],
4952
["esnext.array", "lib.es2019.array.d.ts"],
5053
["esnext.symbol", "lib.es2019.symbol.d.ts"],
5154
["esnext.asynciterable", "lib.es2018.asynciterable.d.ts"],
@@ -210,6 +213,7 @@ namespace ts {
210213
es2017: ScriptTarget.ES2017,
211214
es2018: ScriptTarget.ES2018,
212215
es2019: ScriptTarget.ES2019,
216+
es2020: ScriptTarget.ES2020,
213217
esnext: ScriptTarget.ESNext,
214218
}),
215219
affectsSourceFile: true,

src/compiler/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4756,7 +4756,8 @@ namespace ts {
47564756
ES2017 = 4,
47574757
ES2018 = 5,
47584758
ES2019 = 6,
4759-
ESNext = 7,
4759+
ES2020 = 7,
4760+
ESNext = 8,
47604761
JSON = 100,
47614762
Latest = ESNext,
47624763
}

src/compiler/utilities.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4677,6 +4677,8 @@ namespace ts {
46774677
switch (options.target) {
46784678
case ScriptTarget.ESNext:
46794679
return "lib.esnext.full.d.ts";
4680+
case ScriptTarget.ES2020:
4681+
return "lib.es2020.full.d.ts";
46804682
case ScriptTarget.ES2019:
46814683
return "lib.es2019.full.d.ts";
46824684
case ScriptTarget.ES2018:

src/lib/es2020.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/// <reference lib="es2019" />
2+
/// <reference lib="es2020.string" />
3+
/// <reference lib="es2020.symbol.wellknown" />

src/lib/es2020.full.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/// <reference lib="es2020" />
2+
/// <reference lib="dom" />
3+
/// <reference lib="webworker.importscripts" />
4+
/// <reference lib="scripthost" />
5+
/// <reference lib="dom.iterable" />

src/lib/es2020.string.d.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/// <reference lib="es2015.iterable" />
2+
3+
interface String {
4+
/**
5+
* Matches a string with a regular expression, and returns an iterable of matches
6+
* containing the results of that search.
7+
* @param regexp A variable name or string literal containing the regular expression pattern and flags.
8+
*/
9+
matchAll(regexp: RegExp): IterableIterator<RegExpMatchArray>;
10+
}

src/lib/es2020.symbol.wellknown.d.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/// <reference lib="es2015.iterable" />
2+
/// <reference lib="es2015.symbol" />
3+
4+
interface SymbolConstructor {
5+
/**
6+
* A regular expression method that matches the regular expression against a string. Called
7+
* by the String.prototype.matchAll method.
8+
*/
9+
readonly matchAll: symbol;
10+
}
11+
12+
interface RegExp {
13+
/**
14+
* Matches a string with this regular expression, and returns an iterable of matches
15+
* containing the results of that search.
16+
* @param string A string to search within.
17+
*/
18+
[Symbol.matchAll](str: string): IterableIterator<RegExpMatchArray>;
19+
}

src/lib/libs.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"es2017",
88
"es2018",
99
"es2019",
10+
"es2020",
1011
"esnext",
1112
// Host only
1213
"dom.generated",
@@ -37,6 +38,8 @@
3738
"es2019.array",
3839
"es2019.string",
3940
"es2019.symbol",
41+
"es2020.string",
42+
"es2020.symbol.wellknown",
4043
"esnext.bigint",
4144
"esnext.intl",
4245
// Default libraries
@@ -46,6 +49,7 @@
4649
"es2017.full",
4750
"es2018.full",
4851
"es2019.full",
52+
"es2020.full",
4953
"esnext.full"
5054
],
5155
"paths": {

src/server/protocol.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3046,6 +3046,9 @@ namespace ts.server.protocol {
30463046
ES2015 = "ES2015",
30473047
ES2016 = "ES2016",
30483048
ES2017 = "ES2017",
3049+
ES2018 = "ES2018",
3050+
ES2019 = "ES2019",
3051+
ES2020 = "ES2020",
30493052
ESNext = "ESNext"
30503053
}
30513054
}

src/testRunner/unittests/config/commandLineParsing.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ namespace ts {
5757
assertParseResult(["--lib", "es5,invalidOption", "0.ts"],
5858
{
5959
errors: [{
60-
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'es2019', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.string', 'es2019.symbol', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable', 'esnext.intl', 'esnext.bigint'.",
60+
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.string', 'es2019.symbol', 'es2020.string', 'es2020.symbol.wellknown', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable', 'esnext.intl', 'esnext.bigint'.",
6161
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
6262
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
6363
file: undefined,
@@ -161,7 +161,7 @@ namespace ts {
161161
start: undefined,
162162
length: undefined,
163163
}, {
164-
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'esnext'.",
164+
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'esnext'.",
165165
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
166166
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
167167

@@ -259,7 +259,7 @@ namespace ts {
259259
assertParseResult(["--lib", "es5,", "es7", "0.ts"],
260260
{
261261
errors: [{
262-
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'es2019', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.string', 'es2019.symbol', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable', 'esnext.intl', 'esnext.bigint'.",
262+
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.string', 'es2019.symbol', 'es2020.string', 'es2020.symbol.wellknown', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable', 'esnext.intl', 'esnext.bigint'.",
263263
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
264264
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
265265
file: undefined,
@@ -278,7 +278,7 @@ namespace ts {
278278
assertParseResult(["--lib", "es5, ", "es7", "0.ts"],
279279
{
280280
errors: [{
281-
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'es2019', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.string', 'es2019.symbol', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable', 'esnext.intl', 'esnext.bigint'.",
281+
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.string', 'es2019.symbol', 'es2020.string', 'es2020.symbol.wellknown', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable', 'esnext.intl', 'esnext.bigint'.",
282282
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
283283
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
284284
file: undefined,

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2625,9 +2625,10 @@ declare namespace ts {
26252625
ES2017 = 4,
26262626
ES2018 = 5,
26272627
ES2019 = 6,
2628-
ESNext = 7,
2628+
ES2020 = 7,
2629+
ESNext = 8,
26292630
JSON = 100,
2630-
Latest = 7
2631+
Latest = 8
26312632
}
26322633
enum LanguageVariant {
26332634
Standard = 0,
@@ -8127,6 +8128,9 @@ declare namespace ts.server.protocol {
81278128
ES2015 = "ES2015",
81288129
ES2016 = "ES2016",
81298130
ES2017 = "ES2017",
8131+
ES2018 = "ES2018",
8132+
ES2019 = "ES2019",
8133+
ES2020 = "ES2020",
81308134
ESNext = "ESNext"
81318135
}
81328136
}

tests/baselines/reference/api/typescript.d.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2625,9 +2625,10 @@ declare namespace ts {
26252625
ES2017 = 4,
26262626
ES2018 = 5,
26272627
ES2019 = 6,
2628-
ESNext = 7,
2628+
ES2020 = 7,
2629+
ESNext = 8,
26292630
JSON = 100,
2630-
Latest = 7
2631+
Latest = 8
26312632
}
26322633
enum LanguageVariant {
26332634
Standard = 0,
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//// [regexMatchAll.ts]
2+
const matches = /\w/g[Symbol.matchAll]("matchAll");
3+
const array = [...matches];
4+
const { index, input } = array[0];
5+
6+
7+
//// [regexMatchAll.js]
8+
const matches = /\w/g[Symbol.matchAll]("matchAll");
9+
const array = [...matches];
10+
const { index, input } = array[0];
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
=== tests/cases/compiler/regexMatchAll.ts ===
2+
const matches = /\w/g[Symbol.matchAll]("matchAll");
3+
>matches : Symbol(matches, Decl(regexMatchAll.ts, 0, 5))
4+
>Symbol.matchAll : Symbol(SymbolConstructor.matchAll, Decl(lib.es2020.symbol.wellknown.d.ts, --, --))
5+
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))
6+
>matchAll : Symbol(SymbolConstructor.matchAll, Decl(lib.es2020.symbol.wellknown.d.ts, --, --))
7+
8+
const array = [...matches];
9+
>array : Symbol(array, Decl(regexMatchAll.ts, 1, 5))
10+
>matches : Symbol(matches, Decl(regexMatchAll.ts, 0, 5))
11+
12+
const { index, input } = array[0];
13+
>index : Symbol(index, Decl(regexMatchAll.ts, 2, 7))
14+
>input : Symbol(input, Decl(regexMatchAll.ts, 2, 14))
15+
>array : Symbol(array, Decl(regexMatchAll.ts, 1, 5))
16+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
=== tests/cases/compiler/regexMatchAll.ts ===
2+
const matches = /\w/g[Symbol.matchAll]("matchAll");
3+
>matches : IterableIterator<RegExpMatchArray>
4+
>/\w/g[Symbol.matchAll]("matchAll") : IterableIterator<RegExpMatchArray>
5+
>/\w/g[Symbol.matchAll] : (str: string) => IterableIterator<RegExpMatchArray>
6+
>/\w/g : RegExp
7+
>Symbol.matchAll : symbol
8+
>Symbol : SymbolConstructor
9+
>matchAll : symbol
10+
>"matchAll" : "matchAll"
11+
12+
const array = [...matches];
13+
>array : RegExpMatchArray[]
14+
>[...matches] : RegExpMatchArray[]
15+
>...matches : RegExpMatchArray
16+
>matches : IterableIterator<RegExpMatchArray>
17+
18+
const { index, input } = array[0];
19+
>index : number
20+
>input : string
21+
>array[0] : RegExpMatchArray
22+
>array : RegExpMatchArray[]
23+
>0 : 0
24+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//// [stringMatchAll.ts]
2+
const matches = "matchAll".matchAll(/\w/g);
3+
const array = [...matches];
4+
const { index, input } = array[0];
5+
6+
7+
//// [stringMatchAll.js]
8+
const matches = "matchAll".matchAll(/\w/g);
9+
const array = [...matches];
10+
const { index, input } = array[0];
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
=== tests/cases/compiler/stringMatchAll.ts ===
2+
const matches = "matchAll".matchAll(/\w/g);
3+
>matches : Symbol(matches, Decl(stringMatchAll.ts, 0, 5))
4+
>"matchAll".matchAll : Symbol(String.matchAll, Decl(lib.es2020.string.d.ts, --, --))
5+
>matchAll : Symbol(String.matchAll, Decl(lib.es2020.string.d.ts, --, --))
6+
7+
const array = [...matches];
8+
>array : Symbol(array, Decl(stringMatchAll.ts, 1, 5))
9+
>matches : Symbol(matches, Decl(stringMatchAll.ts, 0, 5))
10+
11+
const { index, input } = array[0];
12+
>index : Symbol(index, Decl(stringMatchAll.ts, 2, 7))
13+
>input : Symbol(input, Decl(stringMatchAll.ts, 2, 14))
14+
>array : Symbol(array, Decl(stringMatchAll.ts, 1, 5))
15+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
=== tests/cases/compiler/stringMatchAll.ts ===
2+
const matches = "matchAll".matchAll(/\w/g);
3+
>matches : IterableIterator<RegExpMatchArray>
4+
>"matchAll".matchAll(/\w/g) : IterableIterator<RegExpMatchArray>
5+
>"matchAll".matchAll : (regexp: RegExp) => IterableIterator<RegExpMatchArray>
6+
>"matchAll" : "matchAll"
7+
>matchAll : (regexp: RegExp) => IterableIterator<RegExpMatchArray>
8+
>/\w/g : RegExp
9+
10+
const array = [...matches];
11+
>array : RegExpMatchArray[]
12+
>[...matches] : RegExpMatchArray[]
13+
>...matches : RegExpMatchArray
14+
>matches : IterableIterator<RegExpMatchArray>
15+
16+
const { index, input } = array[0];
17+
>index : number
18+
>input : string
19+
>array[0] : RegExpMatchArray
20+
>array : RegExpMatchArray[]
21+
>0 : 0
22+

tests/cases/compiler/regexMatchAll.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// @target: es2020
2+
3+
const matches = /\w/g[Symbol.matchAll]("matchAll");
4+
const array = [...matches];
5+
const { index, input } = array[0];
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// @target: es2020
2+
3+
const matches = "matchAll".matchAll(/\w/g);
4+
const array = [...matches];
5+
const { index, input } = array[0];

0 commit comments

Comments
 (0)