From db13d4650c4d0692748960083f377a149979bf4b Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Wed, 6 Sep 2023 22:06:31 +0200 Subject: [PATCH 1/3] `prefer-w`: Add support for `v` flag --- lib/rules/prefer-w.ts | 49 +++++++++++++++++++------------------ tests/lib/rules/prefer-w.ts | 18 ++++++++++++-- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/lib/rules/prefer-w.ts b/lib/rules/prefer-w.ts index 4f11b9e73..0504a649a 100644 --- a/lib/rules/prefer-w.ts +++ b/lib/rules/prefer-w.ts @@ -16,7 +16,7 @@ import { CP_DIGIT_NINE, CP_LOW_LINE, } from "../utils" -import { Chars, toCharSet } from "regexp-ast-analysis" +import { Chars, toUnicodeSet } from "regexp-ast-analysis" import { mention } from "../utils/mention" /** @@ -52,7 +52,7 @@ function isDigitRangeOrSet(node: CharacterClassElement) { (node.type === "CharacterClassRange" && node.min.value === CP_DIGIT_ZERO && node.max.value === CP_DIGIT_NINE) || - (node.type === "CharacterSet" && node.kind === "digit") + (node.type === "CharacterSet" && node.kind === "digit" && !node.negate) ) } @@ -92,30 +92,31 @@ export default createRule("prefer-w", { }: RegExpContext): RegExpVisitor.Handlers { return { onCharacterClassEnter(ccNode: CharacterClass) { - // FIXME: TS Error - // @ts-expect-error -- FIXME - const charSet = toCharSet(ccNode, flags) + const charSet = toUnicodeSet(ccNode, flags) - let predefined: string | undefined = undefined - if (charSet.equals(Chars.word(flags))) { - predefined = "\\w" - } else if (charSet.equals(Chars.word(flags).negate())) { - predefined = "\\W" - } + if (charSet.accept.isEmpty) { + let predefined: string | undefined = undefined + const word = Chars.word(flags) + if (charSet.chars.equals(word)) { + predefined = "\\w" + } else if (charSet.chars.equals(word.negate())) { + predefined = "\\W" + } - if (predefined) { - context.report({ - node, - loc: getRegexpLocation(ccNode), - messageId: "unexpected", - data: { - type: "character class", - expr: mention(ccNode), - instead: predefined, - }, - fix: fixReplaceNode(ccNode, predefined), - }) - return + if (predefined) { + context.report({ + node, + loc: getRegexpLocation(ccNode), + messageId: "unexpected", + data: { + type: "character class", + expr: mention(ccNode), + instead: predefined, + }, + fix: fixReplaceNode(ccNode, predefined), + }) + return + } } const lowerAToZ: CharacterClassElement[] = [] diff --git a/tests/lib/rules/prefer-w.ts b/tests/lib/rules/prefer-w.ts index d7d03cf89..873ddd58f 100644 --- a/tests/lib/rules/prefer-w.ts +++ b/tests/lib/rules/prefer-w.ts @@ -3,13 +3,13 @@ import rule from "../../../lib/rules/prefer-w" const tester = new RuleTester({ parserOptions: { - ecmaVersion: 2020, + ecmaVersion: "latest", sourceType: "module", }, }) tester.run("prefer-w", rule as any, { - valid: ["/\\w/"], + valid: ["/\\w/", "/[\\Da-zA-Z_#]/", "/\\w/v", "/[\\Da-zA-Z_#]/v"], invalid: [ { code: "/[0-9a-zA-Z_]/", @@ -35,6 +35,20 @@ tester.run("prefer-w", rule as any, { }, ], }, + { + code: "/[\\da-zA-Z_#]/", + output: "/[\\w#]/", + errors: [ + "Unexpected character class ranges '[\\da-zA-Z_]'. Use '\\w' instead.", + ], + }, + { + code: "/[0-9a-z_[\\s&&\\p{ASCII}]]/iv", + output: "/[\\w[\\s&&\\p{ASCII}]]/iv", + errors: [ + "Unexpected character class ranges '[0-9a-z_]'. Use '\\w' instead.", + ], + }, { code: "/[0-9a-z_]/i", output: "/\\w/i", From bc8ed3628d173e0685e0c093cb56c5cdd93c9f36 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Thu, 14 Sep 2023 12:40:19 +0200 Subject: [PATCH 2/3] Use new `UnicodeSet` API --- lib/rules/prefer-w.ts | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/lib/rules/prefer-w.ts b/lib/rules/prefer-w.ts index d7f053026..61097e369 100644 --- a/lib/rules/prefer-w.ts +++ b/lib/rules/prefer-w.ts @@ -75,29 +75,27 @@ export default createRule("prefer-w", { onCharacterClassEnter(ccNode: CharacterClass) { const charSet = toUnicodeSet(ccNode, flags) - if (charSet.accept.isEmpty) { - let predefined: string | undefined = undefined - const word = Chars.word(flags) - if (charSet.chars.equals(word)) { - predefined = "\\w" - } else if (charSet.chars.equals(word.negate())) { - predefined = "\\W" - } + let predefined: string | undefined = undefined + const word = Chars.word(flags) + if (charSet.equals(word)) { + predefined = "\\w" + } else if (charSet.equals(word.negate())) { + predefined = "\\W" + } - if (predefined) { - context.report({ - node, - loc: getRegexpLocation(ccNode), - messageId: "unexpected", - data: { - type: "character class", - expr: mention(ccNode), - instead: predefined, - }, - fix: fixReplaceNode(ccNode, predefined), - }) - return - } + if (predefined) { + context.report({ + node, + loc: getRegexpLocation(ccNode), + messageId: "unexpected", + data: { + type: "character class", + expr: mention(ccNode), + instead: predefined, + }, + fix: fixReplaceNode(ccNode, predefined), + }) + return } const lowerAToZ: CharacterClassElement[] = [] From 48da470b68054e96329d01411a672311ce0eb26b Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Thu, 14 Sep 2023 20:01:30 +0900 Subject: [PATCH 3/3] Create tasty-penguins-cheat.md --- .changeset/tasty-penguins-cheat.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/tasty-penguins-cheat.md diff --git a/.changeset/tasty-penguins-cheat.md b/.changeset/tasty-penguins-cheat.md new file mode 100644 index 000000000..cc52915e9 --- /dev/null +++ b/.changeset/tasty-penguins-cheat.md @@ -0,0 +1,5 @@ +--- +"eslint-plugin-regexp": minor +--- + +`prefer-w`: Add support for `v` flag