Repository: eslint/eslint
Pull request #12490 (2019-10-24 22:10:41)

Breaking: Check assignment targets in no-extra-parens
<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

**What is the purpose of this pull request? (put an "X" next to item)**

[X] Changes an existing rule

<!--
    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.)
-->

**What rule do you want to change?**

no-extra-parens

**Does this change cause the rule to produce more or fewer warnings?**

more

**How will the change be implemented? (New option, new default behavior, etc.)?**

new default behavior

**Please provide some example code that this change will affect:**

```js
// left-hand side of assignments
(a) = b;
(a) += b;
(a.b) = c;

// left-hand side of default assignments
[(a) = b] = [];
[(a.b) = c] = [];
({ a: (b) = c } = {});
({ a: (b.c) = d } = {});

// array pattern elements and rest element
[(a)] = [];
[(a.b)] = [];
[...(a)] = [];
[...(a.b)] = [];

// object pattern property values and rest property
({ a: (b) } = {});
({ a: (b.c) } = {});
({ ...(a) } = {});   // these currently aren't allowed in acorn, there is an open issue
({ ...(a.b) } = {});


```

**What does the rule currently do for this code?**

No errors.

**What will the rule do after it's changed?**

All lines will be errors.

<!--
    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)**

Check missed nodes.

**Is there anything you'd like reviewers to focus on?**

Core rules usually don't assume that the syntax can be invalid, and a function like `canBeAssignmentTarget` shouldn't be necessary. But, default assignments (in particular, parenthesised assignments that look like default assignments) seem to a be a common problem for parsers.

For instance, the following simple examples are actually invalid syntax, but interpreted as a valid code by acorn, espree, babel, typescript-eslint and the majority of parsers that can be found on the ast-explorer site:

```js
(a = b) = c; // invalid syntax

[(a = b) = c] = []; // invalid syntax
```

Removing these parens would change semantics, and that's why all checks added in this PR use the `canBeAssignmentTarget` function. This is unusual, but seems to be a safe solution at this moment. Is it okay?

Also, please verify that the examples in the test cases are valid syntax.



kaicataldo: I think this change makes sense. Do we want to add this in v7.0.0 since it will increase warnings?
mdjermanovic: Rebased
mdjermanovic: > I think this change makes sense. Do we want to add this in v7.0.0 since it will increase warnings?

Some changes of a similar kind like #11952, #11973, #11909 were semver-minor. 

On the other hand #12302, which looked like a minor change at the moment, based on feedback ended up with a subsequent option in #12436.

So it indeed might be safe to add this within `v.7.0.0` releases. Perhaps we should label this as `Breaking`? 
kaicataldo: > So it indeed might be safe to add this within v.7.0.0 releases. Perhaps we should label this as Breaking?

I think this makes sense. Might as well take advantage of doing a major release soon :)
mdjermanovic: Changed the title (there are now multiple commits) to `Breaking:`

