From 3d2b0d873fcb52c5ef1874b21b19c548962f7bff Mon Sep 17 00:00:00 2001 From: yosuke ota Date: Sun, 23 Jul 2023 15:26:03 +0900 Subject: [PATCH 1/2] feat: `prefer-regex-literals` support `v` flag --- lib/rules/prefer-regex-literals.js | 12 +++++-- lib/rules/utils/regular-expressions.js | 2 +- tests/lib/rules/prefer-regex-literals.js | 42 +++++++++++++++++++++++- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/lib/rules/prefer-regex-literals.js b/lib/rules/prefer-regex-literals.js index eca805483f4a..ffaaeac3f279 100644 --- a/lib/rules/prefer-regex-literals.js +++ b/lib/rules/prefer-regex-literals.js @@ -241,7 +241,7 @@ module.exports = { /** * Returns a ecmaVersion compatible for regexpp. * @param {number} ecmaVersion The ecmaVersion to convert. - * @returns {import("regexpp/ecma-versions").EcmaVersion} The resulting ecmaVersion compatible for regexpp. + * @returns {import("@eslint-community/regexpp/ecma-versions").EcmaVersion} The resulting ecmaVersion compatible for regexpp. */ function getRegexppEcmaVersion(ecmaVersion) { if (ecmaVersion <= 5) { @@ -297,7 +297,10 @@ module.exports = { const validator = new RegExpValidator({ ecmaVersion: regexppEcmaVersion }); try { - validator.validatePattern(pattern, 0, pattern.length, flags ? flags.includes("u") : false); + validator.validatePattern(pattern, 0, pattern.length, { + unicode: flags ? flags.includes("u") : false, + unicodeSets: flags ? flags.includes("v") : false + }); if (flags) { validator.validateFlags(flags); } @@ -461,7 +464,10 @@ module.exports = { if (regexContent && !noFix) { let charIncrease = 0; - const ast = new RegExpParser({ ecmaVersion: regexppEcmaVersion }).parsePattern(regexContent, 0, regexContent.length, flags ? flags.includes("u") : false); + const ast = new RegExpParser({ ecmaVersion: regexppEcmaVersion }).parsePattern(regexContent, 0, regexContent.length, { + unicode: flags ? flags.includes("u") : false, + unicodeSets: flags ? flags.includes("v") : false + }); visitRegExpAST(ast, { onCharacterEnter(characterNode) { diff --git a/lib/rules/utils/regular-expressions.js b/lib/rules/utils/regular-expressions.js index 234a1cb8b114..92da774c96c7 100644 --- a/lib/rules/utils/regular-expressions.js +++ b/lib/rules/utils/regular-expressions.js @@ -8,7 +8,7 @@ const { RegExpValidator } = require("@eslint-community/regexpp"); -const REGEXPP_LATEST_ECMA_VERSION = 2022; +const REGEXPP_LATEST_ECMA_VERSION = 2024; /** * Checks if the given regular expression pattern would be valid with the `u` flag. diff --git a/tests/lib/rules/prefer-regex-literals.js b/tests/lib/rules/prefer-regex-literals.js index 054d89be1d75..812716276741 100644 --- a/tests/lib/rules/prefer-regex-literals.js +++ b/tests/lib/rules/prefer-regex-literals.js @@ -134,7 +134,10 @@ ruleTester.run("prefer-regex-literals", rule, { { code: "class C { #RegExp; foo() { globalThis.#RegExp('a'); } }", env: { es2020: true } - } + }, + + // ES2024 + "new RegExp('[[A--B]]' + a, 'v')" ], invalid: [ @@ -2808,6 +2811,43 @@ ruleTester.run("prefer-regex-literals", rule, { suggestions: null } ] + }, + + // ES2024 + { + code: "new RegExp('[[A--B]]', 'v')", + parserOptions: { ecmaVersion: 2024 }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/[[A--B]]/v" + } + ] + } + ] + }, + { + code: "new RegExp('[[A--B]]', 'v')", + parserOptions: { ecmaVersion: 2023 }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "new RegExp('[[A&&&]]', 'v')", + parserOptions: { ecmaVersion: 2024 }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] } ] }); From aaed1d1cc9741a1a33884fa64e104cc83e1d8aa7 Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Mon, 24 Jul 2023 23:17:16 +0900 Subject: [PATCH 2/2] Update tests/lib/rules/prefer-regex-literals.js Co-authored-by: Milos Djermanovic --- tests/lib/rules/prefer-regex-literals.js | 140 +++++++++++++++++++++++ 1 file changed, 140 insertions(+) diff --git a/tests/lib/rules/prefer-regex-literals.js b/tests/lib/rules/prefer-regex-literals.js index 812716276741..11f23cac3d5a 100644 --- a/tests/lib/rules/prefer-regex-literals.js +++ b/tests/lib/rules/prefer-regex-literals.js @@ -2848,6 +2848,146 @@ ruleTester.run("prefer-regex-literals", rule, { suggestions: null } ] + }, + { + code: "new RegExp('a', 'uv')", + parserOptions: { ecmaVersion: 2024 }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "new RegExp(/a/, 'v')", + options: [{ disallowRedundantWrapping: true }], + parserOptions: { ecmaVersion: 2024 }, + errors: [ + { + messageId: "unexpectedRedundantRegExpWithFlags", + suggestions: [ + { + messageId: "replaceWithLiteralAndFlags", + output: "/a/v", + data: { + flags: "v" + } + } + ] + } + ] + }, + { + code: "new RegExp(/a/, 'v')", + options: [{ disallowRedundantWrapping: true }], + parserOptions: { ecmaVersion: 2023 }, + errors: [ + { + messageId: "unexpectedRedundantRegExpWithFlags", + suggestions: null + } + ] + }, + { + code: "new RegExp(/a/g, 'v')", + options: [{ disallowRedundantWrapping: true }], + parserOptions: { ecmaVersion: 2024 }, + errors: [ + { + messageId: "unexpectedRedundantRegExpWithFlags", + suggestions: [ + { + messageId: "replaceWithLiteralAndFlags", + output: "/a/v", + data: { + flags: "v" + } + }, + { + messageId: "replaceWithIntendedLiteralAndFlags", + output: "/a/gv", + data: { + flags: "gv" + } + } + ] + } + ] + }, + { + code: "new RegExp(/[[A--B]]/v, 'g')", + options: [{ disallowRedundantWrapping: true }], + parserOptions: { ecmaVersion: 2024 }, + errors: [ + { + messageId: "unexpectedRedundantRegExpWithFlags", + suggestions: [ + { + messageId: "replaceWithIntendedLiteralAndFlags", + output: "/[[A--B]]/vg", + data: { + flags: "vg" + } + } + + // suggestion with flags `g` would be invalid + ] + } + ] + }, + { + code: "new RegExp(/a/u, 'v')", + options: [{ disallowRedundantWrapping: true }], + parserOptions: { ecmaVersion: 2024 }, + errors: [ + { + messageId: "unexpectedRedundantRegExpWithFlags", + suggestions: [ + { + messageId: "replaceWithLiteralAndFlags", + output: "/a/v", + data: { + flags: "v" + } + } + + // suggestion with merged flags `uv` would be invalid + ] + } + ] + }, + { + code: "new RegExp(/a/v, 'u')", + options: [{ disallowRedundantWrapping: true }], + parserOptions: { ecmaVersion: 2024 }, + errors: [ + { + messageId: "unexpectedRedundantRegExpWithFlags", + suggestions: [ + { + messageId: "replaceWithLiteralAndFlags", + output: "/a/u", + data: { + flags: "u" + } + } + + // suggestion with merged flags `vu` would be invalid + ] + } + ] + }, + { + code: "new RegExp(/[[A--B]]/v, 'u')", + options: [{ disallowRedundantWrapping: true }], + parserOptions: { ecmaVersion: 2024 }, + errors: [ + { + messageId: "unexpectedRedundantRegExpWithFlags", + suggestions: null + } + ] } ] });