diff --git a/docs/src/rules/no-misleading-character-class.md b/docs/src/rules/no-misleading-character-class.md index 9d190820146..005127abf48 100644 --- a/docs/src/rules/no-misleading-character-class.md +++ b/docs/src/rules/no-misleading-character-class.md @@ -7,8 +7,6 @@ rule_type: problem - - Disallows characters which are made with multiple code points in character class syntax. Unicode includes the characters which are made with multiple code points. diff --git a/lib/rules/no-misleading-character-class.js b/lib/rules/no-misleading-character-class.js index d3d9d382ac5..94b28784a10 100644 --- a/lib/rules/no-misleading-character-class.js +++ b/lib/rules/no-misleading-character-class.js @@ -4,16 +4,13 @@ "use strict"; const { CALL, CONSTRUCT, ReferenceTracker, getStringIfConstant } = require("eslint-utils"); -const { RegExpValidator, RegExpParser, visitRegExpAST } = require("regexpp"); +const { RegExpParser, visitRegExpAST } = require("regexpp"); const { isCombiningCharacter, isEmojiModifier, isRegionalIndicatorSymbol, isSurrogatePair } = require("./utils/unicode"); -const astUtils = require("./utils/ast-utils.js"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ -const REGEXPP_LATEST_ECMA_VERSION = 2022; - /** * Iterate character sequences of a given nodes. * @@ -112,8 +109,6 @@ module.exports = { url: "https://eslint.org/docs/rules/no-misleading-character-class" }, - hasSuggestions: true, - schema: [], messages: { @@ -121,12 +116,10 @@ module.exports = { combiningClass: "Unexpected combined character in character class.", emojiModifier: "Unexpected modified Emoji in character class.", regionalIndicatorSymbol: "Unexpected national flag in character class.", - zwj: "Unexpected joined character sequence in character class.", - suggestUnicodeFlag: "Add unicode 'u' flag to regex." + zwj: "Unexpected joined character sequence in character class." } }, create(context) { - const sourceCode = context.getSourceCode(); const parser = new RegExpParser(); /** @@ -134,10 +127,17 @@ module.exports = { * @param {Node} node The node to report. * @param {string} pattern The regular expression pattern to verify. * @param {string} flags The flags of the regular expression. - * @param {Function} unicodeFixer Fixer for missing "u" flag. * @returns {void} */ - function verify(node, pattern, flags, unicodeFixer) { + function verify(node, pattern, flags) { + const has = { + surrogatePairWithoutUFlag: false, + combiningClass: false, + variationSelector: false, + emojiModifier: false, + regionalIndicatorSymbol: false, + zwj: false + }; let patternNode; try { @@ -153,75 +153,26 @@ module.exports = { return; } - const foundKinds = new Set(); - visitRegExpAST(patternNode, { onCharacterClassEnter(ccNode) { for (const chars of iterateCharacterSequence(ccNode.elements)) { for (const kind of kinds) { - if (hasCharacterSequence[kind](chars)) { - foundKinds.add(kind); - } + has[kind] = has[kind] || hasCharacterSequence[kind](chars); } } } }); - for (const kind of foundKinds) { - let suggest; - - if (kind === "surrogatePairWithoutUFlag") { - suggest = [{ - messageId: "suggestUnicodeFlag", - fix: unicodeFixer - }]; + for (const kind of kinds) { + if (has[kind]) { + context.report({ node, messageId: kind }); } - - context.report({ - node, - messageId: kind, - suggest - }); } } - /** - * Checks if the given regular expression pattern would be valid with the `u` flag. - * @param {string} pattern The regular expression pattern to verify. - * @returns {boolean} `true` if the pattern would be valid with the `u` flag. - * `false` if the pattern would be invalid with the `u` flag or the configured - * ecmaVersion doesn't support the `u` flag. - */ - function isValidWithUnicodeFlag(pattern) { - const { ecmaVersion } = context.parserOptions; - - // ecmaVersion is unknown or it doesn't support the 'u' flag - if (typeof ecmaVersion !== "number" || ecmaVersion <= 5) { - return false; - } - - const validator = new RegExpValidator({ - ecmaVersion: Math.min(ecmaVersion + 2009, REGEXPP_LATEST_ECMA_VERSION) - }); - - try { - validator.validatePattern(pattern, void 0, void 0, /* uFlag = */ true); - } catch { - return false; - } - - return true; - } - return { "Literal[regex]"(node) { - verify(node, node.regex.pattern, node.regex.flags, fixer => { - if (!isValidWithUnicodeFlag(node.regex.pattern)) { - return null; - } - - return fixer.insertTextAfter(node, "u"); - }); + verify(node, node.regex.pattern, node.regex.flags); }, "Program"() { const scope = context.getScope(); @@ -240,31 +191,7 @@ module.exports = { const flags = getStringIfConstant(flagsNode, scope); if (typeof pattern === "string") { - verify(node, pattern, flags || "", fixer => { - - if (!isValidWithUnicodeFlag(pattern)) { - return null; - } - - if (node.arguments.length === 1) { - const penultimateToken = sourceCode.getLastToken(node, { skip: 1 }); // skip closing parenthesis - - return fixer.insertTextAfter( - penultimateToken, - astUtils.isCommaToken(penultimateToken) - ? ' "u",' - : ', "u"' - ); - } - - if ((flagsNode.type === "Literal" && typeof flagsNode.value === "string") || flagsNode.type === "TemplateLiteral") { - const range = [flagsNode.range[0], flagsNode.range[1] - 1]; - - return fixer.insertTextAfterRange(range, "u"); - } - - return null; - }); + verify(node, pattern, flags || ""); } } } diff --git a/tests/lib/rules/no-misleading-character-class.js b/tests/lib/rules/no-misleading-character-class.js index 0aaf34e5942..a02e5e13e32 100644 --- a/tests/lib/rules/no-misleading-character-class.js +++ b/tests/lib/rules/no-misleading-character-class.js @@ -76,549 +76,223 @@ ruleTester.run("no-misleading-character-class", rule, { // RegExp Literals. { code: "var r = /[πŸ‘]/", - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: "var r = /[πŸ‘]/u" }] - }] + errors: [{ messageId: "surrogatePairWithoutUFlag" }] }, { code: "var r = /[\\uD83D\\uDC4D]/", - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: "var r = /[\\uD83D\\uDC4D]/u" }] - }] - }, - { - code: "var r = /[πŸ‘]/", - parserOptions: { ecmaVersion: 3 }, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: null // ecmaVersion doesn't support the 'u' flag - }] - }, - { - code: "var r = /[πŸ‘]/", - parserOptions: { ecmaVersion: 5 }, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: null // ecmaVersion doesn't support the 'u' flag - }] - }, - { - code: "var r = /[πŸ‘]\\a/", - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: null // pattern would be invalid with the 'u' flag - }] - }, - { - code: "var r = /(?<=[πŸ‘])/", - parserOptions: { ecmaVersion: 9 }, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: "var r = /(?<=[πŸ‘])/u" }] - }] - }, - { - code: "var r = /(?<=[πŸ‘])/", - parserOptions: { ecmaVersion: 2018 }, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: "var r = /(?<=[πŸ‘])/u" }] - }] + errors: [{ messageId: "surrogatePairWithoutUFlag" }] }, { code: "var r = /[Á]/", - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: "var r = /[Á]/u", - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: "var r = /[\\u0041\\u0301]/", - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: "var r = /[\\u0041\\u0301]/u", - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: "var r = /[\\u{41}\\u{301}]/u", - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: "var r = /[❇️]/", - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: "var r = /[❇️]/u", - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: "var r = /[\\u2747\\uFE0F]/", - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: "var r = /[\\u2747\\uFE0F]/u", - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: "var r = /[\\u{2747}\\u{FE0F}]/u", - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: "var r = /[πŸ‘ΆπŸ»]/", - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: "var r = /[πŸ‘ΆπŸ»]/u" }] - }] + errors: [{ messageId: "surrogatePairWithoutUFlag" }] }, { code: "var r = /[πŸ‘ΆπŸ»]/u", - errors: [{ - messageId: "emojiModifier", - suggestions: null - }] + errors: [{ messageId: "emojiModifier" }] }, { code: "var r = /[\\uD83D\\uDC76\\uD83C\\uDFFB]/u", - errors: [{ - messageId: "emojiModifier", - suggestions: null - }] + errors: [{ messageId: "emojiModifier" }] }, { code: "var r = /[\\u{1F476}\\u{1F3FB}]/u", - errors: [{ - messageId: "emojiModifier", - suggestions: null - }] + errors: [{ messageId: "emojiModifier" }] }, { code: "var r = /[πŸ‡―πŸ‡΅]/", - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: "var r = /[πŸ‡―πŸ‡΅]/u" }] - }] - }, - { - code: "var r = /[πŸ‡―πŸ‡΅]/i", - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: "var r = /[πŸ‡―πŸ‡΅]/iu" }] - }] + errors: [{ messageId: "surrogatePairWithoutUFlag" }] }, { code: "var r = /[πŸ‡―πŸ‡΅]/u", - errors: [{ - messageId: "regionalIndicatorSymbol", - suggestions: null - }] + errors: [{ messageId: "regionalIndicatorSymbol" }] }, { code: "var r = /[\\uD83C\\uDDEF\\uD83C\\uDDF5]/u", - errors: [{ - messageId: "regionalIndicatorSymbol", - suggestions: null - }] + errors: [{ messageId: "regionalIndicatorSymbol" }] }, { code: "var r = /[\\u{1F1EF}\\u{1F1F5}]/u", - errors: [{ - messageId: "regionalIndicatorSymbol", - suggestions: null - }] + errors: [{ messageId: "regionalIndicatorSymbol" }] }, { code: "var r = /[πŸ‘¨β€πŸ‘©β€πŸ‘¦]/", errors: [ - { - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: "var r = /[πŸ‘¨β€πŸ‘©β€πŸ‘¦]/u" }] - }, - { - messageId: "zwj", - suggestions: null - } + { messageId: "surrogatePairWithoutUFlag" }, + { messageId: "zwj" } ] }, { code: "var r = /[πŸ‘¨β€πŸ‘©β€πŸ‘¦]/u", - errors: [{ - messageId: "zwj", - suggestions: null - }] + errors: [{ messageId: "zwj" }] }, { code: "var r = /[\\uD83D\\uDC68\\u200D\\uD83D\\uDC69\\u200D\\uD83D\\uDC66]/u", - errors: [{ - messageId: "zwj", - suggestions: null - }] + errors: [{ messageId: "zwj" }] }, { code: "var r = /[\\u{1F468}\\u{200D}\\u{1F469}\\u{200D}\\u{1F466}]/u", - errors: [{ - messageId: "zwj", - suggestions: null - }] + errors: [{ messageId: "zwj" }] }, // RegExp constructors. { code: String.raw`var r = new RegExp("[πŸ‘]", "")`, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: String.raw`var r = new RegExp("[πŸ‘]", "u")` }] - }] - }, - { - code: "var r = new RegExp('[πŸ‘]', ``)", - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: "var r = new RegExp('[πŸ‘]', `u`)" }] - }] - }, - { - code: String.raw`var r = new RegExp("[πŸ‘]", flags)`, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: null - }] - }, - { - code: String.raw`const flags = ""; var r = new RegExp("[πŸ‘]", flags)`, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: null - }] + errors: [{ messageId: "surrogatePairWithoutUFlag" }] }, { code: String.raw`var r = new RegExp("[\\uD83D\\uDC4D]", "")`, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: String.raw`var r = new RegExp("[\\uD83D\\uDC4D]", "u")` }] - }] - }, - { - code: String.raw`var r = new RegExp("[πŸ‘]", "")`, - parserOptions: { ecmaVersion: 3 }, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: null // ecmaVersion doesn't support the 'u' flag - }] - }, - { - code: String.raw`var r = new RegExp("[πŸ‘]", "")`, - parserOptions: { ecmaVersion: 5 }, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: null // ecmaVersion doesn't support the 'u' flag - }] - }, - { - code: String.raw`var r = new RegExp("[πŸ‘]\\a", "")`, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: null // pattern would be invalid with the 'u' flag - }] - }, - { - code: String.raw`var r = new RegExp("/(?<=[πŸ‘])", "")`, - parserOptions: { ecmaVersion: 9 }, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: String.raw`var r = new RegExp("/(?<=[πŸ‘])", "u")` }] - }] - }, - { - code: String.raw`var r = new RegExp("/(?<=[πŸ‘])", "")`, - parserOptions: { ecmaVersion: 2018 }, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: String.raw`var r = new RegExp("/(?<=[πŸ‘])", "u")` }] - }] + errors: [{ messageId: "surrogatePairWithoutUFlag" }] }, { code: String.raw`var r = new RegExp("[Á]", "")`, - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: String.raw`var r = new RegExp("[Á]", "u")`, - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: String.raw`var r = new RegExp("[\\u0041\\u0301]", "")`, - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: String.raw`var r = new RegExp("[\\u0041\\u0301]", "u")`, - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: String.raw`var r = new RegExp("[\\u{41}\\u{301}]", "u")`, - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: String.raw`var r = new RegExp("[❇️]", "")`, - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: String.raw`var r = new RegExp("[❇️]", "u")`, - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: String.raw`var r = new RegExp("[\\u2747\\uFE0F]", "")`, - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: String.raw`var r = new RegExp("[\\u2747\\uFE0F]", "u")`, - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: String.raw`var r = new RegExp("[\\u{2747}\\u{FE0F}]", "u")`, - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: String.raw`var r = new RegExp("[πŸ‘ΆπŸ»]", "")`, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: String.raw`var r = new RegExp("[πŸ‘ΆπŸ»]", "u")` }] - }] + errors: [{ messageId: "surrogatePairWithoutUFlag" }] }, { code: String.raw`var r = new RegExp("[πŸ‘ΆπŸ»]", "u")`, - errors: [{ - messageId: "emojiModifier", - suggestions: null - }] + errors: [{ messageId: "emojiModifier" }] }, { code: String.raw`var r = new RegExp("[\\uD83D\\uDC76\\uD83C\\uDFFB]", "u")`, - errors: [{ - messageId: "emojiModifier", - suggestions: null - }] + errors: [{ messageId: "emojiModifier" }] }, { code: String.raw`var r = new RegExp("[\\u{1F476}\\u{1F3FB}]", "u")`, - errors: [{ - messageId: "emojiModifier", - suggestions: null - }] + errors: [{ messageId: "emojiModifier" }] }, { code: String.raw`var r = new RegExp("[πŸ‡―πŸ‡΅]", "")`, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: String.raw`var r = new RegExp("[πŸ‡―πŸ‡΅]", "u")` }] - }] - }, - { - code: String.raw`var r = new RegExp("[πŸ‡―πŸ‡΅]", "i")`, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: String.raw`var r = new RegExp("[πŸ‡―πŸ‡΅]", "iu")` }] - }] - }, - { - code: "var r = new RegExp('[πŸ‡―πŸ‡΅]', `i`)", - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: "var r = new RegExp('[πŸ‡―πŸ‡΅]', `iu`)" }] - }] - }, - { - code: "var r = new RegExp('[πŸ‡―πŸ‡΅]', `${foo}`)", - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: "var r = new RegExp('[πŸ‡―πŸ‡΅]', `${foo}u`)" }] - }] - }, - { - code: String.raw`var r = new RegExp("[πŸ‡―πŸ‡΅]")`, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: String.raw`var r = new RegExp("[πŸ‡―πŸ‡΅]", "u")` }] - }] - }, - { - code: String.raw`var r = new RegExp("[πŸ‡―πŸ‡΅]",)`, - parserOptions: { ecmaVersion: 2017 }, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: String.raw`var r = new RegExp("[πŸ‡―πŸ‡΅]", "u",)` }] - }] - }, - { - code: String.raw`var r = new RegExp(("[πŸ‡―πŸ‡΅]"))`, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: String.raw`var r = new RegExp(("[πŸ‡―πŸ‡΅]"), "u")` }] - }] - }, - { - code: String.raw`var r = new RegExp((("[πŸ‡―πŸ‡΅]")))`, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: String.raw`var r = new RegExp((("[πŸ‡―πŸ‡΅]")), "u")` }] - }] - }, - { - code: String.raw`var r = new RegExp(("[πŸ‡―πŸ‡΅]"),)`, - parserOptions: { ecmaVersion: 2017 }, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: String.raw`var r = new RegExp(("[πŸ‡―πŸ‡΅]"), "u",)` }] - }] + errors: [{ messageId: "surrogatePairWithoutUFlag" }] }, { code: String.raw`var r = new RegExp("[πŸ‡―πŸ‡΅]", "u")`, - errors: [{ - messageId: "regionalIndicatorSymbol", - suggestions: null - }] + errors: [{ messageId: "regionalIndicatorSymbol" }] }, { code: String.raw`var r = new RegExp("[\\uD83C\\uDDEF\\uD83C\\uDDF5]", "u")`, - errors: [{ - messageId: "regionalIndicatorSymbol", - suggestions: null - }] + errors: [{ messageId: "regionalIndicatorSymbol" }] }, { code: String.raw`var r = new RegExp("[\\u{1F1EF}\\u{1F1F5}]", "u")`, - errors: [{ - messageId: "regionalIndicatorSymbol", - suggestions: null - }] + errors: [{ messageId: "regionalIndicatorSymbol" }] }, { code: String.raw`var r = new RegExp("[πŸ‘¨β€πŸ‘©β€πŸ‘¦]", "")`, errors: [ - { - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: String.raw`var r = new RegExp("[πŸ‘¨β€πŸ‘©β€πŸ‘¦]", "u")` }] - }, - { - messageId: "zwj", - suggestions: null - } + { messageId: "surrogatePairWithoutUFlag" }, + { messageId: "zwj" } ] }, { code: String.raw`var r = new RegExp("[πŸ‘¨β€πŸ‘©β€πŸ‘¦]", "u")`, - errors: [{ - messageId: "zwj", - suggestions: null - }] + errors: [{ messageId: "zwj" }] }, { code: String.raw`var r = new RegExp("[\\uD83D\\uDC68\\u200D\\uD83D\\uDC69\\u200D\\uD83D\\uDC66]", "u")`, - errors: [{ - messageId: "zwj", - suggestions: null - }] + errors: [{ messageId: "zwj" }] }, { code: String.raw`var r = new RegExp("[\\u{1F468}\\u{200D}\\u{1F469}\\u{200D}\\u{1F466}]", "u")`, - errors: [{ - messageId: "zwj", - suggestions: null - }] + errors: [{ messageId: "zwj" }] }, { code: String.raw`var r = new globalThis.RegExp("[❇️]", "")`, env: { es2020: true }, - errors: [{ - messageId: "combiningClass", - suggestions: null - }] + errors: [{ messageId: "combiningClass" }] }, { code: String.raw`var r = new globalThis.RegExp("[πŸ‘ΆπŸ»]", "u")`, env: { es2020: true }, - errors: [{ - messageId: "emojiModifier", - suggestions: null - }] + errors: [{ messageId: "emojiModifier" }] }, { code: String.raw`var r = new globalThis.RegExp("[πŸ‡―πŸ‡΅]", "")`, env: { es2020: true }, - errors: [{ - messageId: "surrogatePairWithoutUFlag", - suggestions: [{ messageId: "suggestUnicodeFlag", output: String.raw`var r = new globalThis.RegExp("[πŸ‡―πŸ‡΅]", "u")` }] - }] + errors: [{ messageId: "surrogatePairWithoutUFlag" }] }, { code: String.raw`var r = new globalThis.RegExp("[\\u{1F468}\\u{200D}\\u{1F469}\\u{200D}\\u{1F466}]", "u")`, env: { es2020: true }, - errors: [{ - messageId: "zwj", - suggestions: null - }] + errors: [{ messageId: "zwj" }] } ] });