Repository: eslint/eslint
Pull request #9873 (2018-01-22 16:04:38)

Docs: Add prefer-destructuring variable reassignment example
add example with a reassignment.

<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

**What is the purpose of this pull request? (put an "X" next to item)**

[ ] Documentation update
[ ] 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
[X] Other, please explain: add code example.

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->

<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->

**What changes did you make? (Give an overview)**


**Is there anything you'd like reviewers to focus on?**




jsf-clabot: [![CLA assistant check](https://cla.js.foundation/pull/badge/not_signed)](https://cla.js.foundation/eslint/eslint?pullRequest=9873) <br/>Thank you for your submission, we really appreciate it. Like many open source projects, we ask that you sign our [Contributor License Agreement](https://cla.js.foundation/eslint/eslint?pullRequest=9873) before we can accept your contribution.<br/>

Patch:
diff --git a/.github/ISSUE_TEMPLATE/CHANGE.md b/.github/ISSUE_TEMPLATE/CHANGE.md
new file mode 100644
index 000000000..b8181f56c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/CHANGE.md
@@ -0,0 +1,25 @@
+<!--
+    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
+
+    This template is for requesting a change that is not a bug fix, rule change, or new rule. If you are here for another reason, please see below:
+
+    1. To report a bug: https://eslint.org/docs/developer-guide/contributing/reporting-bugs
+    2. To request a rule change: https://eslint.org/docs/developer-guide/contributing/rule-changes
+    3. To propose a new rule: https://eslint.org/docs/developer-guide/contributing/new-rules
+    4. If you have any questions, please stop by our chatroom: https://gitter.im/eslint/eslint
+
+    Note that leaving sections blank will make it difficult for us to troubleshoot and we may have to close the issue.
+-->
+
+**Tell us about your environment**
+
+* **ESLint Version:**
+* **Node Version:**
+* **npm Version:**
+
+**What did you do?**
+
+**What happened?**
+
+**What did you expect to happen?**
+
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md
similarity index 72%
rename from .github/ISSUE_TEMPLATE.md
rename to .github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md
index d33ca1105..3cf719784 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md
@@ -1,11 +1,12 @@
 <!--
     ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
 
-    This template is for bug reports. If you are reporting a bug, please continue on. If you are here for another reason, please see below:
+    This template is for bug reports. If you are here for another reason, please see below:
 
     1. To propose a new rule: https://eslint.org/docs/developer-guide/contributing/new-rules
-    2. To request a change: https://eslint.org/docs/developer-guide/contributing/changes
-    3. If you have any questions, please stop by our chatroom: https://gitter.im/eslint/eslint
+    2. To request a rule change: https://eslint.org/docs/developer-guide/contributing/rule-changes
+    3. To request a change that is not a bug fix, rule change, or new rule: https://eslint.org/docs/developer-guide/contributing/changes
+    4. If you have any questions, please stop by our chatroom: https://gitter.im/eslint/eslint
 
     Note that leaving sections blank will make it difficult for us to troubleshoot and we may have to close the issue.
 -->
@@ -26,8 +27,6 @@
 <!-- Paste your configuration below: -->
 ```js
 
-
-
 ```
 
 </details>
@@ -37,10 +36,6 @@
 <!-- Paste the source code below: -->
 ```js
 
-
-
-
-
 ```
 
 <!-- Paste the command you used to run ESLint: -->
diff --git a/.github/ISSUE_TEMPLATE/NEW_RULE.md b/.github/ISSUE_TEMPLATE/NEW_RULE.md
new file mode 100644
index 000000000..81248324b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/NEW_RULE.md
@@ -0,0 +1,31 @@
+<!--
+    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
+
+    This template is for new rule proposals. If you are proposing a new rule, please continue on. If you are here for another reason, please see below:
+
+    1. To report a bug: https://eslint.org/docs/developer-guide/contributing/reporting-bugs
+    2. To request a rule change: https://eslint.org/docs/developer-guide/contributing/rule-changes
+    3. To request a change that is not a bug fix, rule change, or new rule: https://eslint.org/docs/developer-guide/contributing/changes
+    4. If you have any questions, please stop by our chatroom: https://gitter.im/eslint/eslint
+
+    Note that leaving sections blank will make it difficult for us to troubleshoot and we may have to close the issue.
+-->
+
+**Please describe what the rule should do:**
+
+**What category of rule is this? (place an "X" next to just one item)**
+
+[ ] Enforces code style
+[ ] Warns about a potential error
+[ ] Suggests an alternate way of doing something
+[ ] Other (please specify:)
+
+**Provide 2-3 code examples that this rule will warn about:**
+
+<!-- Put your code examples here -->
+```js
+
+```
+
+**Why should this rule be included in ESLint (instead of a plugin)?**
+
diff --git a/.github/ISSUE_TEMPLATE/RULE_CHANGE.md b/.github/ISSUE_TEMPLATE/RULE_CHANGE.md
new file mode 100644
index 000000000..b68b90714
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/RULE_CHANGE.md
@@ -0,0 +1,30 @@
+<!--
+    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
+
+    This template is for requesting a rule change. If you are here for another reason, please see below:
+
+    1. To report a bug: https://eslint.org/docs/developer-guide/contributing/reporting-bugs
+    2. To propose a new rule: https://eslint.org/docs/developer-guide/contributing/new-rules
+    3. To request a change that is not a bug fix, rule change, or new rule: https://eslint.org/docs/developer-guide/contributing/changes
+    4. If you have any questions, please stop by our chatroom: https://gitter.im/eslint/eslint
+
+    Note that leaving sections blank will make it difficult for us to troubleshoot and we may have to close the issue.
+-->
+
+**What rule do you want to change?**
+
+**Does this change cause the rule to produce more or fewer warnings?**
+
+**How will the change be implemented? (New option, new default behavior, etc.)?**
+
+**Please provide some example code that this change will affect:**
+
+<!-- Put your code examples here -->
+```js
+
+```
+
+**What does the rule currently do for this code?**
+
+**What will the rule do after it's changed?**
+
diff --git a/docs/developer-guide/contributing/changes.md b/docs/developer-guide/contributing/changes.md
index 957f1286e..6b5f15901 100644
--- a/docs/developer-guide/contributing/changes.md
+++ b/docs/developer-guide/contributing/changes.md
@@ -1,6 +1,6 @@
 # Change Requests
 
-If you'd like to request a change to ESLint, please [create a new issue](https://github.com/eslint/eslint/issues/new?body=**What%20version%20are%20you%20using%3F**%0A%0A**What%20did%20you%20do%3F**%0A%0A**What%20happened%3F**%0A%0A**What%20did%20you%20expect%20to%20happen%3F**%0A%0A) on GitHub. Be sure to include the following information:
+If you'd like to request a change to ESLint, please [create a new issue](https://github.com/eslint/eslint/issues/new?template=CHANGE.md) on GitHub. Be sure to include the following information:
 
 1. The version of ESLint you are using.
 1. The problem you want to solve.
diff --git a/docs/developer-guide/contributing/new-rules.md b/docs/developer-guide/contributing/new-rules.md
index 072ca6700..c3fe9f454 100644
--- a/docs/developer-guide/contributing/new-rules.md
+++ b/docs/developer-guide/contributing/new-rules.md
@@ -19,7 +19,7 @@ Even though these are the formal criteria for inclusion, each rule is evaluated
 
 ## Proposing a Rule
 
-If you want to propose a new rule, [create a pull request](/docs/developer-guide/contributing/pull-requests.md) or new issue and paste the questions from the [rule proposal template](https://github.com/eslint/eslint/blob/master/templates/rule-proposal.md) into the description.
+If you want to propose a new rule, [create a pull request](/docs/developer-guide/contributing/pull-requests.md) or [new issue](https://github.com/eslint/eslint/issues/new?template=NEW_RULE.md) and fill out the template.
 
 We need all of this information in order to determine whether or not the rule is a good core rule candidate.
 
diff --git a/docs/developer-guide/contributing/reporting-bugs.md b/docs/developer-guide/contributing/reporting-bugs.md
index bfd8660b2..81f5e8562 100644
--- a/docs/developer-guide/contributing/reporting-bugs.md
+++ b/docs/developer-guide/contributing/reporting-bugs.md
@@ -1,6 +1,6 @@
 # Reporting Bugs
 
-If you think you've found a bug in ESLint, please [create a new issue](https://github.com/eslint/eslint/issues/new) or a [pull request](/docs/developer-guide/contributing/pull-requests.md) on GitHub. Be sure to copy the questions from the [bug report template](https://github.com/eslint/eslint/blob/master/templates/bug-report.md).
+If you think you've found a bug in ESLint, please [create a new issue](https://github.com/eslint/eslint/issues/new) or a [pull request](/docs/developer-guide/contributing/pull-requests.md) on GitHub.
 
 Please include as much detail as possible to help us properly address your issue. If we need to triage issues and constantly ask people for more detail, that's time taken away from actually fixing issues. Help us be as efficient as possible by including a lot of detail in your issues.
 
diff --git a/docs/developer-guide/contributing/rule-changes.md b/docs/developer-guide/contributing/rule-changes.md
index 9973d7840..d45ddbe44 100644
--- a/docs/developer-guide/contributing/rule-changes.md
+++ b/docs/developer-guide/contributing/rule-changes.md
@@ -4,7 +4,7 @@ Occasionally, a core ESLint rule needs to be changed. This is not necessarily a
 
 ## Proposing a Rule Change
 
-To propose a change to an existing rule, [create a new issue](https://github.com/eslint/eslint/issues/new) or a [pull request](/docs/developer-guide/contributing/pull-requests.md) on GitHub. Be sure to copy the questions from the [rule change proposal template](https://github.com/eslint/eslint/blob/master/templates/rule-change-proposal.md).
+To propose a change to an existing rule, [create a pull request](/docs/developer-guide/contributing/pull-requests.md) or [new issue](https://github.com/eslint/eslint/issues/new?template=RULE_CHANGE.md) and fill out the template.
 
 We need all of this information in order to determine whether or not the change is a good candidate for inclusion.
 
diff --git a/docs/developer-guide/working-with-rules.md b/docs/developer-guide/working-with-rules.md
index f345f7cdc..f23afb16b 100644
--- a/docs/developer-guide/working-with-rules.md
+++ b/docs/developer-guide/working-with-rules.md
@@ -222,23 +222,26 @@ var foo = 2;
 //  ^ error: Avoid using variables named 'foo'
 
 // In your tests:
-var rule = require('../../../lib/rules/no-insecure-random');
-var RuleTester = require('eslint').RuleTester;
+var rule = require("../../../lib/rules/my-rule");
+var RuleTester = require("eslint").RuleTester;
 
 var ruleTester = new RuleTester();
-ruleTester.run('my-rule', rule, {
-  valid: ['bar', 'baz'],
+ruleTester.run("my-rule", rule, {
+    valid: ["bar", "baz"],
 
-  invalid: [
-    {
-      code: 'foo',
-      errors: [
+    invalid: [
         {
-          messageId: 'foo',
+            code: "foo",
+            errors: [
+                {
+                    messageId: "avoidName",
+                    data: {
+                        name: "foo"
+                    }
+                }
+            ]
         }
-      ]
-    }
-  ]
+    ]
 });
 {% endraw %}
 ```
diff --git a/docs/rules/no-undef.md b/docs/rules/no-undef.md
index 4b21f2c05..49a149fde 100644
--- a/docs/rules/no-undef.md
+++ b/docs/rules/no-undef.md
@@ -4,7 +4,7 @@ This rule can help you locate potential ReferenceErrors resulting from misspelli
 
 ## Rule Details
 
-Any reference to an undeclared variable causes a warning, unless the variable is explicitly mentioned in a `/*global ...*/` comment.
+Any reference to an undeclared variable causes a warning, unless the variable is explicitly mentioned in a `/*global ...*/` comment, or specified in the [`globals` key in the configuration file](https://eslint.org/docs/user-guide/configuring#specifying-globals). A common use case for these is if you intentionally use globals that are defined elsewhere (e.g. in a script sourced from HTML).
 
 Examples of **incorrect** code for this rule:
 
diff --git a/docs/rules/prefer-destructuring.md b/docs/rules/prefer-destructuring.md
index 1cb54b997..e6c2b94bc 100644
--- a/docs/rules/prefer-destructuring.md
+++ b/docs/rules/prefer-destructuring.md
@@ -36,7 +36,11 @@ var foo = array[someIndex];
 
 // With `object` enabled
 var { foo } = object;
+
 var foo = object.bar;
+
+let foo;
+({ foo } = object.bar);
 ```
 
 Examples of **incorrect** code when `enforceForRenamedProperties` is enabled:
diff --git a/docs/rules/space-unary-ops.md b/docs/rules/space-unary-ops.md
index 8853d9239..d04bd4a45 100644
--- a/docs/rules/space-unary-ops.md
+++ b/docs/rules/space-unary-ops.md
@@ -59,7 +59,7 @@ This rule has three options:
 
 In this case, spacing will be disallowed after a `new` operator and required before/after a `++` operator.
 
-Examples of **incorrect** code for this rule with the `{"words": true, "nonwords": false}` option:
+Examples of **incorrect** code for this rule with the default `{"words": true, "nonwords": false}` option:
 
 ```js
 /*eslint space-unary-ops: "error"*/
@@ -90,6 +90,14 @@ function *foo() {
 }
 ```
 
+```js
+/*eslint space-unary-ops: "error"*/
+
+async function foo() {
+    await(bar);
+}
+```
+
 Examples of **correct** code for this rule with the `{"words": true, "nonwords": false}` option:
 
 ```js
@@ -125,3 +133,11 @@ function *foo() {
     yield (0)
 }
 ```
+
+```js
+/*eslint space-unary-ops: "error"*/
+
+async function foo() {
+    await (bar);
+}
+```
diff --git a/lib/rules/space-unary-ops.js b/lib/rules/space-unary-ops.js
index 4d122836a..601d705e6 100644
--- a/lib/rules/space-unary-ops.js
+++ b/lib/rules/space-unary-ops.js
@@ -66,15 +66,6 @@ module.exports = {
                 node.argument && node.argument.type === "UnaryExpression" && node.argument.operator === "!";
         }
 
-        /**
-         * Check if the node's child argument is an "ObjectExpression"
-         * @param {ASTnode} node AST node
-         * @returns {boolean} Whether or not the argument's type is "ObjectExpression"
-         */
-        function isArgumentObjectExpression(node) {
-            return node.argument && node.argument.type && node.argument.type === "ObjectExpression";
-        }
-
         /**
          * Checks if an override exists for a given operator.
          * @param {string} operator Operator
@@ -125,7 +116,7 @@ module.exports = {
          * @returns {void}
          */
         function verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word) {
-            if (isArgumentObjectExpression(node)) {
+            if (astUtils.canTokensBeAdjacent(firstToken, secondToken)) {
                 if (secondToken.range[0] > firstToken.range[1]) {
                     context.report({
                         node,
diff --git a/lib/util/npm-util.js b/lib/util/npm-util.js
index 6c431e039..1c0cc5c6a 100644
--- a/lib/util/npm-util.js
+++ b/lib/util/npm-util.js
@@ -60,7 +60,7 @@ function installSyncSaveDev(packages) {
     if (error && error.code === "ENOENT") {
         const pluralS = packages.length > 1 ? "s" : "";
 
-        log.error(`Could not execute npm. Please install the following package${pluralS} with your package manager of choice: ${packages.join(", ")}`);
+        log.error(`Could not execute npm. Please install the following package${pluralS} with a package manager of your choice: ${packages.join(", ")}`);
     }
 }
 
diff --git a/templates/rule-change-proposal.md b/templates/rule-change-proposal.md
index 689e218a4..ee100011b 100644
--- a/templates/rule-change-proposal.md
+++ b/templates/rule-change-proposal.md
@@ -17,3 +17,4 @@
 
 
 **What will the rule do after it's changed?**
+
diff --git a/templates/rule-proposal.md b/templates/rule-proposal.md
index 9814d5923..383b1b481 100644
--- a/templates/rule-proposal.md
+++ b/templates/rule-proposal.md
@@ -15,3 +15,4 @@
 ```
 
 **Why should this rule be included in ESLint (instead of a plugin)?**
+


Test patch:
diff --git a/tests/lib/rules/space-unary-ops.js b/tests/lib/rules/space-unary-ops.js
index 22efa2088..11b2c96bf 100644
--- a/tests/lib/rules/space-unary-ops.js
+++ b/tests/lib/rules/space-unary-ops.js
@@ -41,6 +41,7 @@ ruleTester.run("space-unary-ops", rule, {
             code: "foo.bar --",
             options: [{ nonwords: true }]
         },
+
         {
             code: "delete foo.bar",
             options: [{ words: true }]
@@ -49,6 +50,14 @@ ruleTester.run("space-unary-ops", rule, {
             code: "delete foo[\"bar\"]",
             options: [{ words: true }]
         },
+        {
+            code: "delete foo.bar",
+            options: [{ words: false }]
+        },
+        {
+            code: "delete(foo.bar)",
+            options: [{ words: false }]
+        },
 
         {
             code: "new Foo",
@@ -79,6 +88,14 @@ ruleTester.run("space-unary-ops", rule, {
             code: "typeof {foo:true}",
             options: [{ words: true }]
         },
+        {
+            code: "typeof (foo)",
+            options: [{ words: true }]
+        },
+        {
+            code: "typeof(foo)",
+            options: [{ words: false }]
+        },
         {
             code: "typeof!foo",
             options: [{ words: false }]
@@ -100,6 +117,14 @@ ruleTester.run("space-unary-ops", rule, {
             code: "void foo",
             options: [{ words: true }]
         },
+        {
+            code: "void foo",
+            options: [{ words: false }]
+        },
+        {
+            code: "void(foo)",
+            options: [{ words: false }]
+        },
 
         {
             code: "-1",
@@ -217,12 +242,12 @@ ruleTester.run("space-unary-ops", rule, {
             options: [{ words: false, overrides: { new: false } }]
         },
         {
-            code: "function *foo () { yield (0) }",
+            code: "function *foo () { yield(0) }",
             options: [{ words: true, overrides: { yield: false } }],
             parserOptions: { ecmaVersion: 6 }
         },
         {
-            code: "function *foo () { yield (0) }",
+            code: "function *foo () { yield(0) }",
             options: [{ words: false, overrides: { yield: false } }],
             parserOptions: { ecmaVersion: 6 }
         }
@@ -247,6 +272,15 @@ ruleTester.run("space-unary-ops", rule, {
                 type: "UnaryExpression"
             }]
         },
+        {
+            code: "delete (foo.bar)",
+            output: "delete(foo.bar)",
+            options: [{ words: false }],
+            errors: [{
+                message: "Unexpected space after unary word operator 'delete'.",
+                type: "UnaryExpression"
+            }]
+        },
         {
             code: "new(Foo)",
             output: "new (Foo)",
@@ -256,6 +290,15 @@ ruleTester.run("space-unary-ops", rule, {
                 type: "NewExpression"
             }]
         },
+        {
+            code: "new (Foo)",
+            output: "new(Foo)",
+            options: [{ words: false }],
+            errors: [{
+                message: "Unexpected space after unary word operator 'new'.",
+                type: "NewExpression"
+            }]
+        },
         {
             code: "new(Foo())",
             output: "new (Foo())",
@@ -265,6 +308,15 @@ ruleTester.run("space-unary-ops", rule, {
                 type: "NewExpression"
             }]
         },
+        {
+            code: "new [foo][0]",
+            output: "new[foo][0]",
+            options: [{ words: false }],
+            errors: [{
+                message: "Unexpected space after unary word operator 'new'.",
+                type: "NewExpression"
+            }]
+        },
 
         {
             code: "typeof(foo)",
@@ -275,6 +327,33 @@ ruleTester.run("space-unary-ops", rule, {
                 type: "UnaryExpression"
             }]
         },
+        {
+            code: "typeof (foo)",
+            output: "typeof(foo)",
+            options: [{ words: false }],
+            errors: [{
+                message: "Unexpected space after unary word operator 'typeof'.",
+                type: "UnaryExpression"
+            }]
+        },
+        {
+            code: "typeof[foo]",
+            output: "typeof [foo]",
+            options: [{ words: true }],
+            errors: [{
+                message: "Unary word operator 'typeof' must be followed by whitespace.",
+                type: "UnaryExpression"
+            }]
+        },
+        {
+            code: "typeof [foo]",
+            output: "typeof[foo]",
+            options: [{ words: false }],
+            errors: [{
+                message: "Unexpected space after unary word operator 'typeof'.",
+                type: "UnaryExpression"
+            }]
+        },
         {
             code: "typeof{foo:true}",
             output: "typeof {foo:true}",
@@ -321,6 +400,15 @@ ruleTester.run("space-unary-ops", rule, {
                 type: "UnaryExpression"
             }]
         },
+        {
+            code: "void[foo];",
+            output: "void [foo];",
+            options: [{ words: true }],
+            errors: [{
+                message: "Unary word operator 'void' must be followed by whitespace.",
+                type: "UnaryExpression"
+            }]
+        },
         {
             code: "void{a:0};",
             output: "void {a:0};",
@@ -330,6 +418,24 @@ ruleTester.run("space-unary-ops", rule, {
                 type: "UnaryExpression"
             }]
         },
+        {
+            code: "void (foo)",
+            output: "void(foo)",
+            options: [{ words: false }],
+            errors: [{
+                message: "Unexpected space after unary word operator 'void'.",
+                type: "UnaryExpression"
+            }]
+        },
+        {
+            code: "void [foo]",
+            output: "void[foo]",
+            options: [{ words: false }],
+            errors: [{
+                message: "Unexpected space after unary word operator 'void'.",
+                type: "UnaryExpression"
+            }]
+        },
 
         {
             code: "! foo",
@@ -488,6 +594,18 @@ ruleTester.run("space-unary-ops", rule, {
                 column: 19
             }]
         },
+        {
+            code: "function *foo() { yield (0) }",
+            output: "function *foo() { yield(0) }",
+            options: [{ words: false }],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [{
+                message: "Unexpected space after unary word operator 'yield'.",
+                type: "YieldExpression",
+                line: 1,
+                column: 19
+            }]
+        },
         {
             code: "function *foo() { yield+0 }",
             output: "function *foo() { yield +0 }",