Repository: eslint/eslint
Pull request #11434 (2019-02-23 18:59:05)

Chore: eslint-config-eslint enable comma-dangle functions: "never"
<!--
    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)**


**Is there anything you'd like reviewers to focus on?**
IMHO, this should be enabled by default.




Patch:
diff --git a/.eslintrc.js b/.eslintrc.js
index 780368769..86cc48017 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,18 +1,13 @@
 "use strict";
 
-const path = require("path");
-const rulesDirPlugin = require("eslint-plugin-rulesdir");
-
-rulesDirPlugin.RULES_DIR = path.join(__dirname, "tools/internal-rules");
-
 module.exports = {
     root: true,
     plugins: [
         "eslint-plugin",
-        "rulesdir"
+        "internal-rules"
     ],
     extends: [
-        "./packages/eslint-config-eslint/default.yml",
+        "eslint",
         "plugin:eslint-plugin/recommended"
     ],
     rules: {
@@ -24,24 +19,30 @@ module.exports = {
         "eslint-plugin/require-meta-type": "error",
         "eslint-plugin/test-case-property-ordering": "error",
         "eslint-plugin/test-case-shorthand-strings": "error",
-        "rulesdir/multiline-comment-style": "error"
+        "internal-rules/multiline-comment-style": "error"
     },
     overrides: [
         {
             files: ["lib/rules/*", "tools/internal-rules/*"],
+            excludedFiles: ["tools/internal-rules/index.js"],
             rules: {
-                "rulesdir/no-invalid-meta": "error",
-                "rulesdir/consistent-docs-description": "error"
+                "internal-rules/no-invalid-meta": "error",
+                "internal-rules/consistent-docs-description": "error"
 
                 /*
                  * TODO: enable it when all the rules using meta.messages
-                 * "rulesdir/consistent-meta-messages": "error"
+                 * "internal-rules/consistent-meta-messages": "error"
                  */
             }
+        }, {
+            files: ["tools/internal-rules/*"],
+            rules: {
+                "node/no-unpublished-require": "off"
+            }
         }, {
             files: ["lib/rules/*"],
             rules: {
-                "rulesdir/consistent-docs-url": "error"
+                "internal-rules/consistent-docs-url": "error"
             }
         }, {
             files: ["tests/**/*"],
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 89eb84613..115a7c3c5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,29 @@
+v5.15.1 - March 4, 2019
+
+* [`fe1a892`](https://github.com/eslint/eslint/commit/fe1a892f85b09c3d2fea05bef011530a678a6af5) Build: bundle espree (fixes eslint/eslint.github.io#546) (#11467) (薛定谔的猫)
+* [`458053b`](https://github.com/eslint/eslint/commit/458053b0b541f857bf233dacbde5ba80681820f8) Fix: avoid creating invalid regex in no-warning-comments (fixes #11471) (#11472) (Teddy Katz)
+
+v5.15.0 - March 1, 2019
+
+* [`4088c6c`](https://github.com/eslint/eslint/commit/4088c6c9d4578cd581ce8ff4385d90b58a75b755) Build: Remove path.resolve in webpack build (#11462) (Kevin Partington)
+* [`ec59ec0`](https://github.com/eslint/eslint/commit/ec59ec09c8d001b8c04f9edc09994e2b0d0af0f9) New: add rule "prefer-named-capture-group" (fixes #11381) (#11392) (Pig Fang)
+* [`a44f750`](https://github.com/eslint/eslint/commit/a44f75073306e5ea4e6722654009a99884fbca4f) Upgrade: eslint-scope@4.0.2 (#11461) (Teddy Katz)
+* [`d3ce611`](https://github.com/eslint/eslint/commit/d3ce611e1c705440ccbcae357f2194134d026541) Sponsors: Sync README with website (ESLint Jenkins)
+* [`ee88475`](https://github.com/eslint/eslint/commit/ee884754e4111e11994ff0df3f0c29e43e1dc3f2) Chore: add utils for rule tests (#11453) (薛定谔的猫)
+* [`d4824e4`](https://github.com/eslint/eslint/commit/d4824e46d7a6ca1618454d3c6198403382108123) Sponsors: Sync README with website (ESLint Jenkins)
+* [`6489518`](https://github.com/eslint/eslint/commit/64895185bde5233223648bcaf46f8deb72c9fb55) Fix: no-extra-parens crash when code is "((let))" (#11444) (Teddy Katz)
+* [`9d20de2`](https://github.com/eslint/eslint/commit/9d20de2b0ac756bd62888119b8e08c7441d8a5aa) Sponsors: Sync README with website (ESLint Jenkins)
+* [`3f14de4`](https://github.com/eslint/eslint/commit/3f14de458ba120e9c013f5fc7c6fe3e9b40c1460) Sponsors: Sync README with website (ESLint Jenkins)
+* [`3d6c770`](https://github.com/eslint/eslint/commit/3d6c7709d47e047b25d91ca1a77d6dab92313061) Sponsors: Sync README with website (ESLint Jenkins)
+* [`de5cbc5`](https://github.com/eslint/eslint/commit/de5cbc526b30405e742b35d85d04361529d49ed4) Update: remove invalid defaults from core rules (fixes #11415) (#11427) (Teddy Katz)
+* [`eb0650b`](https://github.com/eslint/eslint/commit/eb0650ba20cf9f9ad78dbaccfeb7e0e7ab56e31d) Build: fix linting errors on master (#11428) (Teddy Katz)
+* [`5018378`](https://github.com/eslint/eslint/commit/5018378131fd5190bbccca902c0cf4276ee1581a) Chore: enable require-unicode-regexp on ESLint codebase (#11422) (Teddy Katz)
+* [`f6ba633`](https://github.com/eslint/eslint/commit/f6ba633f56eca6be20fc4b0d9496a78b9498d578) Chore: lint all files in the repo at the same time (#11425) (Teddy Katz)
+* [`8f3d717`](https://github.com/eslint/eslint/commit/8f3d71754932669332ad7623bcc4c1aef3897125) Docs: Add non-attending TSC member info (#11411) (Nicholas C. Zakas)
+* [`ce0777d`](https://github.com/eslint/eslint/commit/ce0777da5bc167fe0c529158fd8216d3eaf11565) Docs: use more common spelling (#11417) (薛定谔的猫)
+* [`b9aabe3`](https://github.com/eslint/eslint/commit/b9aabe34311f6189b87c9d8a1aa40f3513fed773) Chore: run fuzzer along with unit tests (#11404) (Teddy Katz)
+* [`db0c5e2`](https://github.com/eslint/eslint/commit/db0c5e2a7f894b7cda71007b0ba43d7814b3fb2e) Build: switch from browserify to webpack (fixes #11366) (#11398) (Pig Fang)
+
 v5.14.1 - February 18, 2019
 
 * [`1d6e639`](https://github.com/eslint/eslint/commit/1d6e63930073e79e52890f552cc6e9a0646b7fb4) Fix: sort-keys throws Error at SpreadElement (fixes #11402) (#11403) (Krist Wongsuphasawat)
diff --git a/Makefile.js b/Makefile.js
index c34b1c8f2..e2ddd2ab2 100644
--- a/Makefile.js
+++ b/Makefile.js
@@ -53,7 +53,7 @@ const NODE = "node ", // intentional extra space
     NODE_MODULES = "./node_modules/",
     TEMP_DIR = "./tmp/",
     DEBUG_DIR = "./debug/",
-    BUILD_DIR = "./build/",
+    BUILD_DIR = "build",
     DOCS_DIR = "../eslint.github.io/docs",
     SITE_DIR = "../eslint.github.io/",
     PERF_TMP_DIR = path.join(TEMP_DIR, "eslint", "performance"),
@@ -783,6 +783,7 @@ target.gensite = function(prereleaseVersion) {
         echo("> Updating the demos (Step 13)");
         target.webpack("production");
         cp("-f", "build/eslint.js", `${SITE_DIR}js/app/eslint.js`);
+        cp("-f", "build/espree.js", `${SITE_DIR}js/app/espree.js`);
     } else {
         echo("> Skipped updating the demos (Step 13)");
     }
@@ -795,7 +796,7 @@ target.gensite = function(prereleaseVersion) {
 };
 
 target.webpack = function(mode = "none") {
-    exec(`${getBinFile("webpack")} --mode=${mode} --output-path=${path.resolve(__dirname, BUILD_DIR)}`);
+    exec(`${getBinFile("webpack")} --mode=${mode} --output-path=${BUILD_DIR}`);
 };
 
 target.checkRuleFiles = function() {
diff --git a/README.md b/README.md
index e0ee6a74f..8ac9fbe4d 100644
--- a/README.md
+++ b/README.md
@@ -266,7 +266,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
 <!-- NOTE: This section is autogenerated. Do not manually edit.-->
 <!--sponsorsstart-->
 <h3>Gold Sponsors</h3>
-<p><a href="https://code.facebook.com/projects/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fres.cloudinary.com%2Fopencollective%2Fimage%2Fupload%2Fv1508519428%2FS9gk78AS_400x400_fulq2l.jpg&height=96" alt="Facebook Open Source" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2F098e3bd0-4d57-11e8-9324-0f6cc1f92bf1.png&height=96" alt="Airbnb" height="96"></a></p><h3>Silver Sponsors</h3>
+<p><a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2F098e3bd0-4d57-11e8-9324-0f6cc1f92bf1.png&height=96" alt="Airbnb" height="96"></a> <a href="https://code.facebook.com/projects/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fres.cloudinary.com%2Fopencollective%2Fimage%2Fupload%2Fv1508519428%2FS9gk78AS_400x400_fulq2l.jpg&height=96" alt="Facebook Open Source" height="96"></a> <a href="https://badoo.com/team?utm_source=eslint"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2Fbbdb9cc0-3b5d-11e9-9537-ad85092287b8.png&height=96" alt="Badoo" height="96"></a></p><h3>Silver Sponsors</h3>
 <p><a href="https://www.ampproject.org/"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Fopencollective-production.s3-us-west-1.amazonaws.com%2F68ed8b70-ebf2-11e6-9958-cb7e79408c56.png&height=96" alt="AMP Project" height="64"></a></p><h3>Bronze Sponsors</h3>
 <p><a href="http://faithlife.com/ref/about"><img src="https://images.opencollective.com/proxy/images/?src=https%3A%2F%2Flogo.clearbit.com%2Ffaithlife.com&height=96" alt="Faithlife" height="32"></a></p>
 <!--sponsorsend-->
diff --git a/docs/developer-guide/nodejs-api.md b/docs/developer-guide/nodejs-api.md
index 7b9ecb6ec..3d41f25b9 100644
--- a/docs/developer-guide/nodejs-api.md
+++ b/docs/developer-guide/nodejs-api.md
@@ -677,6 +677,7 @@ Retrieves a formatter, which you can then use to format a report object. The arg
 * "[table](../user-guide/formatters#table)"
 * "[tap](../user-guide/formatters#tap)"
 * "[unix](../user-guide/formatters#unix)"
+* "[visualstudio](../user-guide/formatters#visualstudio)"
 
 or the full path to a JavaScript file containing a custom formatter. You can also omit the argument to retrieve the default formatter.
 
diff --git a/docs/rules/func-name-matching.md b/docs/rules/func-name-matching.md
index 870510290..53be2a099 100644
--- a/docs/rules/func-name-matching.md
+++ b/docs/rules/func-name-matching.md
@@ -91,7 +91,7 @@ This rule takes an optional string of "always" or "never" (when omitted, it defa
 
 ### considerPropertyDescriptor
 
-A boolean value that defaults to `false`. If `considerPropertyDescriptor` is set to true, the check will take into account the use `Object.create`, `Object.defineProperty`, `Object.defineProperties`, and `Reflect.defineProperty`.
+A boolean value that defaults to `false`. If `considerPropertyDescriptor` is set to true, the check will take into account the use of `Object.create`, `Object.defineProperty`, `Object.defineProperties`, and `Reflect.defineProperty`.
 
 Examples of **correct** code for the `{ considerPropertyDescriptor: true }` option:
 
diff --git a/docs/rules/prefer-named-capture-group.md b/docs/rules/prefer-named-capture-group.md
new file mode 100644
index 000000000..ff8790c83
--- /dev/null
+++ b/docs/rules/prefer-named-capture-group.md
@@ -0,0 +1,43 @@
+# Suggest using named capture group in regular expression (prefer-named-capture-group)
+
+With the landing of ECMAScript 2018, named capture groups can be used in regular expressions, which can improve their readability.
+
+```js
+const regex = /(?<year>[0-9]{4})/;
+```
+
+## Rule Details
+
+This rule is aimed at using named capture groups instead of numbered capture groups in regular expressions.
+
+Examples of **incorrect** code for this rule:
+
+```js
+/*eslint prefer-named-capture-group: "error"*/
+
+const foo = /(ba[rz])/;
+const bar = new RegExp('(ba[rz])');
+const baz = RegExp('(ba[rz])');
+
+foo.exec('bar')[1]; // Retrieve the group result.
+```
+
+Examples of **correct** code for this rule:
+
+```js
+/*eslint prefer-named-capture-group: "error"*/
+
+const foo = /(?<id>ba[rz])/;
+const bar = new RegExp('(?<id>ba[rz])');
+const baz = RegExp('(?<id>ba[rz])');
+
+foo.exec('bar').groups.id; // Retrieve the group result.
+```
+
+## When Not To Use It
+
+If you are targeting ECMAScript 2017 and/or older environments, you can disable this rule, because this ECMAScript feature is only supported in ECMAScript 2018 and/or newer environments.
+
+## Related Rules
+
+* [no-invalid-regexp](./no-invalid-regexp.md)
diff --git a/lib/built-in-rules-index.js b/lib/built-in-rules-index.js
index aaf2f06ec..d75fbbc69 100644
--- a/lib/built-in-rules-index.js
+++ b/lib/built-in-rules-index.js
@@ -232,6 +232,7 @@ module.exports = {
     "prefer-arrow-callback": require("./rules/prefer-arrow-callback"),
     "prefer-const": require("./rules/prefer-const"),
     "prefer-destructuring": require("./rules/prefer-destructuring"),
+    "prefer-named-capture-group": require("./rules/prefer-named-capture-group"),
     "prefer-numeric-literals": require("./rules/prefer-numeric-literals"),
     "prefer-object-spread": require("./rules/prefer-object-spread"),
     "prefer-promise-reject-errors": require("./rules/prefer-promise-reject-errors"),
diff --git a/lib/rules/array-bracket-newline.js b/lib/rules/array-bracket-newline.js
index b98fa9d27..a458e69f7 100644
--- a/lib/rules/array-bracket-newline.js
+++ b/lib/rules/array-bracket-newline.js
@@ -34,13 +34,11 @@ module.exports = {
                         type: "object",
                         properties: {
                             multiline: {
-                                type: "boolean",
-                                default: true
+                                type: "boolean"
                             },
                             minItems: {
                                 type: ["integer", "null"],
-                                minimum: 0,
-                                default: null
+                                minimum: 0
                             }
                         },
                         additionalProperties: false
diff --git a/lib/rules/array-element-newline.js b/lib/rules/array-element-newline.js
index 0efceedd2..dadb26fdd 100644
--- a/lib/rules/array-element-newline.js
+++ b/lib/rules/array-element-newline.js
@@ -34,13 +34,11 @@ module.exports = {
                         type: "object",
                         properties: {
                             multiline: {
-                                type: "boolean",
-                                default: false
+                                type: "boolean"
                             },
                             minItems: {
                                 type: ["integer", "null"],
-                                minimum: 0,
-                                default: null
+                                minimum: 0
                             }
                         },
                         additionalProperties: false
diff --git a/lib/rules/arrow-body-style.js b/lib/rules/arrow-body-style.js
index 28001d7f4..b1fed8c15 100644
--- a/lib/rules/arrow-body-style.js
+++ b/lib/rules/arrow-body-style.js
@@ -46,7 +46,7 @@ module.exports = {
                         {
                             type: "object",
                             properties: {
-                                requireReturnForObjectLiteral: { type: "boolean", default: false }
+                                requireReturnForObjectLiteral: { type: "boolean" }
                             },
                             additionalProperties: false
                         }
diff --git a/lib/rules/capitalized-comments.js b/lib/rules/capitalized-comments.js
index a488eb20b..137be9e93 100644
--- a/lib/rules/capitalized-comments.js
+++ b/lib/rules/capitalized-comments.js
@@ -28,27 +28,22 @@ const SCHEMA_BODY = {
     type: "object",
     properties: {
         ignorePattern: {
-            type: "string",
-            default: ""
+            type: "string"
         },
         ignoreInlineComments: {
-            type: "boolean",
-            default: false
+            type: "boolean"
         },
         ignoreConsecutiveComments: {
-            type: "boolean",
-            default: false
+            type: "boolean"
         }
     },
     additionalProperties: false
 };
-const DEFAULTS = Object.keys(SCHEMA_BODY.properties).reduce(
-    (obj, current) => {
-        obj[current] = SCHEMA_BODY.properties[current].default;
-        return obj;
-    },
-    {}
-);
+const DEFAULTS = {
+    ignorePattern: "",
+    ignoreInlineComments: false,
+    ignoreConsecutiveComments: false
+};
 
 /**
  * Get normalized options for either block or line comments from the given
diff --git a/lib/rules/complexity.js b/lib/rules/complexity.js
index 9f791e6de..56e17ddf2 100644
--- a/lib/rules/complexity.js
+++ b/lib/rules/complexity.js
@@ -41,13 +41,11 @@ module.exports = {
                         properties: {
                             maximum: {
                                 type: "integer",
-                                minimum: 0,
-                                default: 20
+                                minimum: 0
                             },
                             max: {
                                 type: "integer",
-                                minimum: 0,
-                                default: 20
+                                minimum: 0
                             }
                         },
                         additionalProperties: false
@@ -65,7 +63,10 @@ module.exports = {
         const option = context.options[0];
         let THRESHOLD = 20;
 
-        if (typeof option === "object") {
+        if (
+            typeof option === "object" &&
+            (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
+        ) {
             THRESHOLD = option.maximum || option.max;
         } else if (typeof option === "number") {
             THRESHOLD = option;
diff --git a/lib/rules/eqeqeq.js b/lib/rules/eqeqeq.js
index a52de67d7..3e8a392cf 100644
--- a/lib/rules/eqeqeq.js
+++ b/lib/rules/eqeqeq.js
@@ -38,8 +38,7 @@ module.exports = {
                             type: "object",
                             properties: {
                                 null: {
-                                    enum: ["always", "never", "ignore"],
-                                    default: "always"
+                                    enum: ["always", "never", "ignore"]
                                 }
                             },
                             additionalProperties: false
diff --git a/lib/rules/func-call-spacing.js b/lib/rules/func-call-spacing.js
index 348f5a8f4..223756851 100644
--- a/lib/rules/func-call-spacing.js
+++ b/lib/rules/func-call-spacing.js
@@ -50,8 +50,7 @@ module.exports = {
                             type: "object",
                             properties: {
                                 allowNewlines: {
-                                    type: "boolean",
-                                    default: false
+                                    type: "boolean"
                                 }
                             },
                             additionalProperties: false
diff --git a/lib/rules/init-declarations.js b/lib/rules/init-declarations.js
index 484cbef0a..65197358e 100644
--- a/lib/rules/init-declarations.js
+++ b/lib/rules/init-declarations.js
@@ -75,8 +75,7 @@ module.exports = {
                             type: "object",
                             properties: {
                                 ignoreForLoopInit: {
-                                    type: "boolean",
-                                    default: false
+                                    type: "boolean"
                                 }
                             },
                             additionalProperties: false
diff --git a/lib/rules/key-spacing.js b/lib/rules/key-spacing.js
index 3f4d711c1..7da7f9aa0 100644
--- a/lib/rules/key-spacing.js
+++ b/lib/rules/key-spacing.js
@@ -148,20 +148,16 @@ module.exports = {
                                     type: "object",
                                     properties: {
                                         mode: {
-                                            enum: ["strict", "minimum"],
-                                            default: "strict"
+                                            enum: ["strict", "minimum"]
                                         },
                                         on: {
-                                            enum: ["colon", "value"],
-                                            default: "colon"
+                                            enum: ["colon", "value"]
                                         },
                                         beforeColon: {
-                                            type: "boolean",
-                                            default: false
+                                            type: "boolean"
                                         },
                                         afterColon: {
-                                            type: "boolean",
-                                            default: true
+                                            type: "boolean"
                                         }
                                     },
                                     additionalProperties: false
@@ -169,16 +165,13 @@ module.exports = {
                             ]
                         },
                         mode: {
-                            enum: ["strict", "minimum"],
-                            default: "strict"
+                            enum: ["strict", "minimum"]
                         },
                         beforeColon: {
-                            type: "boolean",
-                            default: false
+                            type: "boolean"
                         },
                         afterColon: {
-                            type: "boolean",
-                            default: true
+                            type: "boolean"
                         }
                     },
                     additionalProperties: false
@@ -190,16 +183,13 @@ module.exports = {
                             type: "object",
                             properties: {
                                 mode: {
-                                    enum: ["strict", "minimum"],
-                                    default: "strict"
+                                    enum: ["strict", "minimum"]
                                 },
                                 beforeColon: {
-                                    type: "boolean",
-                                    default: false
+                                    type: "boolean"
                                 },
                                 afterColon: {
-                                    type: "boolean",
-                                    default: true
+                                    type: "boolean"
                                 }
                             },
                             additionalProperties: false
@@ -216,20 +206,16 @@ module.exports = {
                                             type: "object",
                                             properties: {
                                                 mode: {
-                                                    enum: ["strict", "minimum"],
-                                                    default: "strict"
+                                                    enum: ["strict", "minimum"]
                                                 },
                                                 on: {
-                                                    enum: ["colon", "value"],
-                                                    default: "colon"
+                                                    enum: ["colon", "value"]
                                                 },
                                                 beforeColon: {
-                                                    type: "boolean",
-                                                    default: false
+                                                    type: "boolean"
                                                 },
                                                 afterColon: {
-                                                    type: "boolean",
-                                                    default: true
+                                                    type: "boolean"
                                                 }
                                             },
                                             additionalProperties: false
@@ -237,16 +223,13 @@ module.exports = {
                                     ]
                                 },
                                 mode: {
-                                    enum: ["strict", "minimum"],
-                                    default: "strict"
+                                    enum: ["strict", "minimum"]
                                 },
                                 beforeColon: {
-                                    type: "boolean",
-                                    default: false
+                                    type: "boolean"
                                 },
                                 afterColon: {
-                                    type: "boolean",
-                                    default: true
+                                    type: "boolean"
                                 }
                             },
                             additionalProperties: false
@@ -261,16 +244,13 @@ module.exports = {
                             type: "object",
                             properties: {
                                 mode: {
-                                    enum: ["strict", "minimum"],
-                                    default: "strict"
+                                    enum: ["strict", "minimum"]
                                 },
                                 beforeColon: {
-                                    type: "boolean",
-                                    default: false
+                                    type: "boolean"
                                 },
                                 afterColon: {
-                                    type: "boolean",
-                                    default: true
+                                    type: "boolean"
                                 }
                             },
                             additionalProperties: false
@@ -279,16 +259,13 @@ module.exports = {
                             type: "object",
                             properties: {
                                 mode: {
-                                    enum: ["strict", "minimum"],
-                                    default: "strict"
+                                    enum: ["strict", "minimum"]
                                 },
                                 beforeColon: {
-                                    type: "boolean",
-                                    default: false
+                                    type: "boolean"
                                 },
                                 afterColon: {
-                                    type: "boolean",
-                                    default: true
+                                    type: "boolean"
                                 }
                             },
                             additionalProperties: false
@@ -297,20 +274,16 @@ module.exports = {
                             type: "object",
                             properties: {
                                 mode: {
-                                    enum: ["strict", "minimum"],
-                                    default: "strict"
+                                    enum: ["strict", "minimum"]
                                 },
                                 on: {
-                                    enum: ["colon", "value"],
-                                    default: "colon"
+                                    enum: ["colon", "value"]
                                 },
                                 beforeColon: {
-                                    type: "boolean",
-                                    default: false
+                                    type: "boolean"
                                 },
                                 afterColon: {
-                                    type: "boolean",
-                                    default: true
+                                    type: "boolean"
                                 }
                             },
                             additionalProperties: false
diff --git a/lib/rules/line-comment-position.js b/lib/rules/line-comment-position.js
index 21f1127af..0023a1f11 100644
--- a/lib/rules/line-comment-position.js
+++ b/lib/rules/line-comment-position.js
@@ -38,12 +38,10 @@ module.exports = {
                                 type: "string"
                             },
                             applyDefaultPatterns: {
-                                type: "boolean",
-                                default: true
+                                type: "boolean"
                             },
                             applyDefaultIgnorePatterns: {
-                                type: "boolean",
-                                default: true
+                                type: "boolean"
                             }
                         },
                         additionalProperties: false
@@ -74,7 +72,7 @@ module.exports = {
             if (Object.prototype.hasOwnProperty.call(options, "applyDefaultIgnorePatterns")) {
                 applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns;
             } else {
-                applyDefaultIgnorePatterns = options.applyDefaultPatterns;
+                applyDefaultIgnorePatterns = options.applyDefaultPatterns !== false;
             }
         }
 
diff --git a/lib/rules/max-depth.js b/lib/rules/max-depth.js
index 3b997e21b..de684dd92 100644
--- a/lib/rules/max-depth.js
+++ b/lib/rules/max-depth.js
@@ -32,13 +32,11 @@ module.exports = {
                         properties: {
                             maximum: {
                                 type: "integer",
-                                minimum: 0,
-                                default: 4
+                                minimum: 0
                             },
                             max: {
                                 type: "integer",
-                                minimum: 0,
-                                default: 4
+                                minimum: 0
                             }
                         },
                         additionalProperties: false
@@ -61,7 +59,10 @@ module.exports = {
             option = context.options[0];
         let maxDepth = 4;
 
-        if (typeof option === "object") {
+        if (
+            typeof option === "object" &&
+            (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
+        ) {
             maxDepth = option.maximum || option.max;
         }
         if (typeof option === "number") {
diff --git a/lib/rules/max-lines.js b/lib/rules/max-lines.js
index 0fae4ec2f..4e5f23b5d 100644
--- a/lib/rules/max-lines.js
+++ b/lib/rules/max-lines.js
@@ -38,16 +38,13 @@ module.exports = {
                         properties: {
                             max: {
                                 type: "integer",
-                                minimum: 0,
-                                default: 300
+                                minimum: 0
                             },
                             skipComments: {
-                                type: "boolean",
-                                default: false
+                                type: "boolean"
                             },
                             skipBlankLines: {
-                                type: "boolean",
-                                default: false
+                                type: "boolean"
                             }
                         },
                         additionalProperties: false
@@ -64,7 +61,7 @@ module.exports = {
         const option = context.options[0];
         let max = 300;
 
-        if (typeof option === "object") {
+        if (typeof option === "object" && Object.prototype.hasOwnProperty.call(option, "max")) {
             max = option.max;
         } else if (typeof option === "number") {
             max = option;
diff --git a/lib/rules/max-nested-callbacks.js b/lib/rules/max-nested-callbacks.js
index cbbb0ed6c..df1baceeb 100644
--- a/lib/rules/max-nested-callbacks.js
+++ b/lib/rules/max-nested-callbacks.js
@@ -32,13 +32,11 @@ module.exports = {
                         properties: {
                             maximum: {
                                 type: "integer",
-                                minimum: 0,
-                                default: 10
+                                minimum: 0
                             },
                             max: {
                                 type: "integer",
-                                minimum: 0,
-                                default: 10
+                                minimum: 0
                             }
                         },
                         additionalProperties: false
@@ -59,7 +57,10 @@ module.exports = {
         const option = context.options[0];
         let THRESHOLD = 10;
 
-        if (typeof option === "object") {
+        if (
+            typeof option === "object" &&
+            (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
+        ) {
             THRESHOLD = option.maximum || option.max;
         } else if (typeof option === "number") {
             THRESHOLD = option;
diff --git a/lib/rules/max-params.js b/lib/rules/max-params.js
index 5e1e558ab..e1de3ef6f 100644
--- a/lib/rules/max-params.js
+++ b/lib/rules/max-params.js
@@ -40,13 +40,11 @@ module.exports = {
                         properties: {
                             maximum: {
                                 type: "integer",
-                                minimum: 0,
-                                default: 3
+                                minimum: 0
                             },
                             max: {
                                 type: "integer",
-                                minimum: 0,
-                                default: 3
+                                minimum: 0
                             }
                         },
                         additionalProperties: false
@@ -64,7 +62,10 @@ module.exports = {
         const option = context.options[0];
         let numParams = 3;
 
-        if (typeof option === "object") {
+        if (
+            typeof option === "object" &&
+            (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
+        ) {
             numParams = option.maximum || option.max;
         }
         if (typeof option === "number") {
diff --git a/lib/rules/max-statements.js b/lib/rules/max-statements.js
index cd0e50ae3..7dc3fd50c 100644
--- a/lib/rules/max-statements.js
+++ b/lib/rules/max-statements.js
@@ -40,13 +40,11 @@ module.exports = {
                         properties: {
                             maximum: {
                                 type: "integer",
-                                minimum: 0,
-                                default: 10
+                                minimum: 0
                             },
                             max: {
                                 type: "integer",
-                                minimum: 0,
-                                default: 10
+                                minimum: 0
                             }
                         },
                         additionalProperties: false
@@ -80,7 +78,10 @@ module.exports = {
             topLevelFunctions = [];
         let maxStatements = 10;
 
-        if (typeof option === "object") {
+        if (
+            typeof option === "object" &&
+            (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max"))
+        ) {
             maxStatements = option.maximum || option.max;
         } else if (typeof option === "number") {
             maxStatements = option;
diff --git a/lib/rules/no-extra-parens.js b/lib/rules/no-extra-parens.js
index 9f16e0e6c..400ce0c76 100644
--- a/lib/rules/no-extra-parens.js
+++ b/lib/rules/no-extra-parens.js
@@ -44,11 +44,11 @@ module.exports = {
                         {
                             type: "object",
                             properties: {
-                                conditionalAssign: { type: "boolean", default: true },
-                                nestedBinaryExpressions: { type: "boolean", default: true },
-                                returnAssign: { type: "boolean", default: true },
+                                conditionalAssign: { type: "boolean" },
+                                nestedBinaryExpressions: { type: "boolean" },
+                                returnAssign: { type: "boolean" },
                                 ignoreJSX: { enum: ["none", "all", "single-line", "multi-line"] },
-                                enforceForArrowConditionals: { type: "boolean", default: true }
+                                enforceForArrowConditionals: { type: "boolean" }
                             },
                             additionalProperties: false
                         }
@@ -471,6 +471,7 @@ module.exports = {
             const firstToken = isParenthesised(node) ? sourceCode.getTokenBefore(node) : sourceCode.getFirstToken(node);
             const secondToken = sourceCode.getTokenAfter(firstToken, astUtils.isNotOpeningParenToken);
             const thirdToken = secondToken ? sourceCode.getTokenAfter(secondToken) : null;
+            const tokenAfterClosingParens = secondToken ? sourceCode.getTokenAfter(secondToken, astUtils.isNotClosingParenToken) : null;
 
             if (
                 astUtils.isOpeningParenToken(firstToken) &&
@@ -479,7 +480,12 @@ module.exports = {
                     secondToken.type === "Keyword" && (
                         secondToken.value === "function" ||
                         secondToken.value === "class" ||
-                        secondToken.value === "let" && astUtils.isOpeningBracketToken(sourceCode.getTokenAfter(secondToken, astUtils.isNotClosingParenToken))
+                        secondToken.value === "let" &&
+                            tokenAfterClosingParens &&
+                            (
+                                astUtils.isOpeningBracketToken(tokenAfterClosingParens) ||
+                                tokenAfterClosingParens.type === "Identifier"
+                            )
                     ) ||
                     secondToken && secondToken.type === "Identifier" && secondToken.value === "async" && thirdToken && thirdToken.type === "Keyword" && thirdToken.value === "function"
                 )
diff --git a/lib/rules/no-mixed-requires.js b/lib/rules/no-mixed-requires.js
index e79dde0fe..e3164a8ab 100644
--- a/lib/rules/no-mixed-requires.js
+++ b/lib/rules/no-mixed-requires.js
@@ -30,12 +30,10 @@ module.exports = {
                         type: "object",
                         properties: {
                             grouping: {
-                                type: "boolean",
-                                default: false
+                                type: "boolean"
                             },
                             allowCall: {
-                                type: "boolean",
-                                default: false
+                                type: "boolean"
                             }
                         },
                         additionalProperties: false
diff --git a/lib/rules/no-unused-vars.js b/lib/rules/no-unused-vars.js
index de13f26ce..d4c4c6355 100644
--- a/lib/rules/no-unused-vars.js
+++ b/lib/rules/no-unused-vars.js
@@ -37,26 +37,22 @@ module.exports = {
                         type: "object",
                         properties: {
                             vars: {
-                                enum: ["all", "local"],
-                                default: "all"
+                                enum: ["all", "local"]
                             },
                             varsIgnorePattern: {
                                 type: "string"
                             },
                             args: {
-                                enum: ["all", "after-used", "none"],
-                                default: "after-used"
+                                enum: ["all", "after-used", "none"]
                             },
                             ignoreRestSiblings: {
-                                type: "boolean",
-                                default: false
+                                type: "boolean"
                             },
                             argsIgnorePattern: {
                                 type: "string"
                             },
                             caughtErrors: {
-                                enum: ["all", "none"],
-                                default: "none"
+                                enum: ["all", "none"]
                             },
                             caughtErrorsIgnorePattern: {
                                 type: "string"
diff --git a/lib/rules/no-use-before-define.js b/lib/rules/no-use-before-define.js
index 61998c7a8..a98f6c87f 100644
--- a/lib/rules/no-use-before-define.js
+++ b/lib/rules/no-use-before-define.js
@@ -154,9 +154,9 @@ module.exports = {
                     {
                         type: "object",
                         properties: {
-                            functions: { type: "boolean", default: true },
-                            classes: { type: "boolean", default: true },
-                            variables: { type: "boolean", default: true }
+                            functions: { type: "boolean" },
+                            classes: { type: "boolean" },
+                            variables: { type: "boolean" }
                         },
                         additionalProperties: false
                     }
diff --git a/lib/rules/no-warning-comments.js b/lib/rules/no-warning-comments.js
index 0dd0a26c1..1d1b55460 100644
--- a/lib/rules/no-warning-comments.js
+++ b/lib/rules/no-warning-comments.js
@@ -95,7 +95,7 @@ module.exports = {
                  * ^\s*TERM\b.  This checks the word boundary
                  * at the beginning of the comment.
                  */
-                return new RegExp(prefix + escaped + suffix, "iu");
+                return new RegExp(prefix + escaped + suffix, "i"); // eslint-disable-line require-unicode-regexp
             }
 
             /*
@@ -103,7 +103,7 @@ module.exports = {
              * \bTERM\b|\bTERM\b, this checks the entire comment
              * for the term.
              */
-            return new RegExp(prefix + escaped + suffix + eitherOrWordBoundary + term + wordBoundary, "iu");
+            return new RegExp(prefix + escaped + suffix + eitherOrWordBoundary + term + wordBoundary, "i"); // eslint-disable-line require-unicode-regexp
         }
 
         const warningRegExps = warningTerms.map(convertToRegExp);
diff --git a/lib/rules/object-curly-newline.js b/lib/rules/object-curly-newline.js
index d45620d53..d1a6bc20f 100644
--- a/lib/rules/object-curly-newline.js
+++ b/lib/rules/object-curly-newline.js
@@ -26,16 +26,14 @@ const OPTION_VALUE = {
             type: "object",
             properties: {
                 multiline: {
-                    type: "boolean",
-                    default: false
+                    type: "boolean"
                 },
                 minProperties: {
                     type: "integer",
                     minimum: 0
                 },
                 consistent: {
-                    type: "boolean",
-                    default: false
+                    type: "boolean"
                 }
             },
             additionalProperties: false,
@@ -61,9 +59,9 @@ function normalizeOptionValue(value) {
         } else if (value === "never") {
             minProperties = Number.POSITIVE_INFINITY;
         } else {
-            multiline = value.multiline;
+            multiline = Boolean(value.multiline);
             minProperties = value.minProperties || Number.POSITIVE_INFINITY;
-            consistent = value.consistent;
+            consistent = Boolean(value.consistent);
         }
     } else {
         consistent = true;
diff --git a/lib/rules/object-shorthand.js b/lib/rules/object-shorthand.js
index 98917fb6e..31010f0e7 100644
--- a/lib/rules/object-shorthand.js
+++ b/lib/rules/object-shorthand.js
@@ -57,8 +57,7 @@ module.exports = {
                             type: "object",
                             properties: {
                                 avoidQuotes: {
-                                    type: "boolean",
-                                    default: false
+                                    type: "boolean"
                                 }
                             },
                             additionalProperties: false
@@ -77,16 +76,13 @@ module.exports = {
                             type: "object",
                             properties: {
                                 ignoreConstructors: {
-                                    type: "boolean",
-                                    default: false
+                                    type: "boolean"
                                 },
                                 avoidQuotes: {
-                                    type: "boolean",
-                                    default: false
+                                    type: "boolean"
                                 },
                                 avoidExplicitReturnArrows: {
-                                    type: "boolean",
-                                    default: false
+                                    type: "boolean"
                                 }
                             },
                             additionalProperties: false
diff --git a/lib/rules/one-var.js b/lib/rules/one-var.js
index 5a5c71b18..0571cd338 100644
--- a/lib/rules/one-var.js
+++ b/lib/rules/one-var.js
@@ -36,16 +36,13 @@ module.exports = {
                                 default: false
                             },
                             var: {
-                                enum: ["always", "never", "consecutive"],
-                                default: "always"
+                                enum: ["always", "never", "consecutive"]
                             },
                             let: {
-                                enum: ["always", "never", "consecutive"],
-                                default: "always"
+                                enum: ["always", "never", "consecutive"]
                             },
                             const: {
-                                enum: ["always", "never", "consecutive"],
-                                default: "always"
+                                enum: ["always", "never", "consecutive"]
                             }
                         },
                         additionalProperties: false
diff --git a/lib/rules/prefer-destructuring.js b/lib/rules/prefer-destructuring.js
index c30c9170c..dec93d51f 100644
--- a/lib/rules/prefer-destructuring.js
+++ b/lib/rules/prefer-destructuring.js
@@ -36,12 +36,10 @@ module.exports = {
                                 type: "object",
                                 properties: {
                                     array: {
-                                        type: "boolean",
-                                        default: true
+                                        type: "boolean"
                                     },
                                     object: {
-                                        type: "boolean",
-                                        default: true
+                                        type: "boolean"
                                     }
                                 },
                                 additionalProperties: false
@@ -50,12 +48,10 @@ module.exports = {
                                 type: "object",
                                 properties: {
                                     array: {
-                                        type: "boolean",
-                                        default: true
+                                        type: "boolean"
                                     },
                                     object: {
-                                        type: "boolean",
-                                        default: true
+                                        type: "boolean"
                                     }
                                 },
                                 additionalProperties: false
@@ -67,12 +63,10 @@ module.exports = {
                         type: "object",
                         properties: {
                             array: {
-                                type: "boolean",
-                                default: true
+                                type: "boolean"
                             },
                             object: {
-                                type: "boolean",
-                                default: true
+                                type: "boolean"
                             }
                         },
                         additionalProperties: false
@@ -83,8 +77,7 @@ module.exports = {
                 type: "object",
                 properties: {
                     enforceForRenamedProperties: {
-                        type: "boolean",
-                        default: false
+                        type: "boolean"
                     }
                 },
                 additionalProperties: false
diff --git a/lib/rules/prefer-named-capture-group.js b/lib/rules/prefer-named-capture-group.js
new file mode 100644
index 000000000..07e69f022
--- /dev/null
+++ b/lib/rules/prefer-named-capture-group.js
@@ -0,0 +1,123 @@
+/**
+ * @fileoverview Rule to enforce requiring named capture groups in regular expression.
+ * @author Pig Fang <https://github.com/g-plane>
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const {
+    CALL,
+    CONSTRUCT,
+    ReferenceTracker,
+    getStringIfConstant
+} = require("eslint-utils");
+const regexpp = require("regexpp");
+
+//------------------------------------------------------------------------------
+// Helpers
+//------------------------------------------------------------------------------
+
+const parser = new regexpp.RegExpParser();
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = {
+    meta: {
+        type: "suggestion",
+
+        docs: {
+            description: "enforce using named capture group in regular expression",
+            category: "Best Practices",
+            recommended: false,
+            url: "https://eslint.org/docs/rules/prefer-named-capture-group"
+        },
+
+        schema: [],
+
+        messages: {
+            required: "Capture group '{{group}}' should be converted to a named or non-capturing group."
+        }
+    },
+
+    create(context) {
+
+        /**
+         * Function to check regular expression.
+         *
+         * @param {string} regex The regular expression to be check.
+         * @param {ASTNode} node AST node which contains regular expression.
+         * @param {boolean} uFlag Flag indicates whether unicode mode is enabled or not.
+         * @returns {void}
+         */
+        function checkRegex(regex, node, uFlag) {
+            let ast;
+
+            try {
+                ast = parser.parsePattern(regex, 0, regex.length, uFlag);
+            } catch (_) {
+
+                // ignore regex syntax errors
+                return;
+            }
+
+            regexpp.visitRegExpAST(ast, {
+                onCapturingGroupEnter(group) {
+                    if (!group.name) {
+                        const locNode = node.type === "Literal" ? node : node.arguments[0];
+
+                        context.report({
+                            node,
+                            messageId: "required",
+                            loc: {
+                                start: {
+                                    line: locNode.loc.start.line,
+                                    column: locNode.loc.start.column + group.start + 1
+                                },
+                                end: {
+                                    line: locNode.loc.start.line,
+                                    column: locNode.loc.start.column + group.end + 1
+                                }
+                            },
+                            data: {
+                                group: group.raw
+                            }
+                        });
+                    }
+                }
+            });
+        }
+
+        return {
+            Literal(node) {
+                if (node.regex) {
+                    checkRegex(node.regex.pattern, node, node.regex.flags.includes("u"));
+                }
+            },
+            Program() {
+                const scope = context.getScope();
+                const tracker = new ReferenceTracker(scope);
+                const traceMap = {
+                    RegExp: {
+                        [CALL]: true,
+                        [CONSTRUCT]: true
+                    }
+                };
+
+                for (const { node } of tracker.iterateGlobalReferences(traceMap)) {
+                    const regex = getStringIfConstant(node.arguments[0]);
+                    const flags = getStringIfConstant(node.arguments[1]);
+
+                    if (regex) {
+                        checkRegex(regex, node, flags && flags.includes("u"));
+                    }
+                }
+            }
+        };
+    }
+};
diff --git a/lib/rules/quote-props.js b/lib/rules/quote-props.js
index f4582dd1f..7184bd34d 100644
--- a/lib/rules/quote-props.js
+++ b/lib/rules/quote-props.js
@@ -32,8 +32,7 @@ module.exports = {
                     type: "array",
                     items: [
                         {
-                            enum: ["always", "as-needed", "consistent", "consistent-as-needed"],
-                            default: "always"
+                            enum: ["always", "as-needed", "consistent", "consistent-as-needed"]
                         }
                     ],
                     minItems: 0,
@@ -43,23 +42,19 @@ module.exports = {
                     type: "array",
                     items: [
                         {
-                            enum: ["always", "as-needed", "consistent", "consistent-as-needed"],
-                            default: "always"
+                            enum: ["always", "as-needed", "consistent", "consistent-as-needed"]
                         },
                         {
                             type: "object",
                             properties: {
                                 keywords: {
-                                    type: "boolean",
-                                    default: false
+                                    type: "boolean"
                                 },
                                 unnecessary: {
-                                    type: "boolean",
-                                    default: true
+                                    type: "boolean"
                                 },
                                 numbers: {
-                                    type: "boolean",
-                                    default: false
+                                    type: "boolean"
                                 }
                             },
                             additionalProperties: false
diff --git a/lib/rules/quotes.js b/lib/rules/quotes.js
index 887a0b75f..4556b245d 100644
--- a/lib/rules/quotes.js
+++ b/lib/rules/quotes.js
@@ -100,12 +100,10 @@ module.exports = {
                         type: "object",
                         properties: {
                             avoidEscape: {
-                                type: "boolean",
-                                default: false
+                                type: "boolean"
                             },
                             allowTemplateLiterals: {
-                                type: "boolean",
-                                default: false
+                                type: "boolean"
                             }
                         },
                         additionalProperties: false
diff --git a/lib/rules/semi.js b/lib/rules/semi.js
index 740ce53f4..3a6df39c7 100644
--- a/lib/rules/semi.js
+++ b/lib/rules/semi.js
@@ -40,8 +40,7 @@ module.exports = {
                             type: "object",
                             properties: {
                                 beforeStatementContinuationChars: {
-                                    enum: ["always", "any", "never"],
-                                    default: "any"
+                                    enum: ["always", "any", "never"]
                                 }
                             },
                             additionalProperties: false
@@ -59,7 +58,7 @@ module.exports = {
                         {
                             type: "object",
                             properties: {
-                                omitLastInOneLineBlock: { type: "boolean", default: false }
+                                omitLastInOneLineBlock: { type: "boolean" }
                             },
                             additionalProperties: false
                         }
@@ -76,8 +75,8 @@ module.exports = {
         const OPT_OUT_PATTERN = /^[-[(/+`]/u; // One of [(/+-`
         const options = context.options[1];
         const never = context.options[0] === "never";
-        const exceptOneLine = options && options.omitLastInOneLineBlock;
-        const beforeStatementContinuationChars = options && options.beforeStatementContinuationChars;
+        const exceptOneLine = Boolean(options && options.omitLastInOneLineBlock);
+        const beforeStatementContinuationChars = options && options.beforeStatementContinuationChars || "any";
         const sourceCode = context.getSourceCode();
 
         //--------------------------------------------------------------------------
diff --git a/lib/rules/space-before-function-paren.js b/lib/rules/space-before-function-paren.js
index c0d8e509f..64ba72bf9 100644
--- a/lib/rules/space-before-function-paren.js
+++ b/lib/rules/space-before-function-paren.js
@@ -37,16 +37,13 @@ module.exports = {
                         type: "object",
                         properties: {
                             anonymous: {
-                                enum: ["always", "never", "ignore"],
-                                default: "always"
+                                enum: ["always", "never", "ignore"]
                             },
                             named: {
-                                enum: ["always", "never", "ignore"],
-                                default: "always"
+                                enum: ["always", "never", "ignore"]
                             },
                             asyncArrow: {
-                                enum: ["always", "never", "ignore"],
-                                default: "always"
+                                enum: ["always", "never", "ignore"]
                             }
                         },
                         additionalProperties: false
diff --git a/lib/rules/yield-star-spacing.js b/lib/rules/yield-star-spacing.js
index 17124dd6e..20b8e9ea9 100644
--- a/lib/rules/yield-star-spacing.js
+++ b/lib/rules/yield-star-spacing.js
@@ -31,8 +31,8 @@ module.exports = {
                     {
                         type: "object",
                         properties: {
-                            before: { type: "boolean", default: false },
-                            after: { type: "boolean", default: true }
+                            before: { type: "boolean" },
+                            after: { type: "boolean" }
                         },
                         additionalProperties: false
                     }
diff --git a/package.json b/package.json
index 5fea28537..2d9f0d0be 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint",
-  "version": "5.14.1",
+  "version": "5.15.1",
   "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
   "description": "An AST-based pattern checker for JavaScript.",
   "bin": {
@@ -41,7 +41,7 @@
     "cross-spawn": "^6.0.5",
     "debug": "^4.0.1",
     "doctrine": "^3.0.0",
-    "eslint-scope": "^4.0.0",
+    "eslint-scope": "^4.0.2",
     "eslint-utils": "^1.3.1",
     "eslint-visitor-keys": "^1.0.0",
     "espree": "^5.0.1",
@@ -85,11 +85,11 @@
     "coveralls": "^3.0.1",
     "dateformat": "^3.0.3",
     "ejs": "^2.6.1",
+    "eslint-config-eslint": "file:packages/eslint-config-eslint",
     "eslint-plugin-eslint-plugin": "^2.0.1",
+    "eslint-plugin-internal-rules": "file:tools/internal-rules",
     "eslint-plugin-node": "^8.0.0",
-    "eslint-plugin-rulesdir": "^0.1.0",
     "eslint-release": "^1.2.0",
-    "eslint-rule-composer": "^0.3.0",
     "eslump": "^2.0.0",
     "esprima": "^4.0.1",
     "istanbul": "^0.4.5",
diff --git a/packages/eslint-config-eslint/default.yml b/packages/eslint-config-eslint/default.yml
index 0cfe3506b..cad812907 100644
--- a/packages/eslint-config-eslint/default.yml
+++ b/packages/eslint-config-eslint/default.yml
@@ -13,7 +13,7 @@ rules:
     camelcase: "error"
     callback-return: ["error", ["cb", "callback", "next"]]
     class-methods-use-this: "error"
-    comma-dangle: "error"
+    comma-dangle: ["error", { functions: "never" }]
     comma-spacing: "error"
     comma-style: ["error", "last"]
     computed-property-spacing: "error"
diff --git a/tools/internal-rules/index.js b/tools/internal-rules/index.js
new file mode 100644
index 000000000..a3a3cd199
--- /dev/null
+++ b/tools/internal-rules/index.js
@@ -0,0 +1,13 @@
+"use strict";
+
+const fs = require("fs");
+const path = require("path");
+
+module.exports = {
+    rules: Object.assign(
+        {},
+        ...fs.readdirSync(__dirname)
+            .filter(filename => filename.endsWith(".js") && filename !== "index.js")
+            .map(filename => ({ [filename.replace(/\.js$/u, "")]: require(path.resolve(__dirname, filename)) }))
+    )
+};
diff --git a/tools/internal-rules/multiline-comment-style.js b/tools/internal-rules/multiline-comment-style.js
index f0d5755e8..b0a0c9d85 100644
--- a/tools/internal-rules/multiline-comment-style.js
+++ b/tools/internal-rules/multiline-comment-style.js
@@ -13,7 +13,7 @@ const multilineCommentStyle = require("../../lib/rules/multiline-comment-style")
 //------------------------------------------------------------------------------
 
 // The `no-invalid-meta` internal rule has a false positive here.
-// eslint-disable-next-line rulesdir/no-invalid-meta
+// eslint-disable-next-line internal-rules/no-invalid-meta
 module.exports = ruleComposer.filterReports(
     multilineCommentStyle,
     (problem, metadata) => {
diff --git a/tools/internal-rules/package.json b/tools/internal-rules/package.json
new file mode 100644
index 000000000..0d80ed277
--- /dev/null
+++ b/tools/internal-rules/package.json
@@ -0,0 +1,8 @@
+{
+  "name": "eslint-plugin-internal-rules",
+  "version": "0.0.0",
+  "private": true,
+  "dependencies": {
+    "eslint-rule-composer": "^0.3.0"
+  }
+}
diff --git a/tools/rule-types.json b/tools/rule-types.json
index 44c1d48ab..1239e5f3f 100644
--- a/tools/rule-types.json
+++ b/tools/rule-types.json
@@ -222,6 +222,7 @@
     "prefer-arrow-callback": "suggestion",
     "prefer-const": "suggestion",
     "prefer-destructuring": "suggestion",
+    "prefer-named-capture-group": "suggestion",
     "prefer-numeric-literals": "suggestion",
     "prefer-object-spread": "suggestion",
     "prefer-promise-reject-errors": "suggestion",
@@ -264,4 +265,4 @@
     "wrap-regex": "layout",
     "yield-star-spacing": "layout",
     "yoda": "suggestion"
-}
\ No newline at end of file
+}
diff --git a/webpack.config.js b/webpack.config.js
index 134a657e7..4ba329837 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -2,10 +2,13 @@
 
 module.exports = {
     mode: "none",
-    entry: ["@babel/polyfill", "./lib/linter.js"],
+    entry: {
+        eslint: ["@babel/polyfill", "./lib/linter.js"],
+        espree: ["@babel/polyfill", "espree"]
+    },
     output: {
-        filename: "eslint.js",
-        library: "eslint",
+        filename: "[name].js",
+        library: "[name]",
         libraryTarget: "umd",
         globalObject: "this"
     },


Test patch:
diff --git a/tests/lib/code-path-analysis/code-path.js b/tests/lib/code-path-analysis/code-path.js
index 6b90b57bf..be1039fb4 100644
--- a/tests/lib/code-path-analysis/code-path.js
+++ b/tests/lib/code-path-analysis/code-path.js
@@ -66,7 +66,7 @@ function getOrderOfTraversing(codePath, options, callback) {
 describe("CodePathAnalyzer", () => {
     describe(".traverseSegments()", () => {
         describe("should traverse segments from the first to the end:", () => {
-            /* eslint-disable rulesdir/multiline-comment-style */
+            /* eslint-disable internal-rules/multiline-comment-style */
             it("simple", () => {
                 const codePath = parseCodePaths("foo(); bar(); baz();")[0];
                 const order = getOrderOfTraversing(codePath);
diff --git a/tests/lib/rules/_utils.js b/tests/lib/rules/_utils.js
new file mode 100644
index 000000000..a1b642727
--- /dev/null
+++ b/tests/lib/rules/_utils.js
@@ -0,0 +1,25 @@
+/**
+ * @fileoverview uitls for rule tests.
+ * @author 唯然<weiran.zsd@outlook.com>
+ */
+
+"use strict";
+
+/**
+ * Prevents leading spaces in a multiline template literal from appearing in the resulting string
+ * @param {string[]} strings The strings in the template literal
+ * @returns {string} The template literal, with spaces removed from all lines
+ */
+function unIndent(strings) {
+    const templateValue = strings[0];
+    const lines = templateValue.replace(/^\n/u, "").replace(/\n\s*$/u, "").split("\n");
+    const lineIndents = lines.filter(line => line.trim()).map(line => line.match(/ */u)[0].length);
+    const minLineIndent = Math.min(...lineIndents);
+
+    return lines.map(line => line.slice(minLineIndent)).join("\n");
+}
+
+
+module.exports = {
+    unIndent
+};
diff --git a/tests/lib/rules/complexity.js b/tests/lib/rules/complexity.js
index 159d27c8c..93e404468 100644
--- a/tests/lib/rules/complexity.js
+++ b/tests/lib/rules/complexity.js
@@ -106,6 +106,11 @@ ruleTester.run("complexity", rule, {
             code: createComplexity(21),
             errors: [makeError("Function 'test'", 21)]
         },
+        {
+            code: createComplexity(21),
+            options: [{}],
+            errors: [makeError("Function 'test'", 21)]
+        },
 
         // object property options
         { code: "function a(x) {}", options: [{ max: 0 }], errors: [makeError("Function 'a'", 1)] }
diff --git a/tests/lib/rules/indent.js b/tests/lib/rules/indent.js
index 9ce941fb2..45abc654d 100644
--- a/tests/lib/rules/indent.js
+++ b/tests/lib/rules/indent.js
@@ -21,6 +21,8 @@ const path = require("path");
 const fixture = fs.readFileSync(path.join(__dirname, "../../fixtures/rules/indent/indent-invalid-fixture-1.js"), "utf8");
 const fixedFixture = fs.readFileSync(path.join(__dirname, "../../fixtures/rules/indent/indent-valid-fixture-1.js"), "utf8");
 const parser = require("../../fixtures/fixture-parser");
+const { unIndent } = require("./_utils");
+
 
 /**
  * Create error message object for failure cases with a single 'found' indentation type
@@ -54,20 +56,6 @@ function expectedErrors(providedIndentType, providedErrors) {
     }));
 }
 
-/**
- * Prevents leading spaces in a multiline template literal from appearing in the resulting string
- * @param {string[]} strings The strings in the template literal
- * @returns {string} The template literal, with spaces removed from all lines
- */
-function unIndent(strings) {
-    const templateValue = strings[0];
-    const lines = templateValue.replace(/^\n/u, "").replace(/\n\s*$/u, "").split("\n");
-    const lineIndents = lines.filter(line => line.trim()).map(line => line.match(/ */u)[0].length);
-    const minLineIndent = Math.min(...lineIndents);
-
-    return lines.map(line => line.slice(minLineIndent)).join("\n");
-}
-
 const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 8, ecmaFeatures: { jsx: true } } });
 
 ruleTester.run("indent", rule, {
diff --git a/tests/lib/rules/line-comment-position.js b/tests/lib/rules/line-comment-position.js
index 6dfe48561..8a4d07af1 100644
--- a/tests/lib/rules/line-comment-position.js
+++ b/tests/lib/rules/line-comment-position.js
@@ -80,6 +80,10 @@ ruleTester.run("line-comment-position", rule, {
         {
             code: "// above\n1 + 1; // ignored",
             options: [{ ignorePattern: "ignored" }]
+        },
+        {
+            code: "foo; // eslint-disable-line no-alert",
+            options: [{ position: "above" }]
         }
     ],
 
diff --git a/tests/lib/rules/max-depth.js b/tests/lib/rules/max-depth.js
index 086abec58..06029021b 100644
--- a/tests/lib/rules/max-depth.js
+++ b/tests/lib/rules/max-depth.js
@@ -38,6 +38,9 @@ ruleTester.run("max-depth", rule, {
         { code: "function foo() { if (true) { if (false) { if (true) { if (false) { if (true) { } } } } } }", errors: [{ messageId: "tooDeeply", data: { depth: 5 }, type: "IfStatement" }] },
 
         // object property options
-        { code: "function foo() { if (true) { if (false) { if (true) { } } } }", options: [{ max: 2 }], errors: [{ messageId: "tooDeeply", data: { depth: 3 }, type: "IfStatement" }] }
+        { code: "function foo() { if (true) { if (false) { if (true) { } } } }", options: [{ max: 2 }], errors: [{ messageId: "tooDeeply", data: { depth: 3 }, type: "IfStatement" }] },
+
+        { code: "function foo() { if (a) { if (b) { if (c) { if (d) { if (e) {} } } } } }", options: [{}], errors: [{ messageId: "tooDeeply", data: { depth: 5 } }] },
+        { code: "function foo() { if (true) {} }", options: [{ max: 0 }], errors: [{ messageId: "tooDeeply", data: { depth: 1 } }] }
     ]
 });
diff --git a/tests/lib/rules/max-lines.js b/tests/lib/rules/max-lines.js
index 8324b51e1..33f837daa 100644
--- a/tests/lib/rules/max-lines.js
+++ b/tests/lib/rules/max-lines.js
@@ -148,6 +148,16 @@ ruleTester.run("max-lines", rule, {
             ].join("\n"),
             options: [{ max: 2, skipBlankLines: true }],
             errors: [{ messageId: "exceed", data: { max: 2, actual: 6 } }]
+        },
+        {
+            code: "AAAAAAAA\n".repeat(301).trim(),
+            options: [{}],
+            errors: [{ messageId: "exceed", data: { max: 300, actual: 301 } }]
+        },
+        {
+            code: "A",
+            options: [{ max: 0 }],
+            errors: [{ messageId: "exceed", data: { max: 0, actual: 1 } }]
         }
     ]
 });
diff --git a/tests/lib/rules/max-nested-callbacks.js b/tests/lib/rules/max-nested-callbacks.js
index af17ab3b6..91ff8f99a 100644
--- a/tests/lib/rules/max-nested-callbacks.js
+++ b/tests/lib/rules/max-nested-callbacks.js
@@ -75,6 +75,16 @@ ruleTester.run("max-nested-callbacks", rule, {
             code: nestFunctions(11),
             errors: [{ messageId: "exceed", data: { num: 11, max: 10 }, type: "FunctionExpression" }]
         },
+        {
+            code: nestFunctions(11),
+            options: [{}],
+            errors: [{ messageId: "exceed", data: { num: 11, max: 10 }, type: "FunctionExpression" }]
+        },
+        {
+            code: "foo(function() {})",
+            options: [{ max: 0 }],
+            errors: [{ messageId: "exceed", data: { num: 1, max: 0 } }]
+        },
 
         // object property options
         {
diff --git a/tests/lib/rules/max-params.js b/tests/lib/rules/max-params.js
index bdbc8efa0..206ed714f 100644
--- a/tests/lib/rules/max-params.js
+++ b/tests/lib/rules/max-params.js
@@ -94,6 +94,22 @@ ruleTester.run("max-params", rule, {
                 type: "FunctionDeclaration"
             }]
         },
+        {
+            code: "function test(a, b, c, d) {}",
+            options: [{}],
+            errors: [{
+                messageId: "exceed",
+                data: { name: "Function 'test'", count: 4, max: 3 }
+            }]
+        },
+        {
+            code: "function test(a) {}",
+            options: [{ max: 0 }],
+            errors: [{
+                messageId: "exceed",
+                data: { name: "Function 'test'", count: 1, max: 0 }
+            }]
+        },
 
         // Error location should not cover the entire function; just the name.
         {
diff --git a/tests/lib/rules/max-statements.js b/tests/lib/rules/max-statements.js
index 53567448f..2c66ee04c 100644
--- a/tests/lib/rules/max-statements.js
+++ b/tests/lib/rules/max-statements.js
@@ -133,6 +133,16 @@ ruleTester.run("max-statements", rule, {
             code: "var foo = { thing: function() { var bar = 1; var baz = 2; var baz2; } }",
             options: [{ max: 2 }],
             errors: [{ messageId: "exceed", data: { name: "Method 'thing'", count: "3", max: 2 } }]
+        },
+        {
+            code: "function foo() { 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; }",
+            options: [{}],
+            errors: [{ messageId: "exceed", data: { name: "Function 'foo'", count: 11, max: 10 } }]
+        },
+        {
+            code: "function foo() { 1; }",
+            options: [{ max: 0 }],
+            errors: [{ messageId: "exceed", data: { name: "Function 'foo'", count: 1, max: 0 } }]
         }
     ]
 });
diff --git a/tests/lib/rules/no-extra-parens.js b/tests/lib/rules/no-extra-parens.js
index b3481d06a..366a6c39b 100644
--- a/tests/lib/rules/no-extra-parens.js
+++ b/tests/lib/rules/no-extra-parens.js
@@ -452,6 +452,7 @@ ruleTester.run("no-extra-parens", rule, {
         "({}) ? foo() : bar()",
         "({}) + foo",
         "(function(){}) + foo",
+        "(let)\nfoo",
         "(let[foo]) = 1", // setting the 'foo' property of the 'let' variable to 1
         {
             code: "((function(){}).foo.bar)();",
@@ -1092,6 +1093,18 @@ ruleTester.run("no-extra-parens", rule, {
             "Identifier",
             1
         ),
-        invalid("for (a in (b, c));", "for (a in b, c);", "SequenceExpression", null)
+        invalid("for (a in (b, c));", "for (a in b, c);", "SequenceExpression", null),
+        invalid(
+            "(let)",
+            "let",
+            "Identifier",
+            1
+        ),
+        invalid(
+            "((let))",
+            "(let)",
+            "Identifier",
+            1
+        )
     ]
 });
diff --git a/tests/lib/rules/no-warning-comments.js b/tests/lib/rules/no-warning-comments.js
index 3484d0a45..8a9b2c5e2 100644
--- a/tests/lib/rules/no-warning-comments.js
+++ b/tests/lib/rules/no-warning-comments.js
@@ -36,7 +36,8 @@ ruleTester.run("no-warning-comments", rule, {
         { code: "// comments containing terms as substrings like TodoMVC", options: [{ terms: ["todo"], location: "anywhere" }] },
         { code: "// special regex characters don't cause problems", options: [{ terms: ["[aeiou]"], location: "anywhere" }] },
         "/*eslint no-warning-comments: [2, { \"terms\": [\"todo\", \"fixme\", \"any other term\"], \"location\": \"anywhere\" }]*/\n\nvar x = 10;\n",
-        { code: "/*eslint no-warning-comments: [2, { \"terms\": [\"todo\", \"fixme\", \"any other term\"], \"location\": \"anywhere\" }]*/\n\nvar x = 10;\n", options: [{ location: "anywhere" }] }
+        { code: "/*eslint no-warning-comments: [2, { \"terms\": [\"todo\", \"fixme\", \"any other term\"], \"location\": \"anywhere\" }]*/\n\nvar x = 10;\n", options: [{ location: "anywhere" }] },
+        { code: "foo", options: [{ terms: ["foo-bar"] }] }
     ],
     invalid: [
         { code: "// fixme", errors: [{ message: "Unexpected 'fixme' comment." }] },
diff --git a/tests/lib/rules/one-var.js b/tests/lib/rules/one-var.js
index ec7aa9338..bec330c3c 100644
--- a/tests/lib/rules/one-var.js
+++ b/tests/lib/rules/one-var.js
@@ -491,15 +491,11 @@ ruleTester.run("one-var", rule, {
         },
         {
             code: "var a; somethingElse(); var b;",
-            output: null,
-            options: [{ var: "never" }],
-            errors: null
+            options: [{ var: "never" }]
         },
         {
             code: "var foo = 1;\nlet bar = function() { var x; };\nvar baz = 2;",
-            output: null,
-            options: [{ var: "never" }],
-            errors: null
+            options: [{ var: "never" }]
         }
     ],
     invalid: [
diff --git a/tests/lib/rules/prefer-named-capture-group.js b/tests/lib/rules/prefer-named-capture-group.js
new file mode 100644
index 000000000..88047d7c9
--- /dev/null
+++ b/tests/lib/rules/prefer-named-capture-group.js
@@ -0,0 +1,95 @@
+/**
+ * @fileoverview Tests for prefer-named-capture-group rule.
+ * @author Pig Fang <https://github.com/g-plane>
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const rule = require("../../../lib/rules/prefer-named-capture-group"),
+    RuleTester = require("../../../lib/testers/rule-tester");
+
+//------------------------------------------------------------------------------
+// Tests
+//------------------------------------------------------------------------------
+
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018 } });
+
+ruleTester.run("prefer-named-capture-group", rule, {
+    valid: [
+        "/normal_regex/",
+        "/(?:[0-9]{4})/",
+        "/(?<year>[0-9]{4})/",
+        "/\\u{1F680}/u",
+        "new RegExp()",
+        "new RegExp(foo)",
+        "new RegExp('')",
+        "new RegExp('(?<year>[0-9]{4})')",
+        "RegExp()",
+        "RegExp(foo)",
+        "RegExp('')",
+        "RegExp('(?<year>[0-9]{4})')",
+        "RegExp('(')", // invalid regexp should be ignored
+        "RegExp('\\\\u{1F680}', 'u')"
+    ],
+
+    invalid: [
+        {
+            code: "/([0-9]{4})/",
+            errors: [{
+                messageId: "required",
+                type: "Literal",
+                data: { group: "([0-9]{4})" },
+                line: 1,
+                column: 2,
+                endColumn: 12
+            }]
+        },
+        {
+            code: "new RegExp('([0-9]{4})')",
+            errors: [{
+                messageId: "required",
+                type: "NewExpression",
+                data: { group: "([0-9]{4})" },
+                line: 1,
+                column: 13,
+                endColumn: 23
+            }]
+        },
+        {
+            code: "RegExp('([0-9]{4})')",
+            errors: [{
+                messageId: "required",
+                type: "CallExpression",
+                data: { group: "([0-9]{4})" },
+                line: 1,
+                column: 9,
+                endColumn: 19
+            }]
+        },
+        {
+            code: "/([0-9]{4})-(\\w{5})/",
+            errors: [
+                {
+                    messageId: "required",
+                    type: "Literal",
+                    data: { group: "([0-9]{4})" },
+                    line: 1,
+                    column: 2,
+                    endColumn: 12
+                },
+                {
+                    messageId: "required",
+                    type: "Literal",
+                    data: { group: "(\\w{5})" },
+                    line: 1,
+                    column: 13,
+                    endColumn: 20
+                }
+            ]
+        }
+    ]
+});