From 94e77a693fd5124c9057320310b41e92567d7e76 Mon Sep 17 00:00:00 2001 From: Yash Singh Date: Fri, 17 Dec 2021 13:38:06 -0800 Subject: [PATCH] feat: Suggestions support for `prefer-regex-literals` (#15077) * New: Autofix support to prefer-regex-literals Fixes #15029 * Use canTokensBeAdjacent * Fix for NULL * Switch to validatePattern and validateFlags * Fix for unicode * Apply a few suggestions from code review * Fix: Double Escaping? * Tests and fixes for no-unicode regexp * New: Drop usage of getStaticValue * Fix: Remove whitespace changes, fix jsdoc type, and convert to suggestion for unexpectedRegExp * New: More test cases for . * Remove meta.docs.suggestion Co-authored-by: Milos Djermanovic * Fix linting * Don't fix NULL * Remove redundant wrapping suggestions for now * String.raw can have problematic chars * Remove fixable * Fix messed up char increase * Apply suggestion from code review Co-authored-by: Milos Djermanovic * chore: use characterNode.raw instead of characterNode.value * chore: do a bit of simplification of onCharacterEnter * Apply suggestions from code review Co-authored-by: Milos Djermanovic * chore: more changes following code review * chore: Use reliable way of testing if spacing needed Co-authored-by: Milos Djermanovic * diff msg for suggestion than main warning * chore: stricter testing * Apply suggestions from code review Co-authored-by: Milos Djermanovic Co-authored-by: Milos Djermanovic --- lib/rules/prefer-regex-literals.js | 218 +- tests/lib/rules/prefer-regex-literals.js | 2297 +++++++++++++++++++++- 2 files changed, 2475 insertions(+), 40 deletions(-) diff --git a/lib/rules/prefer-regex-literals.js b/lib/rules/prefer-regex-literals.js index afd6a01398e..158f84b940d 100644 --- a/lib/rules/prefer-regex-literals.js +++ b/lib/rules/prefer-regex-literals.js @@ -11,11 +11,15 @@ const astUtils = require("./utils/ast-utils"); const { CALL, CONSTRUCT, ReferenceTracker, findVariable } = require("eslint-utils"); +const { RegExpValidator, visitRegExpAST, RegExpParser } = require("regexpp"); +const { canTokensBeAdjacent } = require("./utils/ast-utils"); //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ +const REGEXPP_LATEST_ECMA_VERSION = 2022; + /** * Determines whether the given node is a string literal. * @param {ASTNode} node Node to check. @@ -43,6 +47,71 @@ function isStaticTemplateLiteral(node) { return node.type === "TemplateLiteral" && node.expressions.length === 0; } +const validPrecedingTokens = [ + "(", + ";", + "[", + ",", + "=", + "+", + "*", + "-", + "?", + "~", + "%", + "**", + "!", + "typeof", + "instanceof", + "&&", + "||", + "??", + "return", + "...", + "delete", + "void", + "in", + "<", + ">", + "<=", + ">=", + "==", + "===", + "!=", + "!==", + "<<", + ">>", + ">>>", + "&", + "|", + "^", + ":", + "{", + "=>", + "*=", + "<<=", + ">>=", + ">>>=", + "^=", + "|=", + "&=", + "??=", + "||=", + "&&=", + "**=", + "+=", + "-=", + "/=", + "%=", + "/", + "do", + "break", + "continue", + "debugger", + "case", + "throw" +]; + //------------------------------------------------------------------------------ // Rule Definition @@ -59,6 +128,8 @@ module.exports = { url: "https://eslint.org/docs/rules/prefer-regex-literals" }, + hasSuggestions: true, + schema: [ { type: "object", @@ -74,6 +145,7 @@ module.exports = { messages: { unexpectedRegExp: "Use a regular expression literal instead of the 'RegExp' constructor.", + replaceWithLiteral: "Replace with an equivalent regular expression literal.", unexpectedRedundantRegExp: "Regular expression literal is unnecessarily wrapped within a 'RegExp' constructor.", unexpectedRedundantRegExpWithFlags: "Use regular expression literal with flags instead of the 'RegExp' constructor." } @@ -81,6 +153,7 @@ module.exports = { create(context) { const [{ disallowRedundantWrapping = false } = {}] = context.options; + const sourceCode = context.getSourceCode(); /** * Determines whether the given identifier node is a reference to a global variable. @@ -107,6 +180,27 @@ module.exports = { isStaticTemplateLiteral(node.quasi); } + /** + * Gets the value of a string + * @param {ASTNode} node The node to get the string of. + * @returns {string|null} The value of the node. + */ + function getStringValue(node) { + if (isStringLiteral(node)) { + return node.value; + } + + if (isStaticTemplateLiteral(node)) { + return node.quasis[0].value.cooked; + } + + if (isStringRawTaggedStaticTemplateLiteral(node)) { + return node.quasi.quasis[0].value.raw; + } + + return null; + } + /** * Determines whether the given node is considered to be a static string by the logic of this rule. * @param {ASTNode} node Node to check. @@ -152,6 +246,53 @@ module.exports = { return false; } + /** + * Returns a ecmaVersion compatible for regexpp. + * @param {any} ecmaVersion The ecmaVersion to convert. + * @returns {import("regexpp/ecma-versions").EcmaVersion} The resulting ecmaVersion compatible for regexpp. + */ + function getRegexppEcmaVersion(ecmaVersion) { + if (typeof ecmaVersion !== "number" || ecmaVersion <= 5) { + return 5; + } + return Math.min(ecmaVersion + 2009, REGEXPP_LATEST_ECMA_VERSION); + } + + /** + * Makes a character escaped or else returns null. + * @param {string} character The character to escape. + * @returns {string} The resulting escaped character. + */ + function resolveEscapes(character) { + switch (character) { + case "\n": + case "\\\n": + return "\\n"; + + case "\r": + case "\\\r": + return "\\r"; + + case "\t": + case "\\\t": + return "\\t"; + + case "\v": + case "\\\v": + return "\\v"; + + case "\f": + case "\\\f": + return "\\f"; + + case "/": + return "\\/"; + + default: + return null; + } + } + return { Program() { const scope = context.getScope(); @@ -171,7 +312,82 @@ module.exports = { context.report({ node, messageId: "unexpectedRedundantRegExp" }); } } else if (hasOnlyStaticStringArguments(node)) { - context.report({ node, messageId: "unexpectedRegExp" }); + let regexContent = getStringValue(node.arguments[0]); + let noFix = false; + let flags; + + if (node.arguments[1]) { + flags = getStringValue(node.arguments[1]); + } + + const regexppEcmaVersion = getRegexppEcmaVersion(context.parserOptions.ecmaVersion); + const RegExpValidatorInstance = new RegExpValidator({ ecmaVersion: regexppEcmaVersion }); + + try { + RegExpValidatorInstance.validatePattern(regexContent, 0, regexContent.length, flags ? flags.includes("u") : false); + if (flags) { + RegExpValidatorInstance.validateFlags(flags); + } + } catch { + noFix = true; + } + + const tokenBefore = sourceCode.getTokenBefore(node); + + if (tokenBefore && !validPrecedingTokens.includes(tokenBefore.value)) { + noFix = true; + } + + if (!/^[-a-zA-Z0-9\\[\](){} \t\r\n\v\f!@#$%^&*+^_=/~`.> 0) { + noFix = true; + } + + if (regexContent && !noFix) { + let charIncrease = 0; + + const ast = new RegExpParser({ ecmaVersion: regexppEcmaVersion }).parsePattern(regexContent, 0, regexContent.length, flags ? flags.includes("u") : false); + + visitRegExpAST(ast, { + onCharacterEnter(characterNode) { + const escaped = resolveEscapes(characterNode.raw); + + if (escaped) { + regexContent = + regexContent.slice(0, characterNode.start + charIncrease) + + escaped + + regexContent.slice(characterNode.end + charIncrease); + + if (characterNode.raw.length === 1) { + charIncrease += 1; + } + } + } + }); + } + + const newRegExpValue = `/${regexContent || "(?:)"}/${flags || ""}`; + + context.report({ + node, + messageId: "unexpectedRegExp", + suggest: noFix ? [] : [{ + messageId: "replaceWithLiteral", + fix(fixer) { + const tokenAfter = sourceCode.getTokenAfter(node); + + return fixer.replaceText( + node, + (tokenBefore && !canTokensBeAdjacent(tokenBefore, newRegExpValue) && tokenBefore.range[1] === node.range[0] ? " " : "") + + newRegExpValue + + (tokenAfter && !canTokensBeAdjacent(newRegExpValue, tokenAfter) && node.range[1] === tokenAfter.range[0] ? " " : "") + ); + } + }] + }); } } } diff --git a/tests/lib/rules/prefer-regex-literals.js b/tests/lib/rules/prefer-regex-literals.js index ccd88ae74fd..f2982cbfb72 100644 --- a/tests/lib/rules/prefer-regex-literals.js +++ b/tests/lib/rules/prefer-regex-literals.js @@ -26,6 +26,8 @@ ruleTester.run("prefer-regex-literals", rule, { // considered as dynamic "new RegExp(pattern)", + "new RegExp('\\\\p{Emoji_Presentation}\\\\P{Script_Extensions=Latin}' + '', `ug`)", + "new RegExp('\\\\cA' + '')", "RegExp(pattern, 'g')", "new RegExp(f('a'))", "RegExp(prefix + 'a')", @@ -33,6 +35,7 @@ ruleTester.run("prefer-regex-literals", rule, { "RegExp(`a` + suffix);", "new RegExp(String.raw`a` + suffix);", "RegExp('a', flags)", + "const flags = 'gu';RegExp('a', flags)", "RegExp('a', 'g' + flags)", "new RegExp(String.raw`a`, flags);", "RegExp(`${prefix}abc`)", @@ -42,8 +45,10 @@ ruleTester.run("prefer-regex-literals", rule, { "new RegExp(String.raw`a${''}c`);", "new RegExp('a' + 'b')", "RegExp(1)", - "new RegExp(/a/, 'u');", - "new RegExp(/a/);", + "new RegExp('(\\\\p{Emoji_Presentation})\\\\1' + '', `ug`)", + "RegExp(String.raw`\\78\\126` + '\\\\5934', '' + `g` + '')", + "func(new RegExp(String.raw`a${''}c\\d`, 'u'),new RegExp(String.raw`a${''}c\\d`, 'u'))", + "new RegExp('\\\\[' + \"b\\\\]\")", { code: "new RegExp(/a/, flags);", options: [{ disallowRedundantWrapping: true }] @@ -134,124 +139,2338 @@ ruleTester.run("prefer-regex-literals", rule, { invalid: [ { code: "new RegExp('abc');", - errors: [{ messageId: "unexpectedRegExp", type: "NewExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/abc/;" + } + ] + } + ] }, { code: "RegExp('abc');", - errors: [{ messageId: "unexpectedRegExp", type: "CallExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "CallExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/abc/;" + } + ] + } + ] }, { code: "new RegExp('abc', 'g');", - errors: [{ messageId: "unexpectedRegExp", type: "NewExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/abc/g;" + } + ] + } + ] }, { code: "RegExp('abc', 'g');", - errors: [{ messageId: "unexpectedRegExp", type: "CallExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "CallExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/abc/g;" + } + ] + } + ] }, { code: "new RegExp(`abc`);", - errors: [{ messageId: "unexpectedRegExp", type: "NewExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/abc/;" + } + ] + } + ] }, { code: "RegExp(`abc`);", - errors: [{ messageId: "unexpectedRegExp", type: "CallExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "CallExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/abc/;" + } + ] + } + ] }, { code: "new RegExp(`abc`, `g`);", - errors: [{ messageId: "unexpectedRegExp", type: "NewExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/abc/g;" + } + ] + } + ] }, { code: "RegExp(`abc`, `g`);", - errors: [{ messageId: "unexpectedRegExp", type: "CallExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "CallExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/abc/g;" + } + ] + } + ] }, { code: "new RegExp(String.raw`abc`);", - errors: [{ messageId: "unexpectedRegExp", type: "NewExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/abc/;" + } + ] + } + ] + }, + { + code: "new RegExp(String.raw`abc\nabc`);", + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/abc\\nabc/;" + } + ] + } + ] + }, + { + code: "new RegExp(String.raw`\tabc\nabc`);", + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\tabc\\nabc/;" + } + ] + } + ] }, { code: "RegExp(String.raw`abc`);", - errors: [{ messageId: "unexpectedRegExp", type: "CallExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "CallExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/abc/;" + } + ] + } + ] }, { code: "new RegExp(String.raw`abc`, String.raw`g`);", - errors: [{ messageId: "unexpectedRegExp", type: "NewExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/abc/g;" + } + ] + } + ] }, { code: "RegExp(String.raw`abc`, String.raw`g`);", - errors: [{ messageId: "unexpectedRegExp", type: "CallExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "CallExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/abc/g;" + } + ] + } + ] }, { code: "new RegExp(String['raw']`a`);", - errors: [{ messageId: "unexpectedRegExp", type: "NewExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/a/;" + } + ] + } + ] }, { code: "new RegExp('');", - errors: [{ messageId: "unexpectedRegExp", type: "NewExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/(?:)/;" + } + ] + } + ] }, { code: "RegExp('', '');", - errors: [{ messageId: "unexpectedRegExp", type: "CallExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "CallExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/(?:)/;" + } + ] + } + ] }, { code: "new RegExp(String.raw``);", - errors: [{ messageId: "unexpectedRegExp", type: "NewExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/(?:)/;" + } + ] + } + ] }, { code: "new RegExp('a', `g`);", - errors: [{ messageId: "unexpectedRegExp", type: "NewExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/a/g;" + } + ] + } + ] }, { code: "RegExp(`a`, 'g');", - errors: [{ messageId: "unexpectedRegExp", type: "CallExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "CallExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/a/g;" + } + ] + } + ] }, { code: "RegExp(String.raw`a`, 'g');", - errors: [{ messageId: "unexpectedRegExp", type: "CallExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "CallExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/a/g;" + } + ] + } + ] }, { code: "new RegExp(String.raw`\\d`, `g`);", - errors: [{ messageId: "unexpectedRegExp", type: "NewExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\d/g;" + } + ] + } + ] + }, + { + code: "new RegExp(String.raw`\\\\d`, `g`);", + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\\\d/g;" + } + ] + } + ] + }, + { + code: "new RegExp(String['raw']`\\\\d`, `g`);", + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\\\d/g;" + } + ] + } + ] + }, + { + code: "new RegExp(String[\"raw\"]`\\\\d`, `g`);", + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\\\d/g;" + } + ] + } + ] }, { code: "RegExp('a', String.raw`g`);", - errors: [{ messageId: "unexpectedRegExp", type: "CallExpression" }] + errors: [ + { + messageId: "unexpectedRegExp", + type: "CallExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/a/g;" + } + ] + } + ] }, { code: "new globalThis.RegExp('a');", - env: { es2020: true }, - errors: [{ messageId: "unexpectedRegExp", type: "NewExpression" }] + env: { + es2020: true + }, + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/a/;" + } + ] + } + ] }, { code: "globalThis.RegExp('a');", - env: { es2020: true }, - errors: [{ messageId: "unexpectedRegExp", type: "CallExpression" }] + env: { + es2020: true + }, + errors: [ + { + messageId: "unexpectedRegExp", + type: "CallExpression", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/a/;" + } + ] + } + ] }, - { code: "new RegExp(/a/);", - options: [{ disallowRedundantWrapping: true }], - errors: [{ messageId: "unexpectedRedundantRegExp", type: "NewExpression", line: 1, column: 1 }] + options: [ + { + disallowRedundantWrapping: true + } + ], + errors: [ + { + messageId: "unexpectedRedundantRegExp", + type: "NewExpression", + line: 1, + column: 1 + } + ] }, { code: "new RegExp(/a/, 'u');", - options: [{ disallowRedundantWrapping: true }], - errors: [{ messageId: "unexpectedRedundantRegExpWithFlags", type: "NewExpression", line: 1, column: 1 }] + options: [ + { + disallowRedundantWrapping: true + } + ], + errors: [ + { + messageId: "unexpectedRedundantRegExpWithFlags", + type: "NewExpression", + line: 1, + column: 1 + } + ] }, { code: "new RegExp(/a/, `u`);", - options: [{ disallowRedundantWrapping: true }], - errors: [{ messageId: "unexpectedRedundantRegExpWithFlags", type: "NewExpression", line: 1, column: 1 }] + options: [ + { + disallowRedundantWrapping: true + } + ], + errors: [ + { + messageId: "unexpectedRedundantRegExpWithFlags", + type: "NewExpression", + line: 1, + column: 1 + } + ] + }, + { + code: "new RegExp(/a/, String.raw`u`);", + options: [ + { + disallowRedundantWrapping: true + } + ], + errors: [ + { + messageId: "unexpectedRedundantRegExpWithFlags", + type: "NewExpression", + line: 1, + column: 1 + } + ] }, { code: "new RegExp('a');", - options: [{ disallowRedundantWrapping: true }], - errors: [{ messageId: "unexpectedRegExp", type: "NewExpression", line: 1, column: 1 }] + options: [ + { + disallowRedundantWrapping: true + } + ], + errors: [ + { + messageId: "unexpectedRegExp", + type: "NewExpression", + line: 1, + column: 1, + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/a/;" + } + ] + } + ] }, - - // Optional chaining { code: "new RegExp((String?.raw)`a`);", - errors: [{ messageId: "unexpectedRegExp" }] + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/a/;" + } + ] + } + ] + }, + { + code: "new RegExp('+');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "new RegExp('*');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "RegExp('+');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "RegExp('*');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "new RegExp('+', 'g');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "new RegExp('*', 'g');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "RegExp('+', 'g');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "RegExp('*', 'g');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "RegExp('abc', 'u');", + parserOptions: { + ecmaVersion: 3 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "new RegExp('abc', 'd');", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "RegExp('abc', 'd');", + parserOptions: { + ecmaVersion: 2022 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/abc/d;" + } + ] + } + ] + }, + { + code: "RegExp('\\\\\\\\', '');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\\\/;" + } + ] + } + ] + }, + { + code: "RegExp('\\n', '');", + parserOptions: { + ecmaVersion: 2022 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\n/;" + } + ] + } + ] + }, + { + code: "RegExp('\\n\\n', '');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\n\\n/;" + } + ] + } + ] + }, + { + code: "RegExp('\\t', '');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\t/;" + } + ] + } + ] + }, + { + code: "RegExp('\\t\\t', '');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\t\\t/;" + } + ] + } + ] + }, + { + code: "RegExp('\\r\\n', '');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\r\\n/;" + } + ] + } + ] + }, + { + code: "RegExp('\\u1234', 'g')", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "RegExp('\\u{1234}', 'g')", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "RegExp('\\u{11111}', 'g')", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "RegExp('\\v', '');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\v/;" + } + ] + } + ] + }, + { + code: "RegExp('\\v\\v', '');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\v\\v/;" + } + ] + } + ] + }, + { + code: "RegExp('\\f', '');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\f/;" + } + ] + } + ] + }, + { + code: "RegExp('\\f\\f', '');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\f\\f/;" + } + ] + } + ] + }, + { + code: "RegExp('\\\\b', '');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\b/;" + } + ] + } + ] + }, + { + code: "RegExp('\\\\b\\\\b', '');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\b\\b/;" + } + ] + } + ] + }, + { + code: "new RegExp('\\\\B\\\\b', '');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\B\\b/;" + } + ] + } + ] + }, + { + code: "RegExp('\\\\w', '');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\w/;" + } + ] + } + ] + }, + { + code: "new globalThis.RegExp('\\\\W', '');", + globals: { + globalThis: "readonly" + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\W/;" + } + ] + } + ] + }, + { + code: "RegExp('\\\\s', '');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\s/;" + } + ] + } + ] + }, + { + code: "new RegExp('\\\\S', '')", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\S/" + } + ] + } + ] + }, + { + code: "globalThis.RegExp('\\\\d', '');", + globals: { + globalThis: "readonly" + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\d/;" + } + ] + } + ] + }, + { + code: "globalThis.RegExp('\\\\D', '')", + globals: { + globalThis: "readonly" + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\D/" + } + ] + } + ] + }, + { + code: "globalThis.RegExp('\\\\\\\\\\\\D', '')", + globals: { + globalThis: "readonly" + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\\\\\D/" + } + ] + } + ] + }, + { + code: "new RegExp('\\\\D\\\\D', '')", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\D\\D/" + } + ] + } + ] + }, + { + code: "new globalThis.RegExp('\\\\0\\\\0', '');", + globals: { + globalThis: "writable" + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\0\\0/;" + } + ] + } + ] + }, + { + code: "new RegExp('\\\\0\\\\0', '');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\0\\0/;" + } + ] + } + ] + }, + { + code: "new RegExp('\\0\\0', 'g');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "RegExp('\\\\0\\\\0\\\\0', '')", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\0\\0\\0/" + } + ] + } + ] + }, + { + code: "RegExp('\\\\78\\\\126\\\\5934', '')", + parserOptions: { + ecmaVersion: 2022 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\78\\126\\5934/" + } + ] + } + ] + }, + { + code: "new window['RegExp']('\\\\x56\\\\x78\\\\x45', '');", + env: { + browser: true + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\x56\\x78\\x45/;" + } + ] + } + ] + }, + { + code: "a in(RegExp('abc'))", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "a in(/abc/)" + } + ] + } + ] + }, + { + code: "x = y\n RegExp(\"foo\").test(x) ? bar() : baz()", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "func(new RegExp(String.raw`\\w{1, 2`, 'u'),new RegExp(String.raw`\\w{1, 2`, 'u'))", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + }, + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "x = y;\n RegExp(\"foo\").test(x) ? bar() : baz()", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "x = y;\n /foo/.test(x) ? bar() : baz()" + } + ] + } + ] + }, + { + code: "typeof RegExp(\"foo\")", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "typeof /foo/" + } + ] + } + ] + }, + { + code: "RegExp(\"foo\") instanceof RegExp(String.raw`blahblah`, 'g') ? typeof new RegExp('(\\\\p{Emoji_Presentation})\\\\1', `ug`) : false", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/foo/ instanceof RegExp(String.raw`blahblah`, 'g') ? typeof new RegExp('(\\\\p{Emoji_Presentation})\\\\1', `ug`) : false" + } + ] + }, + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "RegExp(\"foo\") instanceof /blahblah/g ? typeof new RegExp('(\\\\p{Emoji_Presentation})\\\\1', `ug`) : false" + } + ] + }, + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "RegExp(\"foo\") instanceof RegExp(String.raw`blahblah`, 'g') ? typeof /(\\p{Emoji_Presentation})\\1/ug : false" + } + ] + } + ] + }, + { + code: "[ new RegExp(`someregular`)]", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "[ /someregular/]" + } + ] + } + ] + }, + { + code: "const totallyValidatesEmails = new RegExp(\"\\\\S+@(\\\\S+\\\\.)+\\\\S+\")\n if (typeof totallyValidatesEmails === 'object') {\n runSomethingThatExists(Regexp('stuff'))\n }", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "const totallyValidatesEmails = /\\S+@(\\S+\\.)+\\S+/\n if (typeof totallyValidatesEmails === 'object') {\n runSomethingThatExists(Regexp('stuff'))\n }" + } + ] + } + ] + }, + { + code: "!new RegExp('^Hey, ', 'u') && new RegExp('jk$') && ~new RegExp('^Sup, ') || new RegExp('hi') + new RegExp('person') === -new RegExp('hi again') ? 5 * new RegExp('abc') : 'notregbutstring'", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "!/^Hey, /u && new RegExp('jk$') && ~new RegExp('^Sup, ') || new RegExp('hi') + new RegExp('person') === -new RegExp('hi again') ? 5 * new RegExp('abc') : 'notregbutstring'" + } + ] + }, + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "!new RegExp('^Hey, ', 'u') && /jk$/ && ~new RegExp('^Sup, ') || new RegExp('hi') + new RegExp('person') === -new RegExp('hi again') ? 5 * new RegExp('abc') : 'notregbutstring'" + } + ] + }, + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "!new RegExp('^Hey, ', 'u') && new RegExp('jk$') && ~/^Sup, / || new RegExp('hi') + new RegExp('person') === -new RegExp('hi again') ? 5 * new RegExp('abc') : 'notregbutstring'" + } + ] + }, + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "!new RegExp('^Hey, ', 'u') && new RegExp('jk$') && ~new RegExp('^Sup, ') || /hi/ + new RegExp('person') === -new RegExp('hi again') ? 5 * new RegExp('abc') : 'notregbutstring'" + } + ] + }, + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "!new RegExp('^Hey, ', 'u') && new RegExp('jk$') && ~new RegExp('^Sup, ') || new RegExp('hi') + /person/ === -new RegExp('hi again') ? 5 * new RegExp('abc') : 'notregbutstring'" + } + ] + }, + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "!new RegExp('^Hey, ', 'u') && new RegExp('jk$') && ~new RegExp('^Sup, ') || new RegExp('hi') + new RegExp('person') === -/hi again/ ? 5 * new RegExp('abc') : 'notregbutstring'" + } + ] + }, + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "!new RegExp('^Hey, ', 'u') && new RegExp('jk$') && ~new RegExp('^Sup, ') || new RegExp('hi') + new RegExp('person') === -new RegExp('hi again') ? 5 * /abc/ : 'notregbutstring'" + } + ] + } + ] + }, + { + code: "#!/usr/bin/sh\n RegExp(\"foo\")", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "#!/usr/bin/sh\n /foo/" + } + ] + } + ] + }, + { + code: "async function abc(){await new RegExp(\"foo\")}", + parserOptions: { + ecmaVersion: 8, + sourceType: "module" + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "function* abc(){yield new RegExp(\"foo\")}", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "function* abc(){yield* new RegExp(\"foo\")}", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "function* abc(){yield* /foo/}" + } + ] + } + ] + }, + { + code: "console.log({ ...new RegExp('a') })", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "console.log({ .../a/ })" + } + ] + } + ] + }, + { + code: "delete RegExp('a');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "delete /a/;" + } + ] + } + ] + }, + { + code: "void RegExp('a');", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "void /a/;" + } + ] + } + ] + }, + { + code: "new RegExp(\"\\\\S+@(\\\\S+\\\\.)+\\\\S+\")**RegExp('a')", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\S+@(\\S+\\.)+\\S+/**RegExp('a')" + } + ] + }, + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "new RegExp(\"\\\\S+@(\\\\S+\\\\.)+\\\\S+\")**/a/" + } + ] + } + ] + }, + { + code: "new RegExp(\"\\\\S+@(\\\\S+\\\\.)+\\\\S+\")%RegExp('a')", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\S+@(\\S+\\.)+\\S+/%RegExp('a')" + } + ] + }, + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "new RegExp(\"\\\\S+@(\\\\S+\\\\.)+\\\\S+\")%/a/" + } + ] + } + ] + }, + { + code: "a in RegExp('abc')", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "a in /abc/" + } + ] + } + ] + }, + { + code: "\n /abc/ == new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n /abc/ == /cba/;\n " + } + ] + } + ] + }, + { + code: "\n /abc/ === new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n /abc/ === /cba/;\n " + } + ] + } + ] + }, + { + code: "\n /abc/ != new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n /abc/ != /cba/;\n " + } + ] + } + ] + }, + { + code: "\n /abc/ !== new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n /abc/ !== /cba/;\n " + } + ] + } + ] + }, + { + code: "\n /abc/ > new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n /abc/ > /cba/;\n " + } + ] + } + ] + }, + { + code: "\n /abc/ < new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n /abc/ < /cba/;\n " + } + ] + } + ] + }, + { + code: "\n /abc/ >= new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n /abc/ >= /cba/;\n " + } + ] + } + ] + }, + { + code: "\n /abc/ <= new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n /abc/ <= /cba/;\n " + } + ] + } + ] + }, + { + code: "\n /abc/ << new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n /abc/ << /cba/;\n " + } + ] + } + ] + }, + { + code: "\n /abc/ >> new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n /abc/ >> /cba/;\n " + } + ] + } + ] + }, + { + code: "\n /abc/ >>> new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n /abc/ >>> /cba/;\n " + } + ] + } + ] + }, + { + code: "\n /abc/ ^ new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n /abc/ ^ /cba/;\n " + } + ] + } + ] + }, + { + code: "\n /abc/ & new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n /abc/ & /cba/;\n " + } + ] + } + ] + }, + { + code: "\n /abc/ | new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n /abc/ | /cba/;\n " + } + ] + } + ] + }, + { + code: "\n null ?? new RegExp('blah')\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n null ?? /blah/\n " + } + ] + } + ] + }, + { + code: "\n abc *= new RegExp('blah')\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n abc *= /blah/\n " + } + ] + } + ] + }, + { + code: "\n console.log({a: new RegExp('sup')})\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n console.log({a: /sup/})\n " + } + ] + } + ] + }, + { + code: "\n console.log(() => {new RegExp('sup')})\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n console.log(() => {/sup/})\n " + } + ] + } + ] + }, + { + code: "\n function abc() {new RegExp('sup')}\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n function abc() {/sup/}\n " + } + ] + } + ] + }, + { + code: "\n function abc() {return new RegExp('sup')}\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n function abc() {return /sup/}\n " + } + ] + } + ] + }, + { + code: "\n abc <<= new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n abc <<= /cba/;\n " + } + ] + } + ] + }, + { + code: "\n abc >>= new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n abc >>= /cba/;\n " + } + ] + } + ] + }, + { + code: "\n abc >>>= new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n abc >>>= /cba/;\n " + } + ] + } + ] + }, + { + code: "\n abc ^= new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n abc ^= /cba/;\n " + } + ] + } + ] + }, + { + code: "\n abc &= new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n abc &= /cba/;\n " + } + ] + } + ] + }, + { + code: "\n abc |= new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n abc |= /cba/;\n " + } + ] + } + ] + }, + { + code: "\n abc ??= new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n abc ??= /cba/;\n " + } + ] + } + ] + }, + { + code: "\n abc &&= new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n abc &&= /cba/;\n " + } + ] + } + ] + }, + { + code: "\n abc ||= new RegExp('cba');\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n abc ||= /cba/;\n " + } + ] + } + ] + }, + { + code: "\n abc **= new RegExp('blah')\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n abc **= /blah/\n " + } + ] + } + ] + }, + { + code: "\n abc /= new RegExp('blah')\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n abc /= /blah/\n " + } + ] + } + ] + }, + { + code: "\n abc += new RegExp('blah')\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n abc += /blah/\n " + } + ] + } + ] + }, + { + code: "\n abc -= new RegExp('blah')\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n abc -= /blah/\n " + } + ] + } + ] + }, + { + code: "\n abc %= new RegExp('blah')\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n abc %= /blah/\n " + } + ] + } + ] + }, + { + code: "\n () => new RegExp('blah')\n ", + parserOptions: { + ecmaVersion: 2021 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n () => /blah/\n " + } + ] + } + ] + }, + { + code: "a/RegExp(\"foo\")in b", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "a/ /foo/ in b" + } + ] + } + ] + }, + { + code: "a/RegExp(\"foo\")instanceof b", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "a/ /foo/ instanceof b" + } + ] + } + ] + }, + { + code: "do RegExp(\"foo\")\nwhile (true);", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "do /foo/\nwhile (true);" + } + ] + } + ] + }, + { + code: "for(let i;i<5;i++) { break\nnew RegExp('search')}", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "for(let i;i<5;i++) { break\n/search/}" + } + ] + } + ] + }, + { + code: "for(let i;i<5;i++) { continue\nnew RegExp('search')}", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "for(let i;i<5;i++) { continue\n/search/}" + } + ] + } + ] + }, + { + code: "\n switch (value) {\n case \"possibility\":\n console.log('possibility matched')\n case RegExp('myReg').toString():\n console.log('matches a regexp\\' toString value')\n break;\n }\n ", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "\n switch (value) {\n case \"possibility\":\n console.log('possibility matched')\n case /myReg/.toString():\n console.log('matches a regexp\\' toString value')\n break;\n }\n " + } + ] + } + ] + }, + { + code: "throw new RegExp('abcdefg') // fail with a regular expression", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "throw /abcdefg/ // fail with a regular expression" + } + ] + } + ] + }, + { + code: "for (value of new RegExp('something being searched')) { console.log(value) }", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "(async function(){for await (value of new RegExp('something being searched')) { console.log(value) }})()", + parserOptions: { + ecmaVersion: 2018 + }, + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "for (value in new RegExp('something being searched')) { console.log(value) }", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "for (value in /something being searched/) { console.log(value) }" + } + ] + } + ] + }, + { + code: "if (condition1 && condition2) new RegExp('avalue').test(str);", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] + }, + { + code: "debugger\nnew RegExp('myReg')", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "debugger\n/myReg/" + } + ] + } + ] + }, + { + code: "RegExp(\"\\\\\\n\")", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\n/" + } + ] + } + ] + }, + { + code: "RegExp(\"\\\\\\t\")", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\t/" + } + ] + } + ] + }, + { + code: "RegExp(\"\\\\\\f\")", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\f/" + } + ] + } + ] + }, + { + code: "RegExp(\"\\\\\\v\")", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\v/" + } + ] + } + ] + }, + { + code: "RegExp(\"\\\\\\r\")", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\r/" + } + ] + } + ] + }, + { + code: "new RegExp(\"\t\")", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\t/" + } + ] + } + ] + }, + { + code: "new RegExp(\"/\")", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\//" + } + ] + } + ] + }, + { + code: "new RegExp(\"\\.\")", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/./" + } + ] + } + ] + }, + { + code: "new RegExp(\"\\\\.\")", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\./" + } + ] + } + ] + }, + { + code: "new RegExp(\"\\\\\\n\\\\\\n\")", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\n\\n/" + } + ] + } + ] + }, + { + code: "new RegExp(\"\\\\\\n\\\\\\f\\\\\\n\")", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\n\\f\\n/" + } + ] + } + ] + }, + { + code: "new RegExp(\"\\u000A\\u000A\");", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: [ + { + messageId: "replaceWithLiteral", + output: "/\\n\\n/;" + } + ] + } + ] + }, + { + code: "new RegExp('mysafereg' /* comment explaining its safety */)", + errors: [ + { + messageId: "unexpectedRegExp", + suggestions: null + } + ] } ] });