Repository: eslint/eslint
Pull request #11401 (2019-02-15 19:49:10)

Upgrade: espree@5.0.1
<!--
    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:

<!--
    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)**
Upgrade Espree to the latest release

**Is there anything you'd like reviewers to focus on?**
No




Patch:
diff --git a/docs/maintainer-guide/governance.md b/docs/maintainer-guide/governance.md
index a9852d512..ed110fe65 100644
--- a/docs/maintainer-guide/governance.md
+++ b/docs/maintainer-guide/governance.md
@@ -41,17 +41,39 @@ New Committers can be nominated by any existing Committer. Once they have been n
 
 It is important to recognize that committership is a privilege, not a right. That privilege must be earned and once earned it can be removed by the TSC members by a standard TSC motion. However, under normal circumstances committership exists for as long as the Committer wishes to continue engaging with the project.
 
-A Committer who shows an above-average level of contribution to the project, particularly with respect to its strategic direction and long-term health, may be nominated to become a TSC member, described below.
+A Committer who shows an above-average level of contribution to the project, particularly with respect to its strategic direction and long-term health, may be nominated to become a reviewer, described below.
 
 #### Process for Adding Committers
 
 1. Send email congratulating the new committer and confirming that they would like to accept. This should also outline the responsibilities of a committer with a link to the maintainer guide.
 1. Add the GitHub user to the "ESLint Team" team
 1. Add committer email to the ESLint team mailing list
-1. Add committer to the README
 1. Invite to Gitter team chatroom
 1. Tweet congratulations to the new committer from the ESLint Twitter account
 
