From bf96957bbe5192135aeb72aa0c5dacfd398f83cb Mon Sep 17 00:00:00 2001 From: ota-meshi Date: Fri, 14 Jun 2024 18:51:33 +0900 Subject: [PATCH 1/3] feat: Support ES2025 and RegExp duplicate named capturing groups --- README.md | 7 +- lib/options.js | 3 +- package.json | 2 +- ...apturing-groups-with-disjunction.result.js | 6 + ...d-capturing-groups-with-disjunction.src.js | 1 + ...ed-capturing-groups-with-nesting.result.js | 6 + ...named-capturing-groups-with-nesting.src.js | 1 + ...duplicate-named-capturing-groups.result.js | 6 + ...id-duplicate-named-capturing-groups.src.js | 1 + ...duplicate-named-capturing-groups.result.js | 395 ++++++++++++++++++ ...id-duplicate-named-capturing-groups.src.js | 5 + tests/lib/supported-ecmaversions.js | 4 +- tools/update-ecma-version-tests.js | 3 +- 13 files changed, 432 insertions(+), 8 deletions(-) create mode 100644 tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups-with-disjunction.result.js create mode 100644 tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups-with-disjunction.src.js create mode 100644 tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups-with-nesting.result.js create mode 100644 tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups-with-nesting.src.js create mode 100644 tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups.result.js create mode 100644 tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups.src.js create mode 100644 tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/valid-duplicate-named-capturing-groups.result.js create mode 100644 tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/valid-duplicate-named-capturing-groups.src.js diff --git a/README.md b/README.md index 58b863ce..a694fcb3 100644 --- a/README.md +++ b/README.md @@ -141,7 +141,7 @@ const options = { tokens: false, // Set to 3, 5 (the default), 6, 7, 8, 9, 10, 11, 12, 13, 14 or 15 to specify the version of ECMAScript syntax you want to use. - // You can also set to 2015 (same as 6), 2016 (same as 7), 2017 (same as 8), 2018 (same as 9), 2019 (same as 10), 2020 (same as 11), 2021 (same as 12), 2022 (same as 13), 2023 (same as 14) or 2024 (same as 15) to use the year-based naming. + // You can also set to 2015 (same as 6), 2016 (same as 7), 2017 (same as 8), 2018 (same as 9), 2019 (same as 10), 2020 (same as 11), 2021 (same as 12), 2022 (same as 13), 2023 (same as 14), 2024 (same as 15) or 2025 (same as 16) to use the year-based naming. // You can also set "latest" to use the most recently supported version. ecmaVersion: 3, @@ -231,11 +231,12 @@ We are building on top of Acorn, however, so that we can contribute back and hel ### What ECMAScript features do you support? -Espree supports all ECMAScript 2023 features and partially supports ECMAScript 2024 features. +Espree supports all ECMAScript 2023 features and partially supports ECMAScript 2024 and ECMAScript 2025 features. -Because ECMAScript 2024 is still under development, we are implementing features as they are finalized. Currently, Espree supports: +Because ECMAScript 2024 and ECMAScript 2025 are still under development, we are implementing features as they are finalized. Currently, Espree supports: * [RegExp v flag with set notation + properties of strings](https://github.com/tc39/proposal-regexp-v-flag) +* [RegExp Duplicate named capturing groups](https://github.com/tc39/proposal-duplicate-named-capturing-groups) See [finished-proposals.md](https://github.com/tc39/proposals/blob/master/finished-proposals.md) to know what features are finalized. diff --git a/lib/options.js b/lib/options.js index 8eae1b0c..2cdfb689 100644 --- a/lib/options.js +++ b/lib/options.js @@ -19,7 +19,8 @@ const SUPPORTED_VERSIONS = [ 12, // 2021 13, // 2022 14, // 2023 - 15 // 2024 + 15, // 2024 + 16 // 2025 ]; /** diff --git a/package.json b/package.json index 9eae90be..92a3fa87 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "funding": "https://opencollective.com/eslint", "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.11.3", + "acorn": "^8.12.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.0.0" }, diff --git a/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups-with-disjunction.result.js b/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups-with-disjunction.result.js new file mode 100644 index 00000000..6b97b149 --- /dev/null +++ b/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups-with-disjunction.result.js @@ -0,0 +1,6 @@ +export default { + "index": 13, + "lineNumber": 1, + "column": 14, + "message": "Invalid regular expression: /(?a)|(?b)(?c)/: Duplicate capture group name" +}; \ No newline at end of file diff --git a/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups-with-disjunction.src.js b/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups-with-disjunction.src.js new file mode 100644 index 00000000..8e3a33c0 --- /dev/null +++ b/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups-with-disjunction.src.js @@ -0,0 +1 @@ +const re1 = /(?a)|(?b)(?c)/; diff --git a/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups-with-nesting.result.js b/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups-with-nesting.result.js new file mode 100644 index 00000000..e42d79aa --- /dev/null +++ b/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups-with-nesting.result.js @@ -0,0 +1,6 @@ +export default { + "index": 13, + "lineNumber": 1, + "column": 14, + "message": "Invalid regular expression: /(?a)(?:(?b)|(?c))/: Duplicate capture group name" +}; \ No newline at end of file diff --git a/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups-with-nesting.src.js b/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups-with-nesting.src.js new file mode 100644 index 00000000..46e41888 --- /dev/null +++ b/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups-with-nesting.src.js @@ -0,0 +1 @@ +const re1 = /(?a)(?:(?b)|(?c))/; diff --git a/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups.result.js b/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups.result.js new file mode 100644 index 00000000..8f332db4 --- /dev/null +++ b/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups.result.js @@ -0,0 +1,6 @@ +export default { + "index": 13, + "lineNumber": 1, + "column": 14, + "message": "Invalid regular expression: /(?a)(?b)/: Duplicate capture group name" +}; \ No newline at end of file diff --git a/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups.src.js b/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups.src.js new file mode 100644 index 00000000..3a3252fe --- /dev/null +++ b/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/invalid-duplicate-named-capturing-groups.src.js @@ -0,0 +1 @@ +const re1 = /(?a)(?b)/; diff --git a/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/valid-duplicate-named-capturing-groups.result.js b/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/valid-duplicate-named-capturing-groups.result.js new file mode 100644 index 00000000..51628fc5 --- /dev/null +++ b/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/valid-duplicate-named-capturing-groups.result.js @@ -0,0 +1,395 @@ +import conditionalRegex from "../../../../lib/conditional-regex-value.js"; + +export default { + "type": "Program", + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 2 + } + }, + "range": [ + 0, + 110 + ], + "body": [ + { + "type": "VariableDeclaration", + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 5, + "column": 2 + } + }, + "range": [ + 0, + 110 + ], + "declarations": [ + { + "type": "VariableDeclarator", + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "range": [ + 6, + 109 + ], + "id": { + "type": "Identifier", + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 10 + } + }, + "range": [ + 6, + 10 + ], + "name": "list" + }, + "init": { + "type": "ArrayExpression", + "loc": { + "start": { + "line": 1, + "column": 13 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "range": [ + 13, + 109 + ], + "elements": [ + conditionalRegex({ + "type": "Literal", + "loc": { + "start": { + "line": 2, + "column": 4 + }, + "end": { + "line": 2, + "column": 21 + } + }, + "range": [ + 19, + 36 + ], + "value": null, + "raw": "/(?a)|(?b)/", + "regex": { + "pattern": "(?a)|(?b)", + "flags": "" + } + }), + conditionalRegex({ + "type": "Literal", + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 31 + } + }, + "range": [ + 42, + 69 + ], + "value": null, + "raw": "/(?:(?a)|(?b))\\\\k/", + "regex": { + "pattern": "(?:(?a)|(?b))\\\\k", + "flags": "" + } + }), + conditionalRegex({ + "type": "Literal", + "loc": { + "start": { + "line": 4, + "column": 4 + }, + "end": { + "line": 4, + "column": 35 + } + }, + "range": [ + 75, + 106 + ], + "value": null, + "raw": "/(?a)(?a)|(?b)(?b)/", + "regex": { + "pattern": "(?a)(?a)|(?b)(?b)", + "flags": "" + } + }) + ] + } + } + ], + "kind": "const" + } + ], + "sourceType": "script", + "tokens": [ + { + "type": "Keyword", + "value": "const", + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "range": [ + 0, + 5 + ] + }, + { + "type": "Identifier", + "value": "list", + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 10 + } + }, + "range": [ + 6, + 10 + ] + }, + { + "type": "Punctuator", + "value": "=", + "loc": { + "start": { + "line": 1, + "column": 11 + }, + "end": { + "line": 1, + "column": 12 + } + }, + "range": [ + 11, + 12 + ] + }, + { + "type": "Punctuator", + "value": "[", + "loc": { + "start": { + "line": 1, + "column": 13 + }, + "end": { + "line": 1, + "column": 14 + } + }, + "range": [ + 13, + 14 + ] + }, + { + "type": "RegularExpression", + "value": "/(?a)|(?b)/", + "loc": { + "start": { + "line": 2, + "column": 4 + }, + "end": { + "line": 2, + "column": 21 + } + }, + "range": [ + 19, + 36 + ], + "regex": { + "flags": "", + "pattern": "(?a)|(?b)" + } + }, + { + "type": "Punctuator", + "value": ",", + "loc": { + "start": { + "line": 2, + "column": 21 + }, + "end": { + "line": 2, + "column": 22 + } + }, + "range": [ + 36, + 37 + ] + }, + { + "type": "RegularExpression", + "value": "/(?:(?a)|(?b))\\\\k/", + "loc": { + "start": { + "line": 3, + "column": 4 + }, + "end": { + "line": 3, + "column": 31 + } + }, + "range": [ + 42, + 69 + ], + "regex": { + "flags": "", + "pattern": "(?:(?a)|(?b))\\\\k" + } + }, + { + "type": "Punctuator", + "value": ",", + "loc": { + "start": { + "line": 3, + "column": 31 + }, + "end": { + "line": 3, + "column": 32 + } + }, + "range": [ + 69, + 70 + ] + }, + { + "type": "RegularExpression", + "value": "/(?a)(?a)|(?b)(?b)/", + "loc": { + "start": { + "line": 4, + "column": 4 + }, + "end": { + "line": 4, + "column": 35 + } + }, + "range": [ + 75, + 106 + ], + "regex": { + "flags": "", + "pattern": "(?a)(?a)|(?b)(?b)" + } + }, + { + "type": "Punctuator", + "value": ",", + "loc": { + "start": { + "line": 4, + "column": 35 + }, + "end": { + "line": 4, + "column": 36 + } + }, + "range": [ + 106, + 107 + ] + }, + { + "type": "Punctuator", + "value": "]", + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 5, + "column": 1 + } + }, + "range": [ + 108, + 109 + ] + }, + { + "type": "Punctuator", + "value": ";", + "loc": { + "start": { + "line": 5, + "column": 1 + }, + "end": { + "line": 5, + "column": 2 + } + }, + "range": [ + 109, + 110 + ] + } + ] +}; \ No newline at end of file diff --git a/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/valid-duplicate-named-capturing-groups.src.js b/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/valid-duplicate-named-capturing-groups.src.js new file mode 100644 index 00000000..199374f4 --- /dev/null +++ b/tests/fixtures/ecma-version/16/duplicate-named-capturing-groups/valid-duplicate-named-capturing-groups.src.js @@ -0,0 +1,5 @@ +const list = [ + /(?a)|(?b)/, + /(?:(?a)|(?b))\\k/, + /(?a)(?a)|(?b)(?b)/, +]; diff --git a/tests/lib/supported-ecmaversions.js b/tests/lib/supported-ecmaversions.js index 5ed37f2c..107eb993 100644 --- a/tests/lib/supported-ecmaversions.js +++ b/tests/lib/supported-ecmaversions.js @@ -17,7 +17,7 @@ import * as espree from "../../espree.js"; describe("latestEcmaVersion", () => { it("should return the latest supported ecmaVersion", () => { - assert.strictEqual(espree.latestEcmaVersion, 15); + assert.strictEqual(espree.latestEcmaVersion, 16); }); }); @@ -25,7 +25,7 @@ describe("supportedEcmaVersions", () => { it("should return an array of all supported versions", () => { assert.deepStrictEqual( espree.supportedEcmaVersions, - [3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + [3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] ); }); }); diff --git a/tools/update-ecma-version-tests.js b/tools/update-ecma-version-tests.js index 6591cd91..387e252a 100644 --- a/tools/update-ecma-version-tests.js +++ b/tools/update-ecma-version-tests.js @@ -16,6 +16,7 @@ import path from "node:path"; import { fileURLToPath } from "node:url"; import util from "node:util"; +import fs from "node:fs"; import shelljs from "shelljs"; import tester from "../tests/lib/tester.js"; @@ -42,7 +43,7 @@ function findTests(directory) { * @returns {void} */ function outputResult(result, testResultFilename) { - `export default ${tester.getAstCode(result)};`.to(testResultFilename); + fs.writeFileSync(testResultFilename, `export default ${tester.getAstCode(result)};`); } /** From 11f6b7f66e95f7eeb71168524a98c5c46b119b89 Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Sat, 15 Jun 2024 08:07:39 +0900 Subject: [PATCH 2/3] update readme --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a694fcb3..5dab84a0 100644 --- a/README.md +++ b/README.md @@ -231,11 +231,10 @@ We are building on top of Acorn, however, so that we can contribute back and hel ### What ECMAScript features do you support? -Espree supports all ECMAScript 2023 features and partially supports ECMAScript 2024 and ECMAScript 2025 features. +Espree supports all ECMAScript 2024 features and partially supports ECMAScript 2025 features. -Because ECMAScript 2024 and ECMAScript 2025 are still under development, we are implementing features as they are finalized. Currently, Espree supports: +Because ECMAScript 2025 is still under development, we are implementing features as they are finalized. Currently, Espree supports: -* [RegExp v flag with set notation + properties of strings](https://github.com/tc39/proposal-regexp-v-flag) * [RegExp Duplicate named capturing groups](https://github.com/tc39/proposal-duplicate-named-capturing-groups) See [finished-proposals.md](https://github.com/tc39/proposals/blob/master/finished-proposals.md) to know what features are finalized. From 9b3f8b6dfecd50b0362349163b8c19c7fb23ca12 Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Mon, 17 Jun 2024 23:01:56 +0900 Subject: [PATCH 3/3] Update README.md Co-authored-by: Milos Djermanovic --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5dab84a0..748366ea 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ const options = { // create a top-level tokens array containing all tokens tokens: false, - // Set to 3, 5 (the default), 6, 7, 8, 9, 10, 11, 12, 13, 14 or 15 to specify the version of ECMAScript syntax you want to use. + // Set to 3, 5 (the default), 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 or 16 to specify the version of ECMAScript syntax you want to use. // You can also set to 2015 (same as 6), 2016 (same as 7), 2017 (same as 8), 2018 (same as 9), 2019 (same as 10), 2020 (same as 11), 2021 (same as 12), 2022 (same as 13), 2023 (same as 14), 2024 (same as 15) or 2025 (same as 16) to use the year-based naming. // You can also set "latest" to use the most recently supported version. ecmaVersion: 3,