Repository: eslint/eslint (js)

Issue:
False negative for camelcase with ignoreDestructuring
**Tell us about your environment**

* **ESLint Version: `5.9.0` **
* **Node Version: `11.0.0` **
* **npm Version: `6.4.1` **

**What parser (default, Babel-ESLint, etc.) are you using?**

default

**Please show your full configuration:**

<details>
<summary>Configuration</summary>

```js
camelcase: [2, {ignoreDestructuring: true}]
```

</details>

**What did you do? Please include the actual source code causing the issue, as well as the command that you used to run ESLint.**

minimal working example to reproduce (yes, it's a silly example):

```js
var { [{category_id: 123}]: categoryId } = query;
```

**What did you expect to happen?**

Reported `camelcase` error for `category_id`.

**What actually happened? Please include the actual, raw output from ESLint.**

No error was reported

**Are you willing to submit a pull request to fix this bug?**

yep 😸 


Pull request description:
Fix: handle computed properties in camelcase (fixes #11084)
**What is the purpose of this pull request? (put an "X" next to item)**

[ ] Documentation update
[x] Bug fix ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/bug-report.md))
[ ] New rule ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-proposal.md))
[ ] Changes an existing rule ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-change-proposal.md))
[ ] Add autofixing to a rule
[ ] Add a CLI option
[ ] Add something to the core
[ ] Other, please explain:

**Tell us about your environment**

* **ESLint Version:** `5.9.0`
* **Node Version:** `11.0.0`
* **npm Version:** `6.4.1`

**What parser (default, Babel-ESLint, etc.) are you using?** default

**Please show your full configuration:**

<details>
<summary>Configuration</summary>

```js
camelcase: [2, {ignoreDestructuring: true}]
```

</details>

**What did you do? Please include the actual source code causing the issue.**

```js
var { [category_id]: categoryId } = query;
```

**What did you expect to happen?**

Reported `camelcase` error for `category_id`.

**What actually happened? Please include the actual, raw output from ESLint.**

No errors reported

**What changes did you make? (Give an overview)**

`isInsideObjectPattern` now stops at computed properties (as the computed property can be a simple expression, and `node` cannot be part of an `ObjectPattern` anymore).

**Is there anything you'd like reviewers to focus on?**

I'd be happy to add more tests if you can think of more edge-cases.



Patch:
diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.md b/.github/ISSUE_TEMPLATE/BUG_REPORT.md
index 1e9a73641..1132aab25 100644
--- a/.github/ISSUE_TEMPLATE/BUG_REPORT.md
+++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.md
@@ -2,7 +2,7 @@
 name: "\U0001F41E  Bug report"
 about: Report an issue with ESLint or rules bundled with ESLint
 title: ''
-labels: bug, evaluating
+labels: bug, triage
 assignees: ''
 
 ---
diff --git a/.github/ISSUE_TEMPLATE/CHANGE.md b/.github/ISSUE_TEMPLATE/CHANGE.md
index 35cb70243..6cf642542 100644
--- a/.github/ISSUE_TEMPLATE/CHANGE.md
+++ b/.github/ISSUE_TEMPLATE/CHANGE.md
@@ -2,7 +2,7 @@
 name: "\U0001F4DD Non-rule change request"
 about: Request a change that is not a bug fix, rule change, or new rule
 title: ''
-labels: core, enhancement, evaluating
+labels: enhancement, triage, core
 assignees: ''
 
 ---
diff --git a/.github/ISSUE_TEMPLATE/NEW_RULE.md b/.github/ISSUE_TEMPLATE/NEW_RULE.md
index 0fa62b1cf..598e89c0f 100644
--- a/.github/ISSUE_TEMPLATE/NEW_RULE.md
+++ b/.github/ISSUE_TEMPLATE/NEW_RULE.md
@@ -2,7 +2,7 @@
 name: "\U0001F680 New rule proposal"
 about: Propose a new rule to be added to ESLint
 title: ''
-labels: rule, feature, evaluating
+labels: triage, rule, feature
 assignees: ''
 
 ---