+### Reviewers
+
+Reviewers are community members who have contributed a significant amount of time to the project through triaging of issues, fixing bugs, implementing enhancements/features, and are trusted community leaders.
+
+Reviewers may perform all of the duties of Committers, and also:
+
+* May merge external pull requests for accepted issues upon reviewing and approving the changes.
+* May merge their own pull requests once they have collected the feedback they deem necessary. (No pull request should be merged without at least one Committer/Reviewer/TSC member comment stating they've looked at the code.)
+
+To become a Reviewer:
+
+* Work in a helpful and collaborative way with the community.
+* Have given good feedback on others' submissions and displayed an overall understanding of the code quality standards for the project.
+* Commit to being a part of the community for the long-term.
+* Have submitted a minimum of 50 qualifying pull requests.
+
+A Committer is invited to become a Reviewer by existing Reviewers and TSC members. A nomination will result in discussion and then a decision by the TSC.
+
+#### Process for Adding Reviewers
+
+1. Add the GitHub user to the "ESLint Reviewers" GitHub team
+1. Tweet congratulations to the new Reviewer from the ESLint Twitter account
+
 ### Technical Steering Committee (TSC)
 
 The ESLint project is jointly governed by a Technical Steering Committee (TSC) which is responsible for high-level guidance of the project.
@@ -75,26 +97,22 @@ No more than 1/3 of the TSC members may be affiliated with the same employer. If
 
 TSC members have additional responsibilities over and above those of a Committer. These responsibilities ensure the smooth running of the project. TSC members are expected to review code contributions, approve changes to this document, manage the copyrights within the project outputs, and attend regular TSC meetings.
 
-TSC members fulfill all requirements of Committers, and also:
-
-* May merge external pull requests for accepted issues upon reviewing and approving the changes.
-* May merge their own pull requests once they have collected the feedback they deem necessary. (No pull request should be merged without at least one Committer/TSC member comment stating they've looked at the code.)
+TSC members may perform all of the duties of Reviewers, and also:
 
-To become a TSC member:
+* May release new versions of all ESLint projects.
+* May participate in TSC meetings.
+* May propose budget items.
+* May propose new ESLint projects.
 
-* Work in a helpful and collaborative way with the community.
-* Have given good feedback on others' submissions and displayed an overall understanding of the code quality standards for the project.
-* Commit to being a part of the community for the long-term.
-* Have submitted a minimum of 50 qualifying pull requests.
+There is no specific set of requirements or qualifications for TSC members beyond those that are expected of Reviewers.
 
-A Committer is invited to become a TSC member by existing TSC members. A nomination will result in discussion and then a decision by the TSC.
+A Reviewer is invited to become a TSC member by existing TSC members. A nomination will result in discussion and then a decision by the TSC.
 
 #### Process for Adding TSC Members
 
 1. Add the GitHub user to the "ESLint TSC" GitHub team
 1. Set the GitHub user to be have the "Owner" role for the ESLint organization
 1. Send a welcome email with a link to the [maintainer guide](./) and the [npm 2FA guide](./npm-2fa).
-1. Add the TSC member to the README
 1. Invite to the Gitter TSC chatroom
 1. Make the TSC member an admin on the ESLint team mailing list
 1. Add the TSC member to the recurring TSC meeting event on Google Calendar
@@ -115,7 +133,7 @@ The intention of the agenda is not to approve or review all patches.
 That should happen continuously on GitHub and be handled by the larger
 group of Committers.
 
-Any community member or committer can ask that something be added to
+Any community member, Committer, or Reviewer can ask that something be added to
 the next meeting's agenda by logging a GitHub Issue. Anyone can add the item to the agenda by adding
 the "tsc agenda" tag to the issue.
 
diff --git a/docs/rules/padded-blocks.md b/docs/rules/padded-blocks.md
index 5c7908cff..d8b855ed3 100644
--- a/docs/rules/padded-blocks.md
+++ b/docs/rules/padded-blocks.md
@@ -20,7 +20,10 @@ This rule enforces consistent empty line padding within blocks.
 
 ## Options
 
-This rule has one option, which can be a string option or an object option.
+This rule has two options, the first one can be a string option or an object option.
+The second one is an object option, it can allow exceptions.
+
+### First option
 
 String option:
 
@@ -33,6 +36,10 @@ Object option:
 * `"classes"` require or disallow padding within classes
 * `"switches"` require or disallow padding within `switch` statements
 
+### Second option
+
+* `"allowSingleLineBlocks": true` allows single-line blocks
+
 ### always
 
 Examples of **incorrect** code for this rule with the default `"always"` option:
@@ -346,6 +353,42 @@ if (a) {
 }
 ```
 
+### always + allowSingleLineBlocks
+
+Examples of **incorrect** code for this rule with the `"always", {"allowSingleLineBlocks": true}` options:
+
+```js
+/*eslint padded-blocks: ["error", "always", { allowSingleLineBlocks: true }]*/
+
+if (a) {
+    b();
+}
+
+if (a) {
+
+    b();
+}
+
+if (a) {
+    b();
+
+}
+```
+
+Examples of **correct** code for this rule with the `"always", {"allowSingleLineBlocks": true}` options:
+
+```js
+/*eslint padded-blocks: ["error", "always", { allowSingleLineBlocks: true }]*/
+
+if (a) { b(); }
+
+if (a) {
+
+    b();
+
+}
+```
+
 ## When Not To Use It
 
 You can turn this rule off if you are not concerned with the consistency of padding within blocks.
diff --git a/docs/rules/sort-keys.md b/docs/rules/sort-keys.md
index cd4b78983..e6c515568 100644
--- a/docs/rules/sort-keys.md
+++ b/docs/rules/sort-keys.md
@@ -53,7 +53,7 @@ let obj = {a: 1, ["c" + "d"]: 3, b: 2};
 let obj = {a: 1, [`${c}`]: 3, b: 2};
 let obj = {a: 1, [tag`c`]: 3, b: 2};
 
-// This rule ignores objects that have a spread operator in them.
+// This rule does not report unsorted properties that are separated by a spread property.
 let obj = {b: 1, ...c, a: 2};
 ```
 
diff --git a/docs/rules/space-before-blocks.md b/docs/rules/space-before-blocks.md
index ab4c2a2b4..0b188f260 100644
--- a/docs/rules/space-before-blocks.md
+++ b/docs/rules/space-before-blocks.md
@@ -143,7 +143,7 @@ describe(function(){
   // ...
 });
 
-class Foo {
+class Foo{
   constructor(){}
 }
 ```
diff --git a/lib/rules/comma-spacing.js b/lib/rules/comma-spacing.js
index 789de7843..a9f89676a 100644
--- a/lib/rules/comma-spacing.js
+++ b/lib/rules/comma-spacing.js
@@ -120,6 +120,10 @@ module.exports = {
                 report(reportItem, "before", tokens.left);
             }
 
+            if (tokens.right && astUtils.isClosingParenToken(tokens.right)) {
+                return;
+            }
+
             if (tokens.right && !options.after && tokens.right.type === "Line") {
                 return;
             }
diff --git a/lib/rules/padded-blocks.js b/lib/rules/padded-blocks.js
index 7c0b56ba7..e4dd37f4c 100644
--- a/lib/rules/padded-blocks.js
+++ b/lib/rules/padded-blocks.js
@@ -5,6 +5,12 @@
 
 "use strict";
 
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const astUtils = require("../util/ast-utils");
+
 //------------------------------------------------------------------------------
 // Rule Definition
 //------------------------------------------------------------------------------
@@ -45,32 +51,45 @@ module.exports = {
                         minProperties: 1
                     }
                 ]
+            },
+            {
+                type: "object",
+                properties: {
+                    allowSingleLineBlocks: {
+                        type: "boolean"
+                    }
+                }
             }
         ]
     },
 
     create(context) {
         const options = {};
-        const config = context.options[0] || "always";
+        const typeOptions = context.options[0] || "always";
+        const exceptOptions = context.options[1] || {};
 
-        if (typeof config === "string") {
-            const shouldHavePadding = config === "always";
+        if (typeof typeOptions === "string") {
+            const shouldHavePadding = typeOptions === "always";
 
             options.blocks = shouldHavePadding;
             options.switches = shouldHavePadding;
             options.classes = shouldHavePadding;
         } else {
-            if (Object.prototype.hasOwnProperty.call(config, "blocks")) {
-                options.blocks = config.blocks === "always";
+            if (Object.prototype.hasOwnProperty.call(typeOptions, "blocks")) {
+                options.blocks = typeOptions.blocks === "always";
             }
-            if (Object.prototype.hasOwnProperty.call(config, "switches")) {
-                options.switches = config.switches === "always";
+            if (Object.prototype.hasOwnProperty.call(typeOptions, "switches")) {
+                options.switches = typeOptions.switches === "always";
             }
-            if (Object.prototype.hasOwnProperty.call(config, "classes")) {
-                options.classes = config.classes === "always";
+            if (Object.prototype.hasOwnProperty.call(typeOptions, "classes")) {
+                options.classes = typeOptions.classes === "always";
             }
         }
 
+        if (Object.prototype.hasOwnProperty.call(exceptOptions, "allowSingleLineBlocks")) {
+            options.allowSingleLineBlocks = exceptOptions.allowSingleLineBlocks === true;
+        }
+
         const ALWAYS_MESSAGE = "Block must be padded by blank lines.",
             NEVER_MESSAGE = "Block must not be padded by blank lines.";
 
@@ -177,6 +196,10 @@ module.exports = {
                 blockHasTopPadding = isPaddingBetweenTokens(tokenBeforeFirst, firstBlockToken),
                 blockHasBottomPadding = isPaddingBetweenTokens(lastBlockToken, tokenAfterLast);
 
+            if (options.allowSingleLineBlocks && astUtils.isTokenOnSameLine(tokenBeforeFirst, tokenAfterLast)) {
+                return;
+            }
+
             if (requirePaddingFor(node)) {
                 if (!blockHasTopPadding) {
                     context.report({
diff --git a/lib/rules/sort-keys.js b/lib/rules/sort-keys.js
index 1e8a85e3d..08bfcdf3d 100644
--- a/lib/rules/sort-keys.js
+++ b/lib/rules/sort-keys.js
@@ -129,8 +129,12 @@ module.exports = {
                 stack = stack.upper;
             },
 
+            SpreadElement() {
+                stack.prevName = null;
+            },
+
             Property(node) {
-                if (node.parent.type === "ObjectPattern" || node.parent.properties.some(n => n.type === "SpreadElement")) {
+                if (node.parent.type === "ObjectPattern") {
                     return;
                 }
 
diff --git a/package.json b/package.json
index cd25a4013..b00e984d0 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,7 @@
     "eslint-scope": "^4.0.0",
     "eslint-utils": "^1.3.1",
     "eslint-visitor-keys": "^1.0.0",
-    "espree": "^5.0.0",
+    "espree": "^5.0.1",
     "esquery": "^1.0.1",
     "esutils": "^2.0.2",
     "file-entry-cache": "^5.0.1",


Test patch:
diff --git a/tests/lib/rules/comma-spacing.js b/tests/lib/rules/comma-spacing.js
index d5c8ff0ec..2df7c71fa 100644
--- a/tests/lib/rules/comma-spacing.js
+++ b/tests/lib/rules/comma-spacing.js
@@ -61,6 +61,10 @@ ruleTester.run("comma-spacing", rule, {
         "['  ,  ']",
         { code: "[`  ,  `]", parserOptions: { ecmaVersion: 6 } },
         { code: "`${[1, 2]}`", parserOptions: { ecmaVersion: 6 } },
+        { code: "fn(a, b,)", parserOptions: { ecmaVersion: 2018 } }, // #11295
+        { code: "const fn = (a, b,) => {}", parserOptions: { ecmaVersion: 2018 } }, // #11295
+        { code: "const fn = function (a, b,) {}", parserOptions: { ecmaVersion: 2018 } }, // #11295
+        { code: "function fn(a, b,) {}", parserOptions: { ecmaVersion: 2018 } }, // #11295
         "foo(/,/, 'a')",
         "var x = ',,,,,';",
         "var code = 'var foo = 1, bar = 3;'",
diff --git a/tests/lib/rules/padded-blocks.js b/tests/lib/rules/padded-blocks.js
index fb363cdf3..08ed2856c 100644
--- a/tests/lib/rules/padded-blocks.js
+++ b/tests/lib/rules/padded-blocks.js
@@ -54,6 +54,8 @@ ruleTester.run("padded-blocks", rule, {
         { code: "{\na();}", options: ["never"] },
         { code: "{a();\n}", options: ["never"] },
         { code: "{a();}", options: ["never"] },
+        { code: "{a();}", options: ["always", { allowSingleLineBlocks: true }] },
+        { code: "{\n\na();\n\n}", options: ["always", { allowSingleLineBlocks: true }] },
         { code: "{//comment\na();}", options: ["never"] },
         { code: "{\n//comment\na()\n}", options: ["never"] },
         { code: "{a();//comment\n}", options: ["never"] },
diff --git a/tests/lib/rules/sort-keys.js b/tests/lib/rules/sort-keys.js
index 5a3a0a057..3106d3146 100644
--- a/tests/lib/rules/sort-keys.js
+++ b/tests/lib/rules/sort-keys.js
@@ -33,9 +33,18 @@ ruleTester.run("sort-keys", rule, {
         // ignore non-simple computed properties.
         { code: "var obj = {a:1, b:3, [a + b]: -1, c:2}", options: [], parserOptions: { ecmaVersion: 6 } },
 
-        // ignore spread properties.
+        // ignore properties separated by spread properties
         { code: "var obj = {a:1, ...z, b:1}", options: [], parserOptions: { ecmaVersion: 2018 } },
         { code: "var obj = {b:1, ...z, a:1}", options: [], parserOptions: { ecmaVersion: 2018 } },
+        { code: "var obj = {...a, b:1, ...c, d:1}", options: [], parserOptions: { ecmaVersion: 2018 } },
+        { code: "var obj = {...a, b:1, ...d, ...c, e:2, z:5}", options: [], parserOptions: { ecmaVersion: 2018 } },
+        { code: "var obj = {b:1, ...c, ...d, e:2}", options: [], parserOptions: { ecmaVersion: 2018 } },
+
+        // not ignore properties not separated by spread properties
+        { code: "var obj = {...z, a:1, b:1}", options: [], parserOptions: { ecmaVersion: 2018 } },
+        { code: "var obj = {...z, ...c, a:1, b:1}", options: [], parserOptions: { ecmaVersion: 2018 } },
+        { code: "var obj = {a:1, b:1, ...z}", options: [], parserOptions: { ecmaVersion: 2018 } },
+        { code: "var obj = {...z, ...x, a:1, ...c, ...d, f:5, e:4}", options: ["desc"], parserOptions: { ecmaVersion: 2018 } },
 
         // ignore destructuring patterns.
         { code: "let {a, b} = {}", options: [], parserOptions: { ecmaVersion: 6 } },
@@ -151,6 +160,53 @@ ruleTester.run("sort-keys", rule, {
             errors: ["Expected object keys to be in ascending order. 'Z' should be before 'À'."]
         },
 
+        // not ignore properties not separated by spread properties
+        {
+            code: "var obj = {...z, c:1, b:1}",
+            options: [],
+            parserOptions: { ecmaVersion: 2018 },
+            errors: ["Expected object keys to be in ascending order. 'b' should be before 'c'."]
+        },
+        {
+            code: "var obj = {...z, ...c, d:4, b:1, ...y, ...f, e:2, a:1}",
+            options: [],
+            parserOptions: { ecmaVersion: 2018 },
+            errors: [
+                "Expected object keys to be in ascending order. 'b' should be before 'd'.",
+                "Expected object keys to be in ascending order. 'a' should be before 'e'."
+            ]
+        },
+        {
+            code: "var obj = {c:1, b:1, ...a}",
+            options: [],
+            parserOptions: { ecmaVersion: 2018 },
+            errors: ["Expected object keys to be in ascending order. 'b' should be before 'c'."]
+        },
+        {
+            code: "var obj = {...z, ...a, c:1, b:1}",
+            options: [],
+            parserOptions: { ecmaVersion: 2018 },
+            errors: ["Expected object keys to be in ascending order. 'b' should be before 'c'."]
+        },
+        {
+            code: "var obj = {...z, b:1, a:1, ...d, ...c}",
+            options: [],
+            parserOptions: { ecmaVersion: 2018 },
+            errors: ["Expected object keys to be in ascending order. 'a' should be before 'b'."]
+        },
+        {
+            code: "var obj = {...z, a:2, b:0, ...x, ...c}",
+            options: ["desc"],
+            parserOptions: { ecmaVersion: 2018 },
+            errors: ["Expected object keys to be in descending order. 'b' should be before 'a'."]
+        },
+        {
+            code: "var obj = {...z, a:2, b:0, ...x}",
+            options: ["desc"],
+            parserOptions: { ecmaVersion: 2018 },
+            errors: ["Expected object keys to be in descending order. 'b' should be before 'a'."]
+        },
+
         // not ignore simple computed properties.
         {
             code: "var obj = {a:1, b:3, [a]: -1, c:2}",