Repository: eslint/eslint
Pull request #8359 (2017-03-29 20:50:01)

Fix: no-extra-parens false positive with functions in default exports
**What is the purpose of this pull request? (put an "X" next to item)**

[x] Bug fix

**Tell us about your environment**

* **ESLint Version:** master
* **Node Version:** 7.8.0
* **npm Version:** 4.2.0

**What parser (default, Babel-ESLint, etc.) are you using?**

**Please show your full configuration:**

```yml
parserOptions:
  ecmaVersion: 2015
  sourceType: module

rules:
  no-extra-parens: error
```

**What did you do? Please include the actual source code causing the issue.**

```js
export default (function() {}).foo;

({}).hasOwnProperty.call(foo, bar);
```

**What did you expect to happen?**

No error should be reported, because removing the parentheses would be a syntax error.

**What actually happened? Please include the actual, raw output from ESLint.**

Errors were reported for both lines.

```
1:16  error  Gratuitous parentheses around expression  no-extra-parens
2:1  error  Gratuitous parentheses around expression  no-extra-parens
```

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->

<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (http://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)**

This commit fixes an issue where no-extra-parens would incorrectly report parenthesized functions and classes in `export default` declarations. Previously, our logic for checking whether a token was allowed at the beginning of an expression (e.g. `function` to distinguish between function declarations and function expressions) was incomplete, so this commit refactors that logic.

**Is there anything you'd like reviewers to focus on?**

Nothing in particular


eslintbot: LGTM
not-an-aardvark: I noticed a few related cases where the check still fails, so I'll update this PR in a few minutes.
eslintbot: LGTM
eslintbot: LGTM

Patch:
diff --git a/README.md b/README.md
index a08f276fc..1ccdbb9bf 100644
--- a/README.md
+++ b/README.md
@@ -130,6 +130,7 @@ These folks keep the project moving and are resources for help.
 * Kevin Partington ([@platinumazure](https://github.com/platinumazure))
 * Vitor Balocco ([@vitorbal](https://github.com/vitorbal))
 * James Henry ([@JamesHenry](https://github.com/JamesHenry))
+* Reyad Attiyat ([@soda0289](https://github.com/soda0289))
 
 ## Releases
 
diff --git a/docs/rules/linebreak-style.md b/docs/rules/linebreak-style.md
index 9b7580e00..96f6c9f50 100644
--- a/docs/rules/linebreak-style.md
+++ b/docs/rules/linebreak-style.md
@@ -67,9 +67,19 @@ function foo(params) { // \r\n
 } // \r\n
 ```
 
+## Using this rule with version control systems
+
+Version control systems sometimes have special behavior for linebreaks. To make it easy for developers to contribute to your codebase from different platforms, you may want to configure your VCS to handle linebreaks appropriately.
+
+For example, the default behavior of [git](https://git-scm.com/) on Windows systems is to convert LF linebreaks to CRLF when checking out files, but to store the linebreaks as LF when committing a change. This will cause the `linebreak-style` rule to report errors if configured with the `"unix"` setting, because the files that ESLint sees will have CRLF linebreaks. If you use git, you may want to add a line to your [`.gitattributes` file](https://git-scm.com/docs/gitattributes) to prevent git from converting linebreaks in `.js` files:
+
+```
+*.js text eol=lf
+```
+
 ## When Not To Use It
 
-If you aren't concerned about having different line endings within you code, then you can safely turn this rule off.
+If you aren't concerned about having different line endings within your code, then you can safely turn this rule off.
 
 ## Compatibility
 
diff --git a/docs/rules/no-restricted-syntax.md b/docs/rules/no-restricted-syntax.md
index ffe763c8b..8efbd780e 100644
--- a/docs/rules/no-restricted-syntax.md
+++ b/docs/rules/no-restricted-syntax.md
@@ -12,7 +12,7 @@ This rule disallows specified (that is, user-defined) syntax.
 
 ## Options
 
-This rule takes a list of strings:
+This rule takes a list of strings, where each string is an AST selector:
 
 ```json
 {
@@ -22,6 +22,30 @@ This rule takes a list of strings:
 }
 ```
 
+Alternatively, the rule also accepts objects, where the selector and an optional custom message are specified:
+
+```json
+{
+    "rules": {
+        "no-restricted-syntax": [
+            "error",
+            {
+                "selector": "FunctionExpression",
+                "message": "Function expressions are not allowed."
+            },
+            {
+                "selector": "CallExpression[callee.name='setTimeout'][arguments.length!=2]",
+                "message": "setTimeout must always be invoked with two arguments."
+            }
+        ]
+    }
+}
+```
+
+If a custom message is specified with the `message` property, ESLint will use that message when reporting occurrences of the syntax specified in the `selector` property.
+
+The string and object formats can be freely mixed in the configuration as needed.
+
 Examples of **incorrect** code for this rule with the `"FunctionExpression", "WithStatement", BinaryExpression[operator='in']` options:
 
 ```js
diff --git a/lib/config/plugins.js b/lib/config/plugins.js
index 5073d564a..e28a77929 100644
--- a/lib/config/plugins.js
+++ b/lib/config/plugins.js
@@ -127,14 +127,25 @@ module.exports = {
         if (!plugins[shortName]) {
             try {
                 plugin = require(longName);
-            } catch (err) {
-                debug(`Failed to load plugin ${longName}.`);
-                err.message = `Failed to load plugin ${pluginName}: ${err.message}`;
-                err.messageTemplate = "plugin-missing";
-                err.messageData = {
-                    pluginName: longName
-                };
-                throw err;
+            } catch (pluginLoadErr) {
+                try {
+
+                    // Check whether the plugin exists
+                    require.resolve(longName);
+                } catch (missingPluginErr) {
+
+                    // If the plugin can't be resolved, display the missing plugin error (usually a config or install error)
+                    debug(`Failed to load plugin ${longName}.`);
+                    missingPluginErr.message = `Failed to load plugin ${pluginName}: ${missingPluginErr.message}`;
+                    missingPluginErr.messageTemplate = "plugin-missing";
+                    missingPluginErr.messageData = {
+                        pluginName: longName
+                    };
+                    throw missingPluginErr;
+                }
+
+                // Otherwise, the plugin exists and is throwing on module load for some reason, so print the stack trace.
+                throw pluginLoadErr;
             }
 
             this.define(pluginName, plugin);
diff --git a/lib/rules/no-extra-parens.js b/lib/rules/no-extra-parens.js
index 42a86484b..bbfae735c 100644
--- a/lib/rules/no-extra-parens.js
+++ b/lib/rules/no-extra-parens.js
@@ -60,6 +60,7 @@ module.exports = {
     create(context) {
         const sourceCode = context.getSourceCode();
 
+        const tokensToIgnore = new WeakSet();
         const isParenthesised = astUtils.isParenthesised.bind(astUtils, sourceCode);
         const precedence = astUtils.getPrecedence;
         const ALL_NODES = context.options[0] !== "functions";
@@ -238,69 +239,6 @@ module.exports = {
             return hasDoubleExcessParens(node);
         }
 
-        /**
-         * Checks whether or not a given node is located at the head of ExpressionStatement.
-         * @param {ASTNode} node - A node to check.
-         * @returns {boolean} `true` if the node is located at the head of ExpressionStatement.
-         */
-        function isHeadOfExpressionStatement(node) {
-            let parent = node.parent;
-
-            while (parent) {
-                switch (parent.type) {
-                    case "SequenceExpression":
-                        if (parent.expressions[0] !== node || isParenthesised(node)) {
-                            return false;
-                        }
-                        break;
-
-                    case "UnaryExpression":
-                    case "UpdateExpression":
-                        if (parent.prefix || isParenthesised(node)) {
-                            return false;
-                        }
-                        break;
-
-                    case "BinaryExpression":
-                    case "LogicalExpression":
-                        if (parent.left !== node || isParenthesised(node)) {
-                            return false;
-                        }
-                        break;
-
-                    case "ConditionalExpression":
-                        if (parent.test !== node || isParenthesised(node)) {
-                            return false;
-                        }
-                        break;
-
-                    case "CallExpression":
-                        if (parent.callee !== node || isParenthesised(node)) {
-                            return false;
-                        }
-                        break;
-
-                    case "MemberExpression":
-                        if (parent.object !== node || isParenthesised(node)) {
-                            return false;
-                        }
-                        break;
-
-                    case "ExpressionStatement":
-                        return true;
-
-                    default:
-                        return false;
-                }
-
-                node = parent;
-                parent = parent.parent;
-            }
-
-            /* istanbul ignore next */
-            throw new Error("unreachable");
-        }
-
         /**
          * Determines whether a node should be preceded by an additional space when removing parens
          * @param {ASTNode} node node to evaluate; must be surrounded by parentheses
@@ -345,9 +283,8 @@ module.exports = {
         function report(node) {
             const leftParenToken = sourceCode.getTokenBefore(node);
             const rightParenToken = sourceCode.getTokenAfter(node);
-            const tokenBeforeLeftParen = sourceCode.getTokenBefore(leftParenToken);
 
-            if (tokenBeforeLeftParen && astUtils.isArrowToken(tokenBeforeLeftParen) && astUtils.isOpeningBraceToken(sourceCode.getFirstToken(node))) {
+            if (tokensToIgnore.has(sourceCode.getFirstToken(node)) && !isParenthesisedTwice(node)) {
                 return;
             }
 
@@ -471,6 +408,34 @@ module.exports = {
             }
         }
 
+        /**
+         * Checks the parentheses for an ExpressionStatement or ExportDefaultDeclaration
+         * @param {ASTNode} node The ExpressionStatement.expression or ExportDefaultDeclaration.declaration node
+         * @returns {void}
+         */
+        function checkExpressionOrExportStatement(node) {
+            const firstToken = isParenthesised(node) ? sourceCode.getTokenBefore(node) : sourceCode.getFirstToken(node);
+            const secondToken = sourceCode.getTokenAfter(firstToken, astUtils.isNotOpeningParenToken);
+
+            if (
+                astUtils.isOpeningParenToken(firstToken) &&
+                (
+                    astUtils.isOpeningBraceToken(secondToken) ||
+                    secondToken.type === "Keyword" && (
+                        secondToken.value === "function" ||
+                        secondToken.value === "class" ||
+                        secondToken.value === "let" && astUtils.isOpeningBracketToken(sourceCode.getTokenAfter(secondToken))
+                    )
+                )
+            ) {
+                tokensToIgnore.add(secondToken);
+            }
+
+            if (hasExcessParens(node)) {
+                report(node);
+            }
+        }
+
         return {
             ArrayExpression(node) {
                 [].forEach.call(node.elements, e => {
@@ -486,13 +451,13 @@ module.exports = {
                 }
 
                 if (node.body.type !== "BlockStatement") {
-                    if (hasExcessParens(node.body) && precedence(node.body) >= PRECEDENCE_OF_ASSIGNMENT_EXPR) {
-                        report(node.body);
-                        return;
-                    }
+                    const firstBodyToken = sourceCode.getFirstToken(node.body, astUtils.isNotOpeningParenToken);
+                    const tokenBeforeFirst = sourceCode.getTokenBefore(firstBodyToken);
 
-                    // Object literals *must* be parenthesised
-                    if (node.body.type === "ObjectExpression" && hasDoubleExcessParens(node.body)) {
+                    if (astUtils.isOpeningParenToken(tokenBeforeFirst) && astUtils.isOpeningBraceToken(firstBodyToken)) {
+                        tokensToIgnore.add(firstBodyToken);
+                    }
+                    if (hasExcessParens(node.body) && precedence(node.body) >= PRECEDENCE_OF_ASSIGNMENT_EXPR) {
                         report(node.body);
                     }
                 }
@@ -535,27 +500,8 @@ module.exports = {
                 }
             },
 
-            ExpressionStatement(node) {
-                if (hasExcessParens(node.expression)) {
-                    const firstTokens = sourceCode.getFirstTokens(node.expression, 2);
-                    const firstToken = firstTokens[0];
-                    const secondToken = firstTokens[1];
-
-                    if (
-                        !firstToken ||
-                        firstToken.value !== "{" &&
-                        firstToken.value !== "function" &&
-                        firstToken.value !== "class" &&
-                        (
-                            firstToken.value !== "let" ||
-                            !secondToken ||
-                            secondToken.value !== "["
-                        )
-                    ) {
-                        report(node.expression);
-                    }
-                }
-            },
+            ExportDefaultDeclaration: node => checkExpressionOrExportStatement(node.declaration),
+            ExpressionStatement: node => checkExpressionOrExportStatement(node.expression),
 
             ForInStatement(node) {
                 if (hasExcessParens(node.right)) {
@@ -598,18 +544,11 @@ module.exports = {
                     (
                         node.computed ||
                         !(
-                            (node.object.type === "Literal" &&
-                            typeof node.object.value === "number" &&
-                            astUtils.isDecimalInteger(node.object)) ||
+                            astUtils.isDecimalInteger(node.object) ||
 
                             // RegExp literal is allowed to have parens (#1589)
                             (node.object.type === "Literal" && node.object.regex)
                         )
-                    ) &&
-                    !(
-                        (node.object.type === "FunctionExpression" || node.object.type === "ClassExpression") &&
-                        isHeadOfExpressionStatement(node) &&
-                        !hasDoubleExcessParens(node.object)
                     )
                 ) {
                     report(node.object);
diff --git a/lib/rules/no-native-reassign.js b/lib/rules/no-native-reassign.js
index f721fc278..d3dfefbaf 100644
--- a/lib/rules/no-native-reassign.js
+++ b/lib/rules/no-native-reassign.js
@@ -15,7 +15,7 @@ module.exports = {
         docs: {
             description: "disallow assignments to native objects or read-only global variables",
             category: "Best Practices",
-            recommended: true,
+            recommended: false,
             replacedBy: ["no-global-assign"]
         },
 
diff --git a/lib/rules/no-negated-in-lhs.js b/lib/rules/no-negated-in-lhs.js
index 143518060..495cbc160 100644
--- a/lib/rules/no-negated-in-lhs.js
+++ b/lib/rules/no-negated-in-lhs.js
@@ -15,7 +15,7 @@ module.exports = {
         docs: {
             description: "disallow negating the left operand in `in` expressions",
             category: "Possible Errors",
-            recommended: true,
+            recommended: false,
             replacedBy: ["no-unsafe-negation"]
         },
         deprecated: true,
diff --git a/lib/rules/no-restricted-syntax.js b/lib/rules/no-restricted-syntax.js
index d87e589c7..1798065ec 100644
--- a/lib/rules/no-restricted-syntax.js
+++ b/lib/rules/no-restricted-syntax.js
@@ -18,18 +18,45 @@ module.exports = {
 
         schema: {
             type: "array",
-            items: [{ type: "string" }],
+            items: [{
+                oneOf: [
+                    {
+                        type: "string"
+                    },
+                    {
+                        type: "object",
+                        properties: {
+                            selector: { type: "string" },
+                            message: { type: "string" }
+                        },
+                        required: ["selector"],
+                        additionalProperties: false
+                    }
+                ]
+            }],
             uniqueItems: true,
             minItems: 0
         }
     },
 
     create(context) {
-        return context.options.reduce((result, selector) => Object.assign(result, {
-            [selector](node) {
-                context.report({ node, message: "Using '{{selector}}' is not allowed.", data: { selector } });
-            }
-        }), {});
+        return context.options.reduce((result, selectorOrObject) => {
+            const isStringFormat = (typeof selectorOrObject === "string");
+            const hasCustomMessage = !isStringFormat && Boolean(selectorOrObject.message);
+
+            const selector = isStringFormat ? selectorOrObject : selectorOrObject.selector;
+            const message = hasCustomMessage ? selectorOrObject.message : "Using '{{selector}}' is not allowed.";
+
+            return Object.assign(result, {
+                [selector](node) {
+                    context.report({
+                        node,
+                        message,
+                        data: hasCustomMessage ? {} : { selector }
+                    });
+                }
+            });
+        }, {});
 
     }
 };
diff --git a/lib/rules/no-unsafe-negation.js b/lib/rules/no-unsafe-negation.js
index 4e2378d4d..761dc0338 100644
--- a/lib/rules/no-unsafe-negation.js
+++ b/lib/rules/no-unsafe-negation.js
@@ -44,7 +44,7 @@ module.exports = {
         docs: {
             description: "disallow negating the left operand of relational operators",
             category: "Possible Errors",
-            recommended: false
+            recommended: true
         },
         schema: [],
         fixable: "code"
diff --git a/lib/rules/operator-assignment.js b/lib/rules/operator-assignment.js
index 1c40eed15..99cca356f 100644
--- a/lib/rules/operator-assignment.js
+++ b/lib/rules/operator-assignment.js
@@ -4,6 +4,12 @@
  */
 "use strict";
 
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const astUtils = require("../ast-utils");
+
 //------------------------------------------------------------------------------
 // Helpers
 //------------------------------------------------------------------------------
@@ -171,9 +177,20 @@ module.exports = {
                         if (canBeFixed(node.left)) {
                             const operatorToken = getOperatorToken(node);
                             const leftText = sourceCode.getText().slice(node.range[0], operatorToken.range[0]);
-                            const rightText = sourceCode.getText().slice(operatorToken.range[1], node.range[1]);
+                            const newOperator = node.operator.slice(0, -1);
+                            let rightText;
+
+                            // If this change would modify precedence (e.g. `foo *= bar + 1` => `foo = foo * (bar + 1)`), parenthesize the right side.
+                            if (
+                                astUtils.getPrecedence(node.right) <= astUtils.getPrecedence({ type: "BinaryExpression", operator: newOperator }) &&
+                                !astUtils.isParenthesised(sourceCode, node.right)
+                            ) {
+                                rightText = `${sourceCode.text.slice(operatorToken.range[1], node.right.range[0])}(${sourceCode.getText(node.right)})`;
+                            } else {
+                                rightText = sourceCode.text.slice(operatorToken.range[1], node.range[1]);
+                            }
 
-                            return fixer.replaceText(node, `${leftText}= ${leftText}${node.operator.slice(0, -1)}${rightText}`);
+                            return fixer.replaceText(node, `${leftText}= ${leftText}${newOperator}${rightText}`);
                         }
                         return null;
                     }
diff --git a/lib/rules/prefer-const.js b/lib/rules/prefer-const.js
index 07d8da82a..53bdc2ab7 100644
--- a/lib/rules/prefer-const.js
+++ b/lib/rules/prefer-const.js
@@ -9,7 +9,7 @@
 // Helpers
 //------------------------------------------------------------------------------
 
-const PATTERN_TYPE = /^(?:.+?Pattern|RestElement|Property)$/;
+const PATTERN_TYPE = /^(?:.+?Pattern|RestElement|SpreadProperty|ExperimentalRestProperty|Property)$/;
 const DECLARATION_HOST_TYPE = /^(?:Program|BlockStatement|SwitchCase)$/;
 const DESTRUCTURING_HOST_TYPE = /^(?:VariableDeclarator|AssignmentExpression)$/;
 
diff --git a/lib/rules/space-before-function-paren.js b/lib/rules/space-before-function-paren.js
index c36c5a953..53aac71ed 100644
--- a/lib/rules/space-before-function-paren.js
+++ b/lib/rules/space-before-function-paren.js
@@ -102,34 +102,43 @@ module.exports = {
             return "ignore";
         }
 
-        return {
-            ":function"(node) {
-                const functionConfig = getConfigForFunction(node);
+        /**
+         * Checks the parens of a function node
+         * @param {ASTNode} node A function node
+         * @returns {void}
+         */
+        function checkFunction(node) {
+            const functionConfig = getConfigForFunction(node);
 
-                if (functionConfig === "ignore") {
-                    return;
-                }
+            if (functionConfig === "ignore") {
+                return;
+            }
 
-                const rightToken = sourceCode.getFirstToken(node, astUtils.isOpeningParenToken);
-                const leftToken = sourceCode.getTokenBefore(rightToken);
-                const hasSpacing = sourceCode.isSpaceBetweenTokens(leftToken, rightToken);
-
-                if (hasSpacing && functionConfig === "never") {
-                    context.report({
-                        node,
-                        loc: leftToken.loc.end,
-                        message: "Unexpected space before function parentheses.",
-                        fix: fixer => fixer.removeRange([leftToken.range[1], rightToken.range[0]])
-                    });
-                } else if (!hasSpacing && functionConfig === "always") {
-                    context.report({
-                        node,
-                        loc: leftToken.loc.end,
-                        message: "Missing space before function parentheses.",
-                        fix: fixer => fixer.insertTextAfter(leftToken, " ")
-                    });
-                }
+            const rightToken = sourceCode.getFirstToken(node, astUtils.isOpeningParenToken);
+            const leftToken = sourceCode.getTokenBefore(rightToken);
+            const hasSpacing = sourceCode.isSpaceBetweenTokens(leftToken, rightToken);
+
+            if (hasSpacing && functionConfig === "never") {
+                context.report({
+                    node,
+                    loc: leftToken.loc.end,
+                    message: "Unexpected space before function parentheses.",
+                    fix: fixer => fixer.removeRange([leftToken.range[1], rightToken.range[0]])
+                });
+            } else if (!hasSpacing && functionConfig === "always") {
+                context.report({
+                    node,
+                    loc: leftToken.loc.end,
+                    message: "Missing space before function parentheses.",
+                    fix: fixer => fixer.insertTextAfter(leftToken, " ")
+                });
             }
+        }
+
+        return {
+            ArrowFunctionExpression: checkFunction,
+            FunctionDeclaration: checkFunction,
+            FunctionExpression: checkFunction
         };
     }
 };
diff --git a/lib/util/glob-util.js b/lib/util/glob-util.js
index d414f783f..4c21fc551 100644
--- a/lib/util/glob-util.js
+++ b/lib/util/glob-util.js
@@ -86,7 +86,7 @@ function resolveFileGlobPatterns(patterns, options) {
 
     const processPathExtensions = processPath(options);
 
-    return patterns.map(processPathExtensions);
+    return patterns.filter(p => p.length).map(processPathExtensions);
 }
 
 /**


Test patch:
diff --git a/tests/fixtures/parsers/babel-eslint5/destructuring-object-spread.js b/tests/fixtures/parsers/babel-eslint5/destructuring-object-spread.js
new file mode 100644
index 000000000..985446c22
--- /dev/null
+++ b/tests/fixtures/parsers/babel-eslint5/destructuring-object-spread.js
@@ -0,0 +1,1726 @@
+"use strict";
+
+// The AST from babel-eslint version 5.x, for the following code:
+//
+//     let { name, ...otherStuff } = obj; otherStuff = {};
+//
+
+exports.parse = function() {
+    return {
+        type: "Program",
+        start: 0,
+        end: 53,
+        loc: {
+            start: {
+                line: 1,
+                column: 0
+            },
+            end: {
+                line: 3,
+                column: 0
+            }
+        },
+        sourceType: "module",
+        body: [
+            {
+                type: "VariableDeclaration",
+                start: 0,
+                end: 34,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 0
+                    },
+                    end: {
+                        line: 1,
+                        column: 34
+                    }
+                },
+                declarations: [
+                    {
+                        type: "VariableDeclarator",
+                        start: 4,
+                        end: 33,
+                        loc: {
+                            start: {
+                                line: 1,
+                                column: 4
+                            },
+                            end: {
+                                line: 1,
+                                column: 33
+                            }
+                        },
+                        id: {
+                            type: "ObjectPattern",
+                            start: 4,
+                            end: 27,
+                            loc: {
+                                start: {
+                                    line: 1,
+                                    column: 4
+                                },
+                                end: {
+                                    line: 1,
+                                    column: 27
+                                }
+                            },
+                            properties: [
+                                {
+                                    type: "Property",
+                                    start: 6,
+                                    end: 10,
+                                    loc: {
+                                        start: {
+                                            line: 1,
+                                            column: 6
+                                        },
+                                        end: {
+                                            line: 1,
+                                            column: 10
+                                        }
+                                    },
+                                    method: false,
+                                    shorthand: true,
+                                    computed: false,
+                                    key: {
+                                        type: "Identifier",
+                                        start: 6,
+                                        end: 10,
+                                        loc: {
+                                            start: {
+                                                line: 1,
+                                                column: 6
+                                            },
+                                            end: {
+                                                line: 1,
+                                                column: 10
+                                            }
+                                        },
+                                        name: "name",
+                                        range: [
+                                            6,
+                                            10
+                                        ],
+                                        _babelType: "Identifier"
+                                    },
+                                    kind: "init",
+                                    value: {
+                                        type: "Identifier",
+                                        start: 6,
+                                        end: 10,
+                                        loc: {
+                                            start: {
+                                                line: 1,
+                                                column: 6
+                                            },
+                                            end: {
+                                                line: 1,
+                                                column: 10
+                                            }
+                                        },
+                                        name: "name",
+                                        range: [
+                                            6,
+                                            10
+                                        ],
+                                        _babelType: "Identifier"
+                                    },
+                                    range: [
+                                        6,
+                                        10
+                                    ],
+                                    _babelType: "Property"
+                                },
+                                {
+                                    type: "SpreadProperty",
+                                    start: 12,
+                                    end: 25,
+                                    loc: {
+                                        start: {
+                                            line: 1,
+                                            column: 12
+                                        },
+                                        end: {
+                                            line: 1,
+                                            column: 25
+                                        }
+                                    },
+                                    argument: {
+                                        type: "Identifier",
+                                        start: 15,
+                                        end: 25,
+                                        loc: {
+                                            start: {
+                                                line: 1,
+                                                column: 15
+                                            },
+                                            end: {
+                                                line: 1,
+                                                column: 25
+                                            }
+                                        },
+                                        name: "otherStuff",
+                                        range: [
+                                            15,
+                                            25
+                                        ],
+                                        _babelType: "Identifier"
+                                    },
+                                    range: [
+                                        12,
+                                        25
+                                    ],
+                                    _babelType: "SpreadProperty",
+                                    value: {
+                                        type: "Identifier",
+                                        start: 15,
+                                        end: 25,
+                                        loc: {
+                                            start: {
+                                                line: 1,
+                                                column: 15
+                                            },
+                                            end: {
+                                                line: 1,
+                                                column: 25
+                                            }
+                                        },
+                                        name: "otherStuff",
+                                        range: [
+                                            15,
+                                            25
+                                        ],
+                                        _babelType: "Identifier"
+                                    },
+                                    key: {
+                                        type: "Identifier",
+                                        start: 15,
+                                        end: 25,
+                                        loc: {
+                                            start: {
+                                                line: 1,
+                                                column: 15
+                                            },
+                                            end: {
+                                                line: 1,
+                                                column: 25
+                                            }
+                                        },
+                                        name: "otherStuff",
+                                        range: [
+                                            15,
+                                            25
+                                        ],
+                                        _babelType: "Identifier"
+                                    }
+                                }
+                            ],
+                            range: [
+                                4,
+                                27
+                            ],
+                            _babelType: "ObjectPattern"
+                        },
+                        init: {
+                            type: "Identifier",
+                            start: 30,
+                            end: 33,
+                            loc: {
+                                start: {
+                                    line: 1,
+                                    column: 30
+                                },
+                                end: {
+                                    line: 1,
+                                    column: 33
+                                }
+                            },
+                            name: "obj",
+                            range: [
+                                30,
+                                33
+                            ],
+                            _babelType: "Identifier"
+                        },
+                        range: [
+                            4,
+                            33
+                        ],
+                        _babelType: "VariableDeclarator"
+                    }
+                ],
+                kind: "let",
+                range: [
+                    0,
+                    34
+                ],
+                _babelType: "VariableDeclaration"
+            },
+            {
+                type: "ExpressionStatement",
+                start: 35,
+                end: 51,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 35
+                    },
+                    end: {
+                        line: 1,
+                        column: 51
+                    }
+                },
+                expression: {
+                    type: "AssignmentExpression",
+                    start: 35,
+                    end: 50,
+                    loc: {
+                        start: {
+                            line: 1,
+                            column: 35
+                        },
+                        end: {
+                            line: 1,
+                            column: 50
+                        }
+                    },
+                    operator: "=",
+                    left: {
+                        type: "Identifier",
+                        start: 35,
+                        end: 45,
+                        loc: {
+                            start: {
+                                line: 1,
+                                column: 35
+                            },
+                            end: {
+                                line: 1,
+                                column: 45
+                            }
+                        },
+                        name: "otherStuff",
+                        range: [
+                            35,
+                            45
+                        ],
+                        _babelType: "Identifier"
+                    },
+                    right: {
+                        type: "ObjectExpression",
+                        start: 48,
+                        end: 50,
+                        loc: {
+                            start: {
+                                line: 1,
+                                column: 48
+                            },
+                            end: {
+                                line: 1,
+                                column: 50
+                            }
+                        },
+                        properties: [],
+                        range: [
+                            48,
+                            50
+                        ],
+                        _babelType: "ObjectExpression"
+                    },
+                    range: [
+                        35,
+                        50
+                    ],
+                    _babelType: "AssignmentExpression"
+                },
+                range: [
+                    35,
+                    51
+                ],
+                _babelType: "ExpressionStatement"
+            }
+        ],
+        tokens: [
+            {
+                type: "Keyword",
+                value: "let",
+                start: 0,
+                end: 3,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 0
+                    },
+                    end: {
+                        line: 1,
+                        column: 3
+                    }
+                },
+                range: [
+                    0,
+                    3
+                ]
+            },
+            {
+                type: "Punctuator",
+                value: "{",
+                start: 4,
+                end: 5,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 4
+                    },
+                    end: {
+                        line: 1,
+                        column: 5
+                    }
+                },
+                range: [
+                    4,
+                    5
+                ]
+            },
+            {
+                type: "Identifier",
+                value: "name",
+                start: 6,
+                end: 10,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 6
+                    },
+                    end: {
+                        line: 1,
+                        column: 10
+                    }
+                },
+                range: [
+                    6,
+                    10
+                ]
+            },
+            {
+                type: "Punctuator",
+                value: ",",
+                start: 10,
+                end: 11,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 10
+                    },
+                    end: {
+                        line: 1,
+                        column: 11
+                    }
+                },
+                range: [
+                    10,
+                    11
+                ]
+            },
+            {
+                type: "Punctuator",
+                value: "...",
+                start: 12,
+                end: 15,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 12
+                    },
+                    end: {
+                        line: 1,
+                        column: 15
+                    }
+                },
+                range: [
+                    12,
+                    15
+                ]
+            },
+            {
+                type: "Identifier",
+                value: "otherStuff",
+                start: 15,
+                end: 25,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 15
+                    },
+                    end: {
+                        line: 1,
+                        column: 25
+                    }
+                },
+                range: [
+                    15,
+                    25
+                ]
+            },
+            {
+                type: "Punctuator",
+                value: "}",
+                start: 26,
+                end: 27,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 26
+                    },
+                    end: {
+                        line: 1,
+                        column: 27
+                    }
+                },
+                range: [
+                    26,
+                    27
+                ]
+            },
+            {
+                type: "Punctuator",
+                value: "=",
+                start: 28,
+                end: 29,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 28
+                    },
+                    end: {
+                        line: 1,
+                        column: 29
+                    }
+                },
+                range: [
+                    28,
+                    29
+                ]
+            },
+            {
+                type: "Identifier",
+                value: "obj",
+                start: 30,
+                end: 33,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 30
+                    },
+                    end: {
+                        line: 1,
+                        column: 33
+                    }
+                },
+                range: [
+                    30,
+                    33
+                ]
+            },
+            {
+                type: "Punctuator",
+                value: ";",
+                start: 33,
+                end: 34,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 33
+                    },
+                    end: {
+                        line: 1,
+                        column: 34
+                    }
+                },
+                range: [
+                    33,
+                    34
+                ]
+            },
+            {
+                type: "Identifier",
+                value: "otherStuff",
+                start: 35,
+                end: 45,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 35
+                    },
+                    end: {
+                        line: 1,
+                        column: 45
+                    }
+                },
+                range: [
+                    35,
+                    45
+                ]
+            },
+            {
+                type: "Punctuator",
+                value: "=",
+                start: 46,
+                end: 47,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 46
+                    },
+                    end: {
+                        line: 1,
+                        column: 47
+                    }
+                },
+                range: [
+                    46,
+                    47
+                ]
+            },
+            {
+                type: "Punctuator",
+                value: "{",
+                start: 48,
+                end: 49,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 48
+                    },
+                    end: {
+                        line: 1,
+                        column: 49
+                    }
+                },
+                range: [
+                    48,
+                    49
+                ]
+            },
+            {
+                type: "Punctuator",
+                value: "}",
+                start: 49,
+                end: 50,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 49
+                    },
+                    end: {
+                        line: 1,
+                        column: 50
+                    }
+                },
+                range: [
+                    49,
+                    50
+                ]
+            },
+            {
+                type: "Punctuator",
+                value: ";",
+                start: 50,
+                end: 51,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 50
+                    },
+                    end: {
+                        line: 1,
+                        column: 51
+                    }
+                },
+                range: [
+                    50,
+                    51
+                ]
+            },
+            {
+                type: {
+                    label: "eof",
+                    beforeExpr: false,
+                    startsExpr: false,
+                    rightAssociative: false,
+                    isLoop: false,
+                    isAssign: false,
+                    prefix: false,
+                    postfix: false,
+                    binop: null,
+                    updateContext: null
+                },
+                start: 53,
+                end: 53,
+                loc: {
+                    start: {
+                        line: 3,
+                        column: 0
+                    },
+                    end: {
+                        line: 3,
+                        column: 0
+                    }
+                },
+                range: [
+                    53,
+                    53
+                ]
+            }
+        ],
+        comments: [],
+        range: [
+            0,
+            53
+        ],
+        _paths: [
+            {
+                contexts: [],
+                parent: "[Circular ~]",
+                data: {},
+                shouldSkip: false,
+                shouldStop: false,
+                removed: false,
+                opts: {
+                    noScope: true,
+                    enter: [
+                        null
+                    ],
+                    exit: [
+                        null
+                    ],
+                    _exploded: true,
+                    _verified: true
+                },
+                skipKeys: {},
+                parentPath: null,
+                context: {
+                    queue: null,
+                    opts: {
+                        noScope: true,
+                        enter: [
+                            null
+                        ],
+                        exit: [
+                            null
+                        ],
+                        _exploded: true,
+                        _verified: true
+                    }
+                },
+                container: [
+                    {
+                        type: "VariableDeclaration",
+                        start: 0,
+                        end: 34,
+                        loc: {
+                            start: {
+                                line: 1,
+                                column: 0
+                            },
+                            end: {
+                                line: 1,
+                                column: 34
+                            }
+                        },
+                        declarations: [
+                            {
+                                type: "VariableDeclarator",
+                                start: 4,
+                                end: 33,
+                                loc: {
+                                    start: {
+                                        line: 1,
+                                        column: 4
+                                    },
+                                    end: {
+                                        line: 1,
+                                        column: 33
+                                    }
+                                },
+                                id: {
+                                    type: "ObjectPattern",
+                                    start: 4,
+                                    end: 27,
+                                    loc: {
+                                        start: {
+                                            line: 1,
+                                            column: 4
+                                        },
+                                        end: {
+                                            line: 1,
+                                            column: 27
+                                        }
+                                    },
+                                    properties: [
+                                        {
+                                            type: "Property",
+                                            start: 6,
+                                            end: 10,
+                                            loc: {
+                                                start: {
+                                                    line: 1,
+                                                    column: 6
+                                                },
+                                                end: {
+                                                    line: 1,
+                                                    column: 10
+                                                }
+                                            },
+                                            method: false,
+                                            shorthand: true,
+                                            computed: false,
+                                            key: {
+                                                type: "Identifier",
+                                                start: 6,
+                                                end: 10,
+                                                loc: {
+                                                    start: {
+                                                        line: 1,
+                                                        column: 6
+                                                    },
+                                                    end: {
+                                                        line: 1,
+                                                        column: 10
+                                                    }
+                                                },
+                                                name: "name",
+                                                range: [
+                                                    6,
+                                                    10
+                                                ],
+                                                _babelType: "Identifier"
+                                            },
+                                            kind: "init",
+                                            value: {
+                                                type: "Identifier",
+                                                start: 6,
+                                                end: 10,
+                                                loc: {
+                                                    start: {
+                                                        line: 1,
+                                                        column: 6
+                                                    },
+                                                    end: {
+                                                        line: 1,
+                                                        column: 10
+                                                    }
+                                                },
+                                                name: "name",
+                                                range: [
+                                                    6,
+                                                    10
+                                                ],
+                                                _babelType: "Identifier"
+                                            },
+                                            range: [
+                                                6,
+                                                10
+                                            ],
+                                            _babelType: "Property"
+                                        },
+                                        {
+                                            type: "SpreadProperty",
+                                            start: 12,
+                                            end: 25,
+                                            loc: {
+                                                start: {
+                                                    line: 1,
+                                                    column: 12
+                                                },
+                                                end: {
+                                                    line: 1,
+                                                    column: 25
+                                                }
+                                            },
+                                            argument: {
+                                                type: "Identifier",
+                                                start: 15,
+                                                end: 25,
+                                                loc: {
+                                                    start: {
+                                                        line: 1,
+                                                        column: 15
+                                                    },
+                                                    end: {
+                                                        line: 1,
+                                                        column: 25
+                                                    }
+                                                },
+                                                name: "otherStuff",
+                                                range: [
+                                                    15,
+                                                    25
+                                                ],
+                                                _babelType: "Identifier"
+                                            },
+                                            range: [
+                                                12,
+                                                25
+                                            ],
+                                            _babelType: "SpreadProperty",
+                                            value: {
+                                                type: "Identifier",
+                                                start: 15,
+                                                end: 25,
+                                                loc: {
+                                                    start: {
+                                                        line: 1,
+                                                        column: 15
+                                                    },
+                                                    end: {
+                                                        line: 1,
+                                                        column: 25
+                                                    }
+                                                },
+                                                name: "otherStuff",
+                                                range: [
+                                                    15,
+                                                    25
+                                                ],
+                                                _babelType: "Identifier"
+                                            },
+                                            key: {
+                                                type: "Identifier",
+                                                start: 15,
+                                                end: 25,
+                                                loc: {
+                                                    start: {
+                                                        line: 1,
+                                                        column: 15
+                                                    },
+                                                    end: {
+                                                        line: 1,
+                                                        column: 25
+                                                    }
+                                                },
+                                                name: "otherStuff",
+                                                range: [
+                                                    15,
+                                                    25
+                                                ],
+                                                _babelType: "Identifier"
+                                            }
+                                        }
+                                    ],
+                                    range: [
+                                        4,
+                                        27
+                                    ],
+                                    _babelType: "ObjectPattern"
+                                },
+                                init: {
+                                    type: "Identifier",
+                                    start: 30,
+                                    end: 33,
+                                    loc: {
+                                        start: {
+                                            line: 1,
+                                            column: 30
+                                        },
+                                        end: {
+                                            line: 1,
+                                            column: 33
+                                        }
+                                    },
+                                    name: "obj",
+                                    range: [
+                                        30,
+                                        33
+                                    ],
+                                    _babelType: "Identifier"
+                                },
+                                range: [
+                                    4,
+                                    33
+                                ],
+                                _babelType: "VariableDeclarator"
+                            }
+                        ],
+                        kind: "let",
+                        range: [
+                            0,
+                            34
+                        ],
+                        _babelType: "VariableDeclaration"
+                    },
+                    {
+                        type: "ExpressionStatement",
+                        start: 35,
+                        end: 51,
+                        loc: {
+                            start: {
+                                line: 1,
+                                column: 35
+                            },
+                            end: {
+                                line: 1,
+                                column: 51
+                            }
+                        },
+                        expression: {
+                            type: "AssignmentExpression",
+                            start: 35,
+                            end: 50,
+                            loc: {
+                                start: {
+                                    line: 1,
+                                    column: 35
+                                },
+                                end: {
+                                    line: 1,
+                                    column: 50
+                                }
+                            },
+                            operator: "=",
+                            left: {
+                                type: "Identifier",
+                                start: 35,
+                                end: 45,
+                                loc: {
+                                    start: {
+                                        line: 1,
+                                        column: 35
+                                    },
+                                    end: {
+                                        line: 1,
+                                        column: 45
+                                    }
+                                },
+                                name: "otherStuff",
+                                range: [
+                                    35,
+                                    45
+                                ],
+                                _babelType: "Identifier"
+                            },
+                            right: {
+                                type: "ObjectExpression",
+                                start: 48,
+                                end: 50,
+                                loc: {
+                                    start: {
+                                        line: 1,
+                                        column: 48
+                                    },
+                                    end: {
+                                        line: 1,
+                                        column: 50
+                                    }
+                                },
+                                properties: [],
+                                range: [
+                                    48,
+                                    50
+                                ],
+                                _babelType: "ObjectExpression"
+                            },
+                            range: [
+                                35,
+                                50
+                            ],
+                            _babelType: "AssignmentExpression"
+                        },
+                        range: [
+                            35,
+                            51
+                        ],
+                        _babelType: "ExpressionStatement"
+                    }
+                ],
+                listKey: "body",
+                inList: true,
+                parentKey: "body",
+                key: 0,
+                node: {
+                    type: "VariableDeclaration",
+                    start: 0,
+                    end: 34,
+                    loc: {
+                        start: {
+                            line: 1,
+                            column: 0
+                        },
+                        end: {
+                            line: 1,
+                            column: 34
+                        }
+                    },
+                    declarations: [
+                        {
+                            type: "VariableDeclarator",
+                            start: 4,
+                            end: 33,
+                            loc: {
+                                start: {
+                                    line: 1,
+                                    column: 4
+                                },
+                                end: {
+                                    line: 1,
+                                    column: 33
+                                }
+                            },
+                            id: {
+                                type: "ObjectPattern",
+                                start: 4,
+                                end: 27,
+                                loc: {
+                                    start: {
+                                        line: 1,
+                                        column: 4
+                                    },
+                                    end: {
+                                        line: 1,
+                                        column: 27
+                                    }
+                                },
+                                properties: [
+                                    {
+                                        type: "Property",
+                                        start: 6,
+                                        end: 10,
+                                        loc: {
+                                            start: {
+                                                line: 1,
+                                                column: 6
+                                            },
+                                            end: {
+                                                line: 1,
+                                                column: 10
+                                            }
+                                        },
+                                        method: false,
+                                        shorthand: true,
+                                        computed: false,
+                                        key: {
+                                            type: "Identifier",
+                                            start: 6,
+                                            end: 10,
+                                            loc: {
+                                                start: {
+                                                    line: 1,
+                                                    column: 6
+                                                },
+                                                end: {
+                                                    line: 1,
+                                                    column: 10
+                                                }
+                                            },
+                                            name: "name",
+                                            range: [
+                                                6,
+                                                10
+                                            ],
+                                            _babelType: "Identifier"
+                                        },
+                                        kind: "init",
+                                        value: {
+                                            type: "Identifier",
+                                            start: 6,
+                                            end: 10,
+                                            loc: {
+                                                start: {
+                                                    line: 1,
+                                                    column: 6
+                                                },
+                                                end: {
+                                                    line: 1,
+                                                    column: 10
+                                                }
+                                            },
+                                            name: "name",
+                                            range: [
+                                                6,
+                                                10
+                                            ],
+                                            _babelType: "Identifier"
+                                        },
+                                        range: [
+                                            6,
+                                            10
+                                        ],
+                                        _babelType: "Property"
+                                    },
+                                    {
+                                        type: "SpreadProperty",
+                                        start: 12,
+                                        end: 25,
+                                        loc: {
+                                            start: {
+                                                line: 1,
+                                                column: 12
+                                            },
+                                            end: {
+                                                line: 1,
+                                                column: 25
+                                            }
+                                        },
+                                        argument: {
+                                            type: "Identifier",
+                                            start: 15,
+                                            end: 25,
+                                            loc: {
+                                                start: {
+                                                    line: 1,
+                                                    column: 15
+                                                },
+                                                end: {
+                                                    line: 1,
+                                                    column: 25
+                                                }
+                                            },
+                                            name: "otherStuff",
+                                            range: [
+                                                15,
+                                                25
+                                            ],
+                                            _babelType: "Identifier"
+                                        },
+                                        range: [
+                                            12,
+                                            25
+                                        ],
+                                        _babelType: "SpreadProperty",
+                                        value: {
+                                            type: "Identifier",
+                                            start: 15,
+                                            end: 25,
+                                            loc: {
+                                                start: {
+                                                    line: 1,
+                                                    column: 15
+                                                },
+                                                end: {
+                                                    line: 1,
+                                                    column: 25
+                                                }
+                                            },
+                                            name: "otherStuff",
+                                            range: [
+                                                15,
+                                                25
+                                            ],
+                                            _babelType: "Identifier"
+                                        },
+                                        key: {
+                                            type: "Identifier",
+                                            start: 15,
+                                            end: 25,
+                                            loc: {
+                                                start: {
+                                                    line: 1,
+                                                    column: 15
+                                                },
+                                                end: {
+                                                    line: 1,
+                                                    column: 25
+                                                }
+                                            },
+                                            name: "otherStuff",
+                                            range: [
+                                                15,
+                                                25
+                                            ],
+                                            _babelType: "Identifier"
+                                        }
+                                    }
+                                ],
+                                range: [
+                                    4,
+                                    27
+                                ],
+                                _babelType: "ObjectPattern"
+                            },
+                            init: {
+                                type: "Identifier",
+                                start: 30,
+                                end: 33,
+                                loc: {
+                                    start: {
+                                        line: 1,
+                                        column: 30
+                                    },
+                                    end: {
+                                        line: 1,
+                                        column: 33
+                                    }
+                                },
+                                name: "obj",
+                                range: [
+                                    30,
+                                    33
+                                ],
+                                _babelType: "Identifier"
+                            },
+                            range: [
+                                4,
+                                33
+                            ],
+                            _babelType: "VariableDeclarator"
+                        }
+                    ],
+                    kind: "let",
+                    range: [
+                        0,
+                        34
+                    ],
+                    _babelType: "VariableDeclaration"
+                },
+                scope: null,
+                type: "VariableDeclaration",
+                typeAnnotation: null
+            },
+            {
+                contexts: [],
+                parent: "[Circular ~]",
+                data: {},
+                shouldSkip: false,
+                shouldStop: false,
+                removed: false,
+                opts: {
+                    noScope: true,
+                    enter: [
+                        null
+                    ],
+                    exit: [
+                        null
+                    ],
+                    _exploded: true,
+                    _verified: true
+                },
+                skipKeys: {},
+                parentPath: null,
+                context: {
+                    queue: null,
+                    opts: {
+                        noScope: true,
+                        enter: [
+                            null
+                        ],
+                        exit: [
+                            null
+                        ],
+                        _exploded: true,
+                        _verified: true
+                    }
+                },
+                container: [
+                    {
+                        type: "VariableDeclaration",
+                        start: 0,
+                        end: 34,
+                        loc: {
+                            start: {
+                                line: 1,
+                                column: 0
+                            },
+                            end: {
+                                line: 1,
+                                column: 34
+                            }
+                        },
+                        declarations: [
+                            {
+                                type: "VariableDeclarator",
+                                start: 4,
+                                end: 33,
+                                loc: {
+                                    start: {
+                                        line: 1,
+                                        column: 4
+                                    },
+                                    end: {
+                                        line: 1,
+                                        column: 33
+                                    }
+                                },
+                                id: {
+                                    type: "ObjectPattern",
+                                    start: 4,
+                                    end: 27,
+                                    loc: {
+                                        start: {
+                                            line: 1,
+                                            column: 4
+                                        },
+                                        end: {
+                                            line: 1,
+                                            column: 27
+                                        }
+                                    },
+                                    properties: [
+                                        {
+                                            type: "Property",
+                                            start: 6,
+                                            end: 10,
+                                            loc: {
+                                                start: {
+                                                    line: 1,
+                                                    column: 6
+                                                },
+                                                end: {
+                                                    line: 1,
+                                                    column: 10
+                                                }
+                                            },
+                                            method: false,
+                                            shorthand: true,
+                                            computed: false,
+                                            key: {
+                                                type: "Identifier",
+                                                start: 6,
+                                                end: 10,
+                                                loc: {
+                                                    start: {
+                                                        line: 1,
+                                                        column: 6
+                                                    },
+                                                    end: {
+                                                        line: 1,
+                                                        column: 10
+                                                    }
+                                                },
+                                                name: "name",
+                                                range: [
+                                                    6,
+                                                    10
+                                                ],
+                                                _babelType: "Identifier"
+                                            },
+                                            kind: "init",
+                                            value: {
+                                                type: "Identifier",
+                                                start: 6,
+                                                end: 10,
+                                                loc: {
+                                                    start: {
+                                                        line: 1,
+                                                        column: 6
+                                                    },
+                                                    end: {
+                                                        line: 1,
+                                                        column: 10
+                                                    }
+                                                },
+                                                name: "name",
+                                                range: [
+                                                    6,
+                                                    10
+                                                ],
+                                                _babelType: "Identifier"
+                                            },
+                                            range: [
+                                                6,
+                                                10
+                                            ],
+                                            _babelType: "Property"
+                                        },
+                                        {
+                                            type: "SpreadProperty",
+                                            start: 12,
+                                            end: 25,
+                                            loc: {
+                                                start: {
+                                                    line: 1,
+                                                    column: 12
+                                                },
+                                                end: {
+                                                    line: 1,
+                                                    column: 25
+                                                }
+                                            },
+                                            argument: {
+                                                type: "Identifier",
+                                                start: 15,
+                                                end: 25,
+                                                loc: {
+                                                    start: {
+                                                        line: 1,
+                                                        column: 15
+                                                    },
+                                                    end: {
+                                                        line: 1,
+                                                        column: 25
+                                                    }
+                                                },
+                                                name: "otherStuff",
+                                                range: [
+                                                    15,
+                                                    25
+                                                ],
+                                                _babelType: "Identifier"
+                                            },
+                                            range: [
+                                                12,
+                                                25
+                                            ],
+                                            _babelType: "SpreadProperty",
+                                            value: {
+                                                type: "Identifier",
+                                                start: 15,
+                                                end: 25,
+                                                loc: {
+                                                    start: {
+                                                        line: 1,
+                                                        column: 15
+                                                    },
+                                                    end: {
+                                                        line: 1,
+                                                        column: 25
+                                                    }
+                                                },
+                                                name: "otherStuff",
+                                                range: [
+                                                    15,
+                                                    25
+                                                ],
+                                                _babelType: "Identifier"
+                                            },
+                                            key: {
+                                                type: "Identifier",
+                                                start: 15,
+                                                end: 25,
+                                                loc: {
+                                                    start: {
+                                                        line: 1,
+                                                        column: 15
+                                                    },
+                                                    end: {
+                                                        line: 1,
+                                                        column: 25
+                                                    }
+                                                },
+                                                name: "otherStuff",
+                                                range: [
+                                                    15,
+                                                    25
+                                                ],
+                                                _babelType: "Identifier"
+                                            }
+                                        }
+                                    ],
+                                    range: [
+                                        4,
+                                        27
+                                    ],
+                                    _babelType: "ObjectPattern"
+                                },
+                                init: {
+                                    type: "Identifier",
+                                    start: 30,
+                                    end: 33,
+                                    loc: {
+                                        start: {
+                                            line: 1,
+                                            column: 30
+                                        },
+                                        end: {
+                                            line: 1,
+                                            column: 33
+                                        }
+                                    },
+                                    name: "obj",
+                                    range: [
+                                        30,
+                                        33
+                                    ],
+                                    _babelType: "Identifier"
+                                },
+                                range: [
+                                    4,
+                                    33
+                                ],
+                                _babelType: "VariableDeclarator"
+                            }
+                        ],
+                        kind: "let",
+                        range: [
+                            0,
+                            34
+                        ],
+                        _babelType: "VariableDeclaration"
+                    },
+                    {
+                        type: "ExpressionStatement",
+                        start: 35,
+                        end: 51,
+                        loc: {
+                            start: {
+                                line: 1,
+                                column: 35
+                            },
+                            end: {
+                                line: 1,
+                                column: 51
+                            }
+                        },
+                        expression: {
+                            type: "AssignmentExpression",
+                            start: 35,
+                            end: 50,
+                            loc: {
+                                start: {
+                                    line: 1,
+                                    column: 35
+                                },
+                                end: {
+                                    line: 1,
+                                    column: 50
+                                }
+                            },
+                            operator: "=",
+                            left: {
+                                type: "Identifier",
+                                start: 35,
+                                end: 45,
+                                loc: {
+                                    start: {
+                                        line: 1,
+                                        column: 35
+                                    },
+                                    end: {
+                                        line: 1,
+                                        column: 45
+                                    }
+                                },
+                                name: "otherStuff",
+                                range: [
+                                    35,
+                                    45
+                                ],
+                                _babelType: "Identifier"
+                            },
+                            right: {
+                                type: "ObjectExpression",
+                                start: 48,
+                                end: 50,
+                                loc: {
+                                    start: {
+                                        line: 1,
+                                        column: 48
+                                    },
+                                    end: {
+                                        line: 1,
+                                        column: 50
+                                    }
+                                },
+                                properties: [],
+                                range: [
+                                    48,
+                                    50
+                                ],
+                                _babelType: "ObjectExpression"
+                            },
+                            range: [
+                                35,
+                                50
+                            ],
+                            _babelType: "AssignmentExpression"
+                        },
+                        range: [
+                            35,
+                            51
+                        ],
+                        _babelType: "ExpressionStatement"
+                    }
+                ],
+                listKey: "body",
+                inList: true,
+                parentKey: "body",
+                key: 1,
+                node: {
+                    type: "ExpressionStatement",
+                    start: 35,
+                    end: 51,
+                    loc: {
+                        start: {
+                            line: 1,
+                            column: 35
+                        },
+                        end: {
+                            line: 1,
+                            column: 51
+                        }
+                    },
+                    expression: {
+                        type: "AssignmentExpression",
+                        start: 35,
+                        end: 50,
+                        loc: {
+                            start: {
+                                line: 1,
+                                column: 35
+                            },
+                            end: {
+                                line: 1,
+                                column: 50
+                            }
+                        },
+                        operator: "=",
+                        left: {
+                            type: "Identifier",
+                            start: 35,
+                            end: 45,
+                            loc: {
+                                start: {
+                                    line: 1,
+                                    column: 35
+                                },
+                                end: {
+                                    line: 1,
+                                    column: 45
+                                }
+                            },
+                            name: "otherStuff",
+                            range: [
+                                35,
+                                45
+                            ],
+                            _babelType: "Identifier"
+                        },
+                        right: {
+                            type: "ObjectExpression",
+                            start: 48,
+                            end: 50,
+                            loc: {
+                                start: {
+                                    line: 1,
+                                    column: 48
+                                },
+                                end: {
+                                    line: 1,
+                                    column: 50
+                                }
+                            },
+                            properties: [],
+                            range: [
+                                48,
+                                50
+                            ],
+                            _babelType: "ObjectExpression"
+                        },
+                        range: [
+                            35,
+                            50
+                        ],
+                        _babelType: "AssignmentExpression"
+                    },
+                    range: [
+                        35,
+                        51
+                    ],
+                    _babelType: "ExpressionStatement"
+                },
+                scope: null,
+                type: "ExpressionStatement",
+                typeAnnotation: null
+            }
+        ]
+    };
+};
diff --git a/tests/fixtures/parsers/babel-eslint7/function-type-annotation.js b/tests/fixtures/parsers/babel-eslint7/function-type-annotation.js
new file mode 100644
index 000000000..a663b4e1e
--- /dev/null
+++ b/tests/fixtures/parsers/babel-eslint7/function-type-annotation.js
@@ -0,0 +1,525 @@
+"use strict";
+
+/**
+ * Parser: babel-eslint v7.2.1
+ * Source code:
+ * type TransformFunction = (el: ASTElement, code: string) => string;
+ */
+
+exports.parse = () => ({
+    type: "Program",
+    start: 0,
+    end: 66,
+    loc: {
+        start: {
+            line: 1,
+            column: 0
+        },
+        end: {
+            line: 1,
+            column: 66
+        }
+    },
+    comments: [],
+    tokens: [
+        {
+            type: "Identifier",
+            value: "type",
+            start: 0,
+            end: 4,
+            loc: {
+                start: {
+                    line: 1,
+                    column: 0
+                },
+                end: {
+                    line: 1,
+                    column: 4
+                }
+            },
+            range: [
+                0,
+                4
+            ]
+        },
+        {
+            type: "Identifier",
+            value: "TransformFunction",
+            start: 5,
+            end: 22,
+            loc: {
+                start: {
+                    line: 1,
+                    column: 5
+                },
+                end: {
+                    line: 1,
+                    column: 22
+                }
+            },
+            range: [
+                5,
+                22
+            ]
+        },
+        {
+            type: "Punctuator",
+            value: "=",
+            start: 23,
+            end: 24,
+            loc: {
+                start: {
+                    line: 1,
+                    column: 23
+                },
+                end: {
+                    line: 1,
+                    column: 24
+                }
+            },
+            range: [
+                23,
+                24
+            ]
+        },
+        {
+            type: "Punctuator",
+            value: "(",
+            start: 25,
+            end: 26,
+            loc: {
+                start: {
+                    line: 1,
+                    column: 25
+                },
+                end: {
+                    line: 1,
+                    column: 26
+                }
+            },
+            range: [
+                25,
+                26
+            ]
+        },
+        {
+            type: "Identifier",
+            value: "el",
+            start: 26,
+            end: 28,
+            loc: {
+                start: {
+                    line: 1,
+                    column: 26
+                },
+                end: {
+                    line: 1,
+                    column: 28
+                }
+            },
+            range: [
+                26,
+                28
+            ]
+        },
+        {
+            type: "Punctuator",
+            value: ":",
+            start: 28,
+            end: 29,
+            loc: {
+                start: {
+                    line: 1,
+                    column: 28
+                },
+                end: {
+                    line: 1,
+                    column: 29
+                }
+            },
+            range: [
+                28,
+                29
+            ]
+        },
+        {
+            type: "Identifier",
+            value: "ASTElement",
+            start: 30,
+            end: 40,
+            loc: {
+                start: {
+                    line: 1,
+                    column: 30
+                },
+                end: {
+                    line: 1,
+                    column: 40
+                }
+            },
+            range: [
+                30,
+                40
+            ]
+        },
+        {
+            type: "Punctuator",
+            value: ",",
+            start: 40,
+            end: 41,
+            loc: {
+                start: {
+                    line: 1,
+                    column: 40
+                },
+                end: {
+                    line: 1,
+                    column: 41
+                }
+            },
+            range: [
+                40,
+                41
+            ]
+        },
+        {
+            type: "Identifier",
+            value: "code",
+            start: 42,
+            end: 46,
+            loc: {
+                start: {
+                    line: 1,
+                    column: 42
+                },
+                end: {
+                    line: 1,
+                    column: 46
+                }
+            },
+            range: [
+                42,
+                46
+            ]
+        },
+        {
+            type: "Punctuator",
+            value: ":",
+            start: 46,
+            end: 47,
+            loc: {
+                start: {
+                    line: 1,
+                    column: 46
+                },
+                end: {
+                    line: 1,
+                    column: 47
+                }
+            },
+            range: [
+                46,
+                47
+            ]
+        },
+        {
+            type: "Identifier",
+            value: "string",
+            start: 48,
+            end: 54,
+            loc: {
+                start: {
+                    line: 1,
+                    column: 48
+                },
+                end: {
+                    line: 1,
+                    column: 54
+                }
+            },
+            range: [
+                48,
+                54
+            ]
+        },
+        {
+            type: "Punctuator",
+            value: ")",
+            start: 54,
+            end: 55,
+            loc: {
+                start: {
+                    line: 1,
+                    column: 54
+                },
+                end: {
+                    line: 1,
+                    column: 55
+                }
+            },
+            range: [
+                54,
+                55
+            ]
+        },
+        {
+            type: "Punctuator",
+            value: "=>",
+            start: 56,
+            end: 58,
+            loc: {
+                start: {
+                    line: 1,
+                    column: 56
+                },
+                end: {
+                    line: 1,
+                    column: 58
+                }
+            },
+            range: [
+                56,
+                58
+            ]
+        },
+        {
+            type: "Identifier",
+            value: "string",
+            start: 59,
+            end: 65,
+            loc: {
+                start: {
+                    line: 1,
+                    column: 59
+                },
+                end: {
+                    line: 1,
+                    column: 65
+                }
+            },
+            range: [
+                59,
+                65
+            ]
+        },
+        {
+            type: "Punctuator",
+            value: ";",
+            start: 65,
+            end: 66,
+            loc: {
+                start: {
+                    line: 1,
+                    column: 65
+                },
+                end: {
+                    line: 1,
+                    column: 66
+                }
+            },
+            range: [
+                65,
+                66
+            ]
+        }
+    ],
+    range: [
+        0,
+        66
+    ],
+    sourceType: "module",
+    body: [
+        {
+            type: "TypeAlias",
+            start: 0,
+            end: 66,
+            loc: {
+                start: {
+                    line: 1,
+                    column: 0
+                },
+                end: {
+                    line: 1,
+                    column: 66
+                }
+            },
+            id: {
+                type: "Identifier",
+                start: 5,
+                end: 22,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 5
+                    },
+                    end: {
+                        line: 1,
+                        column: 22
+                    },
+                    identifierName: "TransformFunction"
+                },
+                name: "TransformFunction",
+                range: [
+                    5,
+                    22
+                ],
+                _babelType: "Identifier"
+            },
+            typeParameters: null,
+            right: {
+                type: "FunctionTypeAnnotation",
+                start: 25,
+                end: 65,
+                loc: {
+                    start: {
+                        line: 1,
+                        column: 25
+                    },
+                    end: {
+                        line: 1,
+                        column: 65
+                    }
+                },
+                params: [
+                    {
+                        type: "FunctionTypeParam",
+                        start: 26,
+                        end: 40,
+                        loc: {
+                            start: {
+                                line: 1,
+                                column: 26
+                            },
+                            end: {
+                                line: 1,
+                                column: 40
+                            }
+                        },
+                        optional: false,
+                        typeAnnotation: {
+                            type: "GenericTypeAnnotation",
+                            start: 30,
+                            end: 40,
+                            loc: {
+                                start: {
+                                    line: 1,
+                                    column: 30
+                                },
+                                end: {
+                                    line: 1,
+                                    column: 40
+                                }
+                            },
+                            typeParameters: null,
+                            id: {
+                                type: "Identifier",
+                                start: 30,
+                                end: 40,
+                                loc: {
+                                    start: {
+                                        line: 1,
+                                        column: 30
+                                    },
+                                    end: {
+                                        line: 1,
+                                        column: 40
+                                    },
+                                    identifierName: "ASTElement"
+                                },
+                                name: "ASTElement",
+                                range: [
+                                    30,
+                                    40
+                                ],
+                                _babelType: "Identifier"
+                            },
+                            range: [
+                                30,
+                                40
+                            ],
+                            _babelType: "GenericTypeAnnotation"
+                        },
+                        range: [
+                            26,
+                            40
+                        ],
+                        _babelType: "FunctionTypeParam"
+                    },
+                    {
+                        type: "FunctionTypeParam",
+                        start: 42,
+                        end: 54,
+                        loc: {
+                            start: {
+                                line: 1,
+                                column: 42
+                            },
+                            end: {
+                                line: 1,
+                                column: 54
+                            }
+                        },
+                        optional: false,
+                        typeAnnotation: {
+                            type: "StringTypeAnnotation",
+                            start: 48,
+                            end: 54,
+                            loc: {
+                                start: {
+                                    line: 1,
+                                    column: 48
+                                },
+                                end: {
+                                    line: 1,
+                                    column: 54
+                                }
+                            },
+                            range: [
+                                48,
+                                54
+                            ],
+                            _babelType: "StringTypeAnnotation"
+                        },
+                        range: [
+                            42,
+                            54
+                        ],
+                        _babelType: "FunctionTypeParam"
+                    }
+                ],
+                rest: null,
+                returnType: {
+                    type: "StringTypeAnnotation",
+                    start: 59,
+                    end: 65,
+                    loc: {
+                        start: {
+                            line: 1,
+                            column: 59
+                        },
+                        end: {
+                            line: 1,
+                            column: 65
+                        }
+                    },
+                    range: [
+                        59,
+                        65
+                    ],
+                    _babelType: "StringTypeAnnotation"
+                },
+                typeParameters: null,
+                range: [
+                    25,
+                    65
+                ],
+                _babelType: "FunctionTypeAnnotation"
+            },
+            range: [
+                0,
+                66
+            ],
+            _babelType: "TypeAlias"
+        }
+    ]
+});
diff --git a/tests/lib/config/plugins.js b/tests/lib/config/plugins.js
index 06b2bcd38..61b759797 100644
--- a/tests/lib/config/plugins.js
+++ b/tests/lib/config/plugins.js
@@ -43,7 +43,12 @@ describe("Plugins", () => {
                 "eslint-plugin-example": plugin,
                 "@scope/eslint-plugin-example": scopedPlugin,
                 "./environments": Environments,
-                "../rules": Rules
+                "../rules": Rules,
+                "eslint-plugin-throws-on-load": {
+                    get rules() {
+                        throw new Error("error thrown while loading this module");
+                    }
+                }
             });
         });
 
@@ -106,6 +111,21 @@ describe("Plugins", () => {
             }, /Failed to load plugin/);
         });
 
+        it("should rethrow an error that a plugin throws on load", () => {
+            try {
+                StubbedPlugins.load("throws-on-load");
+            } catch (err) {
+                assert.strictEqual(
+                    err.message,
+                    "error thrown while loading this module",
+                    "should rethrow the same error that was thrown on plugin load"
+                );
+
+                return;
+            }
+            assert.fail(null, null, "should throw an error if a plugin fails to load");
+        });
+
         it("should load a scoped plugin when referenced by short name", () => {
             StubbedPlugins.load("@scope/example");
             assert.equal(StubbedPlugins.get("@scope/example"), scopedPlugin);
diff --git a/tests/lib/rules/no-extra-parens.js b/tests/lib/rules/no-extra-parens.js
index 967d2df05..f554d88b5 100644
--- a/tests/lib/rules/no-extra-parens.js
+++ b/tests/lib/rules/no-extra-parens.js
@@ -426,6 +426,27 @@ ruleTester.run("no-extra-parens", rule, {
         {
             code: "() => ({ foo: 1 }.foo().bar + baz)",
             parserOptions: { ecmaVersion: 2015 }
+        },
+        {
+            code: "export default (function(){}).foo",
+            parserOptions: { ecmaVersion: 2015, sourceType: "module" }
+        },
+        {
+            code: "export default (class{}).foo",
+            parserOptions: { ecmaVersion: 2015, sourceType: "module" }
+        },
+        "({}).hasOwnProperty.call(foo, bar)",
+        "({}) ? foo() : bar()",
+        "({}) + foo",
+        "(function(){}) + foo",
+        "(let[foo]) = 1", // setting the 'foo' property of the 'let' variable to 1
+        {
+            code: "((function(){}).foo.bar)();",
+            options: ["functions"]
+        },
+        {
+            code: "((function(){}).foo)();",
+            options: ["functions"]
         }
     ],
 
@@ -545,8 +566,6 @@ ruleTester.run("no-extra-parens", rule, {
         invalid("bar((function(){}).foo(), 0);", "bar(function(){}.foo(), 0);", "FunctionExpression"),
         invalid("bar[(function(){}).foo()];", "bar[function(){}.foo()];", "FunctionExpression"),
         invalid("var bar = (function(){}).foo();", "var bar = function(){}.foo();", "FunctionExpression"),
-        invalid("((function(){}).foo.bar)();", "(function(){}.foo.bar)();", "FunctionExpression", null, { options: ["functions"] }),
-        invalid("((function(){}).foo)();", "(function(){}.foo)();", "FunctionExpression", null, { options: ["functions"] }),
 
         invalid("((class{})).foo();", "(class{}).foo();", "ClassExpression", null, { parserOptions: { ecmaVersion: 6 } }),
         invalid("((class{}).foo());", "(class{}).foo();", "CallExpression", null, { parserOptions: { ecmaVersion: 6 } }),
@@ -976,17 +995,12 @@ ruleTester.run("no-extra-parens", rule, {
             1,
             { parserOptions: { ecmaVersion: 2015 } }
         ),
-        {
-            code: "() => (({ foo: 1 }).foo)",
-            output: "() => ({ foo: 1 }).foo",
-            parserOptions: { ecmaVersion: 2015 },
-            errors: [
-
-                // 2 errors are reported, but fixing one gets rid of the other
-                { message: "Gratuitous parentheses around expression.", type: "MemberExpression" },
-                { message: "Gratuitous parentheses around expression.", type: "ObjectExpression" }
-            ]
-
-        }
+        invalid(
+            "() => (({ foo: 1 }).foo)",
+            "() => ({ foo: 1 }).foo",
+            "MemberExpression",
+            1,
+            { parserOptions: { ecmaVersion: 2015 } }
+        )
     ]
 });
diff --git a/tests/lib/rules/no-param-reassign.js b/tests/lib/rules/no-param-reassign.js
index caecb5adc..a98a6dfe1 100644
--- a/tests/lib/rules/no-param-reassign.js
+++ b/tests/lib/rules/no-param-reassign.js
@@ -37,7 +37,7 @@ ruleTester.run("no-param-reassign", rule, {
         { code: "function foo(a, z) { a.b = 0; x.y = 0; }", options: [{ props: true, ignorePropertyModificationsFor: ["a", "x"] }] },
         { code: "function foo(a) { a.b.c = 0;}", options: [{ props: true, ignorePropertyModificationsFor: ["a"] }] },
         {
-            code: "function foo(a) { ({ [a]: variable }) = value }",
+            code: "function foo(a) { ({ [a]: variable } = value) }",
             options: [{ props: true }],
             parserOptions: { ecmaVersion: 6 }
         }
diff --git a/tests/lib/rules/no-restricted-syntax.js b/tests/lib/rules/no-restricted-syntax.js
index 7547e302b..3a653a978 100644
--- a/tests/lib/rules/no-restricted-syntax.js
+++ b/tests/lib/rules/no-restricted-syntax.js
@@ -19,6 +19,8 @@ const ruleTester = new RuleTester();
 
 ruleTester.run("no-restricted-syntax", rule, {
     valid: [
+
+        // string format
         { code: "doSomething();" },
         { code: "var foo = 42;", options: ["ConditionalExpression"] },
         { code: "foo += 42;", options: ["VariableDeclaration", "FunctionExpression"] },
@@ -26,9 +28,19 @@ ruleTester.run("no-restricted-syntax", rule, {
         { code: "() => 5", options: ["ArrowFunctionExpression > BlockStatement"], parserOptions: { ecmaVersion: 6 } },
         { code: "({ foo: 1, bar: 2 })", options: ["Property > Literal.key"] },
         { code: "A: for (;;) break;", options: ["BreakStatement[label]"] },
-        { code: "function foo(bar, baz) {}", options: ["FunctionDeclaration[params.length>2]"] }
+        { code: "function foo(bar, baz) {}", options: ["FunctionDeclaration[params.length>2]"] },
+
+        //  object format
+        { code: "var foo = 42;", options: [{ selector: "ConditionalExpression" }] },
+        { code: "({ foo: 1, bar: 2 })", options: [{ selector: "Property > Literal.key" }] },
+        {
+            code: "({ foo: 1, bar: 2 })",
+            options: [{ selector: "FunctionDeclaration[params.length>2]", message: "custom error message." }]
+        }
     ],
     invalid: [
+
+        // string format
         {
             code: "var foo = 41;",
             options: ["VariableDeclaration"],
@@ -82,6 +94,30 @@ ruleTester.run("no-restricted-syntax", rule, {
             code: "function foo(bar, baz, qux) {}",
             options: ["FunctionDeclaration[params.length>2]"],
             errors: [{ message: "Using 'FunctionDeclaration[params.length>2]' is not allowed.", type: "FunctionDeclaration" }]
+        },
+
+        // object format
+        {
+            code: "var foo = 41;",
+            options: [{ selector: "VariableDeclaration" }],
+            errors: [{ message: "Using 'VariableDeclaration' is not allowed.", type: "VariableDeclaration" }]
+        },
+        {
+            code: "function foo(bar, baz, qux) {}",
+            options: [{ selector: "FunctionDeclaration[params.length>2]" }],
+            errors: [{ message: "Using 'FunctionDeclaration[params.length>2]' is not allowed.", type: "FunctionDeclaration" }]
+        },
+        {
+            code: "function foo(bar, baz, qux) {}",
+            options: [{ selector: "FunctionDeclaration[params.length>2]", message: "custom error message." }],
+            errors: [{ message: "custom error message.", type: "FunctionDeclaration" }]
+        },
+
+        // with object format, the custom message may contain the string '{{selector}}'
+        {
+            code: "function foo(bar, baz, qux) {}",
+            options: [{ selector: "FunctionDeclaration[params.length>2]", message: "custom message with {{selector}}" }],
+            errors: [{ message: "custom message with {{selector}}", type: "FunctionDeclaration" }]
         }
     ]
 });
diff --git a/tests/lib/rules/operator-assignment.js b/tests/lib/rules/operator-assignment.js
index 5e5e65564..fb1ff889e 100644
--- a/tests/lib/rules/operator-assignment.js
+++ b/tests/lib/rules/operator-assignment.js
@@ -81,7 +81,8 @@ ruleTester.run("operator-assignment", rule, {
         "x = x === y",
         "x = x !== y",
         "x = x && y",
-        "x = x || y"
+        "x = x || y",
+        "x = x * y + z"
     ],
 
     invalid: [{
@@ -214,6 +215,31 @@ ruleTester.run("operator-assignment", rule, {
         output: "foo = foo ** bar",
         options: ["never"],
         errors: UNEXPECTED_OPERATOR_ASSIGNMENT
+    }, {
+        code: "foo *= bar + 1",
+        output: "foo = foo * (bar + 1)",
+        options: ["never"],
+        errors: UNEXPECTED_OPERATOR_ASSIGNMENT
+    }, {
+        code: "foo -= bar - baz",
+        output: "foo = foo - (bar - baz)",
+        options: ["never"],
+        errors: UNEXPECTED_OPERATOR_ASSIGNMENT
+    }, {
+        code: "foo += bar + baz",
+        output: "foo = foo + (bar + baz)", // addition is not associative in JS, e.g. (1 + 2) + '3' !== 1 + (2 + '3')
+        options: ["never"],
+        errors: UNEXPECTED_OPERATOR_ASSIGNMENT
+    }, {
+        code: "foo += bar = 1",
+        output: "foo = foo + (bar = 1)",
+        options: ["never"],
+        errors: UNEXPECTED_OPERATOR_ASSIGNMENT
+    }, {
+        code: "foo *= (bar + 1)",
+        output: "foo = foo * (bar + 1)",
+        options: ["never"],
+        errors: UNEXPECTED_OPERATOR_ASSIGNMENT
     }]
 
 });
diff --git a/tests/lib/rules/prefer-const.js b/tests/lib/rules/prefer-const.js
index 75821f95a..984649cb4 100644
--- a/tests/lib/rules/prefer-const.js
+++ b/tests/lib/rules/prefer-const.js
@@ -10,6 +10,7 @@
 //------------------------------------------------------------------------------
 
 const rule = require("../../../lib/rules/prefer-const"),
+    fixtureParser = require("../../fixtures/fixture-parser"),
     RuleTester = require("../../../lib/testers/rule-tester");
 
 //------------------------------------------------------------------------------
@@ -88,6 +89,18 @@ ruleTester.run("prefer-const", rule, {
             options: [{ destructuring: "all" }]
         },
 
+        // https://github.com/eslint/eslint/issues/8187
+        {
+            code: "let { name, ...otherStuff } = obj; otherStuff = {};",
+            options: [{ destructuring: "all" }],
+            parserOptions: { ecmaFeatures: { experimentalObjectRestSpread: true } }
+        },
+        {
+            code: "let { name, ...otherStuff } = obj; otherStuff = {};",
+            options: [{ destructuring: "all" }],
+            parser: fixtureParser("babel-eslint5/destructuring-object-spread")
+        },
+
         // ignoreReadBeforeAssign
         {
             code: "let x; function foo() { bar(x); } x = 0;",
@@ -290,6 +303,22 @@ ruleTester.run("prefer-const", rule, {
             errors: [{ message: "'c' is never reassigned. Use 'const' instead.", type: "Identifier" }]
         },
 
+        // https://github.com/eslint/eslint/issues/8187
+        {
+            code: "let { name, ...otherStuff } = obj; otherStuff = {};",
+            output: null,
+            options: [{ destructuring: "any" }],
+            parserOptions: { ecmaFeatures: { experimentalObjectRestSpread: true } },
+            errors: [{ message: "'name' is never reassigned. Use 'const' instead.", type: "Identifier", column: 7 }]
+        },
+        {
+            code: "let { name, ...otherStuff } = obj; otherStuff = {};",
+            output: null,
+            options: [{ destructuring: "any" }],
+            parser: fixtureParser("babel-eslint5/destructuring-object-spread"),
+            errors: [{ message: "'name' is never reassigned. Use 'const' instead.", type: "Identifier", column: 7 }]
+        },
+
         // Warnings are located at declaration if there are reading references before assignments.
         {
             code: "let x; function foo() { bar(x); } x = 0;",
diff --git a/tests/lib/rules/space-before-function-paren.js b/tests/lib/rules/space-before-function-paren.js
index 26180be5f..5e37dfd4e 100644
--- a/tests/lib/rules/space-before-function-paren.js
+++ b/tests/lib/rules/space-before-function-paren.js
@@ -8,8 +8,9 @@
 // Requirements
 //------------------------------------------------------------------------------
 
-const rule = require("../../../lib/rules/space-before-function-paren"),
-    RuleTester = require("../../../lib/testers/rule-tester");
+const rule = require("../../../lib/rules/space-before-function-paren");
+const RuleTester = require("../../../lib/testers/rule-tester");
+const baseParser = require("../../fixtures/fixture-parser");
 
 //------------------------------------------------------------------------------
 // Tests
@@ -95,6 +96,10 @@ ruleTester.run("space-before-function-paren", rule, {
         { code: "var bar = function foo () {}",
             options: [{ named: "ignore", anonymous: "always" }]
         },
+        {
+            code: "type TransformFunction = (el: ASTElement, code: string) => string;",
+            parser: baseParser("babel-eslint7", "function-type-annotation")
+        },
 
         // Async arrow functions
         { code: "() => 1", parserOptions: { ecmaVersion: 6 } },
diff --git a/tests/lib/util/glob-util.js b/tests/lib/util/glob-util.js
index 452ca06b2..47175848f 100644
--- a/tests/lib/util/glob-util.js
+++ b/tests/lib/util/glob-util.js
@@ -144,6 +144,16 @@ describe("globUtil", () => {
             assert.deepEqual(result, ["one-js-file/example.js"]);
         });
 
+        it("should ignore empty patterns", () => {
+            const patterns = [""];
+            const opts = {
+                cwd: getFixturePath()
+            };
+            const result = globUtil.resolveFileGlobPatterns(patterns, opts);
+
+            assert.deepEqual(result, []);
+        });
+
     });
 
     describe("listFilesToProcess()", () => {