That's how I understood, feel free to change it back on deploy if I was wrong :-)
ljharb: Instead of making it breaking, could it be an option whose default is flipped in the next major?
mdjermanovic: Maybe breaking with the option to restore the previous behavior. All other options in this rule are `true` (= doesn't prevent warnings) by default.

If there is a real need for someone to allow parens just in these particular cases?
ljharb: No idea, but it feels like it’s always better to ship everything as minor behind an option so that majors are primarily just flipping defaults - it gives a way to test the new stuff without a major, and an easy way to avoid the breakage and thus allow those impacted to trivially upgrade to the new major.

Patch:
diff --git a/.eslintrc.js b/.eslintrc.js
index e57ac92af..c347bf858 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -19,6 +19,9 @@ module.exports = {
         "eslint",
         "plugin:eslint-plugin/recommended"
     ],
+    parserOptions: {
+        ecmaVersion: 2020
+    },
     rules: {
         "eslint-plugin/consistent-output": "error",
         "eslint-plugin/no-deprecated-context-methods": "error",
diff --git a/docs/rules/array-callback-return.md b/docs/rules/array-callback-return.md
index 34ffeffce..44dccdeff 100644
--- a/docs/rules/array-callback-return.md
+++ b/docs/rules/array-callback-return.md
@@ -21,6 +21,7 @@ This rule finds callback functions of the following methods, then checks usage o
 * [`Array.prototype.filter`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.filter)
 * [`Array.prototype.find`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.find)
 * [`Array.prototype.findIndex`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.findindex)
+* [`Array.prototype.flatMap`](https://www.ecma-international.org/ecma-262/10.0/#sec-array.prototype.flatmap)
 * [`Array.prototype.map`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.map)
 * [`Array.prototype.reduce`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.reduce)
 * [`Array.prototype.reduceRight`](https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.reduceright)
diff --git a/docs/rules/default-case-last.md b/docs/rules/default-case-last.md
new file mode 100644
index 000000000..c9eedbeec
--- /dev/null
+++ b/docs/rules/default-case-last.md
@@ -0,0 +1,125 @@
+# Enforce default clauses in switch statements to be last (default-case-last)
+
+A `switch` statement can optionally have a `default` clause.
+
+If present, it's usually the last clause, but it doesn't need to be. It is also allowed to put the `default` clause before all `case` clauses, or anywhere between. The behavior is mostly the same as if it was the last clause. The `default` block will be still executed only if there is no match in the `case` clauses (including those defined after the `default`), but there is also the ability to "fall through" from the `default` clause to the following clause in the list. However, such flow is not common and it would be confusing to the readers.
+
+Even if there is no "fall through" logic, it's still unexpected to see the `default` clause before or between the `case` clauses. By convention, it is expected to be the last clause.
+
+If a `switch` statement should have a `default` clause, it's considered a best practice to define it as the last clause.
+
+## Rule Details
+
+This rule enforces `default` clauses in `switch` statements to be last.
+
+It applies only to `switch` statements that already have a `default` clause.
+
+This rule does not enforce the existence of `default` clauses. See [default-case](default-case.md) if you also want to enforce the existence of `default` clauses in `switch` statements.
+
+Examples of **incorrect** code for this rule:
+
+```js
+/*eslint default-case-last: "error"*/
+
+switch (foo) {
+    default:
+        bar();
+        break;
+    case "a":
+        baz();
+        break;
+}
+
+switch (foo) {
+    case 1:
+        bar();
+        break;
+    default:
+        baz();
+        break;
+    case 2:
+        quux();
+        break;
+}
+
+switch (foo) {
+    case "x":
+        bar();
+        break;
+    default:
+    case "y":
+        baz();
+        break;
+}
+
+switch (foo) {
+    default:
+        break;
+    case -1:
+        bar();
+        break;
+}
+
+switch (foo) {
+  default:
+    doSomethingIfNotZero();
+  case 0:
+    doSomethingAnyway();
+}
+```
+
+Examples of **correct** code for this rule:
+
+```js
+/*eslint default-case-last: "error"*/
+
+switch (foo) {
+    case "a":
+        baz();
+        break;
+    default:
+        bar();
+        break;
+}
+
+switch (foo) {
+    case 1:
+        bar();
+        break;
+    case 2:
+        quux();
+        break;
+    default:
+        baz();
+        break;
+}
+
+switch (foo) {
+    case "x":
+        bar();
+        break;
+    case "y":
+    default:
+        baz();
+        break;
+}
+
+switch (foo) {
+    case -1:
+        bar();
+        break;
+}
+
+if (foo !== 0) {
+    doSomethingIfNotZero();
+}
+doSomethingAnyway();
+```
+
+## Further Reading
+
+* [MDN switch statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch)
+
+## Related Rules
+
+* [default-case](default-case.md)
diff --git a/docs/rules/no-magic-numbers.md b/docs/rules/no-magic-numbers.md
index 7d1e5a558..f6e1bacbd 100644
--- a/docs/rules/no-magic-numbers.md
+++ b/docs/rules/no-magic-numbers.md
@@ -56,6 +56,9 @@ var dutyFreePrice = 100,
 An array of numbers to ignore. It's set to `[]` by default.
 If provided, it must be an `Array`.
 
+The array can contain values of `number` and `string` types.
+If it's a string, the text must be parsed as `bigint` literal (e.g., `"100n"`).
+
 Examples of **correct** code for the sample `{ "ignore": [1] }` option:
 
 ```js
@@ -65,6 +68,14 @@ var data = ['foo', 'bar', 'baz'];
 var dataLast = data.length && data[data.length - 1];
 ```
 
+Examples of **correct** code for the sample `{ "ignore": ["1n"] }` option:
+
+```js
+/*eslint no-magic-numbers: ["error", { "ignore": ["1n"] }]*/
+
+foo(1n);
+```
+
 ### ignoreArrayIndexes
 
 A boolean to specify if numbers used as array indexes are considered okay. `false` by default.
diff --git a/docs/user-guide/configuring.md b/docs/user-guide/configuring.md
index 6771287d3..93cd5f4c8 100644
--- a/docs/user-guide/configuring.md
+++ b/docs/user-guide/configuring.md
@@ -420,6 +420,25 @@ If a rule has additional options, you can specify them using array literal synta
 
 This comment specifies the "double" option for the [`quotes`](../rules/quotes) rule. The first item in the array is always the rule severity (number or string).
 
+Configuration comments can include descriptions to explain why the comment is necessary. The description must occur after the configuration and is separated from the configuration by two or more consecutive `-` characters. For example:
+
+```js
+/* eslint eqeqeq: "off", curly: "error" -- Here's a description about why this configuration is necessary. */
+```
+
+```js
+/* eslint eqeqeq: "off", curly: "error"
+    --------
+    Here's a description about why this configuration is necessary. */
+```
+
+```js
+/* eslint eqeqeq: "off", curly: "error"
+ * --------
+ * This will not work due to the line above starting with a '*' character.
+ */
+```
+
 ### Using Configuration Files
 
 To configure rules inside of a configuration file, use the `rules` key along with an error level and any options you want to use. For example:
@@ -574,6 +593,13 @@ foo(); // eslint-disable-line example/rule-name
 foo(); /* eslint-disable-line example/rule-name */
 ```
 
+Configuration comments can include descriptions to explain why the comment is necessary. The description must occur after the configuration and is separated from the configuration by two or more consecutive `-` characters. For example:
+
+```js
+// eslint-disable-next-line no-console -- Here's a description about why this configuration is necessary.
+console.log('hello');
+```
+
 **Note:** Comments that disable warnings for a portion of a file tell ESLint not to report rule violations for the disabled code. ESLint still parses the entire file, however, so disabled code still needs to be syntactically valid JavaScript.
 
 
diff --git a/lib/linter/linter.js b/lib/linter/linter.js
index 6d88cb5aa..76d35b49e 100644
--- a/lib/linter/linter.js
+++ b/lib/linter/linter.js
@@ -267,6 +267,15 @@ function createDisableDirectives(options) {
     return result;
 }
 
+/**
+ * Remove the ignored part from a given directive comment and trim it.
+ * @param {string} value The comment text to strip.
+ * @returns {string} The stripped text.
+ */
+function stripDirectiveComment(value) {
+    return value.split(/\s-{2,}\s/u)[0].trim();
+}
+
 /**
  * Parses comments in file to extract file-specific config of rules, globals
  * and environments and merges them with global config; also code blocks
@@ -286,7 +295,7 @@ function getDirectiveComments(filename, ast, ruleMapper, warnInlineConfig) {
     const disableDirectives = [];
 
     ast.comments.filter(token => token.type !== "Shebang").forEach(comment => {
-        const trimmedCommentText = comment.value.trim();
+        const trimmedCommentText = stripDirectiveComment(comment.value);
         const match = /^(eslint(?:-env|-enable|-disable(?:(?:-next)?-line)?)?|exported|globals?)(?:\s|$)/u.exec(trimmedCommentText);
 
         if (!match) {
@@ -444,8 +453,11 @@ function findEslintEnv(text) {
 
     eslintEnvPattern.lastIndex = 0;
 
-    while ((match = eslintEnvPattern.exec(text))) {
-        retv = Object.assign(retv || {}, commentParser.parseListConfig(match[1]));
+    while ((match = eslintEnvPattern.exec(text)) !== null) {
+        retv = Object.assign(
+            retv || {},
+            commentParser.parseListConfig(stripDirectiveComment(match[1]))
+        );
     }
 
     return retv;
diff --git a/lib/rules/array-callback-return.js b/lib/rules/array-callback-return.js
index d632a3f30..6e425dcdc 100644
--- a/lib/rules/array-callback-return.js
+++ b/lib/rules/array-callback-return.js
@@ -18,7 +18,7 @@ const astUtils = require("./utils/ast-utils");
 //------------------------------------------------------------------------------
 
 const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/u;
-const TARGET_METHODS = /^(?:every|filter|find(?:Index)?|map|reduce(?:Right)?|some|sort)$/u;
+const TARGET_METHODS = /^(?:every|filter|find(?:Index)?|flatMap|map|reduce(?:Right)?|some|sort)$/u;
 
 /**
  * Checks a given code path segment is reachable.
diff --git a/lib/rules/computed-property-spacing.js b/lib/rules/computed-property-spacing.js
index a0bd7f48c..48bea6a6f 100644
--- a/lib/rules/computed-property-spacing.js
+++ b/lib/rules/computed-property-spacing.js
@@ -67,7 +67,7 @@ module.exports = {
         function reportNoBeginningSpace(node, token, tokenAfter) {
             context.report({
                 node,
-                loc: token.loc.start,
+                loc: { start: token.loc.end, end: tokenAfter.loc.start },
                 messageId: "unexpectedSpaceAfter",
                 data: {
                     tokenValue: token.value
@@ -88,7 +88,7 @@ module.exports = {
         function reportNoEndingSpace(node, token, tokenBefore) {
             context.report({
                 node,
-                loc: token.loc.start,
+                loc: { start: tokenBefore.loc.end, end: token.loc.start },
                 messageId: "unexpectedSpaceBefore",
                 data: {
                     tokenValue: token.value
@@ -108,7 +108,7 @@ module.exports = {
         function reportRequiredBeginningSpace(node, token) {
             context.report({
                 node,
-                loc: token.loc.start,
+                loc: token.loc,
                 messageId: "missingSpaceAfter",
                 data: {
                     tokenValue: token.value
@@ -128,7 +128,7 @@ module.exports = {
         function reportRequiredEndingSpace(node, token) {
             context.report({
                 node,
-                loc: token.loc.start,
+                loc: token.loc,
                 messageId: "missingSpaceBefore",
                 data: {
                     tokenValue: token.value
diff --git a/lib/rules/default-case-last.js b/lib/rules/default-case-last.js
new file mode 100644
index 000000000..80c5d6bda
--- /dev/null
+++ b/lib/rules/default-case-last.js
@@ -0,0 +1,44 @@
+/**
+ * @fileoverview Rule to enforce default clauses in switch statements to be last
+ * @author Milos Djermanovic
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = {
+    meta: {
+        type: "suggestion",
+
+        docs: {
+            description: "enforce default clauses in switch statements to be last",
+            category: "Best Practices",
+            recommended: false,
+            url: "https://eslint.org/docs/rules/default-case-last"
+        },
+
+        schema: [],
+
+        messages: {
+            notLast: "Default clause should be the last clause."
+        }
+    },
+
+    create(context) {
+        return {
+            SwitchStatement(node) {
+                const cases = node.cases,
+                    indexOfDefault = cases.findIndex(c => c.test === null);
+
+                if (indexOfDefault !== -1 && indexOfDefault !== cases.length - 1) {
+                    const defaultClause = cases[indexOfDefault];
+
+                    context.report({ node: defaultClause, messageId: "notLast" });
+                }
+            }
+        };
+    }
+};
diff --git a/lib/rules/id-blacklist.js b/lib/rules/id-blacklist.js
index 53be62e68..e5dcdc630 100644
--- a/lib/rules/id-blacklist.js
+++ b/lib/rules/id-blacklist.js
@@ -61,9 +61,12 @@ module.exports = {
          * @returns {boolean} whether an error should be reported or not
          */
         function shouldReport(effectiveParent, name) {
-            return effectiveParent.type !== "CallExpression" &&
+            return (
+                effectiveParent.type !== "CallExpression" &&
                 effectiveParent.type !== "NewExpression" &&
-                isInvalid(name);
+                effectiveParent.parent.type !== "ObjectPattern" &&
+                isInvalid(name)
+            );
         }
 
         /**
@@ -98,11 +101,11 @@ module.exports = {
                             report(node);
                         }
 
-                        // Report AssignmentExpressions only if they are the left side of the assignment
+                    // Report AssignmentExpressions only if they are the left side of the assignment
                     } else if (effectiveParent.type === "AssignmentExpression" &&
                         (effectiveParent.right.type !== "MemberExpression" ||
-                        effectiveParent.left.type === "MemberExpression" &&
-                        effectiveParent.left.property.name === node.name)) {
+                            effectiveParent.left.type === "MemberExpression" &&
+                            effectiveParent.left.property.name === node.name)) {
                         if (isInvalid(name)) {
                             report(node);
                         }
@@ -115,7 +118,7 @@ module.exports = {
                         report(node);
                     }
 
-                // Report anything that is a match and not a CallExpression
+                    // Report anything that is a match and not a CallExpression
                 } else if (shouldReport(effectiveParent, name)) {
                     report(node);
                 }
diff --git a/lib/rules/indent.js b/lib/rules/indent.js
index 59d50e2cc..d576fde03 100644
--- a/lib/rules/indent.js
+++ b/lib/rules/indent.js
@@ -933,7 +933,11 @@ module.exports = {
 
             parameterParens.add(openingParen);
             parameterParens.add(closingParen);
-            offsets.setDesiredOffset(openingParen, sourceCode.getTokenBefore(openingParen), 0);
+
+            const offsetAfterToken = node.callee.type === "TaggedTemplateExpression" ? sourceCode.getFirstToken(node.callee.quasi) : openingParen;
+            const offsetToken = sourceCode.getTokenBefore(offsetAfterToken);
+
+            offsets.setDesiredOffset(openingParen, offsetToken, 0);
 
             addElementListIndent(node.arguments, openingParen, closingParen, options.CallExpression.arguments);
         }
diff --git a/lib/rules/index.js b/lib/rules/index.js
index 74b0a3fb9..7f563eb2e 100644
--- a/lib/rules/index.js
+++ b/lib/rules/index.js
@@ -37,6 +37,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
     "constructor-super": () => require("./constructor-super"),
     curly: () => require("./curly"),
     "default-case": () => require("./default-case"),
+    "default-case-last": () => require("./default-case-last"),
     "default-param-last": () => require("./default-param-last"),
     "dot-location": () => require("./dot-location"),
     "dot-notation": () => require("./dot-notation"),
diff --git a/lib/rules/key-spacing.js b/lib/rules/key-spacing.js
index 6d1b9121c..c40504379 100644
--- a/lib/rules/key-spacing.js
+++ b/lib/rules/key-spacing.js
@@ -414,8 +414,7 @@ module.exports = {
             if (property.computed) {
                 return sourceCode.getText().slice(key.range[0], key.range[1]);
             }
-
-            return property.key.name || property.key.value;
+            return astUtils.getStaticPropertyName(property);
         }
 
         /**
diff --git a/lib/rules/new-cap.js b/lib/rules/new-cap.js
index cee979310..7cce968c5 100644
--- a/lib/rules/new-cap.js
+++ b/lib/rules/new-cap.js
@@ -9,6 +9,8 @@
 // Requirements
 //------------------------------------------------------------------------------
 
+const astUtils = require("./utils/ast-utils");
+
 //------------------------------------------------------------------------------
 // Helpers
 //------------------------------------------------------------------------------
@@ -160,13 +162,7 @@ module.exports = {
             let name = "";
 
             if (node.callee.type === "MemberExpression") {
-                const property = node.callee.property;
-
-                if (property.type === "Literal" && (typeof property.value === "string")) {
-                    name = property.value;
-                } else if (property.type === "Identifier" && !node.callee.computed) {
-                    name = property.name;
-                }
+                name = astUtils.getStaticPropertyName(node.callee) || "";
             } else {
                 name = node.callee.name;
             }
diff --git a/lib/rules/no-dupe-class-members.js b/lib/rules/no-dupe-class-members.js
index 6041e9e37..55639746b 100644
--- a/lib/rules/no-dupe-class-members.js
+++ b/lib/rules/no-dupe-class-members.js
@@ -5,6 +5,8 @@
 
 "use strict";
 
+const astUtils = require("./utils/ast-utils");
+
 //------------------------------------------------------------------------------
 // Rule Definition
 //------------------------------------------------------------------------------
@@ -53,21 +55,6 @@ module.exports = {
             return stateMap[key][isStatic ? "static" : "nonStatic"];
         }
 
-        /**
-         * Gets the name text of a given node.
-         * @param {ASTNode} node A node to get the name.
-         * @returns {string} The name text of the node.
-         */
-        function getName(node) {
-            switch (node.type) {
-                case "Identifier": return node.name;
-                case "Literal": return String(node.value);
-
-                /* istanbul ignore next: syntax error */
-                default: return "";
-            }
-        }
-
         return {
 
             // Initializes the stack of state of member declarations.
@@ -91,7 +78,7 @@ module.exports = {
                     return;
                 }
 
-                const name = getName(node.key);
+                const name = astUtils.getStaticPropertyName(node) || "";
                 const state = getState(name, node.static);
                 let isDuplicate = false;
 
diff --git a/lib/rules/no-extra-parens.js b/lib/rules/no-extra-parens.js
index e0ab32b4e..e70353576 100644
--- a/lib/rules/no-extra-parens.js
+++ b/lib/rules/no-extra-parens.js
@@ -342,6 +342,17 @@ module.exports = {
             return node.type === "CallExpression" && node.callee.type === "FunctionExpression";
         }
 
+        /**
+         * Determines if the given node can be the assignment target in destructuring or the LHS of an assignment.
+         * This is to avoid an autofix that could change behavior because parsers mistakenly allow invalid syntax,
+         * such as `(a = b) = c` and `[(a = b) = c] = []`. Ideally, this function shouldn't be necessary.
+         * @param {ASTNode} [node] The node to check
+         * @returns {boolean} `true` if the given node can be a valid assignment target
+         */
+        function canBeAssignmentTarget(node) {
+            return node && (node.type === "Identifier" || node.type === "MemberExpression");
+        }
+
         /**
          * Report the node
          * @param {ASTNode} node node to evaluate
@@ -679,6 +690,12 @@ module.exports = {
                     .forEach(report);
             },
 
+            ArrayPattern(node) {
+                node.elements
+                    .filter(e => canBeAssignmentTarget(e) && hasExcessParens(e))
+                    .forEach(report);
+            },
+
             ArrowFunctionExpression(node) {
                 if (isReturnAssignException(node)) {
                     return;
@@ -705,6 +722,10 @@ module.exports = {
             },
 
             AssignmentExpression(node) {
+                if (canBeAssignmentTarget(node.left) && hasExcessParens(node.left)) {
+                    report(node.left);
+                }
+
                 if (!isReturnAssignException(node) && hasExcessParensWithPrecedence(node.right, precedence(node))) {
                     report(node.right);
                 }
@@ -947,6 +968,15 @@ module.exports = {
                     .forEach(property => report(property.value));
             },
 
+            ObjectPattern(node) {
+                node.properties
+                    .filter(property => {
+                        const value = property.value;
+
+                        return canBeAssignmentTarget(value) && hasExcessParens(value);
+                    }).forEach(property => report(property.value));
+            },
+
             Property(node) {
                 if (node.computed) {
                     const { key } = node;
@@ -957,6 +987,14 @@ module.exports = {
                 }
             },
 
+            RestElement(node) {
+                const argument = node.argument;
+
+                if (canBeAssignmentTarget(argument) && hasExcessParens(argument)) {
+                    report(argument);
+                }
+            },
+
             ReturnStatement(node) {
                 const returnToken = sourceCode.getFirstToken(node);
 
@@ -1054,7 +1092,11 @@ module.exports = {
             },
 
             AssignmentPattern(node) {
-                const { right } = node;
+                const { left, right } = node;
+
+                if (canBeAssignmentTarget(left) && hasExcessParens(left)) {
+                    report(left);
+                }
 
                 if (right && hasExcessParensWithPrecedence(right, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
                     report(right);
diff --git a/lib/rules/no-magic-numbers.js b/lib/rules/no-magic-numbers.js
index 0909e3166..4bf24996c 100644
--- a/lib/rules/no-magic-numbers.js
+++ b/lib/rules/no-magic-numbers.js
@@ -5,10 +5,24 @@
 
 "use strict";
 
+const { isNumericLiteral } = require("./utils/ast-utils");
+
 //------------------------------------------------------------------------------
 // Rule Definition
 //------------------------------------------------------------------------------
 
+/**
+ * Convert the value to bigint if it's a string. Otherwise return the value as-is.
+ * @param {bigint|number|string} x The value to normalize.
+ * @returns {bigint|number} The normalized value.
+ */
+function normalizeIgnoreValue(x) {
+    if (typeof x === "string") {
+        return BigInt(x.slice(0, -1));
+    }
+    return x;
+}
+
 module.exports = {
     meta: {
         type: "suggestion",
@@ -34,7 +48,10 @@ module.exports = {
                 ignore: {
                     type: "array",
                     items: {
-                        type: "number"
+                        anyOf: [
+                            { type: "number" },
+                            { type: "string", pattern: "^[+-]?(?:0|[1-9][0-9]*)n$" }
+                        ]
                     },
                     uniqueItems: true
                 },
@@ -56,18 +73,9 @@ module.exports = {
         const config = context.options[0] || {},
             detectObjects = !!config.detectObjects,
             enforceConst = !!config.enforceConst,
-            ignore = config.ignore || [],
+            ignore = (config.ignore || []).map(normalizeIgnoreValue),
             ignoreArrayIndexes = !!config.ignoreArrayIndexes;
 
-        /**
-         * Returns whether the node is number literal
-         * @param {Node} node the node literal being evaluated
-         * @returns {boolean} true if the node is a number literal
-         */
-        function isNumber(node) {
-            return typeof node.value === "number";
-        }
-
         /**
          * Returns whether the number should be ignored
          * @param {number} num the number
@@ -113,7 +121,7 @@ module.exports = {
             Literal(node) {
                 const okTypes = detectObjects ? [] : ["ObjectExpression", "Property", "AssignmentExpression"];
 
-                if (!isNumber(node)) {
+                if (!isNumericLiteral(node)) {
                     return;
                 }
 
diff --git a/lib/rules/no-restricted-imports.js b/lib/rules/no-restricted-imports.js
index 5514b979c..c205dad8b 100644
--- a/lib/rules/no-restricted-imports.js
+++ b/lib/rules/no-restricted-imports.js
@@ -91,6 +91,7 @@ module.exports = {
     },
 
     create(context) {
+        const sourceCode = context.getSourceCode();
         const options = Array.isArray(context.options) ? context.options : [];
         const isPathAndPatternsObject =
             typeof options[0] === "object" &&
@@ -216,30 +217,36 @@ module.exports = {
          */
         function checkNode(node) {
             const importSource = node.source.value.trim();
-            const importNames = node.specifiers ? node.specifiers.reduce((map, specifier) => {
-                let name;
-                const specifierData = { loc: specifier.loc };
-
-                if (specifier.type === "ImportDefaultSpecifier") {
-                    name = "default";
-                } else if (specifier.type === "ImportNamespaceSpecifier") {
-                    name = "*";
-                } else if (specifier.imported) {
-                    name = specifier.imported.name;
-                } else if (specifier.local) {
-                    name = specifier.local.name;
-                }
+            const importNames = new Map();
+
+            if (node.type === "ExportAllDeclaration") {
+                const starToken = sourceCode.getFirstToken(node, 1);
+
+                importNames.set("*", [{ loc: starToken.loc }]);
+            } else if (node.specifiers) {
+                for (const specifier of node.specifiers) {
+                    let name;
+                    const specifierData = { loc: specifier.loc };
+
+                    if (specifier.type === "ImportDefaultSpecifier") {
+                        name = "default";
+                    } else if (specifier.type === "ImportNamespaceSpecifier") {
+                        name = "*";
+                    } else if (specifier.imported) {
+                        name = specifier.imported.name;
+                    } else if (specifier.local) {
+                        name = specifier.local.name;
+                    }
 
-                if (name) {
-                    if (map.has(name)) {
-                        map.get(name).push(specifierData);
-                    } else {
-                        map.set(name, [specifierData]);
+                    if (name) {
+                        if (importNames.has(name)) {
+                            importNames.get(name).push(specifierData);
+                        } else {
+                            importNames.set(name, [specifierData]);
+                        }
                     }
                 }
-
-                return map;
-            }, new Map()) : new Map();
+            }
 
             checkRestrictedPathAndReport(importSource, importNames, node);
 
diff --git a/lib/rules/no-useless-computed-key.js b/lib/rules/no-useless-computed-key.js
index b5e53174e..0e0acbea7 100644
--- a/lib/rules/no-useless-computed-key.js
+++ b/lib/rules/no-useless-computed-key.js
@@ -71,14 +71,11 @@ module.exports = {
                     message: MESSAGE_UNNECESSARY_COMPUTED,
                     data: { property: sourceCode.getText(key) },
                     fix(fixer) {
-                        const leftSquareBracket = sourceCode.getFirstToken(node, astUtils.isOpeningBracketToken);
-                        const rightSquareBracket = sourceCode.getFirstTokenBetween(node.key, node.value, astUtils.isClosingBracketToken);
-                        const tokensBetween = sourceCode.getTokensBetween(leftSquareBracket, rightSquareBracket, 1);
+                        const leftSquareBracket = sourceCode.getTokenBefore(key, astUtils.isOpeningBracketToken);
+                        const rightSquareBracket = sourceCode.getTokenAfter(key, astUtils.isClosingBracketToken);
 
-                        if (tokensBetween.slice(0, -1).some((token, index) =>
-                            sourceCode.getText().slice(token.range[1], tokensBetween[index + 1].range[0]).trim())) {
-
-                            // If there are comments between the brackets and the property name, don't do a fix.
+                        // If there are comments between the brackets and the property name, don't do a fix.
+                        if (sourceCode.commentsExistBetween(leftSquareBracket, rightSquareBracket)) {
                             return null;
                         }
 
diff --git a/lib/rules/prefer-object-spread.js b/lib/rules/prefer-object-spread.js
index bbcd88bee..00f5fb6d4 100644
--- a/lib/rules/prefer-object-spread.js
+++ b/lib/rules/prefer-object-spread.js
@@ -25,6 +25,36 @@ function hasArraySpread(node) {
     return node.arguments.some(arg => arg.type === "SpreadElement");
 }
 
+/**
+ * Determines whether the given node is an accessor property (getter/setter).
+ * @param {ASTNode} node Node to check.
+ * @returns {boolean} `true` if the node is a getter or a setter.
+ */
+function isAccessorProperty(node) {
+    return node.type === "Property" &&
+        (node.kind === "get" || node.kind === "set");
+}
+
+/**
+ * Determines whether the given object expression node has accessor properties (getters/setters).
+ * @param {ASTNode} node `ObjectExpression` node to check.
+ * @returns {boolean} `true` if the node has at least one getter/setter.
+ */
+function hasAccessors(node) {
+    return node.properties.some(isAccessorProperty);
+}
+
+/**
+ * Determines whether the given call expression node has object expression arguments with accessor properties (getters/setters).
+ * @param {ASTNode} node `CallExpression` node to check.
+ * @returns {boolean} `true` if the node has at least one argument that is an object expression with at least one getter/setter.
+ */
+function hasArgumentsWithAccessors(node) {
+    return node.arguments
+        .filter(arg => arg.type === "ObjectExpression")
+        .some(hasAccessors);
+}
+
 /**
  * Helper that checks if the node needs parentheses to be valid JS.
  * The default is to wrap the node in parentheses to avoid parsing errors.
@@ -249,7 +279,11 @@ module.exports = {
                     if (
                         node.arguments.length >= 1 &&
                         node.arguments[0].type === "ObjectExpression" &&
-                        !hasArraySpread(node)
+                        !hasArraySpread(node) &&
+                        !(
+                            node.arguments.length > 1 &&
+                            hasArgumentsWithAccessors(node)
+                        )
                     ) {
                         const messageId = node.arguments.length === 1
                             ? "useLiteralMessage"
diff --git a/lib/rules/quote-props.js b/lib/rules/quote-props.js
index ab09b8fa9..4cc53b988 100644
--- a/lib/rules/quote-props.js
+++ b/lib/rules/quote-props.js
@@ -8,8 +8,9 @@
 // Requirements
 //------------------------------------------------------------------------------
 
-const espree = require("espree"),
-    keywords = require("./utils/keywords");
+const espree = require("espree");
+const astUtils = require("./utils/ast-utils");
+const keywords = require("./utils/keywords");
 
 //------------------------------------------------------------------------------
 // Rule Definition
@@ -177,7 +178,7 @@ module.exports = {
                     data: { property: key.name },
                     fix: fixer => fixer.replaceText(key, getQuotedKey(key))
                 });
-            } else if (NUMBERS && key.type === "Literal" && typeof key.value === "number") {
+            } else if (NUMBERS && key.type === "Literal" && astUtils.isNumericLiteral(key)) {
                 context.report({
                     node,
                     message: MESSAGE_NUMERIC,
diff --git a/lib/rules/utils/ast-utils.js b/lib/rules/utils/ast-utils.js
index b4e8e2980..e10544dd6 100644
--- a/lib/rules/utils/ast-utils.js
+++ b/lib/rules/utils/ast-utils.js
@@ -884,6 +884,9 @@ module.exports = {
                     if (node.regex) {
                         return `/${node.regex.pattern}/${node.regex.flags}`;
                     }
+                    if (node.bigint) {
+                        return node.bigint;
+                    }
 
                     // Otherwise, this is an unknown literal. The function will return null.
 
@@ -1014,6 +1017,7 @@ module.exports = {
      * 0o5     // false
      * 5e0     // false
      * '5'     // false
+     * 5n      // false
      */
     isDecimalInteger(node) {
         return node.type === "Literal" && typeof node.value === "number" &&
@@ -1333,6 +1337,18 @@ module.exports = {
         return node.type === "Literal" && node.value === null && !node.regex && !node.bigint;
     },
 
+    /**
+     * Check if a given node is a numeric literal or not.
+     * @param {ASTNode} node The node to check.
+     * @returns {boolean} `true` if the node is a number or bigint literal.
+     */
+    isNumericLiteral(node) {
+        return (
+            node.type === "Literal" &&
+            (typeof node.value === "number" || Boolean(node.bigint))
+        );
+    },
+
     /**
      * Determines whether two tokens can safely be placed next to each other without merging into a single token
      * @param {Token|string} leftValue The left token. If this is a string, it will be tokenized and the last token will be used.
diff --git a/lib/rules/yoda.js b/lib/rules/yoda.js
index b00acf82c..be5c59ce0 100644
--- a/lib/rules/yoda.js
+++ b/lib/rules/yoda.js
@@ -53,8 +53,7 @@ function looksLikeLiteral(node) {
     return (node.type === "UnaryExpression" &&
         node.operator === "-" &&
         node.prefix &&
-        node.argument.type === "Literal" &&
-        typeof node.argument.value === "number");
+        astUtils.isNumericLiteral(node.argument));
 }
 
 /**
diff --git a/tools/rule-types.json b/tools/rule-types.json
index 54f01e099..c3c249855 100644
--- a/tools/rule-types.json
+++ b/tools/rule-types.json
@@ -24,6 +24,7 @@
     "constructor-super": "problem",
     "curly": "suggestion",
     "default-case": "suggestion",
+    "default-case-last": "suggestion",
     "default-param-last": "suggestion",
     "dot-location": "layout",
     "dot-notation": "suggestion",


Test patch:
diff --git a/tests/lib/linter/linter.js b/tests/lib/linter/linter.js
index e444aea92..71bfd262a 100644
--- a/tests/lib/linter/linter.js
+++ b/tests/lib/linter/linter.js
@@ -3759,6 +3759,314 @@ describe("Linter", () => {
             linter.verify("x", { rules: { "foo-bar-baz": "error" } });
             assert(spy.calledOnce);
         });
+
+        describe("descriptions in directive comments", () => {
+            it("should ignore the part preceded by '--' in '/*eslint*/'.", () => {
+                const aaa = sinon.stub().returns({});
+                const bbb = sinon.stub().returns({});
+
+                linter.defineRule("aaa", { create: aaa });
+                linter.defineRule("bbb", { create: bbb });
+                const messages = linter.verify(`
+                    /*eslint aaa:error -- bbb:error */
+                    console.log("hello")
+                `, {});
+
+                // Don't include syntax error of the comment.
+                assert.deepStrictEqual(messages, []);
+
+                // Use only `aaa`.
+                assert.strictEqual(aaa.callCount, 1);
+                assert.strictEqual(bbb.callCount, 0);
+            });
+
+            it("should ignore the part preceded by '--' in '/*eslint-env*/'.", () => {
+                const messages = linter.verify(`
+                    /*eslint-env es2015 -- es2017 */
+                    var Promise = {}
+                    var Atomics = {}
+                `, { rules: { "no-redeclare": "error" } });
+
+                // Don't include `Atomics`
+                assert.deepStrictEqual(
+                    messages,
+                    [{
+                        column: 25,
+                        endColumn: 32,
+                        endLine: 3,
+                        line: 3,
+                        message: "'Promise' is already defined as a built-in global variable.",
+                        messageId: "redeclaredAsBuiltin",
+                        nodeType: "Identifier",
+                        ruleId: "no-redeclare",
+                        severity: 2
+                    }]
+                );
+            });
+
+            it("should ignore the part preceded by '--' in '/*global*/'.", () => {
+                const messages = linter.verify(`
+                    /*global aaa -- bbb */
+                    var aaa = {}
+                    var bbb = {}
+                `, { rules: { "no-redeclare": "error" } });
+
+                // Don't include `bbb`
+                assert.deepStrictEqual(
+                    messages,
+                    [{
+                        column: 30,
+                        line: 2,
+                        message: "'aaa' is already defined by a variable declaration.",
+                        messageId: "redeclaredBySyntax",
+                        nodeType: "Block",
+                        ruleId: "no-redeclare",
+                        severity: 2
+                    }]
+                );
+            });
+
+            it("should ignore the part preceded by '--' in '/*globals*/'.", () => {
+                const messages = linter.verify(`
+                    /*globals aaa -- bbb */
+                    var aaa = {}
+                    var bbb = {}
+                `, { rules: { "no-redeclare": "error" } });
+
+                // Don't include `bbb`
+                assert.deepStrictEqual(
+                    messages,
+                    [{
+                        column: 31,
+                        line: 2,
+                        message: "'aaa' is already defined by a variable declaration.",
+                        messageId: "redeclaredBySyntax",
+                        nodeType: "Block",
+                        ruleId: "no-redeclare",
+                        severity: 2
+                    }]
+                );
+            });
+
+            it("should ignore the part preceded by '--' in '/*exported*/'.", () => {
+                const messages = linter.verify(`
+                    /*exported aaa -- bbb */
+                    var aaa = {}
+                    var bbb = {}
+                `, { rules: { "no-unused-vars": "error" } });
+
+                // Don't include `aaa`
+                assert.deepStrictEqual(
+                    messages,
+                    [{
+                        column: 25,
+                        endColumn: 28,
+                        endLine: 4,
+                        line: 4,
+                        message: "'bbb' is assigned a value but never used.",
+                        nodeType: "Identifier",
+                        ruleId: "no-unused-vars",
+                        severity: 2
+                    }]
+                );
+            });
+
+            it("should ignore the part preceded by '--' in '/*eslint-disable*/'.", () => {
+                const messages = linter.verify(`
+                    /*eslint-disable no-redeclare -- no-unused-vars */
+                    var aaa = {}
+                    var aaa = {}
+                `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } });
+
+                // Do include `no-unused-vars` but not `no-redeclare`
+                assert.deepStrictEqual(
+                    messages,
+                    [{
+                        column: 25,
+                        endLine: 3,
+                        endColumn: 28,
+                        line: 3,
+                        message: "'aaa' is assigned a value but never used.",
+                        nodeType: "Identifier",
+                        ruleId: "no-unused-vars",
+                        severity: 2
+                    }]
+                );
+            });
+
+            it("should ignore the part preceded by '--' in '/*eslint-enable*/'.", () => {
+                const messages = linter.verify(`
+                    /*eslint-disable no-redeclare, no-unused-vars */
+                    /*eslint-enable no-redeclare -- no-unused-vars */
+                    var aaa = {}
+                    var aaa = {}
+                `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } });
+
+                // Do include `no-redeclare` but not `no-unused-vars`
+                assert.deepStrictEqual(
+                    messages,
+                    [{
+                        column: 25,
+                        endLine: 5,
+                        endColumn: 28,
+                        line: 5,
+                        message: "'aaa' is already defined.",
+                        messageId: "redeclared",
+                        nodeType: "Identifier",
+                        ruleId: "no-redeclare",
+                        severity: 2
+                    }]
+                );
+            });
+
+            it("should ignore the part preceded by '--' in '//eslint-disable-line'.", () => {
+                const messages = linter.verify(`
+                    var aaa = {} //eslint-disable-line no-redeclare -- no-unused-vars
+                    var aaa = {} //eslint-disable-line no-redeclare -- no-unused-vars
+                `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } });
+
+                // Do include `no-unused-vars` but not `no-redeclare`
+                assert.deepStrictEqual(
+                    messages,
+                    [{
+                        column: 25,
+                        endLine: 2,
+                        endColumn: 28,
+                        line: 2,
+                        message: "'aaa' is assigned a value but never used.",
+                        nodeType: "Identifier",
+                        ruleId: "no-unused-vars",
+                        severity: 2
+                    }]
+                );
+            });
+
+            it("should ignore the part preceded by '--' in '/*eslint-disable-line*/'.", () => {
+                const messages = linter.verify(`
+                    var aaa = {} /*eslint-disable-line no-redeclare -- no-unused-vars */
+                    var aaa = {} /*eslint-disable-line no-redeclare -- no-unused-vars */
+                `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } });
+
+                // Do include `no-unused-vars` but not `no-redeclare`
+                assert.deepStrictEqual(
+                    messages,
+                    [{
+                        column: 25,
+                        endLine: 2,
+                        endColumn: 28,
+                        line: 2,
+                        message: "'aaa' is assigned a value but never used.",
+                        nodeType: "Identifier",
+                        ruleId: "no-unused-vars",
+                        severity: 2
+                    }]
+                );
+            });
+
+            it("should ignore the part preceded by '--' in '//eslint-disable-next-line'.", () => {
+                const messages = linter.verify(`
+                    //eslint-disable-next-line no-redeclare -- no-unused-vars
+                    var aaa = {}
+                    //eslint-disable-next-line no-redeclare -- no-unused-vars
+                    var aaa = {}
+                `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } });
+
+                // Do include `no-unused-vars` but not `no-redeclare`
+                assert.deepStrictEqual(
+                    messages,
+                    [{
+                        column: 25,
+                        endLine: 3,
+                        endColumn: 28,
+                        line: 3,
+                        message: "'aaa' is assigned a value but never used.",
+                        nodeType: "Identifier",
+                        ruleId: "no-unused-vars",
+                        severity: 2
+                    }]
+                );
+            });
+
+            it("should ignore the part preceded by '--' in '/*eslint-disable-next-line*/'.", () => {
+                const messages = linter.verify(`
+                    /*eslint-disable-next-line no-redeclare -- no-unused-vars */
+                    var aaa = {}
+                    /*eslint-disable-next-line no-redeclare -- no-unused-vars */
+                    var aaa = {}
+                `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } });
+
+                // Do include `no-unused-vars` but not `no-redeclare`
+                assert.deepStrictEqual(
+                    messages,
+                    [{
+                        column: 25,
+                        endLine: 3,
+                        endColumn: 28,
+                        line: 3,
+                        message: "'aaa' is assigned a value but never used.",
+                        nodeType: "Identifier",
+                        ruleId: "no-unused-vars",
+                        severity: 2
+                    }]
+                );
+            });
+
+            it("should not ignore the part preceded by '--' if the '--' is not surrounded by whitespaces.", () => {
+                const rule = sinon.stub().returns({});
+
+                linter.defineRule("a--rule", { create: rule });
+                const messages = linter.verify(`
+                    /*eslint a--rule:error */
+                    console.log("hello")
+                `, {});
+
+                // Don't include syntax error of the comment.
+                assert.deepStrictEqual(messages, []);
+
+                // Use `a--rule`.
+                assert.strictEqual(rule.callCount, 1);
+            });
+
+            it("should ignore the part preceded by '--' even if the '--' is longer than 2.", () => {
+                const aaa = sinon.stub().returns({});
+                const bbb = sinon.stub().returns({});
+
+                linter.defineRule("aaa", { create: aaa });
+                linter.defineRule("bbb", { create: bbb });
+                const messages = linter.verify(`
+                    /*eslint aaa:error -------- bbb:error */
+                    console.log("hello")
+                `, {});
+
+                // Don't include syntax error of the comment.
+                assert.deepStrictEqual(messages, []);
+
+                // Use only `aaa`.
+                assert.strictEqual(aaa.callCount, 1);
+                assert.strictEqual(bbb.callCount, 0);
+            });
+
+            it("should ignore the part preceded by '--' with line breaks.", () => {
+                const aaa = sinon.stub().returns({});
+                const bbb = sinon.stub().returns({});
+
+                linter.defineRule("aaa", { create: aaa });
+                linter.defineRule("bbb", { create: bbb });
+                const messages = linter.verify(`
+                    /*eslint aaa:error
+                        --------
+                        bbb:error */
+                    console.log("hello")
+                `, {});
+
+                // Don't include syntax error of the comment.
+                assert.deepStrictEqual(messages, []);
+
+                // Use only `aaa`.
+                assert.strictEqual(aaa.callCount, 1);
+                assert.strictEqual(bbb.callCount, 0);
+            });
+        });
     });
 
     describe("context.getScope()", () => {
diff --git a/tests/lib/rules/array-callback-return.js b/tests/lib/rules/array-callback-return.js
index de39efcf6..2816d7962 100644
--- a/tests/lib/rules/array-callback-return.js
+++ b/tests/lib/rules/array-callback-return.js
@@ -36,6 +36,7 @@ ruleTester.run("array-callback-return", rule, {
         "foo.filter(function() { return true; })",
         "foo.find(function() { return true; })",
         "foo.findIndex(function() { return true; })",
+        "foo.flatMap(function() { return true; })",
         "foo.map(function() { return true; })",
         "foo.reduce(function() { return true; })",
         "foo.reduceRight(function() { return true; })",
@@ -47,6 +48,7 @@ ruleTester.run("array-callback-return", rule, {
         { code: "foo.filter(function() { return; })", options: allowImplicitOptions },
         { code: "foo.find(function() { return; })", options: allowImplicitOptions },
         { code: "foo.findIndex(function() { return; })", options: allowImplicitOptions },
+        { code: "foo.flatMap(function() { return; })", options: allowImplicitOptions },
         { code: "foo.map(function() { return; })", options: allowImplicitOptions },
         { code: "foo.reduce(function() { return; })", options: allowImplicitOptions },
         { code: "foo.reduceRight(function() { return; })", options: allowImplicitOptions },
@@ -94,6 +96,8 @@ ruleTester.run("array-callback-return", rule, {
         { code: "foo.find(function foo() {})", errors: [{ messageId: "expectedInside", data: { name: "function 'foo'" } }] },
         { code: "foo.findIndex(function() {})", errors: [{ messageId: "expectedInside", data: { name: "function" } }] },
         { code: "foo.findIndex(function foo() {})", errors: [{ messageId: "expectedInside", data: { name: "function 'foo'" } }] },
+        { code: "foo.flatMap(function() {})", errors: [{ messageId: "expectedInside", data: { name: "function" } }] },
+        { code: "foo.flatMap(function foo() {})", errors: [{ messageId: "expectedInside", data: { name: "function 'foo'" } }] },
         { code: "foo.map(function() {})", errors: [{ messageId: "expectedInside", data: { name: "function" } }] },
         { code: "foo.map(function foo() {})", errors: [{ messageId: "expectedInside", data: { name: "function 'foo'" } }] },
         { code: "foo.reduce(function() {})", errors: [{ messageId: "expectedInside", data: { name: "function" } }] },
diff --git a/tests/lib/rules/computed-property-spacing.js b/tests/lib/rules/computed-property-spacing.js
index 3a0bd9e0e..3f656ff55 100644
--- a/tests/lib/rules/computed-property-spacing.js
+++ b/tests/lib/rules/computed-property-spacing.js
@@ -184,6 +184,8 @@ ruleTester.run("computed-property-spacing", rule, {
             options: ["always", { enforceForClassMembers: true }],
             parserOptions: { ecmaVersion: 6 }
         },
+
+        // handling of parens and comments
         {
             code: [
                 "const foo = {",
@@ -277,8 +279,11 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MemberExpression",
+                    line: 1,
                     column: 17,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 18
+
                 }
             ]
         },
@@ -291,8 +296,10 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MemberExpression",
+                    line: 1,
                     column: 14,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 15
                 }
             ]
         },
@@ -305,8 +312,10 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MemberExpression",
-                    column: 14,
-                    line: 1
+                    line: 1,
+                    column: 15,
+                    endLine: 1,
+                    endColumn: 16
                 }
             ]
         },
@@ -318,7 +327,11 @@ ruleTester.run("computed-property-spacing", rule, {
                 {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
-                    type: "MemberExpression"
+                    type: "MemberExpression",
+                    line: 1,
+                    column: 16,
+                    endLine: 1,
+                    endColumn: 17
                 }
             ]
         },
@@ -331,15 +344,19 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MemberExpression",
-                    column: 4,
-                    line: 1
+                    line: 1,
+                    column: 5,
+                    endLine: 1,
+                    endColumn: 6
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MemberExpression",
-                    column: 10,
-                    line: 1
+                    line: 1,
+                    column: 9,
+                    endLine: 1,
+                    endColumn: 10
                 }
             ]
         },
@@ -352,8 +369,10 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MemberExpression",
-                    column: 9,
-                    line: 1
+                    line: 1,
+                    column: 8,
+                    endLine: 1,
+                    endColumn: 9
                 }
             ]
         },
@@ -366,8 +385,10 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MemberExpression",
-                    column: 4,
-                    line: 1
+                    line: 1,
+                    column: 5,
+                    endLine: 1,
+                    endColumn: 6
                 }
             ]
         },
@@ -380,15 +401,128 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MemberExpression",
+                    line: 1,
                     column: 14,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 15
                 },
                 {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MemberExpression",
+                    line: 1,
                     column: 16,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 17
+                }
+            ]
+        },
+
+        // multiple spaces
+        {
+            code: "obj[    foo]",
+            output: "obj[foo]",
+            options: ["never"],
+            errors: [
+                {
+                    messageId: "unexpectedSpaceAfter",
+                    data: { tokenValue: "[" },
+                    type: "MemberExpression",
+                    line: 1,
+                    column: 5,
+                    endLine: 1,
+                    endColumn: 9
+                }
+            ]
+        },
+        {
+            code: "obj[  foo  ]",
+            output: "obj[foo]",
+            options: ["never"],
+            errors: [
+                {
+                    messageId: "unexpectedSpaceAfter",
+                    data: { tokenValue: "[" },
+                    type: "MemberExpression",
+                    line: 1,
+                    column: 5,
+                    endLine: 1,
+                    endColumn: 7
+                },
+                {
+                    messageId: "unexpectedSpaceBefore",
+                    data: { tokenValue: "]" },
+                    type: "MemberExpression",
+                    line: 1,
+                    column: 10,
+                    endLine: 1,
+                    endColumn: 12
+                }
+            ]
+        },
+        {
+            code: "obj[   foo ]",
+            output: "obj[foo]",
+            options: ["never"],
+            errors: [
+                {
+                    messageId: "unexpectedSpaceAfter",
+                    data: { tokenValue: "[" },
+                    type: "MemberExpression",
+                    line: 1,
+                    column: 5,
+                    endLine: 1,
+                    endColumn: 8
+                },
+                {
+                    messageId: "unexpectedSpaceBefore",
+                    data: { tokenValue: "]" },
+                    type: "MemberExpression",
+                    line: 1,
+                    column: 11,
+                    endLine: 1,
+                    endColumn: 12
+                }
+            ]
+        },
+        {
+            code: "obj[ foo + \n  bar   ]",
+            output: "obj[foo + \n  bar]",
+            options: ["never"],
+            errors: [
+                {
+                    messageId: "unexpectedSpaceAfter",
+                    data: { tokenValue: "[" },
+                    type: "MemberExpression",
+                    line: 1,
+                    column: 5,
+                    endLine: 1,
+                    endColumn: 6
+                },
+                {
+                    messageId: "unexpectedSpaceBefore",
+                    data: { tokenValue: "]" },
+                    type: "MemberExpression",
+                    line: 2,
+                    column: 6,
+                    endLine: 2,
+                    endColumn: 9
+                }
+            ]
+        },
+        {
+            code: "obj[\n foo  ]",
+            output: "obj[\n foo]",
+            options: ["never"],
+            errors: [
+                {
+                    messageId: "unexpectedSpaceBefore",
+                    data: { tokenValue: "]" },
+                    type: "MemberExpression",
+                    line: 2,
+                    column: 5,
+                    endLine: 2,
+                    endColumn: 7
                 }
             ]
         },
@@ -404,15 +538,19 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "Property",
+                    line: 1,
                     column: 10,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 11
                 },
                 {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "Property",
+                    line: 1,
                     column: 12,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 13
                 }
             ]
         },
@@ -426,8 +564,10 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "Property",
+                    line: 1,
                     column: 10,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 11
                 }
             ]
         },
@@ -441,8 +581,10 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "Property",
+                    line: 1,
                     column: 13,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 14
                 }
             ]
         },
@@ -458,15 +600,19 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "Property",
-                    column: 10,
-                    line: 1
+                    line: 1,
+                    column: 11,
+                    endLine: 1,
+                    endColumn: 12
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "Property",
-                    column: 14,
-                    line: 1
+                    line: 1,
+                    column: 13,
+                    endLine: 1,
+                    endColumn: 14
                 }
             ]
         },
@@ -480,8 +626,10 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "Property",
-                    column: 13,
-                    line: 1
+                    line: 1,
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 }
             ]
         },
@@ -495,8 +643,10 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "Property",
-                    column: 10,
-                    line: 1
+                    line: 1,
+                    column: 11,
+                    endLine: 1,
+                    endColumn: 12
                 }
             ]
         },
@@ -510,17 +660,15 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "Property",
-                    column: 10,
-                    line: 1
+                    line: 1,
+                    column: 11,
+                    endLine: 1,
+                    endColumn: 12
                 }
             ]
         },
 
-        //------------------------------------------------------------------------------
-        // Classes
-        //------------------------------------------------------------------------------
-
-        // never
+        // never - classes
         {
             code: "class A { [ a](){} }",
             output: "class A { [a](){} }",
@@ -531,8 +679,10 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
-                    column: 11,
-                    line: 1
+                    line: 1,
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 }
             ]
         },
@@ -546,8 +696,10 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
-                    column: 37,
-                    line: 1
+                    line: 1,
+                    column: 36,
+                    endLine: 1,
+                    endColumn: 37
                 }
             ]
         },
@@ -561,29 +713,37 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
-                    column: 18,
-                    line: 1
+                    line: 1,
+                    column: 17,
+                    endLine: 1,
+                    endColumn: 18
                 },
                 {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
-                    column: 28,
-                    line: 1
+                    line: 1,
+                    column: 29,
+                    endLine: 1,
+                    endColumn: 30
                 },
                 {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
-                    column: 81,
-                    line: 1
+                    line: 1,
+                    column: 82,
+                    endLine: 1,
+                    endColumn: 83
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
-                    column: 104,
-                    line: 1
+                    line: 1,
+                    column: 103,
+                    endLine: 1,
+                    endColumn: 104
                 }
             ]
         },
@@ -597,90 +757,114 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
-                    column: 13,
-                    line: 1
+                    line: 1,
+                    column: 14,
+                    endLine: 1,
+                    endColumn: 15
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
-                    column: 17,
-                    line: 1
+                    line: 1,
+                    column: 16,
+                    endLine: 1,
+                    endColumn: 17
                 },
                 {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
-                    column: 27,
-                    line: 1
+                    line: 1,
+                    column: 28,
+                    endLine: 1,
+                    endColumn: 29
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
-                    column: 31,
-                    line: 1
+                    line: 1,
+                    column: 30,
+                    endLine: 1,
+                    endColumn: 31
                 },
                 {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
-                    column: 41,
-                    line: 1
+                    line: 1,
+                    column: 42,
+                    endLine: 1,
+                    endColumn: 43
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
-                    column: 45,
-                    line: 1
+                    line: 1,
+                    column: 44,
+                    endLine: 1,
+                    endColumn: 45
                 },
                 {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
-                    column: 61,
-                    line: 1
+                    line: 1,
+                    column: 62,
+                    endLine: 1,
+                    endColumn: 63
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
-                    column: 65,
-                    line: 1
+                    line: 1,
+                    column: 64,
+                    endLine: 1,
+                    endColumn: 65
                 },
                 {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
-                    column: 82,
-                    line: 1
+                    line: 1,
+                    column: 83,
+                    endLine: 1,
+                    endColumn: 84
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
-                    column: 86,
-                    line: 1
+                    line: 1,
+                    column: 85,
+                    endLine: 1,
+                    endColumn: 86
                 },
                 {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
-                    column: 103,
-                    line: 1
+                    line: 1,
+                    column: 104,
+                    endLine: 1,
+                    endColumn: 105
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
-                    column: 107,
-                    line: 1
+                    line: 1,
+                    column: 106,
+                    endLine: 1,
+                    endColumn: 107
                 }
             ]
         },
 
-        // always
+        // always - classes
         {
             code: "class A { [ a](){} }",
             output: "class A { [ a ](){} }",
@@ -691,8 +875,10 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 14,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 15
                 }
             ]
         },
@@ -706,8 +892,10 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 36,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 37
                 }
             ]
         },
@@ -721,29 +909,37 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 15,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 16
                 },
                 {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 31,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 32
                 },
                 {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 84,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 85
                 },
                 {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 101,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 102
                 }
             ]
         },
@@ -757,88 +953,114 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 13,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 14
                 },
                 {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 15,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 16
                 },
                 {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 25,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 26
                 },
                 {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 27,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 28
                 },
                 {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 37,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 38
                 },
                 {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 39,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 40
                 },
                 {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 55,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 56
                 },
                 {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 57,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 58
                 },
                 {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 74,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 75
                 },
                 {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 76,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 77
                 },
                 {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 93,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 94
                 },
                 {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MethodDefinition",
+                    line: 1,
                     column: 95,
-                    line: 1
+                    endLine: 1,
+                    endColumn: 96
                 }
             ]
         },
+
+        // handling of parens and comments
         {
             code: [
                 "const foo = {",
@@ -857,15 +1079,19 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "Property",
+                    line: 2,
                     column: 3,
-                    line: 2
+                    endLine: 2,
+                    endColumn: 4
                 },
                 {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "Property",
+                    line: 2,
                     column: 7,
-                    line: 2
+                    endLine: 2,
+                    endColumn: 8
                 }
             ]
         },
@@ -887,15 +1113,19 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "Property",
+                    line: 2,
                     column: 3,
-                    line: 2
+                    endLine: 2,
+                    endColumn: 4
                 },
                 {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "Property",
+                    line: 2,
                     column: 9,
-                    line: 2
+                    endLine: 2,
+                    endColumn: 10
                 }
             ]
         },
@@ -917,15 +1147,19 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "Property",
-                    column: 3,
-                    line: 2
+                    line: 2,
+                    column: 4,
+                    endLine: 2,
+                    endColumn: 5
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "Property",
-                    column: 11,
-                    line: 2
+                    line: 2,
+                    column: 10,
+                    endLine: 2,
+                    endColumn: 11
                 }
             ]
         },
@@ -947,15 +1181,19 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "Property",
+                    line: 2,
                     column: 3,
-                    line: 2
+                    endLine: 2,
+                    endColumn: 4
                 },
                 {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "Property",
+                    line: 2,
                     column: 15,
-                    line: 2
+                    endLine: 2,
+                    endColumn: 16
                 }
             ]
         },
@@ -977,15 +1215,19 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "Property",
-                    column: 3,
-                    line: 2
+                    line: 2,
+                    column: 4,
+                    endLine: 2,
+                    endColumn: 5
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "Property",
-                    column: 17,
-                    line: 2
+                    line: 2,
+                    column: 16,
+                    endLine: 2,
+                    endColumn: 17
                 }
             ]
         },
@@ -1007,29 +1249,37 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "Property",
+                    line: 2,
                     column: 3,
-                    line: 2
+                    endLine: 2,
+                    endColumn: 4
                 },
                 {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MemberExpression",
+                    line: 2,
                     column: 5,
-                    line: 2
+                    endLine: 2,
+                    endColumn: 6
                 },
                 {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MemberExpression",
+                    line: 2,
                     column: 7,
-                    line: 2
+                    endLine: 2,
+                    endColumn: 8
                 },
                 {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "Property",
+                    line: 2,
                     column: 8,
-                    line: 2
+                    endLine: 2,
+                    endColumn: 9
                 }
             ]
         },
@@ -1051,29 +1301,37 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "Property",
-                    column: 3,
-                    line: 2
+                    line: 2,
+                    column: 4,
+                    endLine: 2,
+                    endColumn: 5
                 },
                 {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MemberExpression",
-                    column: 6,
-                    line: 2
+                    line: 2,
+                    column: 7,
+                    endLine: 2,
+                    endColumn: 8
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MemberExpression",
-                    column: 10,
-                    line: 2
+                    line: 2,
+                    column: 9,
+                    endLine: 2,
+                    endColumn: 10
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "Property",
-                    column: 12,
-                    line: 2
+                    line: 2,
+                    column: 11,
+                    endLine: 2,
+                    endColumn: 12
                 }
             ]
         },
@@ -1095,22 +1353,28 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "Property",
+                    line: 2,
                     column: 3,
-                    line: 2
+                    endLine: 2,
+                    endColumn: 4
                 },
                 {
                     messageId: "missingSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MemberExpression",
+                    line: 2,
                     column: 5,
-                    line: 2
+                    endLine: 2,
+                    endColumn: 6
                 },
                 {
                     messageId: "missingSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "Property",
+                    line: 2,
                     column: 18,
-                    line: 2
+                    endLine: 2,
+                    endColumn: 19
                 }
             ]
         },
@@ -1132,22 +1396,28 @@ ruleTester.run("computed-property-spacing", rule, {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "Property",
-                    column: 3,
-                    line: 2
+                    line: 2,
+                    column: 4,
+                    endLine: 2,
+                    endColumn: 5
                 },
                 {
                     messageId: "unexpectedSpaceAfter",
                     data: { tokenValue: "[" },
                     type: "MemberExpression",
-                    column: 10,
-                    line: 2
+                    line: 2,
+                    column: 11,
+                    endLine: 2,
+                    endColumn: 12
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
                     data: { tokenValue: "]" },
                     type: "MemberExpression",
-                    column: 19,
-                    line: 2
+                    line: 2,
+                    column: 18,
+                    endLine: 2,
+                    endColumn: 19
                 }
             ]
         }
diff --git a/tests/lib/rules/default-case-last.js b/tests/lib/rules/default-case-last.js
new file mode 100644
index 000000000..9f75329ab
--- /dev/null
+++ b/tests/lib/rules/default-case-last.js
@@ -0,0 +1,128 @@
+/**
+ * @fileoverview Tests for the default-case-last rule
+ * @author Milos Djermanovic
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const rule = require("../../../lib/rules/default-case-last");
+const { RuleTester } = require("../../../lib/rule-tester");
+
+//------------------------------------------------------------------------------
+// Helpers
+//------------------------------------------------------------------------------
+
+/**
+ * Creates an error object.
+ * @param {number} [column] Reported column.
+ * @returns {Object} The error object.
+ */
+function error(column) {
+    const errorObject = {
+        messageId: "notLast",
+        type: "SwitchCase"
+    };
+
+    if (column) {
+        errorObject.column = column;
+    }
+
+    return errorObject;
+}
+
+//------------------------------------------------------------------------------
+// Tests
+//------------------------------------------------------------------------------
+
+const ruleTester = new RuleTester();
+
+ruleTester.run("default-case-last", rule, {
+    valid: [
+        "switch (foo) {}",
+        "switch (foo) { case 1: bar(); break; }",
+        "switch (foo) { case 1: break; }",
+        "switch (foo) { case 1: }",
+        "switch (foo) { case 1: bar(); break; case 2: baz(); break; }",
+        "switch (foo) { case 1: break; case 2: break; }",
+        "switch (foo) { case 1: case 2: break; }",
+        "switch (foo) { case 1: case 2: }",
+        "switch (foo) { default: bar(); break; }",
+        "switch (foo) { default: bar(); }",
+        "switch (foo) { default: break; }",
+        "switch (foo) { default: }",
+        "switch (foo) { case 1: break; default: break; }",
+        "switch (foo) { case 1: break; default: }",
+        "switch (foo) { case 1: default: break; }",
+        "switch (foo) { case 1: default: }",
+        "switch (foo) { case 1: baz(); break; case 2: quux(); break; default: quuux(); break; }",
+        "switch (foo) { case 1: break; case 2: break; default: break; }",
+        "switch (foo) { case 1: break; case 2: break; default: }",
+        "switch (foo) { case 1: case 2: break; default: break; }",
+        "switch (foo) { case 1: break; case 2: default: break; }",
+        "switch (foo) { case 1: break; case 2: default: }",
+        "switch (foo) { case 1: case 2: default: }"
+    ],
+
+    invalid: [
+        {
+            code: "switch (foo) { default: bar(); break; case 1: baz(); break; }",
+            errors: [error(16)]
+        },
+        {
+            code: "switch (foo) { default: break; case 1: break; }",
+            errors: [error(16)]
+        },
+        {
+            code: "switch (foo) { default: break; case 1: }",
+            errors: [error(16)]
+        },
+        {
+            code: "switch (foo) { default: case 1: break; }",
+            errors: [error(16)]
+        },
+        {
+            code: "switch (foo) { default: case 1: }",
+            errors: [error(16)]
+        },
+        {
+            code: "switch (foo) { default: break; case 1: break; case 2: break; }",
+            errors: [error(16)]
+        },
+        {
+            code: "switch (foo) { default: case 1: break; case 2: break; }",
+            errors: [error(16)]
+        },
+        {
+            code: "switch (foo) { default: case 1: case 2: break; }",
+            errors: [error(16)]
+        },
+        {
+            code: "switch (foo) { default: case 1: case 2: }",
+            errors: [error(16)]
+        },
+        {
+            code: "switch (foo) { case 1: break; default: break; case 2: break; }",
+            errors: [error(31)]
+        },
+        {
+            code: "switch (foo) { case 1: default: break; case 2: break; }",
+            errors: [error(24)]
+        },
+        {
+            code: "switch (foo) { case 1: break; default: case 2: break; }",
+            errors: [error(31)]
+        },
+        {
+            code: "switch (foo) { case 1: default: case 2: break; }",
+            errors: [error(24)]
+        },
+        {
+            code: "switch (foo) { case 1: default: case 2: }",
+            errors: [error(24)]
+        }
+    ]
+});
diff --git a/tests/lib/rules/id-blacklist.js b/tests/lib/rules/id-blacklist.js
index f4380e2b8..5e92a4d5b 100644
--- a/tests/lib/rules/id-blacklist.js
+++ b/tests/lib/rules/id-blacklist.js
@@ -65,6 +65,26 @@ ruleTester.run("id-blacklist", rule, {
             code: "var obj = { key: foo.bar };",
             options: ["f", "fo", "fooo", "b", "ba", "barr", "bazz", "bingg"]
         },
+        {
+            code: "const {foo: bar} = baz",
+            options: ["foo", "bar"],
+            parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "const {foo: {bar: baz}} = qux",
+            options: ["foo", "bar", "baz"],
+            parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "function foo({ bar: baz }) {}",
+            options: ["bar", "baz"],
+            parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "function foo({ bar: {baz: qux} }) {}",
+            options: ["bar", "baz", "qux"],
+            parserOptions: { ecmaVersion: 6 }
+        },
         {
             code: "var arr = [foo.bar];",
             options: ["f", "fo", "fooo", "b", "ba", "barr", "bazz", "bingg"]
diff --git a/tests/lib/rules/indent.js b/tests/lib/rules/indent.js
index 99e7dfa02..7496da218 100644
--- a/tests/lib/rules/indent.js
+++ b/tests/lib/rules/indent.js
@@ -5506,6 +5506,224 @@ ruleTester.run("indent", rule, {
                 )
             `,
             parserOptions: { ecmaVersion: 2020 }
+        },
+
+        // https://github.com/eslint/eslint/issues/12122
+        {
+            code: unIndent`
+                foo(() => {
+                    tag\`
+                    multiline
+                    template
+                    literal
+                    \`(() => {
+                        bar();
+                    });
+                });
+            `,
+            parserOptions: { ecmaVersion: 2015 }
+        },
+        {
+            code: unIndent`
+                {
+                    tag\`
+                    multiline
+                    template
+                    \${a} \${b}
+                    literal
+                    \`(() => {
+                        bar();
+                    });
+                }
+            `,
+            parserOptions: { ecmaVersion: 2015 }
+        },
+        {
+            code: unIndent`
+                foo(() => {
+                    tagOne\`
+                    multiline
+                    template
+                    literal
+                    \${a} \${b}
+                    \`(() => {
+                        tagTwo\`
+                        multiline
+                        template
+                        literal
+                        \`(() => {
+                            bar();
+                        });
+
+                        baz();
+                    });
+                });
+            `,
+            parserOptions: { ecmaVersion: 2015 }
+        },
+        {
+            code: unIndent`
+                {
+                    tagOne\`
+                    \${a} \${b}
+                    multiline
+                    template
+                    literal
+                    \`(() => {
+                        tagTwo\`
+                        multiline
+                        template
+                        literal
+                        \`(() => {
+                            bar();
+                        });
+
+                        baz();
+                    });
+                };
+            `,
+            parserOptions: { ecmaVersion: 2015 }
+        },
+        {
+            code: unIndent`
+                tagOne\`multiline
+                        \${a} \${b}
+                        template
+                        literal
+                        \`(() => {        
+                    foo();
+                    
+                    tagTwo\`multiline
+                            template
+                            literal
+                        \`({
+                        bar: 1,
+                        baz: 2
+                    });
+                });
+            `,
+            parserOptions: { ecmaVersion: 2015 }
+        },
+        {
+            code: unIndent`
+                tagOne\`multiline
+                    template
+                    literal
+                    \${a} \${b}\`({        
+                    foo: 1,
+                    bar: tagTwo\`multiline
+                        template
+                        literal\`(() => {
+                        
+                        baz();
+                    })
+                });
+            `,
+            parserOptions: { ecmaVersion: 2015 }
+        },
+        {
+            code: unIndent`
+                foo.bar\` template literal \`(() => {
+                    baz();
+                })
+            `,
+            parserOptions: { ecmaVersion: 2015 }
+        },
+        {
+            code: unIndent`
+                foo.bar.baz\` template literal \`(() => {
+                    baz();
+                })
+            `,
+            parserOptions: { ecmaVersion: 2015 }
+        },
+        {
+            code: unIndent`
+                foo
+                    .bar\` template
+                        literal \`(() => {
+                        baz();
+                    })
+            `,
+            parserOptions: { ecmaVersion: 2015 }
+        },
+        {
+            code: unIndent`
+                foo
+                    .bar
+                    .baz\` template 
+                        literal \`(() => {
+                        baz();
+                    })
+            `,
+            parserOptions: { ecmaVersion: 2015 }
+        },
+        {
+            code: unIndent`
+                foo.bar\`
+                    \${a} \${b}
+                    \`(() => {
+                    baz();
+                })
+            `,
+            parserOptions: { ecmaVersion: 2015 }
+        },
+        {
+            code: unIndent`
+                foo.bar1.bar2\`
+                    \${a} \${b}
+                    \`(() => {
+                    baz();
+                })
+            `,
+            parserOptions: { ecmaVersion: 2015 }
+        },
+        {
+            code: unIndent`
+                foo
+                    .bar1
+                    .bar2\`
+                    \${a} \${b}
+                    \`(() => {
+                        baz();
+                    })
+            `,
+            parserOptions: { ecmaVersion: 2015 }
+        },
+        {
+            code: unIndent`
+                foo
+                    .bar\`
+                    \${a} \${b}
+                    \`(() => {
+                        baz();
+                    })
+            `,
+            parserOptions: { ecmaVersion: 2015 }
+        },
+        {
+            code: unIndent`
+                foo
+                .test\`
+                    \${a} \${b}
+                    \`(() => {
+                    baz();
+                })
+            `,
+            options: [4, { MemberExpression: 0 }],
+            parserOptions: { ecmaVersion: 2015 }
+        },
+        {
+            code: unIndent`
+                foo
+                        .test\`
+                    \${a} \${b}
+                    \`(() => {
+                            baz();
+                        })
+            `,
+            options: [4, { MemberExpression: 2 }],
+            parserOptions: { ecmaVersion: 2015 }
         }
     ],
 
@@ -10831,6 +11049,331 @@ ruleTester.run("indent", rule, {
                 [2, 4, 0, "Identifier"],
                 [3, 0, 4, "Punctuator"]
             ])
+        },
+
+        // https://github.com/eslint/eslint/issues/12122
+        {
+            code: unIndent`
+                foo(() => {
+                    tag\`
+                    multiline
+                    template\${a} \${b}
+                    literal
+                    \`(() => {
+                    bar();
+                    });
+                });
+            `,
+            output: unIndent`
+                foo(() => {
+                    tag\`
+                    multiline
+                    template\${a} \${b}
+                    literal
+                    \`(() => {
+                        bar();
+                    });
+                });
+            `,
+            parserOptions: { ecmaVersion: 2015 },
+            errors: expectedErrors([
+                [7, 8, 4, "Identifier"]
+            ])
+        },
+        {
+            code: unIndent`
+                {
+                        tag\`
+                    multiline
+                    template
+                    literal
+                    \${a} \${b}\`(() => {
+                            bar();
+                        });
+                }
+            `,
+            output: unIndent`
+                {
+                    tag\`
+                    multiline
+                    template
+                    literal
+                    \${a} \${b}\`(() => {
+                        bar();
+                    });
+                }
+            `,
+            parserOptions: { ecmaVersion: 2015 },
+            errors: expectedErrors([
+                [2, 4, 8, "Identifier"],
+                [7, 8, 12, "Identifier"],
+                [8, 4, 8, "Punctuator"]
+            ])
+        },
+        {
+            code: unIndent`
+                foo(() => {
+                    tagOne\`\${a} \${b}
+                    multiline
+                    template
+                    literal
+                    \`(() => {
+                            tagTwo\`
+                        multiline
+                        template
+                        literal
+                        \`(() => {
+                            bar();
+                        });
+
+                            baz();
+                });
+                });
+            `,
+            output: unIndent`
+                foo(() => {
+                    tagOne\`\${a} \${b}
+                    multiline
+                    template
+                    literal
+                    \`(() => {
+                        tagTwo\`
+                        multiline
+                        template
+                        literal
+                        \`(() => {
+                            bar();
+                        });
+
+                        baz();
+                    });
+                });
+            `,
+            parserOptions: { ecmaVersion: 2015 },
+            errors: expectedErrors([
+                [7, 8, 12, "Identifier"],
+                [15, 8, 12, "Identifier"],
+                [16, 4, 0, "Punctuator"]
+            ])
+        },
+        {
+            code: unIndent`
+                {
+                    tagOne\`
+                    multiline
+                    template
+                    literal
+                    \${a} \${b}\`(() => {
+                            tagTwo\`
+                        multiline
+                        template
+                        literal
+                        \`(() => {
+                            bar();
+                        });
+
+                            baz();
+                });
+                }
+            `,
+            output: unIndent`
+                {
+                    tagOne\`
+                    multiline
+                    template
+                    literal
+                    \${a} \${b}\`(() => {
+                        tagTwo\`
+                        multiline
+                        template
+                        literal
+                        \`(() => {
+                            bar();
+                        });
+
+                        baz();
+                    });
+                }
+            `,
+            parserOptions: { ecmaVersion: 2015 },
+            errors: expectedErrors([
+                [7, 8, 12, "Identifier"],
+                [15, 8, 12, "Identifier"],
+                [16, 4, 0, "Punctuator"]
+            ])
+        },
+        {
+            code: unIndent`
+                tagOne\`multiline \${a} \${b}
+                        template
+                        literal
+                        \`(() => {        
+                foo();
+                    
+                    tagTwo\`multiline
+                            template
+                            literal
+                        \`({
+                    bar: 1,
+                        baz: 2
+                    });
+                });
+            `,
+            output: unIndent`
+                tagOne\`multiline \${a} \${b}
+                        template
+                        literal
+                        \`(() => {        
+                    foo();
+                    
+                    tagTwo\`multiline
+                            template
+                            literal
+                        \`({
+                        bar: 1,
+                        baz: 2
+                    });
+                });
+            `,
+            parserOptions: { ecmaVersion: 2015 },
+            errors: expectedErrors([
+                [5, 4, 0, "Identifier"],
+                [11, 8, 4, "Identifier"]
+            ])
+        },
+        {
+            code: unIndent`
+                tagOne\`multiline
+                    template \${a} \${b}
+                    literal\`({
+                        foo: 1,
+                bar: tagTwo\`multiline
+                        template
+                        literal\`(() => {
+                        
+                baz();
+                    })
+                });
+            `,
+            output: unIndent`
+                tagOne\`multiline
+                    template \${a} \${b}
+                    literal\`({
+                    foo: 1,
+                    bar: tagTwo\`multiline
+                        template
+                        literal\`(() => {
+                        
+                        baz();
+                    })
+                });
+            `,
+            parserOptions: { ecmaVersion: 2015 },
+            errors: expectedErrors([
+                [4, 4, 8, "Identifier"],
+                [5, 4, 0, "Identifier"],
+                [9, 8, 0, "Identifier"]
+            ])
+        },
+        {
+            code: unIndent`
+                foo.bar\` template literal \`(() => {
+                        baz();
+                })
+            `,
+            output: unIndent`
+                foo.bar\` template literal \`(() => {
+                    baz();
+                })
+            `,
+            parserOptions: { ecmaVersion: 2015 },
+            errors: expectedErrors([
+                [2, 4, 8, "Identifier"]
+            ])
+        },
+        {
+            code: unIndent`
+                foo.bar.baz\` template literal \`(() => {
+                baz();
+                    })
+            `,
+            output: unIndent`
+                foo.bar.baz\` template literal \`(() => {
+                    baz();
+                })
+            `,
+            parserOptions: { ecmaVersion: 2015 },
+            errors: expectedErrors([
+                [2, 4, 0, "Identifier"],
+                [3, 0, 4, "Punctuator"]
+            ])
+        },
+        {
+            code: unIndent`
+                foo
+                    .bar\` template
+                        literal \`(() => {
+                        baz();
+                })
+            `,
+            output: unIndent`
+                foo
+                    .bar\` template
+                        literal \`(() => {
+                        baz();
+                    })
+            `,
+            parserOptions: { ecmaVersion: 2015 },
+            errors: expectedErrors([
+                [5, 4, 0, "Punctuator"]
+            ])
+        },
+        {
+            code: unIndent`
+                foo
+                    .test\`
+                    \${a} \${b}
+                    \`(() => {
+                bar();
+                    })
+            `,
+            output: unIndent`
+                foo
+                    .test\`
+                    \${a} \${b}
+                    \`(() => {
+                        bar();
+                    })
+            `,
+            parserOptions: { ecmaVersion: 2015 },
+            errors: expectedErrors([
+                [5, 8, 0, "Identifier"]
+            ])
+        },
+        {
+            code: unIndent`
+                foo
+                    .test\`
+                    \${a} \${b}
+                    \`(() => {
+                bar();
+                    })
+            `,
+            output: unIndent`
+                foo
+                .test\`
+                    \${a} \${b}
+                    \`(() => {
+                    bar();
+                })
+            `,
+            options: [4, { MemberExpression: 0 }],
+            parserOptions: { ecmaVersion: 2015 },
+            errors: expectedErrors([
+                [2, 0, 4, "Punctuator"],
+                [5, 4, 0, "Identifier"],
+                [6, 0, 4, "Punctuator"]
+            ])
         }
     ]
 });
