Repository: eslint/eslint
Pull request #15421 (2021-12-12 11:57:25)

docs: Mention character classes in no-useless-escape
<!--
    Thank you for contributing!

    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

#### Prerequisites checklist

- [X] I have read the [contributing guidelines](https://github.com/eslint/eslint/blob/HEAD/CONTRIBUTING.md).

#### What is the purpose of this pull request? (put an "X" next to an item)

<!--
    The following template is intentionally not a markdown checkbox list for the reasons
    explained in https://github.com/eslint/eslint/pull/12848#issuecomment-580302888
-->

[X] Documentation update
[ ] Bug fix ([template](https://raw.githubusercontent.com/eslint/eslint/HEAD/templates/bug-report.md))
[ ] New rule ([template](https://raw.githubusercontent.com/eslint/eslint/HEAD/templates/rule-proposal.md))
[ ] Changes an existing rule ([template](https://raw.githubusercontent.com/eslint/eslint/HEAD/templates/rule-change-proposal.md))
[ ] Add autofix to a rule
[ ] Add a CLI option
[ ] Add something to the core
[ ] Other, please explain:

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->

<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->

#### What changes did you make? (Give an overview)

In regex literals, `/[\[]/` and `/[a\-]/` contain useless escapes within character classes, but these cases are not very well-known, so I’ve included them. A recent Stack Overflow question (<https://stackoverflow.com/q/70322972/4642212>) prompted this PR, but of course there’s also issue #13826 _right here_: getting a linter warning for these cases may be confusing. Therefore, I’ve explicitly mentioned this in the documentation. Note: this behavior is already part of the tests.

#### Is there anything you'd like reviewers to focus on?

Nothing specific.

linux-foundation-easycla[bot]: <a href="https://api.easycla.lfx.linuxfoundation.org/v2/repository-provider/github/sign/19114526/11061773/15421/#/?version=2"><img src="https://s3.amazonaws.com/cla-project-logo-prod/cla-not-signed.svg" alt="CLA Not Signed" align="left" height="28" width="328" ></a><br/><br /><ul><li><a href='https://api.easycla.lfx.linuxfoundation.org/v2/repository-provider/github/sign/19114526/11061773/15421/#/?version=2' target='_blank'>:x:</a> - Sebastian Simon The commit (46c39a4f7a08ab7261248ee64c8d8b6424e69c69) is not authorized under a signed CLA. <a href='https://api.easycla.lfx.linuxfoundation.org/v2/repository-provider/github/sign/19114526/11061773/15421/#/?version=2' target='_blank'>Please click here to be authorized</a>. For further assistance with EasyCLA, <a href='https://jira.linuxfoundation.org/servicedesk/customer/portal/4' target='_blank'>please submit a support request ticket</a>.</li></ul>

Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 1087ab4e4..5d9aa9536 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -31,9 +31,9 @@ jobs:
         node: [17.x, 16.x, 14.x, 12.x, "12.22.0"]
         include:
         - os: windows-latest
-          node: "12.x"
+          node: "16.x"
         - os: macOS-latest
-          node: "12.x"
+          node: "16.x"
     runs-on: ${{ matrix.os }}
     steps:
     - uses: actions/checkout@v2
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d1190eb26..a65d12a17 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,19 @@
+v8.5.0 - December 17, 2021
+
+* [`7d832d4`](https://github.com/eslint/eslint/commit/7d832d4ad55f3c987aca8d858809cbcb77697648) fix: improve `prefer-template` fixer (#15230) (Nitin Kumar)
+* [`94e77a6`](https://github.com/eslint/eslint/commit/94e77a693fd5124c9057320310b41e92567d7e76) feat: Suggestions support for `prefer-regex-literals` (#15077) (Yash Singh)
+* [`314c84c`](https://github.com/eslint/eslint/commit/314c84c1b83b32e75587ce7a77130eac7e2a8f49) docs: add an incorrect code example in for-direction (#15434) (Holger Jeromin)
+* [`981fb48`](https://github.com/eslint/eslint/commit/981fb48991448bec171d7d4332d7dc514252f83f) fix: do not report global references in `id-match` rule (#15420) (Nitin Kumar)
+* [`3928175`](https://github.com/eslint/eslint/commit/3928175d01c6ac2b37147b3256c56df8faf2c6c4) docs: add destructuring examples for `computed-property-spacing` (#15423) (Nitin Kumar)
+* [`225f211`](https://github.com/eslint/eslint/commit/225f2111ebcfc6bcd2d475f5261c85eb00fb0191) test: add destructuring test cases for `computed-property-spacing` (#15424) (Nitin Kumar)
+* [`f13d4a6`](https://github.com/eslint/eslint/commit/f13d4a6cf7c7ff6160be7426fc6fe02e3e37a0b7) fix: improve autofix of `prefer-object-has-own` (#15419) (Nitin Kumar)
+* [`f4559a0`](https://github.com/eslint/eslint/commit/f4559a0f7150ad7494658bd5ea846cfca5073caf) fix: add helpful message when test case has non-string code/name (#15425) (Bryan Mishkin)
+* [`a53e59e`](https://github.com/eslint/eslint/commit/a53e59eab7da52e3df095a679a6fdab74a7bce6f) docs: add more examples for `array-element-newline` rule (#15427) (Nitin Kumar)
+* [`f2c7ba6`](https://github.com/eslint/eslint/commit/f2c7ba6c34c8943dc24a1c41317d536c1a63cb36) ci: use node v16 for `macOS` and `windows` jobs (#15418) (Nitin Kumar)
+* [`eafaf52`](https://github.com/eslint/eslint/commit/eafaf52464c01072fcf7be2bd2d91cd0b3ae67d0) feat: add `prefer-object-has-own` rule (#15346) (Nitin Kumar)
+* [`74cf0a0`](https://github.com/eslint/eslint/commit/74cf0a040e1a83990d8d7eb57e1f5ce919a11ebe) docs: update CLA info (#15370) (Nitin Kumar)
+* [`e84195e`](https://github.com/eslint/eslint/commit/e84195ea39b5cf54d7a551c62671af80b859f1ac) docs: fix heading level for an option in `class-methods-use-this` rule (#15399) (Takuya Fukuju)
+
 v8.4.1 - December 6, 2021
 
 * [`234e3d9`](https://github.com/eslint/eslint/commit/234e3d98eeab8956cefb14c982b9c348c21bb2d9) fix: revert changes to reported locations in max-lines-per-function (#15397) (Milos Djermanovic)
diff --git a/docs/rules/array-element-newline.md b/docs/rules/array-element-newline.md
index cee739d74..650a00892 100644
--- a/docs/rules/array-element-newline.md
+++ b/docs/rules/array-element-newline.md
@@ -42,7 +42,12 @@ Examples of **incorrect** code for this rule with the default `"always"` option:
 
 var c = [1, 2];
 var d = [1, 2, 3];
-var e = [
+var e = [1, 2, 3
+];
+var f = [
+  1, 2, 3
+];
+var g = [
     function foo() {
         dosomething();
     }, function bar() {
@@ -63,6 +68,11 @@ var c = [1,
 var d = [1,
     2,
     3];
+var d = [
+  1, 
+  2, 
+  3
+];
 var e = [
     function foo() {
         dosomething();
@@ -109,6 +119,11 @@ var b = [1];
 var c = [1, 2];
 var d = [1, 2, 3];
 var e = [
+    1, 2, 3];
+var f = [
+  1, 2, 3
+];
+var g = [
     function foo() {
         dosomething();
     }, function bar() {
diff --git a/docs/rules/computed-property-spacing.md b/docs/rules/computed-property-spacing.md
index 3fdd70ce0..903642391 100644
--- a/docs/rules/computed-property-spacing.md
+++ b/docs/rules/computed-property-spacing.md
@@ -48,6 +48,9 @@ obj[foo ]
 obj[ 'foo']
 var x = {[ b ]: a}
 obj[foo[ bar ]]
+
+const { [ a ]: someProp } = obj;
+({ [ b ]: anotherProp } = anotherObj);
 ```
 
 Examples of **correct** code for this rule with the default `"never"` option:
@@ -60,6 +63,9 @@ obj[foo]
 obj['foo']
 var x = {[b]: a}
 obj[foo[bar]]
+
+const { [a]: someProp } = obj;
+({ [b]: anotherProp } = anotherObj);
 ```
 
 ### always
@@ -76,6 +82,8 @@ obj[ foo]
 obj['foo' ]
 obj[foo[ bar ]]
 var x = {[ b]: a}
+const { [a]: someProp } = obj;
+({ [b ]: anotherProp } = anotherObj);
 ```
 
 Examples of **correct** code for this rule with the `"always"` option:
@@ -88,6 +96,8 @@ obj[ foo ]
 obj[ 'foo' ]
 var x = {[ b ]: a}
 obj[ foo[ bar ] ]
+const { [ a ]: someProp } = obj;
+({ [ b ]: anotherProp } = anotherObj);
 ```
 
 #### enforceForClassMembers
diff --git a/docs/rules/for-direction.md b/docs/rules/for-direction.md
index be24f7f73..ecacabc2c 100644
--- a/docs/rules/for-direction.md
+++ b/docs/rules/for-direction.md
@@ -13,6 +13,9 @@ for (var i = 0; i < 10; i--) {
 
 for (var i = 10; i >= 0; i++) {
 }
+
+for (var i = 0; i > 10; i++) {
+}
 ```
 
 Examples of **correct** code for this rule:
diff --git a/docs/rules/no-useless-escape.md b/docs/rules/no-useless-escape.md
index 6088c5cb0..1f54b588d 100644
--- a/docs/rules/no-useless-escape.md
+++ b/docs/rules/no-useless-escape.md
@@ -26,7 +26,8 @@ Examples of **incorrect** code for this rule:
 `\#{foo}`;
 /\!/;
 /\@/;
-
+/[\[]/;
+/[a-z\-]/;
 ```
 
 Examples of **correct** code for this rule:
@@ -46,7 +47,9 @@ Examples of **correct** code for this rule:
 /\\/g;
 /\t/g;
 /\w\$\*\^\./;
-
+/[[]/;
+/[\]]/;
+/[a-z-]/;
 ```
 
 ## When Not To Use It
diff --git a/lib/rules/id-match.js b/lib/rules/id-match.js
index bcc07a8e3..15908da8c 100644
--- a/lib/rules/id-match.js
+++ b/lib/rules/id-match.js
@@ -67,6 +67,8 @@ module.exports = {
             onlyDeclarations = !!options.onlyDeclarations,
             ignoreDestructuring = !!options.ignoreDestructuring;
 
+        let globalScope;
+
         //--------------------------------------------------------------------------
         // Helpers
         //--------------------------------------------------------------------------
@@ -77,6 +79,19 @@ module.exports = {
         const DECLARATION_TYPES = new Set(["FunctionDeclaration", "VariableDeclarator"]);
         const IMPORT_TYPES = new Set(["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"]);
 
+        /**
+         * Checks whether the given node represents a reference to a global variable that is not declared in the source code.
+         * These identifiers will be allowed, as it is assumed that user has no control over the names of external global variables.
+         * @param {ASTNode} node `Identifier` node to check.
+         * @returns {boolean} `true` if the node is a reference to a global variable.
+         */
+        function isReferenceToGlobalVariable(node) {
+            const variable = globalScope.set.get(node.name);
+
+            return variable && variable.defs.length === 0 &&
+                variable.references.some(ref => ref.identifier === node);
+        }
+
         /**
          * Checks if a string matches the provided pattern
          * @param {string} name The string to check.
@@ -155,11 +170,19 @@ module.exports = {
 
         return {
 
+            Program() {
+                globalScope = context.getScope();
+            },
+
             Identifier(node) {
                 const name = node.name,
                     parent = node.parent,
                     effectiveParent = (parent.type === "MemberExpression") ? parent.parent : parent;
 
+                if (isReferenceToGlobalVariable(node)) {
+                    return;
+                }
+
                 if (parent.type === "MemberExpression") {
 
                     if (!checkProperties) {
diff --git a/lib/rules/prefer-object-has-own.js b/lib/rules/prefer-object-has-own.js
index dd21e95d4..19abdb315 100644
--- a/lib/rules/prefer-object-has-own.js
+++ b/lib/rules/prefer-object-has-own.js
@@ -12,6 +12,10 @@
 
 const astUtils = require("./utils/ast-utils");
 
+//------------------------------------------------------------------------------
+// Helpers
+//------------------------------------------------------------------------------
+
 /**
  * Checks if the given node is considered to be an access to a property of `Object.prototype`.
  * @param {ASTNode} node `MemberExpression` node to evaluate.
@@ -87,6 +91,17 @@ module.exports = {
                                 return null;
                             }
 
+                            const tokenJustBeforeNode = sourceCode.getTokenBefore(node.callee, { includeComments: true });
+
+                            // for https://github.com/eslint/eslint/pull/15346#issuecomment-991417335
+                            if (
+                                tokenJustBeforeNode &&
+                                tokenJustBeforeNode.range[1] === node.callee.range[0] &&
+                                !astUtils.canTokensBeAdjacent(tokenJustBeforeNode, "Object.hasOwn")
+                            ) {
+                                return fixer.replaceText(node.callee, " Object.hasOwn");
+                            }
+
                             return fixer.replaceText(node.callee, "Object.hasOwn");
                         }
                     });
diff --git a/lib/rules/prefer-regex-literals.js b/lib/rules/prefer-regex-literals.js
index afd6a0139..158f84b94 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!@#$%^&*+^_=/~`.><?,'"|:;]*$/u.test(regexContent)) {
+                            noFix = true;
+                        }
+
+                        if (sourceCode.getCommentsInside(node).length > 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/lib/rules/prefer-template.js b/lib/rules/prefer-template.js
index 953155d8f..e61eac1d6 100644
--- a/lib/rules/prefer-template.js
+++ b/lib/rules/prefer-template.js
@@ -188,7 +188,7 @@ module.exports = {
                 return sourceCode.getText(currentNode);
             }
 
-            if (isConcatenation(currentNode) && hasStringLiteral(currentNode) && hasNonStringLiteral(currentNode)) {
+            if (isConcatenation(currentNode) && hasStringLiteral(currentNode)) {
                 const plusSign = sourceCode.getFirstTokenBetween(currentNode.left, currentNode.right, token => token.value === "+");
                 const textBeforePlus = getTextBetween(currentNode.left, plusSign);
                 const textAfterPlus = getTextBetween(plusSign, currentNode.right);
diff --git a/package.json b/package.json
index 43a7138fc..fee3bf0f6 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint",
-  "version": "8.4.1",
+  "version": "8.5.0",
   "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
   "description": "An AST-based pattern checker for JavaScript.",
   "bin": {


Test patch:
diff --git a/lib/rule-tester/rule-tester.js b/lib/rule-tester/rule-tester.js
index 7f590a5ea..fe520a58a 100644
--- a/lib/rule-tester/rule-tester.js
+++ b/lib/rule-tester/rule-tester.js
@@ -216,6 +216,9 @@ function freezeDeeply(x) {
  * @returns {string} The sanitized text.
  */
 function sanitize(text) {
+    if (typeof text !== "string") {
+        return "";
+    }
     return text.replace(
         /[\u0000-\u0009\u000b-\u001a]/gu, // eslint-disable-line no-control-regex -- Escaping controls
         c => `\\u${c.codePointAt(0).toString(16).padStart(4, "0")}`
@@ -691,6 +694,13 @@ class RuleTester {
          * @private
          */
         function testValidTemplate(item) {
+            const code = typeof item === "object" ? item.code : item;
+
+            assert.ok(typeof code === "string", "Test case must specify a string value for 'code'");
+            if (item.name) {
+                assert.ok(typeof item.name === "string", "Optional test case property 'name' must be a string");
+            }
+
             const result = runRuleForItem(item);
             const messages = result.messages;
 
@@ -731,6 +741,10 @@ class RuleTester {
          * @private
          */
         function testInvalidTemplate(item) {
+            assert.ok(typeof item.code === "string", "Test case must specify a string value for 'code'");
+            if (item.name) {
+                assert.ok(typeof item.name === "string", "Optional test case property 'name' must be a string");
+            }
             assert.ok(item.errors || item.errors === 0,
                 `Did not specify errors for an invalid test of ${ruleName}`);
 
diff --git a/tests/lib/rule-tester/rule-tester.js b/tests/lib/rule-tester/rule-tester.js
index 5018a037b..c6383837d 100644
--- a/tests/lib/rule-tester/rule-tester.js
+++ b/tests/lib/rule-tester/rule-tester.js
@@ -2441,6 +2441,65 @@ describe("RuleTester", () => {
 
             return assertion;
         });
+
+        it('should throw if "name" property is not a string', () => {
+            assert.throws(() => {
+                ruleTester.run("foo", require("../../fixtures/testers/rule-tester/no-var"), {
+                    valid: [{ code: "foo", name: 123 }],
+                    invalid: [{ code: "foo" }]
+
+                });
+            }, /Optional test case property 'name' must be a string/u);
+
+            assert.throws(() => {
+                ruleTester.run("foo", require("../../fixtures/testers/rule-tester/no-var"), {
+                    valid: ["foo"],
+                    invalid: [{ code: "foo", name: 123 }]
+                });
+            }, /Optional test case property 'name' must be a string/u);
+        });
+
+        it('should throw if "code" property is not a string', () => {
+            assert.throws(() => {
+                ruleTester.run("foo", require("../../fixtures/testers/rule-tester/no-var"), {
+                    valid: [{ code: 123 }],
+                    invalid: [{ code: "foo" }]
+
+                });
+            }, /Test case must specify a string value for 'code'/u);
+
+            assert.throws(() => {
+                ruleTester.run("foo", require("../../fixtures/testers/rule-tester/no-var"), {
+                    valid: [123],
+                    invalid: [{ code: "foo" }]
+
+                });
+            }, /Test case must specify a string value for 'code'/u);
+
+            assert.throws(() => {
+                ruleTester.run("foo", require("../../fixtures/testers/rule-tester/no-var"), {
+                    valid: ["foo"],
+                    invalid: [{ code: 123 }]
+                });
+            }, /Test case must specify a string value for 'code'/u);
+        });
+
+        it('should throw if "code" property is missing', () => {
+            assert.throws(() => {
+                ruleTester.run("foo", require("../../fixtures/testers/rule-tester/no-var"), {
+                    valid: [{ }],
+                    invalid: [{ code: "foo" }]
+
+                });
+            }, /Test case must specify a string value for 'code'/u);
+
+            assert.throws(() => {
+                ruleTester.run("foo", require("../../fixtures/testers/rule-tester/no-var"), {
+                    valid: ["foo"],
+                    invalid: [{ }]
+                });
+            }, /Test case must specify a string value for 'code'/u);
+        });
     });
 
     // https://github.com/eslint/eslint/issues/11615
diff --git a/tests/lib/rules/computed-property-spacing.js b/tests/lib/rules/computed-property-spacing.js
index eff0c0a73..35533d9e6 100644
--- a/tests/lib/rules/computed-property-spacing.js
+++ b/tests/lib/rules/computed-property-spacing.js
@@ -265,7 +265,30 @@ ruleTester.run("computed-property-spacing", rule, {
             ].join("\n"),
             options: ["never"],
             parserOptions: { ecmaVersion: 6 }
+        },
+
+        // Destructuring Assignment
+        {
+            code: "const { [a]: someProp } = obj;",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "({ [a]: someProp } = obj);",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "const { [ a ]: someProp } = obj;",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "({ [ a ]: someProp } = obj);",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 6 }
         }
+
     ],
 
     invalid: [
@@ -2062,6 +2085,66 @@ ruleTester.run("computed-property-spacing", rule, {
                 { messageId: "unexpectedSpaceAfter", data: { tokenValue: "[" } },
                 { messageId: "unexpectedSpaceBefore", data: { tokenValue: "]" } }
             ]
+        },
+
+        // Destructuring Assignment
+        {
+            code: "const { [ a]: someProp } = obj;",
+            output: "const { [a]: someProp } = obj;",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 2022 },
+            errors: [
+                { messageId: "unexpectedSpaceAfter", data: { tokenValue: "[" } }
+            ]
+        },
+        {
+            code: "const { [a ]: someProp } = obj;",
+            output: "const { [a]: someProp } = obj;",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 2022 },
+            errors: [
+                { messageId: "unexpectedSpaceBefore", data: { tokenValue: "]" } }
+            ]
+        },
+        {
+            code: "const { [ a ]: someProp } = obj;",
+            output: "const { [a]: someProp } = obj;",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 2022 },
+            errors: [
+                { messageId: "unexpectedSpaceAfter", data: { tokenValue: "[" } },
+                { messageId: "unexpectedSpaceBefore", data: { tokenValue: "]" } }
+            ]
+        },
+        {
+            code: "({ [ a ]: someProp } = obj);",
+            output: "({ [a]: someProp } = obj);",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 2022 },
+            errors: [
+                { messageId: "unexpectedSpaceAfter", data: { tokenValue: "[" } },
+                { messageId: "unexpectedSpaceBefore", data: { tokenValue: "]" } }
+            ]
+        },
+        {
+            code: "const { [a]: someProp } = obj;",
+            output: "const { [ a ]: someProp } = obj;",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 2022 },
+            errors: [
+                { messageId: "missingSpaceAfter", data: { tokenValue: "[" } },
+                { messageId: "missingSpaceBefore", data: { tokenValue: "]" } }
+            ]
+        },
+        {
+            code: "({ [a]: someProp } = obj);",
+            output: "({ [ a ]: someProp } = obj);",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 2022 },
+            errors: [
+                { messageId: "missingSpaceAfter", data: { tokenValue: "[" } },
+                { messageId: "missingSpaceBefore", data: { tokenValue: "]" } }
+            ]
         }
     ]
 });
diff --git a/tests/lib/rules/id-match.js b/tests/lib/rules/id-match.js
index d1fad2ecb..2f48a4b2d 100644
--- a/tests/lib/rules/id-match.js
+++ b/tests/lib/rules/id-match.js
@@ -185,6 +185,19 @@ ruleTester.run("id-match", rule, {
             }]
         },
 
+        // Should not report for global references - https://github.com/eslint/eslint/issues/15395
+        {
+            code: `
+            const foo = Object.keys(bar);
+            const a = Array.from(b);
+            const bar = () => Array;
+            `,
+            options: ["^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$", {
+                properties: true
+            }],
+            parserOptions: { ecmaVersion: 2022 }
+        },
+
         // Class Methods
         {
             code: "class x { foo() {} }",
@@ -641,6 +654,76 @@ ruleTester.run("id-match", rule, {
             ]
         },
 
+        // https://github.com/eslint/eslint/issues/15395
+        {
+            code: `
+            const foo_variable = 1;
+            class MyClass {
+            }
+            let a = new MyClass();
+            let b = {id: 1};
+            let c = Object.keys(b);
+            let d = Array.from(b);
+            let e = (Object) => Object.keys(obj, prop); // not global Object
+            let f = (Array) => Array.from(obj, prop); // not global Array
+            foo.Array = 5; // not global Array
+            `,
+            options: ["^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$", {
+                properties: true
+            }],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                {
+                    message: "Identifier 'foo_variable' does not match the pattern '^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$'.",
+                    type: "Identifier",
+                    line: 2,
+                    column: 19
+                },
+                {
+                    message: "Identifier 'MyClass' does not match the pattern '^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$'.",
+                    type: "Identifier",
+                    line: 3,
+                    column: 19
+                },
+
+                // let e = (Object) => Object.keys(obj, prop)
+                {
+                    message: "Identifier 'Object' does not match the pattern '^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$'.",
+                    type: "Identifier",
+                    line: 9,
+                    column: 22
+                },
+                {
+                    message: "Identifier 'Object' does not match the pattern '^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$'.",
+                    type: "Identifier",
+                    line: 9,
+                    column: 33
+                },
+
+                // let f =(Array) => Array.from(obj, prop);
+                {
+                    message: "Identifier 'Array' does not match the pattern '^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$'.",
+                    type: "Identifier",
+                    line: 10,
+                    column: 22
+                },
+                {
+                    message: "Identifier 'Array' does not match the pattern '^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$'.",
+                    type: "Identifier",
+                    line: 10,
+                    column: 32
+                },
+
+                // foo.Array = 5;
+                {
+                    message: "Identifier 'Array' does not match the pattern '^\\$?[a-z]+([A-Z0-9][a-z0-9]+)*$'.",
+                    type: "Identifier",
+                    line: 11,
+                    column: 17
+                }
+            ]
+        },
+
         // Class Methods
         {
             code: "class x { _foo() {} }",
diff --git a/tests/lib/rules/prefer-object-has-own.js b/tests/lib/rules/prefer-object-has-own.js
index a34cf7745..d58f7f5c2 100644
--- a/tests/lib/rules/prefer-object-has-own.js
+++ b/tests/lib/rules/prefer-object-has-own.js
@@ -224,6 +224,17 @@ ruleTester.run("prefer-object-has-own", rule, {
                 endColumn: 61
             }]
         },
+        {
+            code: "const hasProperty={}.hasOwnProperty.call(object, property);",
+            output: "const hasProperty=Object.hasOwn(object, property);",
+            errors: [{
+                messageId: "useHasOwn",
+                line: 1,
+                column: 19,
+                endLine: 1,
+                endColumn: 59
+            }]
+        },
         {
             code: "const hasProperty = (( {}.hasOwnProperty.call(object, property) ));",
             output: "const hasProperty = (( Object.hasOwn(object, property) ));",
@@ -279,6 +290,107 @@ ruleTester.run("prefer-object-has-own", rule, {
                 endColumn: 63
             }]
         },
+
+        // https://github.com/eslint/eslint/pull/15346#issuecomment-991417335
+        {
+            code: "function foo(){return{}.hasOwnProperty.call(object, property)}",
+            output: "function foo(){return Object.hasOwn(object, property)}",
+            errors: [{
+                messageId: "useHasOwn",
+                line: 1,
+                column: 22,
+                endLine: 1,
+                endColumn: 62
+            }]
+        },
+        {
+            code: "function foo(){return/*comment*/{}.hasOwnProperty.call(object, property)}",
+            output: "function foo(){return/*comment*/Object.hasOwn(object, property)}",
+            errors: [{
+                messageId: "useHasOwn",
+                line: 1,
+                column: 33,
+                endLine: 1,
+                endColumn: 73
+            }]
+        },
+        {
+            code: "async function foo(){return await{}.hasOwnProperty.call(object, property)}",
+            output: "async function foo(){return await Object.hasOwn(object, property)}",
+            errors: [{
+                messageId: "useHasOwn",
+                line: 1,
+                column: 34,
+                endLine: 1,
+                endColumn: 74
+            }]
+        },
+        {
+            code: "async function foo(){return await/*comment*/{}.hasOwnProperty.call(object, property)}",
+            output: "async function foo(){return await/*comment*/Object.hasOwn(object, property)}",
+            errors: [{
+                messageId: "useHasOwn",
+                line: 1,
+                column: 45,
+                endLine: 1,
+                endColumn: 85
+            }]
+        },
+        {
+            code: "for (const x of{}.hasOwnProperty.call(object, property).toString());",
+            output: "for (const x of Object.hasOwn(object, property).toString());",
+            errors: [{
+                messageId: "useHasOwn",
+                line: 1,
+                column: 16,
+                endLine: 1,
+                endColumn: 56
+            }]
+        },
+        {
+            code: "for (const x of/*comment*/{}.hasOwnProperty.call(object, property).toString());",
+            output: "for (const x of/*comment*/Object.hasOwn(object, property).toString());",
+            errors: [{
+                messageId: "useHasOwn",
+                line: 1,
+                column: 27,
+                endLine: 1,
+                endColumn: 67
+            }]
+        },
+        {
+            code: "for (const x in{}.hasOwnProperty.call(object, property).toString());",
+            output: "for (const x in Object.hasOwn(object, property).toString());",
+            errors: [{
+                messageId: "useHasOwn",
+                line: 1,
+                column: 16,
+                endLine: 1,
+                endColumn: 56
+            }]
+        },
+        {
+            code: "for (const x in/*comment*/{}.hasOwnProperty.call(object, property).toString());",
+            output: "for (const x in/*comment*/Object.hasOwn(object, property).toString());",
+            errors: [{
+                messageId: "useHasOwn",
+                line: 1,
+                column: 27,
+                endLine: 1,
+                endColumn: 67
+            }]
+        },
+        {
+            code: "function foo(){return({}.hasOwnProperty.call)(object, property)}",
+            output: "function foo(){return(Object.hasOwn)(object, property)}",
+            errors: [{
+                messageId: "useHasOwn",
+                line: 1,
+                column: 22,
+                endLine: 1,
+                endColumn: 64
+            }]
+        },
         {
             code: "Object['prototype']['hasOwnProperty']['call'](object, property);",
             output: "Object.hasOwn(object, property);",
diff --git a/tests/lib/rules/prefer-regex-literals.js b/tests/lib/rules/prefer-regex-literals.js
index ccd88ae74..f2982cbfb 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
+                }
+            ]
         }
     ]
 });
diff --git a/tests/lib/rules/prefer-template.js b/tests/lib/rules/prefer-template.js
index eea0255f1..a89a36a9d 100644
--- a/tests/lib/rules/prefer-template.js
+++ b/tests/lib/rules/prefer-template.js
@@ -223,6 +223,187 @@ ruleTester.run("prefer-template", rule, {
             code: "foo + '\\0'",
             output: "`${foo  }\\0`",
             errors
+        },
+
+        // https://github.com/eslint/eslint/issues/15083
+        {
+            code: `"default-src 'self' https://*.google.com;"
+            + "frame-ancestors 'none';"
+            + "report-to " + foo + ";"`,
+            output: `\`default-src 'self' https://*.google.com;\`
+            + \`frame-ancestors 'none';\`
+            + \`report-to \${  foo  };\``,
+            errors
+        },
+        {
+            code: "'a' + 'b' + foo",
+            output: "`a` + `b${  foo}`",
+            errors
+        },
+        {
+            code: "'a' + 'b' + foo + 'c' + 'd'",
+            output: "`a` + `b${  foo  }c` + `d`",
+            errors
+        },
+        {
+            code: "'a' + 'b + c' + foo + 'd' + 'e'",
+            output: "`a` + `b + c${  foo  }d` + `e`",
+            errors
+        },
+        {
+            code: "'a' + 'b' + foo + ('c' + 'd')",
+            output: "`a` + `b${  foo  }c` + `d`",
+            errors
+        },
+        {
+            code: "'a' + 'b' + foo + ('a' + 'b')",
+            output: "`a` + `b${  foo  }a` + `b`",
+            errors
+        },
+        {
+            code: "'a' + 'b' + foo + ('c' + 'd') + ('e' + 'f')",
+            output: "`a` + `b${  foo  }c` + `d` + `e` + `f`",
+            errors
+        },
+        {
+            code: "foo + ('a' + 'b') + ('c' + 'd')",
+            output: "`${foo  }a` + `b` + `c` + `d`",
+            errors
+        },
+        {
+            code: "'a' + foo + ('b' + 'c') + ('d' + bar + 'e')",
+            output: "`a${  foo  }b` + `c` + `d${  bar  }e`",
+            errors
+        },
+        {
+            code: "foo + ('b' + 'c') + ('d' + bar + 'e')",
+            output: "`${foo  }b` + `c` + `d${  bar  }e`",
+            errors
+        },
+        {
+            code: "'a' + 'b' + foo + ('c' + 'd' + 'e')",
+            output: "`a` + `b${  foo  }c` + `d` + `e`",
+            errors
+        },
+        {
+            code: "'a' + 'b' + foo + ('c' + bar + 'd')",
+            output: "`a` + `b${  foo  }c${  bar  }d`",
+            errors
+        },
+        {
+            code: "'a' + 'b' + foo + ('c' + bar + ('d' + 'e') + 'f')",
+            output: "`a` + `b${  foo  }c${  bar  }d` + `e` + `f`",
+            errors
+        },
+        {
+            code: "'a' + 'b' + foo + ('c' + bar + 'e') + 'f' + test",
+            output: "`a` + `b${  foo  }c${  bar  }e` + `f${  test}`",
+            errors
+        },
+        {
+            code: "'a' + foo + ('b' + bar + 'c') + ('d' + test)",
+            output: "`a${  foo  }b${  bar  }c` + `d${  test}`",
+            errors
+        },
+        {
+            code: "'a' + foo + ('b' + 'c') + ('d' + bar)",
+            output: "`a${  foo  }b` + `c` + `d${  bar}`",
+            errors
+        },
+        {
+            code: "foo + ('a' + bar + 'b') + 'c' + test",
+            output: "`${foo  }a${  bar  }b` + `c${  test}`",
+            errors
+        },
+        {
+            code: "'a' + '`b`' + c",
+            output: "`a` + `\\`b\\`${  c}`",
+            errors
+        },
+        {
+            code: "'a' + '`b` + `c`' + d",
+            output: "`a` + `\\`b\\` + \\`c\\`${  d}`",
+            errors
+        },
+        {
+            code: "'a' + b + ('`c`' + '`d`')",
+            output: "`a${  b  }\\`c\\`` + `\\`d\\``",
+            errors
+        },
+        {
+            code: "'`a`' + b + ('`c`' + '`d`')",
+            output: "`\\`a\\`${  b  }\\`c\\`` + `\\`d\\``",
+            errors
+        },
+        {
+            code: "foo + ('`a`' + bar + '`b`') + '`c`' + test",
+            output: "`${foo  }\\`a\\`${  bar  }\\`b\\`` + `\\`c\\`${  test}`",
+            errors
+        },
+        {
+            code: "'a' + ('b' + 'c') + d",
+            output: "`a` + `b` + `c${  d}`",
+            errors
+        },
+        {
+            code: "'a' + ('`b`' + '`c`') + d",
+            output: "`a` + `\\`b\\`` + `\\`c\\`${  d}`",
+            errors
+        },
+        {
+            code: "a + ('b' + 'c') + d",
+            output: "`${a  }b` + `c${  d}`",
+            errors
+        },
+        {
+            code: "a + ('b' + 'c') + (d + 'e')",
+            output: "`${a  }b` + `c${  d  }e`",
+            errors
+        },
+        {
+            code: "a + ('`b`' + '`c`') + d",
+            output: "`${a  }\\`b\\`` + `\\`c\\`${  d}`",
+            errors
+        },
+        {
+            code: "a + ('`b` + `c`' + '`d`') + e",
+            output: "`${a  }\\`b\\` + \\`c\\`` + `\\`d\\`${  e}`",
+            errors
+        },
+        {
+            code: "'a' + ('b' + 'c' + 'd') + e",
+            output: "`a` + `b` + `c` + `d${  e}`",
+            errors
+        },
+        {
+            code: "'a' + ('b' + 'c' + 'd' + (e + 'f') + 'g' +'h' + 'i') + j",
+            output: "`a` + `b` + `c` + `d${  e  }fg` +`h` + `i${  j}`",
+            errors
+        },
+        {
+            code: "a + (('b' + 'c') + 'd')",
+            output: "`${a  }b` + `c` + `d`",
+            errors
+        },
+        {
+            code: "(a + 'b') + ('c' + 'd') + e",
+            output: "`${a  }b` + `c` + `d${  e}`",
+            errors
+        },
+        {
+            code: "var foo = \"Hello \" + \"world \" + \"another \" + test",
+            output: "var foo = `Hello ` + `world ` + `another ${  test}`",
+            errors
+        },
+        {
+            code: "'Hello ' + '\"world\" ' + test",
+            output: "`Hello ` + `\"world\" ${  test}`",
+            errors
+        },
+        {
+            code: "\"Hello \" + \"'world' \" + test",
+            output: "`Hello ` + `'world' ${  test}`",
+            errors
         }
     ]
 });