diff --git a/.github/ISSUE_TEMPLATE/RULE_CHANGE.md b/.github/ISSUE_TEMPLATE/RULE_CHANGE.md
index 88e250f96..d735010f6 100644
--- a/.github/ISSUE_TEMPLATE/RULE_CHANGE.md
+++ b/.github/ISSUE_TEMPLATE/RULE_CHANGE.md
@@ -2,7 +2,7 @@
 name: "\U0001F4DD Rule change request"
 about: Request a change to an existing rule
 title: ''
-labels: enhancement, evaluating, rule
+labels: enhancement, triage, rule
 assignees: ''
 
 ---
diff --git a/docs/developer-guide/working-with-plugins.md b/docs/developer-guide/working-with-plugins.md
index 4d0ab55d5..83f107512 100644
--- a/docs/developer-guide/working-with-plugins.md
+++ b/docs/developer-guide/working-with-plugins.md
@@ -52,31 +52,33 @@ Plugin environments can define the following objects:
 You can also create plugins that would tell ESLint how to process files other than JavaScript. In order to create a processor, the object that is exported from your module has to conform to the following interface:
 
 ```js
-processors: {
+module.exports = {
+    processors: {
 
-    // assign to the file extension you want (.js, .jsx, .html, etc.)
-    ".ext": {
-        // takes text of the file and filename
-        preprocess: function(text, filename) {
-            // here, you can strip out any non-JS content
-            // and split into multiple strings to lint
+        // assign to the file extension you want (.js, .jsx, .html, etc.)
+        ".ext": {
+            // takes text of the file and filename
+            preprocess: function(text, filename) {
+                // here, you can strip out any non-JS content
+                // and split into multiple strings to lint
 
-            return [string];  // return an array of strings to lint
-        },
+                return [string];  // return an array of strings to lint
+            },
 
-        // takes a Message[][] and filename
-        postprocess: function(messages, filename) {
-            // `messages` argument contains two-dimensional array of Message objects
-            // where each top-level array item contains array of lint messages related
-            // to the text that was returned in array from preprocess() method
+            // takes a Message[][] and filename
+            postprocess: function(messages, filename) {
+                // `messages` argument contains two-dimensional array of Message objects
+                // where each top-level array item contains array of lint messages related
+                // to the text that was returned in array from preprocess() method
 
-            // you need to return a one-dimensional array of the messages you want to keep
-            return [Message];
-        },
+                // you need to return a one-dimensional array of the messages you want to keep
+                return messages[0];
+            },
 
-        supportsAutofix: true // (optional, defaults to false)
+            supportsAutofix: true // (optional, defaults to false)
+        }
     }
-}
+};
 ```
 
 The `preprocess` method takes the file contents and filename as arguments, and returns an array of strings to lint. The strings will be linted separately but still be registered to the filename. It's up to the plugin to decide if it needs to return just one part, or multiple pieces. For example in the case of processing `.html` files, you might want to return just one item in the array by combining all scripts, but for `.md` file where each JavaScript block might be independent, you can return multiple items.
@@ -117,22 +119,45 @@ To support multiple extensions, add each one to the `processors` element and poi
 
 ### Configs in Plugins
 
-You can bundle configurations inside a plugin. This can be useful when you want to provide not just code style, but also some custom rules to support it. You can specify configurations under `configs` key. Please note that when exposing configurations, you have to name each one, and there is no default. So your users will have to specify the name of the configuration they want to use.
+You can bundle configurations inside a plugin by specifying them under the `configs` key. This can be useful when you want to provide not just code style, but also some custom rules to support it. Multiple configurations are supported per plugin. Note that it is not possible to specify a default configuration for a given plugin and that users must specify in their configuration file when they want to use one.
 
 ```js
-configs: {
-    myConfig: {
-        env: ["browser"],
-        rules: {
-            semi: 2,
-            "myPlugin/my-rule": 2,
-            "eslint-plugin-myPlugin/another-rule": 2
+// eslint-plugin-myPlugin
+
+module.exports = {
+    configs: {
+        myConfig: {
+            plugins: ["myPlugin"],
+            env: ["browser"],
+            rules: {
+                semi: "error",
+                "myPlugin/my-rule": "error",
+                "eslint-plugin-myPlugin/another-rule": "error"
+            }
+        },
+        myOtherConfig: {
+            plugins: ["myPlugin"],
+            env: ["node"],
+            rules: {
+                "myPlugin/my-rule": "off",
+                "eslint-plugin-myPlugin/another-rule": "off"
+                "eslint-plugin-myPlugin/yet-another-rule": "error"
+            }
         }
     }
+};
+```
+
+If the example plugin above were called `eslint-plugin-myPlugin`, the `myConfig` and `myOtherConfig` configurations would then be usable by extending off of `"plugin:myPlugin/myConfig"` and `"plugin:myPlugin/myOtherConfig"`, respectively.
+
+```json
+{
+    "extends": ["plugin:myPlugin/myConfig"]
 }
+
 ```
 
