From 1a75d525fa5e87bc94af0403f036933e77717c26 Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Fri, 26 Apr 2019 06:11:50 +0900 Subject: [PATCH] add ES2020 matchAll APIs (#30936) --- src/compiler/commandLineParser.ts | 4 ++++ src/compiler/types.ts | 3 ++- src/compiler/utilities.ts | 2 ++ src/lib/es2020.d.ts | 3 +++ src/lib/es2020.full.d.ts | 5 ++++ src/lib/es2020.string.d.ts | 10 ++++++++ src/lib/es2020.symbol.wellknown.d.ts | 19 +++++++++++++++ src/lib/libs.json | 4 ++++ src/server/protocol.ts | 3 +++ .../unittests/config/commandLineParsing.ts | 8 +++---- .../reference/api/tsserverlibrary.d.ts | 8 +++++-- tests/baselines/reference/api/typescript.d.ts | 5 ++-- tests/baselines/reference/regexMatchAll.js | 10 ++++++++ .../baselines/reference/regexMatchAll.symbols | 16 +++++++++++++ tests/baselines/reference/regexMatchAll.types | 24 +++++++++++++++++++ tests/baselines/reference/stringMatchAll.js | 10 ++++++++ .../reference/stringMatchAll.symbols | 15 ++++++++++++ .../baselines/reference/stringMatchAll.types | 22 +++++++++++++++++ tests/cases/compiler/regexMatchAll.ts | 5 ++++ tests/cases/compiler/stringMatchAll.ts | 5 ++++ 20 files changed, 172 insertions(+), 9 deletions(-) create mode 100644 src/lib/es2020.d.ts create mode 100644 src/lib/es2020.full.d.ts create mode 100644 src/lib/es2020.string.d.ts create mode 100644 src/lib/es2020.symbol.wellknown.d.ts create mode 100644 tests/baselines/reference/regexMatchAll.js create mode 100644 tests/baselines/reference/regexMatchAll.symbols create mode 100644 tests/baselines/reference/regexMatchAll.types create mode 100644 tests/baselines/reference/stringMatchAll.js create mode 100644 tests/baselines/reference/stringMatchAll.symbols create mode 100644 tests/baselines/reference/stringMatchAll.types create mode 100644 tests/cases/compiler/regexMatchAll.ts create mode 100644 tests/cases/compiler/stringMatchAll.ts diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index e1a8d77b7675a..527217e860e6f 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -16,6 +16,7 @@ namespace ts { ["es2017", "lib.es2017.d.ts"], ["es2018", "lib.es2018.d.ts"], ["es2019", "lib.es2019.d.ts"], + ["es2020", "lib.es2020.d.ts"], ["esnext", "lib.esnext.d.ts"], // Host only ["dom", "lib.dom.d.ts"], @@ -46,6 +47,8 @@ namespace ts { ["es2019.array", "lib.es2019.array.d.ts"], ["es2019.string", "lib.es2019.string.d.ts"], ["es2019.symbol", "lib.es2019.symbol.d.ts"], + ["es2020.string", "lib.es2020.string.d.ts"], + ["es2020.symbol.wellknown", "lib.es2020.symbol.wellknown.d.ts"], ["esnext.array", "lib.es2019.array.d.ts"], ["esnext.symbol", "lib.es2019.symbol.d.ts"], ["esnext.asynciterable", "lib.es2018.asynciterable.d.ts"], @@ -210,6 +213,7 @@ namespace ts { es2017: ScriptTarget.ES2017, es2018: ScriptTarget.ES2018, es2019: ScriptTarget.ES2019, + es2020: ScriptTarget.ES2020, esnext: ScriptTarget.ESNext, }), affectsSourceFile: true, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b421efa19e0d8..62d0f27a6981b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4756,7 +4756,8 @@ namespace ts { ES2017 = 4, ES2018 = 5, ES2019 = 6, - ESNext = 7, + ES2020 = 7, + ESNext = 8, JSON = 100, Latest = ESNext, } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 7deb2c823cdc1..76fb001de0dd9 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4677,6 +4677,8 @@ namespace ts { switch (options.target) { case ScriptTarget.ESNext: return "lib.esnext.full.d.ts"; + case ScriptTarget.ES2020: + return "lib.es2020.full.d.ts"; case ScriptTarget.ES2019: return "lib.es2019.full.d.ts"; case ScriptTarget.ES2018: diff --git a/src/lib/es2020.d.ts b/src/lib/es2020.d.ts new file mode 100644 index 0000000000000..fb55d987ebb5e --- /dev/null +++ b/src/lib/es2020.d.ts @@ -0,0 +1,3 @@ +/// +/// +/// diff --git a/src/lib/es2020.full.d.ts b/src/lib/es2020.full.d.ts new file mode 100644 index 0000000000000..0d4b6d45d55ad --- /dev/null +++ b/src/lib/es2020.full.d.ts @@ -0,0 +1,5 @@ +/// +/// +/// +/// +/// diff --git a/src/lib/es2020.string.d.ts b/src/lib/es2020.string.d.ts new file mode 100644 index 0000000000000..335a0ac000577 --- /dev/null +++ b/src/lib/es2020.string.d.ts @@ -0,0 +1,10 @@ +/// + +interface String { + /** + * Matches a string with a regular expression, and returns an iterable of matches + * containing the results of that search. + * @param regexp A variable name or string literal containing the regular expression pattern and flags. + */ + matchAll(regexp: RegExp): IterableIterator; +} diff --git a/src/lib/es2020.symbol.wellknown.d.ts b/src/lib/es2020.symbol.wellknown.d.ts new file mode 100644 index 0000000000000..76e377e0be270 --- /dev/null +++ b/src/lib/es2020.symbol.wellknown.d.ts @@ -0,0 +1,19 @@ +/// +/// + +interface SymbolConstructor { + /** + * A regular expression method that matches the regular expression against a string. Called + * by the String.prototype.matchAll method. + */ + readonly matchAll: symbol; +} + +interface RegExp { + /** + * Matches a string with this regular expression, and returns an iterable of matches + * containing the results of that search. + * @param string A string to search within. + */ + [Symbol.matchAll](str: string): IterableIterator; +} diff --git a/src/lib/libs.json b/src/lib/libs.json index fa5f4060acd6a..74611a938609c 100644 --- a/src/lib/libs.json +++ b/src/lib/libs.json @@ -7,6 +7,7 @@ "es2017", "es2018", "es2019", + "es2020", "esnext", // Host only "dom.generated", @@ -37,6 +38,8 @@ "es2019.array", "es2019.string", "es2019.symbol", + "es2020.string", + "es2020.symbol.wellknown", "esnext.bigint", "esnext.intl", // Default libraries @@ -46,6 +49,7 @@ "es2017.full", "es2018.full", "es2019.full", + "es2020.full", "esnext.full" ], "paths": { diff --git a/src/server/protocol.ts b/src/server/protocol.ts index e5580874369e6..3da890a766ff7 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -3046,6 +3046,9 @@ namespace ts.server.protocol { ES2015 = "ES2015", ES2016 = "ES2016", ES2017 = "ES2017", + ES2018 = "ES2018", + ES2019 = "ES2019", + ES2020 = "ES2020", ESNext = "ESNext" } } diff --git a/src/testRunner/unittests/config/commandLineParsing.ts b/src/testRunner/unittests/config/commandLineParsing.ts index ccb2378c644a8..450b27e01ed4f 100644 --- a/src/testRunner/unittests/config/commandLineParsing.ts +++ b/src/testRunner/unittests/config/commandLineParsing.ts @@ -57,7 +57,7 @@ namespace ts { assertParseResult(["--lib", "es5,invalidOption", "0.ts"], { errors: [{ - 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'.", + 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'.", category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, @@ -161,7 +161,7 @@ namespace ts { start: undefined, length: undefined, }, { - messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'esnext'.", + messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'esnext'.", category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, @@ -259,7 +259,7 @@ namespace ts { assertParseResult(["--lib", "es5,", "es7", "0.ts"], { errors: [{ - 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'.", + 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'.", category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, @@ -278,7 +278,7 @@ namespace ts { assertParseResult(["--lib", "es5, ", "es7", "0.ts"], { errors: [{ - 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'.", + 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'.", category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 5d5472e840592..621b9149a68b4 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2625,9 +2625,10 @@ declare namespace ts { ES2017 = 4, ES2018 = 5, ES2019 = 6, - ESNext = 7, + ES2020 = 7, + ESNext = 8, JSON = 100, - Latest = 7 + Latest = 8 } enum LanguageVariant { Standard = 0, @@ -8127,6 +8128,9 @@ declare namespace ts.server.protocol { ES2015 = "ES2015", ES2016 = "ES2016", ES2017 = "ES2017", + ES2018 = "ES2018", + ES2019 = "ES2019", + ES2020 = "ES2020", ESNext = "ESNext" } } diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index e8e2bed3bb8f9..643c68abe97ec 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2625,9 +2625,10 @@ declare namespace ts { ES2017 = 4, ES2018 = 5, ES2019 = 6, - ESNext = 7, + ES2020 = 7, + ESNext = 8, JSON = 100, - Latest = 7 + Latest = 8 } enum LanguageVariant { Standard = 0, diff --git a/tests/baselines/reference/regexMatchAll.js b/tests/baselines/reference/regexMatchAll.js new file mode 100644 index 0000000000000..5b169725ae27e --- /dev/null +++ b/tests/baselines/reference/regexMatchAll.js @@ -0,0 +1,10 @@ +//// [regexMatchAll.ts] +const matches = /\w/g[Symbol.matchAll]("matchAll"); +const array = [...matches]; +const { index, input } = array[0]; + + +//// [regexMatchAll.js] +const matches = /\w/g[Symbol.matchAll]("matchAll"); +const array = [...matches]; +const { index, input } = array[0]; diff --git a/tests/baselines/reference/regexMatchAll.symbols b/tests/baselines/reference/regexMatchAll.symbols new file mode 100644 index 0000000000000..aa811a1f67614 --- /dev/null +++ b/tests/baselines/reference/regexMatchAll.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/regexMatchAll.ts === +const matches = /\w/g[Symbol.matchAll]("matchAll"); +>matches : Symbol(matches, Decl(regexMatchAll.ts, 0, 5)) +>Symbol.matchAll : Symbol(SymbolConstructor.matchAll, Decl(lib.es2020.symbol.wellknown.d.ts, --, --)) +>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, --, --)) +>matchAll : Symbol(SymbolConstructor.matchAll, Decl(lib.es2020.symbol.wellknown.d.ts, --, --)) + +const array = [...matches]; +>array : Symbol(array, Decl(regexMatchAll.ts, 1, 5)) +>matches : Symbol(matches, Decl(regexMatchAll.ts, 0, 5)) + +const { index, input } = array[0]; +>index : Symbol(index, Decl(regexMatchAll.ts, 2, 7)) +>input : Symbol(input, Decl(regexMatchAll.ts, 2, 14)) +>array : Symbol(array, Decl(regexMatchAll.ts, 1, 5)) + diff --git a/tests/baselines/reference/regexMatchAll.types b/tests/baselines/reference/regexMatchAll.types new file mode 100644 index 0000000000000..a109cdc46116b --- /dev/null +++ b/tests/baselines/reference/regexMatchAll.types @@ -0,0 +1,24 @@ +=== tests/cases/compiler/regexMatchAll.ts === +const matches = /\w/g[Symbol.matchAll]("matchAll"); +>matches : IterableIterator +>/\w/g[Symbol.matchAll]("matchAll") : IterableIterator +>/\w/g[Symbol.matchAll] : (str: string) => IterableIterator +>/\w/g : RegExp +>Symbol.matchAll : symbol +>Symbol : SymbolConstructor +>matchAll : symbol +>"matchAll" : "matchAll" + +const array = [...matches]; +>array : RegExpMatchArray[] +>[...matches] : RegExpMatchArray[] +>...matches : RegExpMatchArray +>matches : IterableIterator + +const { index, input } = array[0]; +>index : number +>input : string +>array[0] : RegExpMatchArray +>array : RegExpMatchArray[] +>0 : 0 + diff --git a/tests/baselines/reference/stringMatchAll.js b/tests/baselines/reference/stringMatchAll.js new file mode 100644 index 0000000000000..fbb3c1174b731 --- /dev/null +++ b/tests/baselines/reference/stringMatchAll.js @@ -0,0 +1,10 @@ +//// [stringMatchAll.ts] +const matches = "matchAll".matchAll(/\w/g); +const array = [...matches]; +const { index, input } = array[0]; + + +//// [stringMatchAll.js] +const matches = "matchAll".matchAll(/\w/g); +const array = [...matches]; +const { index, input } = array[0]; diff --git a/tests/baselines/reference/stringMatchAll.symbols b/tests/baselines/reference/stringMatchAll.symbols new file mode 100644 index 0000000000000..91ad541338ad4 --- /dev/null +++ b/tests/baselines/reference/stringMatchAll.symbols @@ -0,0 +1,15 @@ +=== tests/cases/compiler/stringMatchAll.ts === +const matches = "matchAll".matchAll(/\w/g); +>matches : Symbol(matches, Decl(stringMatchAll.ts, 0, 5)) +>"matchAll".matchAll : Symbol(String.matchAll, Decl(lib.es2020.string.d.ts, --, --)) +>matchAll : Symbol(String.matchAll, Decl(lib.es2020.string.d.ts, --, --)) + +const array = [...matches]; +>array : Symbol(array, Decl(stringMatchAll.ts, 1, 5)) +>matches : Symbol(matches, Decl(stringMatchAll.ts, 0, 5)) + +const { index, input } = array[0]; +>index : Symbol(index, Decl(stringMatchAll.ts, 2, 7)) +>input : Symbol(input, Decl(stringMatchAll.ts, 2, 14)) +>array : Symbol(array, Decl(stringMatchAll.ts, 1, 5)) + diff --git a/tests/baselines/reference/stringMatchAll.types b/tests/baselines/reference/stringMatchAll.types new file mode 100644 index 0000000000000..d63de9540b5f6 --- /dev/null +++ b/tests/baselines/reference/stringMatchAll.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/stringMatchAll.ts === +const matches = "matchAll".matchAll(/\w/g); +>matches : IterableIterator +>"matchAll".matchAll(/\w/g) : IterableIterator +>"matchAll".matchAll : (regexp: RegExp) => IterableIterator +>"matchAll" : "matchAll" +>matchAll : (regexp: RegExp) => IterableIterator +>/\w/g : RegExp + +const array = [...matches]; +>array : RegExpMatchArray[] +>[...matches] : RegExpMatchArray[] +>...matches : RegExpMatchArray +>matches : IterableIterator + +const { index, input } = array[0]; +>index : number +>input : string +>array[0] : RegExpMatchArray +>array : RegExpMatchArray[] +>0 : 0 + diff --git a/tests/cases/compiler/regexMatchAll.ts b/tests/cases/compiler/regexMatchAll.ts new file mode 100644 index 0000000000000..b18ab9fd2968b --- /dev/null +++ b/tests/cases/compiler/regexMatchAll.ts @@ -0,0 +1,5 @@ +// @target: es2020 + +const matches = /\w/g[Symbol.matchAll]("matchAll"); +const array = [...matches]; +const { index, input } = array[0]; diff --git a/tests/cases/compiler/stringMatchAll.ts b/tests/cases/compiler/stringMatchAll.ts new file mode 100644 index 0000000000000..9b2ae1a9d641f --- /dev/null +++ b/tests/cases/compiler/stringMatchAll.ts @@ -0,0 +1,5 @@ +// @target: es2020 + +const matches = "matchAll".matchAll(/\w/g); +const array = [...matches]; +const { index, input } = array[0];