From 509f75395035822280245772e2a95732a0dde0e1 Mon Sep 17 00:00:00 2001 From: Yosuke Ota Date: Tue, 25 Jul 2023 21:08:50 +0900 Subject: [PATCH] feat: `no-misleading-character-class` support `v` flag (#17406) * feat: `no-misleading-character-class` support `v` flag * fix: lib/rules/utils/regular-expressions.js * fix: iterateCharacterSequence --- .../rules/no-misleading-character-class.md | 1 + lib/rules/no-misleading-character-class.js | 10 ++++++++-- lib/rules/utils/regular-expressions.js | 2 +- .../rules/no-misleading-character-class.js | 20 ++++++++++++++++++- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/docs/src/rules/no-misleading-character-class.md b/docs/src/rules/no-misleading-character-class.md index a0d9e6d0693..e1b182c2ef5 100644 --- a/docs/src/rules/no-misleading-character-class.md +++ b/docs/src/rules/no-misleading-character-class.md @@ -79,6 +79,7 @@ Examples of **correct** code for this rule: /^[abc]$/ /^[πŸ‘]$/u +/^[\q{πŸ‘ΆπŸ»}]$/v ``` ::: diff --git a/lib/rules/no-misleading-character-class.js b/lib/rules/no-misleading-character-class.js index 47ee84ec857..99aa9404868 100644 --- a/lib/rules/no-misleading-character-class.js +++ b/lib/rules/no-misleading-character-class.js @@ -18,7 +18,7 @@ const { isValidWithUnicodeFlag } = require("./utils/regular-expressions"); * * CharacterClassRange syntax can steal a part of character sequence, * so this function reverts CharacterClassRange syntax and restore the sequence. - * @param {regexpp.AST.CharacterClassElement[]} nodes The node list to iterate character sequences. + * @param {import('@eslint-community/regexpp').AST.CharacterClassElement[]} nodes The node list to iterate character sequences. * @returns {IterableIterator} The list of character sequences. */ function *iterateCharacterSequence(nodes) { @@ -37,6 +37,9 @@ function *iterateCharacterSequence(nodes) { break; case "CharacterSet": + case "CharacterClass": // [[]] nesting character class + case "ClassStringDisjunction": // \q{...} + case "ExpressionCharacterClass": // [A--B] if (seq.length > 0) { yield seq; seq = []; @@ -144,7 +147,10 @@ module.exports = { pattern, 0, pattern.length, - flags.includes("u") + { + unicode: flags.includes("u"), + unicodeSets: flags.includes("v") + } ); } catch { diff --git a/lib/rules/utils/regular-expressions.js b/lib/rules/utils/regular-expressions.js index 92da774c96c..12e544e379d 100644 --- a/lib/rules/utils/regular-expressions.js +++ b/lib/rules/utils/regular-expressions.js @@ -28,7 +28,7 @@ function isValidWithUnicodeFlag(ecmaVersion, pattern) { }); try { - validator.validatePattern(pattern, void 0, void 0, /* uFlag = */ true); + validator.validatePattern(pattern, void 0, void 0, { unicode: /* uFlag = */ true }); } catch { return false; } diff --git a/tests/lib/rules/no-misleading-character-class.js b/tests/lib/rules/no-misleading-character-class.js index 5cc5cba5261..54c97149313 100644 --- a/tests/lib/rules/no-misleading-character-class.js +++ b/tests/lib/rules/no-misleading-character-class.js @@ -70,7 +70,14 @@ ruleTester.run("no-misleading-character-class", rule, { "var r = new RegExp('[Á] [ ');", "var r = RegExp('{ [Á]', 'u');", { code: "var r = new globalThis.RegExp('[Á] [ ');", env: { es2020: true } }, - { code: "var r = globalThis.RegExp('{ [Á]', 'u');", env: { es2020: true } } + { code: "var r = globalThis.RegExp('{ [Á]', 'u');", env: { es2020: true } }, + + // ES2024 + { code: "var r = /[πŸ‘]/v", parserOptions: { ecmaVersion: 2024 } }, + { code: String.raw`var r = /^[\q{πŸ‘ΆπŸ»}]$/v`, parserOptions: { ecmaVersion: 2024 } }, + { code: String.raw`var r = /[πŸ‡―\q{abc}πŸ‡΅]/v`, parserOptions: { ecmaVersion: 2024 } }, + { code: "var r = /[πŸ‡―[A]πŸ‡΅]/v", parserOptions: { ecmaVersion: 2024 } }, + { code: "var r = /[πŸ‡―[A--B]πŸ‡΅]/v", parserOptions: { ecmaVersion: 2024 } } ], invalid: [ @@ -620,6 +627,17 @@ ruleTester.run("no-misleading-character-class", rule, { messageId: "zwj", suggestions: null }] + }, + + + // ES2024 + { + code: "var r = /[[πŸ‘ΆπŸ»]]/v", + parserOptions: { ecmaVersion: 2024 }, + errors: [{ + messageId: "emojiModifier", + suggestions: null + }] } ] });