Repository: ota-meshi/eslint-plugin-regexp
Pull request #578 (2023-09-06 20:09:17)

`prefer-w`: Add support for `v` flag
Besides adding support for the `v` flag, I also fixed a bug. `\D` was incorrectly detected as `\d` in `isDigitRangeOrSet`.

changeset-bot[bot]: ###  ⚠️  No Changeset found

Latest commit: db13d4650c4d0692748960083f377a149979bf4b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. **If these changes should result in a version bump, you need to add a changeset.**

<details><summary>This PR includes no changesets</summary>

  When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

</details>

[Click here to learn what changesets are, and how to add one](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add a changeset to this PR](https://github.com/ota-meshi/eslint-plugin-regexp/new/prefer-w-v-flag?filename=.changeset/healthy-olives-report.md&value=---%0A%22eslint-plugin-regexp%22%3A%20patch%0A---%0A%0A%60prefer-w%60%3A%20Add%20support%20for%20%60v%60%20flag%0A)


RunDevelopment: Still a draft because I'm working on improving the API of `UnicodeSet` right now. I'm making it more `CharSet`-like to make the migration to `toUnicodeSet` easier.

Patch:
diff --git a/.changeset/tasty-penguins-cheat.md b/.changeset/tasty-penguins-cheat.md
new file mode 100644
index 0000000..cc52915
--- /dev/null
+++ b/.changeset/tasty-penguins-cheat.md
@@ -0,0 +1,5 @@
+---
+"eslint-plugin-regexp": minor
+---
+
+`prefer-w`: Add support for `v` flag
diff --git a/lib/rules/prefer-w.ts b/lib/rules/prefer-w.ts
index 6db0c70..61097e3 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"
 
 function isSmallLetterRange(node: CharacterClassElement) {
@@ -40,7 +40,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)
     )
 }
 
@@ -73,14 +73,13 @@ 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))) {
+                    const word = Chars.word(flags)
+                    if (charSet.equals(word)) {
                         predefined = "\\w"
-                    } else if (charSet.equals(Chars.word(flags).negate())) {
+                    } else if (charSet.equals(word.negate())) {
                         predefined = "\\W"
                     }
 


Test patch:
diff --git a/tests/lib/rules/prefer-w.ts b/tests/lib/rules/prefer-w.ts
index d7d03cf..873ddd5 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",