diff --git a/tests/lib/rules/no-extend-native.js b/tests/lib/rules/no-extend-native.js
index 7c1b2514a..a38177431 100644
--- a/tests/lib/rules/no-extend-native.js
+++ b/tests/lib/rules/no-extend-native.js
@@ -56,6 +56,14 @@ ruleTester.run("no-extend-native", rule, {
             data: { builtin: "Object" },
             type: "AssignmentExpression"
         }]
+    }, {
+        code: "BigInt.prototype.p = 0",
+        env: { es2020: true },
+        errors: [{
+            messageId: "unexpected",
+            data: { builtin: "BigInt" },
+            type: "AssignmentExpression"
+        }]
     }, {
         code: "Function.prototype['p'] = 0",
         errors: [{
diff --git a/tests/lib/rules/no-extra-parens.js b/tests/lib/rules/no-extra-parens.js
index 26f682bae..8d20ba7cd 100644
--- a/tests/lib/rules/no-extra-parens.js
+++ b/tests/lib/rules/no-extra-parens.js
@@ -1403,6 +1403,30 @@ ruleTester.run("no-extra-parens", rule, {
         invalid("const [a = (b)] = []", "const [a = b] = []", "Identifier"),
         invalid("const {a = (b)} = {}", "const {a = b} = {}", "Identifier"),
 
+        // LHS of assigments/Assignment targets
+        invalid("(a) = b", "a = b", "Identifier"),
+        invalid("(a.b) = c", "a.b = c", "MemberExpression"),
+        invalid("(a) += b", "a += b", "Identifier"),
+        invalid("(a.b) >>= c", "a.b >>= c", "MemberExpression"),
+        invalid("[(a) = b] = []", "[a = b] = []", "Identifier"),
+        invalid("[(a.b) = c] = []", "[a.b = c] = []", "MemberExpression"),
+        invalid("({ a: (b) = c } = {})", "({ a: b = c } = {})", "Identifier"),
+        invalid("({ a: (b.c) = d } = {})", "({ a: b.c = d } = {})", "MemberExpression"),
+        invalid("[(a)] = []", "[a] = []", "Identifier"),
+        invalid("[(a.b)] = []", "[a.b] = []", "MemberExpression"),
+        invalid("[,(a),,] = []", "[,a,,] = []", "Identifier"),
+        invalid("[...(a)] = []", "[...a] = []", "Identifier"),
+        invalid("[...(a.b)] = []", "[...a.b] = []", "MemberExpression"),
+        invalid("({ a: (b) } = {})", "({ a: b } = {})", "Identifier"),
+        invalid("({ a: (b.c) } = {})", "({ a: b.c } = {})", "MemberExpression"),
+
+        /*
+         * TODO: Add these tests for RestElement's parenthesized arguments in object patterns when that becomes supported by Espree.
+         *
+         * invalid("({ ...(a) } = {})", "({ ...a } = {})", "Identifier"),
+         * invalid("({ ...(a.b) } = {})", "({ ...a.b } = {})", "MemberExpression")
+         */
+
         // https://github.com/eslint/eslint/issues/11706 (also in valid[])
         {
             code: "for ((a = (b in c)); ;);",
diff --git a/tests/lib/rules/no-magic-numbers.js b/tests/lib/rules/no-magic-numbers.js
index 8ebd8c93d..bda02662e 100644
--- a/tests/lib/rules/no-magic-numbers.js
+++ b/tests/lib/rules/no-magic-numbers.js
@@ -75,6 +75,16 @@ ruleTester.run("no-magic-numbers", rule, {
                     jsx: true
                 }
             }
+        },
+        {
+            code: "f(100n)",
+            options: [{ ignore: ["100n"] }],
+            parserOptions: { ecmaVersion: 2020 }
+        },
+        {
+            code: "f(-100n)",
+            options: [{ ignore: ["-100n"] }],
+            parserOptions: { ecmaVersion: 2020 }
         }
     ],
     invalid: [
@@ -93,6 +103,26 @@ ruleTester.run("no-magic-numbers", rule, {
                 { messageId: "noMagic", data: { raw: "1" } }
             ]
         },
+        {
+            code: "var foo = 42n",
+            options: [{
+                enforceConst: true
+            }],
+            parserOptions: {
+                ecmaVersion: 2020
+            },
+            errors: [{ messageId: "useConst" }]
+        },
+        {
+            code: "var foo = 0n + 1n;",
+            parserOptions: {
+                ecmaVersion: 2020
+            },
+            errors: [
+                { messageId: "noMagic", data: { raw: "0n" } },
+                { messageId: "noMagic", data: { raw: "1n" } }
+            ]
+        },
         {
             code: "a = a + 5;",
             errors: [
@@ -227,6 +257,37 @@ ruleTester.run("no-magic-numbers", rule, {
                 { messageId: "noMagic", data: { raw: "10" }, line: 1 },
                 { messageId: "noMagic", data: { raw: "4" }, line: 1 }
             ]
+        },
+        {
+            code: "f(100n)",
+            options: [{ ignore: [100] }],
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [
+                { messageId: "noMagic", data: { raw: "100n" }, line: 1 }
+            ]
+        },
+        {
+            code: "f(-100n)",
+            options: [{ ignore: ["100n"] }],
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [
+                { messageId: "noMagic", data: { raw: "-100n" }, line: 1 }
+            ]
+        },
+        {
+            code: "f(100n)",
+            options: [{ ignore: ["-100n"] }],
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [
+                { messageId: "noMagic", data: { raw: "100n" }, line: 1 }
+            ]
+        },
+        {
+            code: "f(100)",
+            options: [{ ignore: ["100n"] }],
+            errors: [
+                { messageId: "noMagic", data: { raw: "100" }, line: 1 }
+            ]
         }
     ]
 });
diff --git a/tests/lib/rules/no-restricted-imports.js b/tests/lib/rules/no-restricted-imports.js
index 958395f45..680bc1352 100644
--- a/tests/lib/rules/no-restricted-imports.js
+++ b/tests/lib/rules/no-restricted-imports.js
@@ -168,6 +168,17 @@ ruleTester.run("no-restricted-imports", rule, {
         {
             code: "import {\nAllowedObject,\nDisallowedObject, // eslint-disable-line\n} from \"foo\";",
             options: [{ paths: [{ name: "foo", importNames: ["DisallowedObject"] }] }]
+        },
+        {
+            code: "export * from \"foo\";",
+            options: ["bar"]
+        },
+        {
+            code: "export * from \"foo\";",
+            options: [{
+                name: "bar",
+                importNames: ["DisallowedObject"]
+            }]
         }
     ],
     invalid: [{
@@ -356,6 +367,37 @@ ruleTester.run("no-restricted-imports", rule, {
             endColumn: 16
         }]
     },
+    {
+        code: "export * from \"foo\";",
+        options: [{
+            paths: [{
+                name: "foo",
+                importNames: ["DisallowedObject"],
+                message: "Please import 'DisallowedObject' from /bar/ instead."
+            }]
+        }],
+        errors: [{
+            message: "* import is invalid because 'DisallowedObject' from 'foo' is restricted. Please import 'DisallowedObject' from /bar/ instead.",
+            type: "ExportAllDeclaration",
+            line: 1,
+            column: 8,
+            endColumn: 9
+        }]
+    },
+    {
+        code: "export * from \"foo\";",
+        options: [{
+            name: "foo",
+            importNames: ["DisallowedObject1, DisallowedObject2"]
+        }],
+        errors: [{
+            message: "* import is invalid because 'DisallowedObject1, DisallowedObject2' from 'foo' is restricted.",
+            type: "ExportAllDeclaration",
+            line: 1,
+            column: 8,
+            endColumn: 9
+        }]
+    },
     {
         code: "import { DisallowedObject } from \"foo\";",
         options: [{
diff --git a/tests/lib/rules/no-useless-computed-key.js b/tests/lib/rules/no-useless-computed-key.js
index cd33cc732..a5907aede 100644
--- a/tests/lib/rules/no-useless-computed-key.js
+++ b/tests/lib/rules/no-useless-computed-key.js
@@ -40,7 +40,16 @@ ruleTester.run("no-useless-computed-key", rule, {
         { code: "class Foo { ['x']() {} }", options: [{ enforceForClassMembers: false }] },
         { code: "(class { ['x']() {} })", options: [{ enforceForClassMembers: false }] },
         { code: "class Foo { static ['constructor']() {} }", options: [{ enforceForClassMembers: false }] },
-        { code: "class Foo { ['prototype']() {} }", options: [{ enforceForClassMembers: false }] }
+        { code: "class Foo { ['prototype']() {} }", options: [{ enforceForClassMembers: false }] },
+
+        /*
+         * Well-known browsers throw syntax error bigint literals on property names,
+         * so, this rule doesn't touch those for now.
+         */
+        {
+            code: "({ [99999999999999999n]: 0 })",
+            parserOptions: { ecmaVersion: 2020 }
+        }
     ],
     invalid: [
         {
diff --git a/tests/lib/rules/prefer-object-spread.js b/tests/lib/rules/prefer-object-spread.js
index 11c16d60c..9ec3cf630 100644
--- a/tests/lib/rules/prefer-object-spread.js
+++ b/tests/lib/rules/prefer-object-spread.js
@@ -59,7 +59,19 @@ ruleTester.run("prefer-object-spread", rule, {
         `
         import { Object, Array } from 'globals';
         Object.assign({ foo: 'bar' });
-        `
+        `,
+
+        // ignore Object.assign() with > 1 arguments if any of the arguments is an object expression with a getter/setter
+        "Object.assign({ get a() {} }, {})",
+        "Object.assign({ set a(val) {} }, {})",
+        "Object.assign({ get a() {} }, foo)",
+        "Object.assign({ set a(val) {} }, foo)",
+        "Object.assign({ foo: 'bar', get a() {}, baz: 'quux' }, quuux)",
+        "Object.assign({ foo: 'bar', set a(val) {} }, { baz: 'quux' })",
+        "Object.assign({}, { get a() {} })",
+        "Object.assign({}, { set a(val) {} })",
+        "Object.assign({}, { foo: 'bar', get a() {} }, {})",
+        "Object.assign({ foo }, bar, {}, { baz: 'quux', set a(val) {}, quuux }, {})"
     ],
 
     invalid: [
@@ -834,6 +846,20 @@ ruleTester.run("prefer-object-spread", rule, {
                     column: 1
                 }
             ]
+        },
+
+        // report Object.assign() with getters/setters if the function call has only 1 argument
+        {
+            code: "Object.assign({ get a() {}, set b(val) {} })",
+            output: "({get a() {}, set b(val) {}})",
+            errors: [
+                {
+                    messageId: "useLiteralMessage",
+                    type: "CallExpression",
+                    line: 1,
+                    column: 1
+                }
+            ]
         }
     ]
 });
diff --git a/tests/lib/rules/quote-props.js b/tests/lib/rules/quote-props.js
index c1cd10e50..9d033dfb8 100644
--- a/tests/lib/rules/quote-props.js
+++ b/tests/lib/rules/quote-props.js
@@ -73,7 +73,13 @@ ruleTester.run("quote-props", rule, {
         { code: "({1: 1, x: 2})", options: ["consistent-as-needed", { numbers: true }] },
         { code: "({ ...x })", options: ["as-needed"], parserOptions: { ecmaVersion: 2018 } },
         { code: "({ ...x })", options: ["consistent"], parserOptions: { ecmaVersion: 2018 } },
-        { code: "({ ...x })", options: ["consistent-as-needed"], parserOptions: { ecmaVersion: 2018 } }
+        { code: "({ ...x })", options: ["consistent-as-needed"], parserOptions: { ecmaVersion: 2018 } },
+        { code: "({ 1n: 1 })", options: ["as-needed"], parserOptions: { ecmaVersion: 2020 } },
+        { code: "({ 1n: 1 })", options: ["as-needed", { numbers: false }], parserOptions: { ecmaVersion: 2020 } },
+        { code: "({ 1n: 1 })", options: ["consistent"], parserOptions: { ecmaVersion: 2020 } },
+        { code: "({ 1n: 1 })", options: ["consistent-as-needed"], parserOptions: { ecmaVersion: 2020 } },
+        { code: "({ '99999999999999999': 1 })", options: ["as-needed"], parserOptions: { ecmaVersion: 2020 } },
+        { code: "({ '1n': 1 })", options: ["as-needed"], parserOptions: { ecmaVersion: 2020 } }
     ],
     invalid: [{
         code: "({ a: 0 })",
@@ -304,5 +310,17 @@ ruleTester.run("quote-props", rule, {
         errors: [{
             message: "Unquoted property '5' found."
         }]
+    }, {
+        code: "({ 1n: 1 })",
+        output: "({ \"1\": 1 })",
+        options: ["always"],
+        parserOptions: { ecmaVersion: 2020 },
+        errors: [{ message: "Unquoted property '1' found." }]
+    }, {
+        code: "({ 1n: 1 })",
+        output: "({ \"1\": 1 })",
+        options: ["as-needed", { numbers: true }],
+        parserOptions: { ecmaVersion: 2020 },
+        errors: [{ message: "Unquoted number literal '1' used as key." }]
     }]
 });
diff --git a/tests/lib/rules/yoda.js b/tests/lib/rules/yoda.js
index 414cb5a04..72f013964 100644
--- a/tests/lib/rules/yoda.js
+++ b/tests/lib/rules/yoda.js
@@ -91,6 +91,22 @@ ruleTester.run("yoda", rule, {
         }, {
             code: "if (0 <= a.b && a[\"b\"] <= 100) {}",
             options: ["never", { exceptRange: true }]
+        }, {
+            code: "if (-1n < x && x <= 1n) {}",
+            options: ["never", { exceptRange: true }],
+            parserOptions: { ecmaVersion: 2020 }
+        }, {
+            code: "if (x < -1n || 1n <= x) {}",
+            options: ["never", { exceptRange: true }],
+            parserOptions: { ecmaVersion: 2020 }
+        }, {
+            code: "if (-1n <= x && x < 1n) {}",
+            options: ["always", { exceptRange: true }],
+            parserOptions: { ecmaVersion: 2020 }
+        }, {
+            code: "if (x < -1n || 1n <= x) {}",
+            options: ["always", { exceptRange: true }],
+            parserOptions: { ecmaVersion: 2020 }
         }, {
             code: "if (1 <= a['/(?<zero>0)/'] && a[/(?<zero>0)/] <= 100) {}",
             options: ["never", { exceptRange: true }],
@@ -140,6 +156,19 @@ ruleTester.run("yoda", rule, {
                 }
             ]
         },
+        {
+            code: "if (5n != value) {}",
+            output: "if (value != 5n) {}",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [
+                {
+                    messageId: "expected",
+                    data: { expectedSide: "right", operator: "!=" },
+                    type: "BinaryExpression"
+                }
+            ]
+        },
         {
             code: "if (null !== value) {}",
             output: "if (value !== null) {}",
@@ -236,6 +265,19 @@ ruleTester.run("yoda", rule, {
                 }
             ]
         },
+        {
+            code: "if (value === 5n) {}",
+            output: "if (5n === value) {}",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [
+                {
+                    messageId: "expected",
+                    data: { expectedSide: "left", operator: "===" },
+                    type: "BinaryExpression"
+                }
+            ]
+        },
         {
             code: "if (a < 0 && 0 <= b && b < 1) {}",
             output: "if (a < 0 && b >= 0 && b < 1) {}",