-**Note:** Please note that configuration will not automatically attach your rules and you have to specify your plugin name and any rules you want to enable that are part of the plugin. Any plugin rules must be prefixed with the short or long plugin name. See [Configuring Plugins](../user-guide/configuring.md#configuring-plugins)
+**Note:** Please note that configuration will not enable any of the plugin's rules by default, and instead should be treated as a standalone config. This means that you must specify your plugin name in the `plugins` array as well as any rules you want to enable that are part of the plugin. Any plugin rules must be prefixed with the short or long plugin name. See [Configuring Plugins](../user-guide/configuring.md#configuring-plugins) for more information.
 
 ### Peer Dependency
 
diff --git a/docs/rules/no-unused-expressions.md b/docs/rules/no-unused-expressions.md
index 480915ee2..8a9748d3d 100644
--- a/docs/rules/no-unused-expressions.md
+++ b/docs/rules/no-unused-expressions.md
@@ -2,7 +2,7 @@
 
 An unused expression which has no effect on the state of the program indicates a logic error.
 
-For example, `n + 1;` is not a syntax error, but it might be a typing mistake where a programmer meant an assignment statement `n += 1;` instead.
+For example, `n + 1;` is not a syntax error, but it might be a typing mistake where a programmer meant an assignment statement `n += 1;` instead. Sometimes, such unused expressions may be eliminated by some build tools in production environment, which possibly breaks application logic.
 
 ## Rule Details
 
diff --git a/docs/rules/no-unused-vars.md b/docs/rules/no-unused-vars.md
index 996dea181..2b3f093cc 100644
--- a/docs/rules/no-unused-vars.md
+++ b/docs/rules/no-unused-vars.md
@@ -4,16 +4,16 @@ Variables that are declared and not used anywhere in the code are most likely an
 
 ## Rule Details
 
-This rule is aimed at eliminating unused variables, functions, and parameters of functions.
+This rule is aimed at eliminating unused variables, functions, and function parameters.
 
-A variable is considered to be used if any of the following are true:
+A variable `foo` is considered to be used if any of the following are true:
 
-* It represents a function that is called (`doSomething()`)
-* It is read (`var y = x`)
-* It is passed into a function as an argument (`doSomething(x)`)
+* It is called (`foo()`) or constructed (`new foo()`)
+* It is read (`var bar = foo`)
+* It is passed into a function as an argument (`doSomething(foo)`)
 * It is read inside of a function that is passed to another function (`doSomething(function() { foo(); })`)
 
-A variable is *not* considered to be used if it is only ever assigned to (`var x = 5`) or declared.
+A variable is *not* considered to be used if it is only ever declared (`var foo = 5`) or assigned to (`foo = 7`).
 
 Examples of **incorrect** code for this rule:
 
diff --git a/docs/rules/padded-blocks.md b/docs/rules/padded-blocks.md
index 3393d090e..5c7908cff 100644
--- a/docs/rules/padded-blocks.md
+++ b/docs/rules/padded-blocks.md
@@ -51,11 +51,6 @@ if (a)
     b();
 }
 
