Repository: eslint/eslint
Pull request #8247 (2017-03-14 05:22:08)

Fix: func-name-matching crash on destructuring assignment to functions
**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.7.2
* **npm Version:** 4.1.2

**What parser (default, Babel-ESLint, etc.) are you using?**

default

**Please show your full configuration:**

```yml
rules:
  func-name-matching: error
parserOptions:
  ecmaVersion: 6
```

**What did you do? Please include the actual source code causing the issue.**

```js
[a] = function foo() {};
```

**What did you expect to happen?**

I expected ESLint to not crash.

**What actually happened? Please include the actual, raw output from ESLint.**

ESLint crashed.

```
Cannot read property 'length' of undefined
TypeError: Cannot read property 'length' of undefined
    at isIdentifierNameES5 (/path/to/eslint/node_modules/esutils/lib/keyword.js:100:15)
    at Object.isIdentifierES5 (/path/to/eslint/node_modules/esutils/lib/keyword.js:146:16)
    at isIdentifier (/path/to/eslint/lib/rules/func-name-matching.js:50:28)
    at EventEmitter.AssignmentExpression (/path/to/eslint/lib/rules/func-name-matching.js:161:38)
    at emitOne (events.js:96:13)
    at EventEmitter.emit (events.js:191:7)
    at NodeEventGenerator.enterNode (/path/to/eslint/lib/util/node-event-generator.js:39:22)
    at CodePathAnalyzer.enterNode (/path/to/eslint/lib/code-path-analysis/code-path-analyzer.js:607:23)
    at CommentEventGenerator.enterNode (/path/to/eslint/lib/util/comment-event-generator.js:98:23)
    at Controller.enter (/path/to/eslint/lib/eslint.js:928:36)
```

**What changes did you make? (Give an overview)**

The func-name-matching rule checks for assignments to function expressions so that it can determine whether names match. However, due to a missing type-check, the rule would crash when run on a destructuring assignment to a function expression. This commit updates the rule to ignore destructuring assignments to function expressions.

Note: This is unrelated to https://github.com/eslint/eslint/pull/8246.

**Is there anything you'd like reviewers to focus on?**

Nothing in particular


mention-bot: @not-an-aardvark, thanks for your PR! By analyzing the history of the files in this pull request, we identified @azhang496 and @ljharb to be potential reviewers.
eslintbot: LGTM
eslintbot: LGTM

Patch:
diff --git a/lib/rules/func-name-matching.js b/lib/rules/func-name-matching.js
index e33efb7aa..db06d5d46 100644
--- a/lib/rules/func-name-matching.js
+++ b/lib/rules/func-name-matching.js
@@ -148,7 +148,7 @@ module.exports = {
         return {
 
             VariableDeclarator(node) {
-                if (!node.init || node.init.type !== "FunctionExpression") {
+                if (!node.init || node.init.type !== "FunctionExpression" || node.id.type !== "Identifier") {
                     return;
                 }
                 if (node.init.id && shouldWarn(node.id.name, node.init.id.name)) {
@@ -157,10 +157,12 @@ module.exports = {
             },
 
             AssignmentExpression(node) {
-                if (node.right.type !== "FunctionExpression" ||
-                   (node.left.computed && node.left.property.type !== "Literal") ||
-                    (!includeModuleExports && isModuleExports(node.left))
-                   ) {
+                if (
+                    node.right.type !== "FunctionExpression" ||
+                    (node.left.computed && node.left.property.type !== "Literal") ||
+                    (!includeModuleExports && isModuleExports(node.left)) ||
+                    (node.left.type !== "Identifier" && node.left.type !== "MemberExpression")
+                ) {
                     return;
                 }
 


Test patch:
diff --git a/tests/lib/rules/func-name-matching.js b/tests/lib/rules/func-name-matching.js
index 667570ed6..8f0d81425 100644
--- a/tests/lib/rules/func-name-matching.js
+++ b/tests/lib/rules/func-name-matching.js
@@ -145,6 +145,38 @@ ruleTester.run("func-name-matching", rule, {
         {
             code: "({[{x: 1}]: function foo() {}})",
             parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "[] = function foo() {}",
+            parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "({} = function foo() {})",
+            parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "[a] = function foo() {}",
+            parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "({a} = function foo() {})",
+            parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "var [] = function foo() {}",
+            parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "var {} = function foo() {}",
+            parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "var [a] = function foo() {}",
+            parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "var {a} = function foo() {}",
+            parserOptions: { ecmaVersion: 6 }
         }
     ],
     invalid: [