From 6bd747b5b7731195224875b952a9ea61445a9938 Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Fri, 6 Aug 2021 04:51:39 +0900 Subject: [PATCH] Breaking: support new regex d flag (fixes #14640) (#14653) * Update: support new regex d flag (fixes #14640) * Upgrade regexpp * Update lib/rules/no-invalid-regexp.js Co-authored-by: Jordan Harband * Upgrade espree Co-authored-by: Jordan Harband Co-authored-by: Nicholas C. Zakas --- lib/rules/no-empty-character-class.js | 25 +++++++-------------- lib/rules/no-invalid-regexp.js | 2 +- package.json | 2 +- tests/lib/rules/no-empty-character-class.js | 4 +++- tests/lib/rules/no-invalid-regexp.js | 3 +++ 5 files changed, 16 insertions(+), 20 deletions(-) diff --git a/lib/rules/no-empty-character-class.js b/lib/rules/no-empty-character-class.js index 7dc219fe1a7..301f03bf3d1 100644 --- a/lib/rules/no-empty-character-class.js +++ b/lib/rules/no-empty-character-class.js @@ -12,16 +12,13 @@ /* * plain-English description of the following regexp: * 0. `^` fix the match at the beginning of the string - * 1. `\/`: the `/` that begins the regexp - * 2. `([^\\[]|\\.|\[([^\\\]]|\\.)+\])*`: regexp contents; 0 or more of the following - * 2.0. `[^\\[]`: any character that's not a `\` or a `[` (anything but escape sequences and character classes) - * 2.1. `\\.`: an escape sequence - * 2.2. `\[([^\\\]]|\\.)+\]`: a character class that isn't empty - * 3. `\/` the `/` that ends the regexp - * 4. `[gimuy]*`: optional regexp flags - * 5. `$`: fix the match at the end of the string + * 1. `([^\\[]|\\.|\[([^\\\]]|\\.)+\])*`: regexp contents; 0 or more of the following + * 1.0. `[^\\[]`: any character that's not a `\` or a `[` (anything but escape sequences and character classes) + * 1.1. `\\.`: an escape sequence + * 1.2. `\[([^\\\]]|\\.)+\]`: a character class that isn't empty + * 2. `$`: fix the match at the end of the string */ -const regex = /^\/([^\\[]|\\.|\[([^\\\]]|\\.)+\])*\/[gimuys]*$/u; +const regex = /^([^\\[]|\\.|\[([^\\\]]|\\.)+\])*$/u; //------------------------------------------------------------------------------ // Rule Definition @@ -46,18 +43,12 @@ module.exports = { }, create(context) { - const sourceCode = context.getSourceCode(); - return { - - Literal(node) { - const token = sourceCode.getFirstToken(node); - - if (token.type === "RegularExpression" && !regex.test(token.value)) { + "Literal[regex]"(node) { + if (!regex.test(node.regex.pattern)) { context.report({ node, messageId: "unexpected" }); } } - }; } diff --git a/lib/rules/no-invalid-regexp.js b/lib/rules/no-invalid-regexp.js index 94ad5ba6d5c..e3c8682e65b 100644 --- a/lib/rules/no-invalid-regexp.js +++ b/lib/rules/no-invalid-regexp.js @@ -10,7 +10,7 @@ const RegExpValidator = require("regexpp").RegExpValidator; const validator = new RegExpValidator(); -const validFlags = /[gimuys]/gu; +const validFlags = /[dgimsuy]/gu; const undefined1 = void 0; //------------------------------------------------------------------------------ diff --git a/package.json b/package.json index 1981419c5c1..593bebf07f4 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "natural-compare": "^1.4.0", "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^3.1.0", + "regexpp": "^3.2.0", "semver": "^7.2.1", "strip-ansi": "^6.0.0", "strip-json-comments": "^3.1.0", diff --git a/tests/lib/rules/no-empty-character-class.js b/tests/lib/rules/no-empty-character-class.js index 1421c2ad614..fd4cef8ed77 100644 --- a/tests/lib/rules/no-empty-character-class.js +++ b/tests/lib/rules/no-empty-character-class.js @@ -32,6 +32,7 @@ ruleTester.run("no-empty-character-class", rule, { "var foo = /\\s*:\\s*/gim;", { code: "var foo = /[\\]]/uy;", parserOptions: { ecmaVersion: 6 } }, { code: "var foo = /[\\]]/s;", parserOptions: { ecmaVersion: 2018 } }, + { code: "var foo = /[\\]]/d;", parserOptions: { ecmaVersion: 2022 } }, "var foo = /\\[]/" ], invalid: [ @@ -41,6 +42,7 @@ ruleTester.run("no-empty-character-class", rule, { { code: "if (/^abc[]/.test(foo)) {}", errors: [{ messageId: "unexpected", type: "Literal" }] }, { code: "var foo = /[]]/;", errors: [{ messageId: "unexpected", type: "Literal" }] }, { code: "var foo = /\\[[]/;", errors: [{ messageId: "unexpected", type: "Literal" }] }, - { code: "var foo = /\\[\\[\\]a-z[]/;", errors: [{ messageId: "unexpected", type: "Literal" }] } + { code: "var foo = /\\[\\[\\]a-z[]/;", errors: [{ messageId: "unexpected", type: "Literal" }] }, + { code: "var foo = /[]]/d;", parserOptions: { ecmaVersion: 2022 }, errors: [{ messageId: "unexpected", type: "Literal" }] } ] }); diff --git a/tests/lib/rules/no-invalid-regexp.js b/tests/lib/rules/no-invalid-regexp.js index 6484db816db..f1f2b404415 100644 --- a/tests/lib/rules/no-invalid-regexp.js +++ b/tests/lib/rules/no-invalid-regexp.js @@ -59,6 +59,9 @@ ruleTester.run("no-invalid-regexp", rule, { "new RegExp('(?<𝒜>.)', 'g');", "new RegExp('\\\\p{Script=Nandinagari}', 'u');", + // ES2022 + "new RegExp('a+(?z)?', 'd')", + // allowConstructorFlags { code: "new RegExp('.', 'g')",