-if (a) {
-
-    b();
-}
-
 if (a) {
     b();
 
diff --git a/docs/rules/require-jsdoc.md b/docs/rules/require-jsdoc.md
index 8f6ffeb73..1e31aedf7 100644
--- a/docs/rules/require-jsdoc.md
+++ b/docs/rules/require-jsdoc.md
@@ -1,6 +1,6 @@
 # require JSDoc comments (require-jsdoc)
 
-This rule was **deprecated** in ESLint v5.10.0.
+This rule was [**deprecated**](https://eslint.org/blog/2018/11/jsdoc-end-of-life) in ESLint v5.10.0.
 
 [JSDoc](http://usejsdoc.org) is a JavaScript API documentation generator. It uses specially-formatted comments inside of code to generate API documentation automatically. For example, this is what a JSDoc comment looks like for a function:
 
diff --git a/docs/rules/valid-jsdoc.md b/docs/rules/valid-jsdoc.md
index 876453721..2d503828f 100644
--- a/docs/rules/valid-jsdoc.md
+++ b/docs/rules/valid-jsdoc.md
@@ -1,6 +1,6 @@
 # enforce valid JSDoc comments (valid-jsdoc)
 
-This rule was **deprecated** in ESLint v5.10.0.
+This rule was [**deprecated**](https://eslint.org/blog/2018/11/jsdoc-end-of-life) in ESLint v5.10.0.
 
 [JSDoc](http://usejsdoc.org) generates application programming interface (API) documentation from specially-formatted comments in JavaScript code. For example, this is a JSDoc comment for a function:
 
diff --git a/lib/rules/camelcase.js b/lib/rules/camelcase.js
index 6fb8760f1..a8341c84b 100644
--- a/lib/rules/camelcase.js
+++ b/lib/rules/camelcase.js
@@ -100,14 +100,20 @@ module.exports = {
          * @private
          */
         function isInsideObjectPattern(node) {
-            let { parent } = node;
+            let current = node;
 
-            while (parent) {
-                if (parent.type === "ObjectPattern") {
+            while (current) {
+                const parent = current.parent;
+
+                if (parent && parent.type === "Property" && parent.computed && parent.key === current) {
+                    return false;
+                }
+
+                if (current.type === "ObjectPattern") {
                     return true;
                 }
 
-                parent = parent.parent;
+                current = parent;
             }
 
             return false;
@@ -169,12 +175,15 @@ module.exports = {
 
                     if (node.parent.parent && node.parent.parent.type === "ObjectPattern") {
                         if (node.parent.shorthand && node.parent.value.left && nameIsUnderscored) {
-
                             report(node);
                         }
 
                         const assignmentKeyEqualsValue = node.parent.key.name === node.parent.value.name;
 
+                        if (isUnderscored(name) && node.parent.computed) {
+                            report(node);
+                        }
+
                         // prevent checking righthand side of destructured object
                         if (node.parent.key === node && node.parent.value !== node) {
                             return;
diff --git a/lib/rules/no-irregular-whitespace.js b/lib/rules/no-irregular-whitespace.js
index 7920ebdc5..90d1a79a1 100644
--- a/lib/rules/no-irregular-whitespace.js
+++ b/lib/rules/no-irregular-whitespace.js
@@ -30,7 +30,7 @@ module.exports = {
         type: "problem",
 
         docs: {
-            description: "disallow irregular whitespace outside of strings and comments",
+            description: "disallow irregular whitespace",
             category: "Possible Errors",
             recommended: true,
             url: "https://eslint.org/docs/rules/no-irregular-whitespace"


Test patch:
diff --git a/tests/lib/rules/camelcase.js b/tests/lib/rules/camelcase.js
index d1ce3b3fd..eb80b4ef4 100644
--- a/tests/lib/rules/camelcase.js
+++ b/tests/lib/rules/camelcase.js
@@ -106,6 +106,11 @@ ruleTester.run("camelcase", rule, {
             options: [{ ignoreDestructuring: true }],
             parserOptions: { ecmaVersion: 6 }
         },
+        {
+            code: "var { [{category_id} = query]: categoryId } = query;",
+            options: [{ ignoreDestructuring: true }],
+            parserOptions: { ecmaVersion: 6 }
+        },
         {
             code: "var { category_id: category } = query;",
             parserOptions: { ecmaVersion: 6 }
@@ -345,6 +350,29 @@ ruleTester.run("camelcase", rule, {
                 }
             ]
         },
+        {
+            code: "var { [category_id]: categoryId } = query;",
+            options: [{ ignoreDestructuring: true }],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                {
+                    messageId: "notCamelCase",
+                    data: { name: "category_id" },
+                    type: "Identifier"
+                }
+            ]
+        },
+        {
+            code: "var { [category_id]: categoryId } = query;",
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                {
+                    messageId: "notCamelCase",
+                    data: { name: "category_id" },
+                    type: "Identifier"
+                }
+            ]
+        },
         {
             code: "var { category_id: categoryId, ...other_props } = query;",
             options: [{ ignoreDestructuring: true }],