Repository: eslint/eslint
Pull request #11075 (2018-11-10 16:25:08)

Update all-files-ignored error message to point out the problem to the user 


<!--
    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: Update error message text.

<!--
    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)**
Edited `messages/all-files-ignored.txt` to make the problem more obvious to the user.


**Is there anything you'd like reviewers to focus on?**
No.




Patch:
diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.md b/.github/ISSUE_TEMPLATE/BUG_REPORT.md
index a614d6b2f..1e9a73641 100644
--- a/.github/ISSUE_TEMPLATE/BUG_REPORT.md
+++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.md
@@ -1,6 +1,9 @@
 ---
 name: "\U0001F41E  Bug report"
 about: Report an issue with ESLint or rules bundled with ESLint
+title: ''
+labels: bug, evaluating
+assignees: ''
 
 ---
 
@@ -56,5 +59,3 @@ about: Report an issue with ESLint or rules bundled with ESLint
 
 
 **Are you willing to submit a pull request to fix this bug?**
-
-
diff --git a/.github/ISSUE_TEMPLATE/CHANGE.md b/.github/ISSUE_TEMPLATE/CHANGE.md
index 3fe2fe241..35cb70243 100644
--- a/.github/ISSUE_TEMPLATE/CHANGE.md
+++ b/.github/ISSUE_TEMPLATE/CHANGE.md
@@ -1,6 +1,9 @@
 ---
 name: "\U0001F4DD Non-rule change request"
 about: Request a change that is not a bug fix, rule change, or new rule
+title: ''
+labels: core, enhancement, evaluating
+assignees: ''
 
 ---
 
@@ -27,4 +30,3 @@ about: Request a change that is not a bug fix, rule change, or new rule
 
 
 **Are you willing to submit a pull request to implement this change?**
-
diff --git a/.github/ISSUE_TEMPLATE/NEW_RULE.md b/.github/ISSUE_TEMPLATE/NEW_RULE.md
index 5a50001b0..0fa62b1cf 100644
--- a/.github/ISSUE_TEMPLATE/NEW_RULE.md
+++ b/.github/ISSUE_TEMPLATE/NEW_RULE.md
@@ -1,6 +1,9 @@
 ---
-/name: "\U0001F680 New rule proposal"
+name: "\U0001F680 New rule proposal"
 about: Propose a new rule to be added to ESLint
+title: ''
+labels: rule, feature, evaluating
+assignees: ''
 
 ---
 
@@ -37,4 +40,3 @@ about: Propose a new rule to be added to ESLint
 
 
 **Are you willing to submit a pull request to implement this rule?**
-
diff --git a/.github/ISSUE_TEMPLATE/QUESTION.md b/.github/ISSUE_TEMPLATE/QUESTION.md
index ba96b4104..375e2170a 100644
--- a/.github/ISSUE_TEMPLATE/QUESTION.md
+++ b/.github/ISSUE_TEMPLATE/QUESTION.md
@@ -1,6 +1,9 @@
 ---
 name: "⛔ Question"
 about: Please go to https://gitter.im/eslint/eslint
+title: ''
+labels: ''
+assignees: ''
 
 ---
 
diff --git a/.github/ISSUE_TEMPLATE/RULE_CHANGE.md b/.github/ISSUE_TEMPLATE/RULE_CHANGE.md
index 9ecb2d002..88e250f96 100644
--- a/.github/ISSUE_TEMPLATE/RULE_CHANGE.md
+++ b/.github/ISSUE_TEMPLATE/RULE_CHANGE.md
@@ -1,6 +1,9 @@
 ---
 name: "\U0001F4DD Rule change request"
 about: Request a change to an existing rule
+title: ''
+labels: enhancement, evaluating, rule
+assignees: ''
 
 ---
 
@@ -34,4 +37,4 @@ about: Request a change to an existing rule
 
 **What will the rule do after it's changed?**
 
-**Are you willing to submit a pull request to implement this change?**
\ No newline at end of file
+**Are you willing to submit a pull request to implement this change?**
diff --git a/.github/ISSUE_TEMPLATE/SECURITY.md b/.github/ISSUE_TEMPLATE/SECURITY.md
index 8cc33ec6e..c04f52536 100644
--- a/.github/ISSUE_TEMPLATE/SECURITY.md
+++ b/.github/ISSUE_TEMPLATE/SECURITY.md
@@ -1,6 +1,9 @@
 ---
 name: "⛔ Security issue"
 about: Please file security issues at https://hackerone.com/eslint
+title: ''
+labels: ''
+assignees: ''
 
 ---
 
diff --git a/Makefile.js b/Makefile.js
index e468d0a16..eb2c586a7 100644
--- a/Makefile.js
+++ b/Makefile.js
@@ -350,7 +350,7 @@ function publishRelease() {
 /**
  * Splits a command result to separate lines.
  * @param {string} result The command result string.
- * @returns {array} The separated lines.
+ * @returns {Array} The separated lines.
  */
 function splitCommandResultToLines(result) {
     return result.trim().split("\n");
@@ -416,7 +416,7 @@ function getFirstVersionOfDeletion(filePath) {
 
 /**
  * Lints Markdown files.
- * @param {array} files Array of file names to lint.
+ * @param {Array} files Array of file names to lint.
  * @returns {Object} exec-style exit code object.
  * @private
  */
diff --git a/README.md b/README.md
index 572cd8a07..65ee43400 100644
--- a/README.md
+++ b/README.md
@@ -38,7 +38,7 @@ If you want to include ESLint as part of your project's build system, we recomme
 $ npm install eslint --save-dev
 ```
 
-You should then setup a configuration file:
+You should then set up a configuration file:
 
 ```
 $ ./node_modules/.bin/eslint --init
@@ -60,7 +60,7 @@ If you want to make ESLint available to tools that run across all of your projec
 $ npm install -g eslint
 ```
 
-You should then setup a configuration file:
+You should then set up a configuration file:
 
 ```
 $ eslint --init
diff --git a/docs/developer-guide/nodejs-api.md b/docs/developer-guide/nodejs-api.md
index 834fecefd..7b9ecb6ec 100644
--- a/docs/developer-guide/nodejs-api.md
+++ b/docs/developer-guide/nodejs-api.md
@@ -339,17 +339,17 @@ var CLIEngine = require("eslint").CLIEngine;
 The `CLIEngine` is a constructor, and you can create a new instance by passing in the options you want to use. The available options are:
 
 * `allowInlineConfig` - Set to `false` to disable the use of configuration comments (such as `/*eslint-disable*/`). Corresponds to `--no-inline-config`.
-* `baseConfig` - Can optionally be set to a config object. This will used as a default config, and will be merged with any configuration defined in `.eslintrc.*` files, with the `.eslintrc.*` files having precedence.
+* `baseConfig` - Can optionally be set to a config object that has the same schema as `.eslintrc.*`. This will used as a default config, and will be merged with any configuration defined in `.eslintrc.*` files, with the `.eslintrc.*` files having precedence.
 * `cache` - Operate only on changed files (default: `false`). Corresponds to `--cache`.
 * `cacheFile` - Name of the file where the cache will be stored (default: `.eslintcache`). Corresponds to `--cache-file`. Deprecated: use `cacheLocation` instead.
 * `cacheLocation` - Name of the file or directory where the cache will be stored (default: `.eslintcache`). Corresponds to `--cache-location`.
 * `configFile` - The configuration file to use (default: null). If `useEslintrc` is true or not specified, this configuration will be merged with any configuration defined in `.eslintrc.*` files, with options in this configuration having precedence. Corresponds to `-c`.
 * `cwd` - Path to a directory that should be considered as the current working directory.
-* `envs` - An array of environments to load (default: empty array). Corresponds to `--env`.
-* `extensions` - An array of filename extensions that should be checked for code. The default is an array containing just `".js"`. Corresponds to `--ext`. It is only used in conjunction with directories, not with filenames or glob patterns.
+* `envs` - An array of environments to load (default: empty array). Corresponds to `--env`. Note: This differs from `.eslintrc.*` / `baseConfig`, where instead the option is called `env` and is an object.
+* `extensions` - An array of filename extensions that should be checked for code. The default is an array containing just `".js"`. Corresponds to `--ext`. It is only used in conjunction with directories, not with filenames, glob patterns or when using `executeOnText()`.
 * `fix` - A boolean or a function (default: `false`). If a function, it will be passed each linting message and should return a boolean indicating whether the fix should be included with the output report (errors and warnings will not be listed if fixed). Files on disk are never changed regardless of the value of `fix`. To persist changes to disk, call [`outputFixes()`](#cliengineoutputfixes).
 * `fixTypes` - An array of rule types for which fixes should be applied (default: `null`). This array acts like a filter, only allowing rules of the given types to apply fixes. Possible array values are `"problem"`, `"suggestion"`, and `"layout"`.
-* `globals` - An array of global variables to declare (default: empty array). Corresponds to `--global`.
+* `globals` - An array of global variables to declare (default: empty array). Corresponds to `--global`, and similarly supports passing `'name:true'` to denote a writeable global. Note: This differs from `.eslintrc.*` / `baseConfig`, where `globals` is an object.
 * `ignore` - False disables use of `.eslintignore`, `ignorePath` and `ignorePattern` (default: true). Corresponds to `--no-ignore`.
 * `ignorePath` - The ignore file to use instead of `.eslintignore` (default: null). Corresponds to `--ignore-path`.
 * `ignorePattern` - Glob patterns for paths to ignore. String or array of strings.
@@ -362,7 +362,8 @@ The `CLIEngine` is a constructor, and you can create a new instance by passing i
 * `useEslintrc` - Set to false to disable use of `.eslintrc` files (default: true). Corresponds to `--no-eslintrc`.
 * `globInputPaths` - Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file.
 
-
+To programmatically set `.eslintrc.*` options not supported above (such as `extends`,
+`overrides` and `settings`), define them in a config object passed to `baseConfig` instead.
 
 For example:
 
@@ -370,6 +371,12 @@ For example:
 var CLIEngine = require("eslint").CLIEngine;
 
 var cli = new CLIEngine({
+    baseConfig: {
+        extends: ["eslint-config-shared"],
+        settings: {
+            sharedData: "Hello"
+        }
+    },
     envs: ["browser", "mocha"],
     useEslintrc: false,
     rules: {
@@ -378,7 +385,13 @@ var cli = new CLIEngine({
 });
 ```
 
-In this code, a new `CLIEngine` instance is created that sets two environments, `"browser"` and `"mocha"`, disables loading of `.eslintrc` and `package.json` files, and enables the `semi` rule as an error. You can then call methods on `cli` and these options will be used to perform the correct action.
+In this example, a new `CLIEngine` instance is created that extends a configuration called
+`"eslint-config-shared"`, a setting named `"sharedData"` and two environments (`"browser"`
+and `"mocha"`) are defined, loading of `.eslintrc` and `package.json` files are disabled,
+and the `semi` rule enabled as an error. You can then call methods on `cli` and these options
+will be used to perform the correct action.
+
+Note: Currently `CLIEngine` does not validate options passed to it, but may start doing so in the future.
 
 ### CLIEngine#executeOnFiles()
 
diff --git a/docs/rules/id-match.md b/docs/rules/id-match.md
index 55f5e3253..0d9deebd7 100644
--- a/docs/rules/id-match.md
+++ b/docs/rules/id-match.md
@@ -23,20 +23,6 @@ For example, to enforce a camelcase naming convention:
 }
 ```
 
-Examples of **correct** code for this rule with the `"^[a-z]+([A-Z][a-z]+)*$"` option:
-
-```js
-/*eslint id-match: ["error", "^[a-z]+([A-Z][a-z]+)*$"]*/
-
-var myFavoriteColor   = "#112C85";
-var foo = bar.baz_boom;
-var foo = { qux: bar.baz_boom };
-do_something();
-var obj = {
-    my_pref: 1
-};
-```
-
 Examples of **incorrect** code for this rule with the `"^[a-z]+([A-Z][a-z]+)*$"` option:
 
 ```js
@@ -54,6 +40,20 @@ obj.do_something = function() {
 };
 ```
 
+Examples of **correct** code for this rule with the `"^[a-z]+([A-Z][a-z]+)*$"` option:
+
+```js
+/*eslint id-match: ["error", "^[a-z]+([A-Z][a-z]+)*$"]*/
+
+var myFavoriteColor   = "#112C85";
+var foo = bar.baz_boom;
+var foo = { qux: bar.baz_boom };
+do_something();
+var obj = {
+    my_pref: 1
+};
+```
+
 This rule has an object option:
 
 * `"properties": true` requires object properties to match the specified regular expression
diff --git a/docs/rules/no-console.md b/docs/rules/no-console.md
index 1c36a85f9..bc163b937 100644
--- a/docs/rules/no-console.md
+++ b/docs/rules/no-console.md
@@ -78,10 +78,11 @@ However, you might not want to manually add `eslint-disable-next-line` or `eslin
 ```json
 {
     "rules": {
+        "no-console": "off",
         "no-restricted-syntax": [
             "error",
             {
-                "selector": "CallExpression[callee.object.name='console'][callee.property.name=/^(log|warn|error|info|trace)$/]",
+                "selector": "CallExpression[callee.object.name='console'][callee.property.name!=/^(log|warn|error|info|trace)$/]",
                 "message": "Unexpected property on console object was called"
             }
         ]
diff --git a/docs/rules/object-shorthand.md b/docs/rules/object-shorthand.md
index 6f2471faf..79e76655c 100644
--- a/docs/rules/object-shorthand.md
+++ b/docs/rules/object-shorthand.md
@@ -84,7 +84,7 @@ var foo = {
 
 See Also:
 
-- [`no-useless-rename`](https://eslint.org/docs/rules/object-shorthand) which disallows renaming import, export, and destructured assignments to the same name.
+- [`no-useless-rename`](https://eslint.org/docs/rules/no-useless-rename) which disallows renaming import, export, and destructured assignments to the same name.
 
 ## Options
 
diff --git a/lib/cli-engine.js b/lib/cli-engine.js
index 652d68b59..ce9fe289b 100644
--- a/lib/cli-engine.js
+++ b/lib/cli-engine.js
@@ -20,7 +20,7 @@ const fs = require("fs"),
     defaultOptions = require("../conf/default-cli-options"),
     Linter = require("./linter"),
     lodash = require("lodash"),
-    IgnoredPaths = require("./ignored-paths"),
+    IgnoredPaths = require("./util/ignored-paths"),
     Config = require("./config"),
     ConfigOps = require("./config/config-ops"),
     LintResultCache = require("./util/lint-result-cache"),
diff --git a/lib/config.js b/lib/config.js
index 8ea9aeb6f..abcb38b50 100644
--- a/lib/config.js
+++ b/lib/config.js
@@ -15,8 +15,7 @@ const path = require("path"),
     ConfigFile = require("./config/config-file"),
     ConfigCache = require("./config/config-cache"),
     Plugins = require("./config/plugins"),
-    FileFinder = require("./util/file-finder"),
-    isResolvable = require("is-resolvable");
+    FileFinder = require("./util/file-finder");
 
 const debug = require("debug")("eslint:config");
 
@@ -41,6 +40,20 @@ function hasRules(options) {
     return options.rules && Object.keys(options.rules).length > 0;
 }
 
+/**
+ * Determines if a module is can be resolved.
+ * @param {string} moduleId The ID (name) of the module
+ * @returns {boolean} True if it is resolvable; False otherwise.
+ */
+function isResolvable(moduleId) {
+    try {
+        require.resolve(moduleId);
+        return true;
+    } catch (err) {
+        return false;
+    }
+}
+
 //------------------------------------------------------------------------------
 // API
 //------------------------------------------------------------------------------
diff --git a/lib/config/autoconfig.js b/lib/config/autoconfig.js
index 8536fdc55..f2c707be8 100644
--- a/lib/config/autoconfig.js
+++ b/lib/config/autoconfig.js
@@ -102,7 +102,6 @@ class Registry {
      *
      * The length of the returned array will be <= MAX_CONFIG_COMBINATIONS.
      *
-     * @param   {Object}   registry The autoconfig registry
      * @returns {Object[]}          "rules" configurations to use for linting
      */
     buildRuleSets() {
diff --git a/lib/config/config-rule.js b/lib/config/config-rule.js
index 27d29446d..e4221406d 100644
--- a/lib/config/config-rule.js
+++ b/lib/config/config-rule.js
@@ -37,9 +37,9 @@ function explodeArray(xs) {
  * For example:
  * combineArrays([a, [b, c]], [x, y]); // -> [[a, x], [a, y], [b, c, x], [b, c, y]]
  *
- * @param   {array} arr1 The first array to combine.
- * @param   {array} arr2 The second array to combine.
- * @returns {array}      A mixture of the elements of the first and second arrays.
+ * @param   {Array} arr1 The first array to combine.
+ * @param   {Array} arr2 The second array to combine.
+ * @returns {Array}      A mixture of the elements of the first and second arrays.
  */
 function combineArrays(arr1, arr2) {
     const res = [];
@@ -268,7 +268,7 @@ class RuleConfigSet {
 /**
  * Generate valid rule configurations based on a schema object
  * @param   {Object} schema  A rule's schema object
- * @returns {array[]}        Valid rule configurations
+ * @returns {Array[]}        Valid rule configurations
  */
 function generateConfigsFromSchema(schema) {
     const configSet = new RuleConfigSet();
diff --git a/lib/config/config-validator.js b/lib/config/config-validator.js
index 6b151f46a..0c63b68f7 100644
--- a/lib/config/config-validator.js
+++ b/lib/config/config-validator.js
@@ -83,7 +83,7 @@ function validateRuleSeverity(options) {
 /**
  * Validates the non-severity options passed to a rule, based on its schema.
  * @param {{create: Function}} rule The rule to validate
- * @param {array} localOptions The options for the rule, excluding severity
+ * @param {Array} localOptions The options for the rule, excluding severity
  * @returns {void}
  */
 function validateRuleSchema(rule, localOptions) {
@@ -111,7 +111,7 @@ function validateRuleSchema(rule, localOptions) {
  * Validates a rule's options against its schema.
  * @param {{create: Function}|null} rule The rule that the config is being validated for
  * @param {string} ruleId The rule's unique name.
- * @param {array|number} options The given options for the rule.
+ * @param {Array|number} options The given options for the rule.
  * @param {string|null} source The name of the configuration source to report in any errors. If null or undefined,
  * no source is prepended to the message.
  * @returns {void}
diff --git a/lib/linter.js b/lib/linter.js
index b47e6eb1f..d6d635f9f 100644
--- a/lib/linter.js
+++ b/lib/linter.js
@@ -11,7 +11,6 @@
 
 const eslintScope = require("eslint-scope"),
     evk = require("eslint-visitor-keys"),
-    levn = require("levn"),
     lodash = require("lodash"),
     CodePathAnalyzer = require("./code-path-analysis/code-path-analyzer"),
     ConfigOps = require("./config/config-ops"),
@@ -22,9 +21,10 @@ const eslintScope = require("eslint-scope"),
     NodeEventGenerator = require("./util/node-event-generator"),
     SourceCode = require("./util/source-code"),
     Traverser = require("./util/traverser"),
-    createReportTranslator = require("./report-translator"),
+    createReportTranslator = require("./util/report-translator"),
     Rules = require("./rules"),
     timing = require("./util/timing"),
+    ConfigCommentParser = require("./util/config-comment-parser"),
     astUtils = require("./util/ast-utils"),
     pkg = require("../package.json"),
     SourceCodeFixer = require("./util/source-code-fixer");
@@ -32,6 +32,7 @@ const eslintScope = require("eslint-scope"),
 const debug = require("debug")("eslint:linter");
 const MAX_AUTOFIX_PASSES = 10;
 const DEFAULT_PARSER_NAME = "espree";
+const commentParser = new ConfigCommentParser();
 
 //------------------------------------------------------------------------------
 // Typedefs
@@ -59,117 +60,6 @@ const DEFAULT_PARSER_NAME = "espree";
 // Helpers
 //------------------------------------------------------------------------------
 
-/**
- * Parses a list of "name:boolean_value" or/and "name" options divided by comma or
- * whitespace.
- * @param {string} string The string to parse.
- * @param {Comment} comment The comment node which has the string.
- * @returns {Object} Result map object of names and boolean values
- */
-function parseBooleanConfig(string, comment) {
-    const items = {};
-
-    // Collapse whitespace around `:` and `,` to make parsing easier
-    const trimmedString = string.replace(/\s*([:,])\s*/g, "$1");
-
-    trimmedString.split(/\s|,+/).forEach(name => {
-        if (!name) {
-            return;
-        }
-        const pos = name.indexOf(":");
-
-        if (pos === -1) {
-            items[name] = {
-                value: false,
-                comment
-            };
-        } else {
-            items[name.slice(0, pos)] = {
-                value: name.slice(pos + 1) === "true",
-                comment
-            };
-        }
-    });
-    return items;
-}
-
-/**
- * Parses a JSON-like config.
- * @param {string} string The string to parse.
- * @param {Object} location Start line and column of comments for potential error message.
- * @returns {({success: true, config: Object}|{success: false, error: Problem})} Result map object
- */
-function parseJsonConfig(string, location) {
-    let items = {};
-
-    // Parses a JSON-like comment by the same way as parsing CLI option.
-    try {
-        items = levn.parse("Object", string) || {};
-
-        // Some tests say that it should ignore invalid comments such as `/*eslint no-alert:abc*/`.
-        // Also, commaless notations have invalid severity:
-        //     "no-alert: 2 no-console: 2" --> {"no-alert": "2 no-console: 2"}
-        // Should ignore that case as well.
-        if (ConfigOps.isEverySeverityValid(items)) {
-            return {
-                success: true,
-                config: items
-            };
-        }
-    } catch (ex) {
-
-        // ignore to parse the string by a fallback.
-    }
-
-    /*
-     * Optionator cannot parse commaless notations.
-     * But we are supporting that. So this is a fallback for that.
-     */
-    items = {};
-    const normalizedString = string.replace(/([a-zA-Z0-9\-/]+):/g, "\"$1\":").replace(/(]|[0-9])\s+(?=")/, "$1,");
-
-    try {
-        items = JSON.parse(`{${normalizedString}}`);
-    } catch (ex) {
-        return {
-            success: false,
-            error: {
-                ruleId: null,
-                fatal: true,
-                severity: 2,
-                message: `Failed to parse JSON from '${normalizedString}': ${ex.message}`,
-                line: location.start.line,
-                column: location.start.column + 1
-            }
-        };
-
-    }
-
-    return {
-        success: true,
-        config: items
-    };
-}
-
-/**
- * Parses a config of values separated by comma.
- * @param {string} string The string to parse.
- * @returns {Object} Result map of values and true values
- */
-function parseListConfig(string) {
-    const items = {};
-
-    // Collapse whitespace around ,
-    string.replace(/\s*,\s*/g, ",").split(/,+/).forEach(name => {
-        const trimmedName = name.trim();
-
-        if (trimmedName) {
-            items[trimmedName] = true;
-        }
-    });
-    return items;
-}
-
 /**
  * Ensures that variables representing built-in properties of the Global Object,
  * and any globals declared by special block comments, are present in the global
@@ -248,7 +138,7 @@ function addDeclaredGlobals(globalScope, configGlobals, commentDirectives) {
  * @returns {DisableDirective[]} Directives from the comment
  */
 function createDisableDirectives(type, loc, value) {
-    const ruleIds = Object.keys(parseListConfig(value));
+    const ruleIds = Object.keys(commentParser.parseListConfig(value));
     const directiveRules = ruleIds.length ? ruleIds : [null];
 
     return directiveRules.map(ruleId => ({ type, line: loc.line, column: loc.column + 1, ruleId }));
@@ -301,12 +191,12 @@ function getDirectiveComments(filename, ast, ruleMapper) {
         } else if (comment.type === "Block") {
             switch (match[1]) {
                 case "exported":
-                    Object.assign(exportedVariables, parseBooleanConfig(directiveValue, comment));
+                    Object.assign(exportedVariables, commentParser.parseBooleanConfig(directiveValue, comment));
                     break;
 
                 case "globals":
                 case "global":
-                    Object.assign(enabledGlobals, parseBooleanConfig(directiveValue, comment));
+                    Object.assign(enabledGlobals, commentParser.parseBooleanConfig(directiveValue, comment));
                     break;
 
                 case "eslint-disable":
@@ -318,7 +208,7 @@ function getDirectiveComments(filename, ast, ruleMapper) {
                     break;
 
                 case "eslint": {
-                    const parseResult = parseJsonConfig(directiveValue, comment.loc);
+                    const parseResult = commentParser.parseJsonConfig(directiveValue, comment.loc);
 
                     if (parseResult.success) {
                         Object.keys(parseResult.config).forEach(name => {
@@ -398,7 +288,7 @@ function findEslintEnv(text) {
     eslintEnvPattern.lastIndex = 0;
 
     while ((match = eslintEnvPattern.exec(text))) {
-        retv = Object.assign(retv || {}, parseListConfig(match[1]));
+        retv = Object.assign(retv || {}, commentParser.parseListConfig(match[1]));
     }
 
     return retv;
@@ -1032,8 +922,6 @@ module.exports = class Linter {
      * @param {(string|Object)} [filenameOrOptions] The optional filename of the file being checked.
      *      If this is not set, the filename will default to '<input>' in the rule context. If
      *      an object, then it has "filename", "saveState", and "allowInlineConfig" properties.
-     * @param {boolean} [saveState] Indicates if the state from the last run should be saved.
-     *      Mostly useful for testing purposes.
      * @param {boolean} [filenameOrOptions.allowInlineConfig] Allow/disallow inline comments' ability to change config once it is set. Defaults to true if not supplied.
      *      Useful if you want to validate JS without comments overriding rules.
      * @param {function(string): string[]} [filenameOrOptions.preprocess] preprocessor for source text. If provided,
diff --git a/lib/rules/array-element-newline.js b/lib/rules/array-element-newline.js
index 440290917..dadb26fdd 100644
--- a/lib/rules/array-element-newline.js
+++ b/lib/rules/array-element-newline.js
@@ -173,7 +173,6 @@ module.exports = {
          * Reports a given node if it violated this rule.
          *
          * @param {ASTNode} node - A node to check. This is an ObjectExpression node or an ObjectPattern node.
-         * @param {{multiline: boolean, minItems: number}} options - An option object.
          * @returns {void}
          */
         function check(node) {
diff --git a/lib/rules/camelcase.js b/lib/rules/camelcase.js
index 8aeb4b5bd..6fb8760f1 100644
--- a/lib/rules/camelcase.js
+++ b/lib/rules/camelcase.js
@@ -132,9 +132,10 @@ module.exports = {
 
                 /*
                  * Leading and trailing underscores are commonly used to flag
-                 * private/protected identifiers, strip them
+                 * private/protected identifiers, strip them before checking if underscored
                  */
-                const name = node.name.replace(/^_+|_+$/g, ""),
+                const name = node.name,
+                    nameIsUnderscored = isUnderscored(name.replace(/^_+|_+$/g, "")),
                     effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent;
 
                 // First, we ignore the node if it match the ignore list
@@ -151,11 +152,11 @@ module.exports = {
                     }
 
                     // Always report underscored object names
-                    if (node.parent.object.type === "Identifier" && node.parent.object.name === node.name && isUnderscored(name)) {
+                    if (node.parent.object.type === "Identifier" && node.parent.object.name === node.name && nameIsUnderscored) {
                         report(node);
 
                     // Report AssignmentExpressions only if they are the left side of the assignment
-                    } else if (effectiveParent.type === "AssignmentExpression" && isUnderscored(name) && (effectiveParent.right.type !== "MemberExpression" || effectiveParent.left.type === "MemberExpression" && effectiveParent.left.property.name === node.name)) {
+                    } else if (effectiveParent.type === "AssignmentExpression" && nameIsUnderscored && (effectiveParent.right.type !== "MemberExpression" || effectiveParent.left.type === "MemberExpression" && effectiveParent.left.property.name === node.name)) {
                         report(node);
                     }
 
@@ -167,7 +168,7 @@ module.exports = {
                 } else if (node.parent.type === "Property" || node.parent.type === "AssignmentPattern") {
 
                     if (node.parent.parent && node.parent.parent.type === "ObjectPattern") {
-                        if (node.parent.shorthand && node.parent.value.left && isUnderscored(name)) {
+                        if (node.parent.shorthand && node.parent.value.left && nameIsUnderscored) {
 
                             report(node);
                         }
@@ -179,7 +180,7 @@ module.exports = {
                             return;
                         }
 
-                        const valueIsUnderscored = node.parent.value.name && isUnderscored(name);
+                        const valueIsUnderscored = node.parent.value.name && nameIsUnderscored;
 
                         // ignore destructuring if the option is set, unless a new identifier is created
                         if (valueIsUnderscored && !(assignmentKeyEqualsValue && ignoreDestructuring)) {
@@ -193,7 +194,7 @@ module.exports = {
                     }
 
                     // don't check right hand side of AssignmentExpression to prevent duplicate warnings
-                    if (isUnderscored(name) && !ALLOWED_PARENT_TYPES.has(effectiveParent.type) && !(node.parent.right === node)) {
+                    if (nameIsUnderscored && !ALLOWED_PARENT_TYPES.has(effectiveParent.type) && !(node.parent.right === node)) {
                         report(node);
                     }
 
@@ -201,12 +202,12 @@ module.exports = {
                 } else if (["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"].indexOf(node.parent.type) >= 0) {
 
                     // Report only if the local imported identifier is underscored
-                    if (node.parent.local && node.parent.local.name === node.name && isUnderscored(name)) {
+                    if (node.parent.local && node.parent.local.name === node.name && nameIsUnderscored) {
                         report(node);
                     }
 
                 // Report anything that is underscored that isn't a CallExpression
-                } else if (isUnderscored(name) && !ALLOWED_PARENT_TYPES.has(effectiveParent.type)) {
+                } else if (nameIsUnderscored && !ALLOWED_PARENT_TYPES.has(effectiveParent.type)) {
                     report(node);
                 }
             }
diff --git a/lib/rules/comma-style.js b/lib/rules/comma-style.js
index 2586cf66e..78438a858 100644
--- a/lib/rules/comma-style.js
+++ b/lib/rules/comma-style.js
@@ -85,7 +85,7 @@ module.exports = {
         function getReplacedText(styleType, text) {
             switch (styleType) {
                 case "between":
-                    return `,${text.replace("\n", "")}`;
+                    return `,${text.replace(astUtils.LINEBREAK_MATCHER, "")}`;
 
                 case "first":
                     return `${text},`;
@@ -138,6 +138,11 @@ module.exports = {
             } else if (!astUtils.isTokenOnSameLine(commaToken, currentItemToken) &&
                     !astUtils.isTokenOnSameLine(previousItemToken, commaToken)) {
 
+                const comment = sourceCode.getCommentsAfter(commaToken)[0];
+                const styleType = comment && comment.type === "Block" && astUtils.isTokenOnSameLine(commaToken, comment)
+                    ? style
+                    : "between";
+
                 // lone comma
                 context.report({
                     node: reportItem,
@@ -146,7 +151,7 @@ module.exports = {
                         column: commaToken.loc.start.column
                     },
                     messageId: "unexpectedLineBeforeAndAfterComma",
-                    fix: getFixerFunction("between", previousItemToken, commaToken, currentItemToken)
+                    fix: getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken)
                 });
 
             } else if (style === "first" && !astUtils.isTokenOnSameLine(commaToken, currentItemToken)) {
diff --git a/lib/rules/eqeqeq.js b/lib/rules/eqeqeq.js
index 715c5ce7c..3e8a392cf 100644
--- a/lib/rules/eqeqeq.js
+++ b/lib/rules/eqeqeq.js
@@ -119,7 +119,6 @@ module.exports = {
         /**
          * Gets the location (line and column) of the binary expression's operator
          * @param {ASTNode} node The binary expression node to check
-         * @param {string} operator The operator to find
          * @returns {Object} { line, column } location of operator
          * @private
          */
diff --git a/lib/rules/handle-callback-err.js b/lib/rules/handle-callback-err.js
index c62016d58..5845aff4b 100644
--- a/lib/rules/handle-callback-err.js
+++ b/lib/rules/handle-callback-err.js
@@ -59,7 +59,7 @@ module.exports = {
         /**
          * Get the parameters of a given function scope.
          * @param {Object} scope The function scope.
-         * @returns {array} All parameters of the given scope.
+         * @returns {Array} All parameters of the given scope.
          */
         function getParameters(scope) {
             return scope.variables.filter(variable => variable.defs[0] && variable.defs[0].type === "Parameter");
diff --git a/lib/rules/implicit-arrow-linebreak.js b/lib/rules/implicit-arrow-linebreak.js
index cd729f8ad..a883b2264 100644
--- a/lib/rules/implicit-arrow-linebreak.js
+++ b/lib/rules/implicit-arrow-linebreak.js
@@ -44,7 +44,6 @@ module.exports = {
         /**
          * Validates the location of an arrow function body
          * @param {ASTNode} node The arrow function body
-         * @param {string} keywordName The applicable keyword name for the arrow function body
          * @returns {void}
          */
         function validateExpression(node) {
diff --git a/lib/rules/indent-legacy.js b/lib/rules/indent-legacy.js
index 16687b521..cfb807e34 100644
--- a/lib/rules/indent-legacy.js
+++ b/lib/rules/indent-legacy.js
@@ -300,7 +300,6 @@ module.exports = {
          * @param {int} gottenTabs Indentation tab count in the actual node/code
          * @param {Object=} loc Error line and column location
          * @param {boolean} isLastNodeCheck Is the error for last node check
-         * @param {int} lastNodeCheckEndOffset Number of charecters to skip from the end
          * @returns {void}
          */
         function report(node, needed, gottenSpaces, gottenTabs, loc, isLastNodeCheck) {
@@ -365,7 +364,6 @@ module.exports = {
          * Check indent for node
          * @param {ASTNode} node Node to check
          * @param {int} neededIndent needed indent
-         * @param {boolean} [excludeCommas=false] skip comma on start of line
          * @returns {void}
          */
         function checkNodeIndent(node, neededIndent) {
@@ -413,7 +411,6 @@ module.exports = {
          * Check indent for nodes list
          * @param {ASTNode[]} nodes list of node objects
          * @param {int} indent needed indent
-         * @param {boolean} [excludeCommas=false] skip comma on start of line
          * @returns {void}
          */
         function checkNodesIndent(nodes, indent) {
diff --git a/lib/rules/indent.js b/lib/rules/indent.js
index dc9fbaf90..0b87412c8 100644
--- a/lib/rules/indent.js
+++ b/lib/rules/indent.js
@@ -1229,9 +1229,13 @@ module.exports = {
                 }
 
                 const fromToken = sourceCode.getLastToken(node, token => token.type === "Identifier" && token.value === "from");
+                const sourceToken = sourceCode.getLastToken(node, token => token.type === "String");
+                const semiToken = sourceCode.getLastToken(node, token => token.type === "Punctuator" && token.value === ";");
 
                 if (fromToken) {
-                    offsets.setDesiredOffsets([fromToken.range[0], node.range[1]], sourceCode.getFirstToken(node), 1);
+                    const end = semiToken && semiToken.range[1] === sourceToken.range[1] ? node.range[1] : sourceToken.range[1];
+
+                    offsets.setDesiredOffsets([fromToken.range[0], end], sourceCode.getFirstToken(node), 1);
                 }
             },
 
diff --git a/lib/rules/keyword-spacing.js b/lib/rules/keyword-spacing.js
index 66ce2cb34..790d7b031 100644
--- a/lib/rules/keyword-spacing.js
+++ b/lib/rules/keyword-spacing.js
@@ -453,6 +453,10 @@ module.exports = {
             checkSpacingBefore(firstToken, PREV_TOKEN_M);
             checkSpacingAfter(firstToken, NEXT_TOKEN_M);
 
+            if (node.type === "ExportDefaultDeclaration") {
+                checkSpacingAround(sourceCode.getTokenAfter(firstToken));
+            }
+
             if (node.source) {
                 const fromToken = sourceCode.getTokenBefore(node.source);
 
@@ -554,7 +558,7 @@ module.exports = {
             // Statements - Declarations
             ClassDeclaration: checkSpacingForClass,
             ExportNamedDeclaration: checkSpacingForModuleDeclaration,
-            ExportDefaultDeclaration: checkSpacingAroundFirstToken,
+            ExportDefaultDeclaration: checkSpacingForModuleDeclaration,
             ExportAllDeclaration: checkSpacingForModuleDeclaration,
             FunctionDeclaration: checkSpacingForFunction,
             ImportDeclaration: checkSpacingForModuleDeclaration,
diff --git a/lib/rules/newline-before-return.js b/lib/rules/newline-before-return.js
index 2743bf7a8..6a0ec8d5e 100644
--- a/lib/rules/newline-before-return.js
+++ b/lib/rules/newline-before-return.js
@@ -36,7 +36,7 @@ module.exports = {
         /**
          * Tests whether node is preceded by supplied tokens
          * @param {ASTNode} node - node to check
-         * @param {array} testTokens - array of tokens to test against
+         * @param {Array} testTokens - array of tokens to test against
          * @returns {boolean} Whether or not the node is preceded by one of the supplied tokens
          * @private
          */
diff --git a/lib/rules/no-constant-condition.js b/lib/rules/no-constant-condition.js
index 88984c36e..8d7934d8a 100644
--- a/lib/rules/no-constant-condition.js
+++ b/lib/rules/no-constant-condition.js
@@ -173,7 +173,6 @@ module.exports = {
 
         /**
          * Reports when the set still contains stored constant conditions
-         * @param {ASTNode} node The AST node to check.
          * @returns {void}
          * @private
          */
diff --git a/lib/rules/no-else-return.js b/lib/rules/no-else-return.js
index eebdec76e..5ba02de29 100644
--- a/lib/rules/no-else-return.js
+++ b/lib/rules/no-else-return.js
@@ -183,7 +183,6 @@ module.exports = {
          * code paths.
          *
          * @param {Node} node The consequent or body node
-         * @param {Node} alternate The alternate node
          * @returns {boolean} `true` if it is a Return/If node that always returns.
          */
         function checkForReturnOrIf(node) {
diff --git a/lib/rules/no-implied-eval.js b/lib/rules/no-implied-eval.js
index d31b5dfee..afa24ab8e 100644
--- a/lib/rules/no-implied-eval.js
+++ b/lib/rules/no-implied-eval.js
@@ -38,7 +38,7 @@ module.exports = {
 
         /**
          * Get the last element of an array, without modifying arr, like pop(), but non-destructive.
-         * @param {array} arr What to inspect
+         * @param {Array} arr What to inspect
          * @returns {*} The last element of arr
          * @private
          */
diff --git a/lib/rules/no-restricted-imports.js b/lib/rules/no-restricted-imports.js
index b8fcca1aa..b8917ee9c 100644
--- a/lib/rules/no-restricted-imports.js
+++ b/lib/rules/no-restricted-imports.js
@@ -195,7 +195,7 @@ module.exports = {
         /**
          * Check if the given importNames are restricted given a list of restrictedImportNames.
          * @param {Set.<string>} importNames - Set of import names that are being imported
-         * @param {[string]} restrictedImportNames - array of import names that are restricted for this import
+         * @param {string[]} restrictedImportNames - array of import names that are restricted for this import
          * @returns {boolean} whether the objectName is restricted
          * @private
          */
diff --git a/lib/rules/no-this-before-super.js b/lib/rules/no-this-before-super.js
index 93fb094e9..bca379bf9 100644
--- a/lib/rules/no-this-before-super.js
+++ b/lib/rules/no-this-before-super.js
@@ -171,7 +171,6 @@ module.exports = {
              * invalid node.
              *
              * @param {CodePath} codePath - A code path which was ended.
-             * @param {ASTNode} node - The current node.
              * @returns {void}
              */
             onCodePathEnd(codePath) {
diff --git a/lib/rules/object-curly-newline.js b/lib/rules/object-curly-newline.js
index c460ea56b..d1a6bc20f 100644
--- a/lib/rules/object-curly-newline.js
+++ b/lib/rules/object-curly-newline.js
@@ -172,7 +172,6 @@ module.exports = {
         /**
          * Reports a given node if it violated this rule.
          * @param {ASTNode} node - A node to check. This is an ObjectExpression, ObjectPattern, ImportDeclaration or ExportNamedDeclaration node.
-         * @param {{multiline: boolean, minProperties: number, consistent: boolean}} options - An option object.
          * @returns {void}
          */
         function check(node) {
diff --git a/lib/rules/one-var.js b/lib/rules/one-var.js
index 44f05fb70..0e9dff416 100644
--- a/lib/rules/one-var.js
+++ b/lib/rules/one-var.js
@@ -310,7 +310,6 @@ module.exports = {
         /**
          * Fixer to split a VariableDeclaration into individual declarations
          * @param   {VariableDeclaration}   declaration The `VariableDeclaration` to split
-         * @param   {?Function}             filter      Function to filter the declarations
          * @returns {Function}                          The fixer function
          */
         function splitDeclarations(declaration) {
diff --git a/lib/rules/quotes.js b/lib/rules/quotes.js
index e0db17fcb..c3c077822 100644
--- a/lib/rules/quotes.js
+++ b/lib/rules/quotes.js
@@ -228,6 +228,34 @@ module.exports = {
             }
         }
 
+        /**
+         * Checks whether or not a given TemplateLiteral node is actually using any of the special features provided by template literal strings.
+         * @param {ASTNode} node - A TemplateLiteral node to check.
+         * @returns {boolean} Whether or not the TemplateLiteral node is using any of the special features provided by template literal strings.
+         * @private
+         */
+        function isUsingFeatureOfTemplateLiteral(node) {
+            const hasTag = node.parent.type === "TaggedTemplateExpression" && node === node.parent.quasi;
+
+            if (hasTag) {
+                return true;
+            }
+
+            const hasStringInterpolation = node.expressions.length > 0;
+
+            if (hasStringInterpolation) {
+                return true;
+            }
+
+            const isMultilineString = node.quasis.length >= 1 && UNESCAPED_LINEBREAK_PATTERN.test(node.quasis[0].value.raw);
+
+            if (isMultilineString) {
+                return true;
+            }
+
+            return false;
+        }
+
         return {
 
             Literal(node) {
@@ -260,39 +288,34 @@ module.exports = {
 
             TemplateLiteral(node) {
 
-                // If backticks are expected or it's a tagged template, then this shouldn't throw an errors
+                // Don't throw an error if backticks are expected or a template literal feature is in use.
                 if (
                     allowTemplateLiterals ||
                     quoteOption === "backtick" ||
-                    node.parent.type === "TaggedTemplateExpression" && node === node.parent.quasi
+                    isUsingFeatureOfTemplateLiteral(node)
                 ) {
                     return;
                 }
 
-                // A warning should be produced if the template literal only has one TemplateElement, and has no unescaped newlines.
-                const shouldWarn = node.quasis.length === 1 && !UNESCAPED_LINEBREAK_PATTERN.test(node.quasis[0].value.raw);
-
-                if (shouldWarn) {
-                    context.report({
-                        node,
-                        message: "Strings must use {{description}}.",
-                        data: {
-                            description: settings.description
-                        },
-                        fix(fixer) {
-                            if (isPartOfDirectivePrologue(node)) {
-
-                                /*
-                                 * TemplateLiterals in a directive prologue aren't actually directives, but if they're
-                                 * in the directive prologue, then fixing them might turn them into directives and change
-                                 * the behavior of the code.
-                                 */
-                                return null;
-                            }
-                            return fixer.replaceText(node, settings.convert(sourceCode.getText(node)));
+                context.report({
+                    node,
+                    message: "Strings must use {{description}}.",
+                    data: {
+                        description: settings.description
+                    },
+                    fix(fixer) {
+                        if (isPartOfDirectivePrologue(node)) {
+
+                            /*
+                             * TemplateLiterals in a directive prologue aren't actually directives, but if they're
+                             * in the directive prologue, then fixing them might turn them into directives and change
+                             * the behavior of the code.
+                             */
+                            return null;
                         }
-                    });
-                }
+                        return fixer.replaceText(node, settings.convert(sourceCode.getText(node)));
+                    }
+                });
             }
         };
 
diff --git a/lib/rules/require-jsdoc.js b/lib/rules/require-jsdoc.js
index 949314993..389bfb692 100644
--- a/lib/rules/require-jsdoc.js
+++ b/lib/rules/require-jsdoc.js
@@ -43,7 +43,10 @@ module.exports = {
                 },
                 additionalProperties: false
             }
-        ]
+        ],
+
+        deprecated: true,
+        replacedBy: []
     },
 
     create(context) {
diff --git a/lib/rules/space-in-parens.js b/lib/rules/space-in-parens.js
index 88f4f0b50..306866263 100644
--- a/lib/rules/space-in-parens.js
+++ b/lib/rules/space-in-parens.js
@@ -61,7 +61,6 @@ module.exports = {
 
         /**
          * Produces an object with the opener and closer exception values
-         * @param {Object} opts The exception options
          * @returns {Object} `openers` and `closers` exception values
          * @private
          */
diff --git a/lib/rules/valid-jsdoc.js b/lib/rules/valid-jsdoc.js
index b434491bf..b40a20f6b 100644
--- a/lib/rules/valid-jsdoc.js
+++ b/lib/rules/valid-jsdoc.js
@@ -64,7 +64,10 @@ module.exports = {
             }
         ],
 
-        fixable: "code"
+        fixable: "code",
+
+        deprecated: true,
+        replacedBy: []
     },
 
     create(context) {
diff --git a/lib/util/config-comment-parser.js b/lib/util/config-comment-parser.js
new file mode 100644
index 000000000..88504caf1
--- /dev/null
+++ b/lib/util/config-comment-parser.js
@@ -0,0 +1,144 @@
+/**
+ * @fileoverview Config Comment Parser
+ * @author Nicholas C. Zakas
+ */
+
+/* eslint-disable class-methods-use-this*/
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const levn = require("levn"),
+    ConfigOps = require("../config/config-ops");
+
+const debug = require("debug")("eslint:config-comment-parser");
+
+//------------------------------------------------------------------------------
+// Public Interface
+//------------------------------------------------------------------------------
+
+/**
+ * Object to parse ESLint configuration comments inside JavaScript files.
+ * @name ConfigCommentParser
+ */
+module.exports = class ConfigCommentParser {
+
+    /**
+     * Parses a list of "name:boolean_value" or/and "name" options divided by comma or
+     * whitespace. Used for "global" and "exported" comments.
+     * @param {string} string The string to parse.
+     * @param {Comment} comment The comment node which has the string.
+     * @returns {Object} Result map object of names and boolean values
+     */
+    parseBooleanConfig(string, comment) {
+        debug("Parsing Boolean config");
+
+        const items = {};
+
+        // Collapse whitespace around `:` and `,` to make parsing easier
+        const trimmedString = string.replace(/\s*([:,])\s*/g, "$1");
+
+        trimmedString.split(/\s|,+/).forEach(name => {
+            if (!name) {
+                return;
+            }
+
+            // value defaults to "false" (if not provided), e.g: "foo" => ["foo", "false"]
+            const [key, value = "false"] = name.split(":");
+
+            items[key] = {
+                value: value === "true",
+                comment
+            };
+        });
+        return items;
+    }
+
+    /**
+     * Parses a JSON-like config.
+     * @param {string} string The string to parse.
+     * @param {Object} location Start line and column of comments for potential error message.
+     * @returns {({success: true, config: Object}|{success: false, error: Problem})} Result map object
+     */
+    parseJsonConfig(string, location) {
+        debug("Parsing JSON config");
+
+        let items = {};
+
+        // Parses a JSON-like comment by the same way as parsing CLI option.
+        try {
+            items = levn.parse("Object", string) || {};
+
+            // Some tests say that it should ignore invalid comments such as `/*eslint no-alert:abc*/`.
+            // Also, commaless notations have invalid severity:
+            //     "no-alert: 2 no-console: 2" --> {"no-alert": "2 no-console: 2"}
+            // Should ignore that case as well.
+            if (ConfigOps.isEverySeverityValid(items)) {
+                return {
+                    success: true,
+                    config: items
+                };
+            }
+        } catch (ex) {
+
+            debug("Levn parsing failed; falling back to manual parsing.");
+
+            // ignore to parse the string by a fallback.
+        }
+
+        /*
+         * Optionator cannot parse commaless notations.
+         * But we are supporting that. So this is a fallback for that.
+         */
+        items = {};
+        const normalizedString = string.replace(/([a-zA-Z0-9\-/]+):/g, "\"$1\":").replace(/(]|[0-9])\s+(?=")/, "$1,");
+
+        try {
+            items = JSON.parse(`{${normalizedString}}`);
+        } catch (ex) {
+            debug("Manual parsing failed.");
+
+            return {
+                success: false,
+                error: {
+                    ruleId: null,
+                    fatal: true,
+                    severity: 2,
+                    message: `Failed to parse JSON from '${normalizedString}': ${ex.message}`,
+                    line: location.start.line,
+                    column: location.start.column + 1
+                }
+            };
+
+        }
+
+        return {
+            success: true,
+            config: items
+        };
+    }
+
+    /**
+     * Parses a config of values separated by comma.
+     * @param {string} string The string to parse.
+     * @returns {Object} Result map of values and true values
+     */
+    parseListConfig(string) {
+        debug("Parsing list config");
+
+        const items = {};
+
+        // Collapse whitespace around commas
+        string.replace(/\s*,\s*/g, ",").split(/,+/).forEach(name => {
+            const trimmedName = name.trim();
+
+            if (trimmedName) {
+                items[trimmedName] = true;
+            }
+        });
+        return items;
+    }
+
+};
diff --git a/lib/util/glob-utils.js b/lib/util/glob-utils.js
index a2be0f042..fd4cfa008 100644
--- a/lib/util/glob-utils.js
+++ b/lib/util/glob-utils.js
@@ -14,7 +14,7 @@ const lodash = require("lodash"),
     GlobSync = require("./glob"),
 
     pathUtils = require("./path-utils"),
-    IgnoredPaths = require("../ignored-paths");
+    IgnoredPaths = require("./ignored-paths");
 
 const debug = require("debug")("eslint:glob-utils");
 
diff --git a/lib/ignored-paths.js b/lib/util/ignored-paths.js
similarity index 98%
rename from lib/ignored-paths.js
rename to lib/util/ignored-paths.js
index 8520090af..de4a79cde 100644
--- a/lib/ignored-paths.js
+++ b/lib/util/ignored-paths.js
@@ -12,7 +12,7 @@
 const fs = require("fs"),
     path = require("path"),
     ignore = require("ignore"),
-    pathUtils = require("./util/path-utils");
+    pathUtils = require("./path-utils");
 
 const debug = require("debug")("eslint:ignored-paths");
 
@@ -296,7 +296,7 @@ class IgnoredPaths {
     /**
      * read ignore filepath
      * @param {string} filePath, file to add to ig
-     * @returns {array} raw ignore rules
+     * @returns {Array} raw ignore rules
      */
     readIgnoreFile(filePath) {
         if (typeof this.cache[filePath] === "undefined") {
@@ -307,8 +307,8 @@ class IgnoredPaths {
 
     /**
      * add ignore file to node-ignore instance
-     * @param {Object} ig, instance of node-ignore
-     * @param {string} filePath, file to add to ig
+     * @param {Object} ig instance of node-ignore
+     * @param {string} filePath file to add to ig
      * @returns {void}
      */
     addIgnoreFile(ig, filePath) {
diff --git a/lib/report-translator.js b/lib/util/report-translator.js
similarity index 99%
rename from lib/report-translator.js
rename to lib/util/report-translator.js
index f82830586..3dfdca0e4 100644
--- a/lib/report-translator.js
+++ b/lib/util/report-translator.js
@@ -10,8 +10,8 @@
 //------------------------------------------------------------------------------
 
 const assert = require("assert");
-const ruleFixer = require("./util/rule-fixer");
-const interpolate = require("./util/interpolate");
+const ruleFixer = require("./rule-fixer");
+const interpolate = require("./interpolate");
 
 //------------------------------------------------------------------------------
 // Typedefs
diff --git a/lib/util/source-code.js b/lib/util/source-code.js
index dd45f6112..4e90ac1aa 100644
--- a/lib/util/source-code.js
+++ b/lib/util/source-code.js
@@ -87,7 +87,7 @@ class SourceCode extends TokenStore {
      * @param {string|Object} textOrConfig - The source code text or config object.
      * @param {string} textOrConfig.text - The source code text.
      * @param {ASTNode} textOrConfig.ast - The Program node of the AST representing the code. This AST should be created from the text that BOM was stripped.
-     * @param {Object|null} textOrConfig.parserServices - The parser srevices.
+     * @param {Object|null} textOrConfig.parserServices - The parser services.
      * @param {ScopeManager|null} textOrConfig.scopeManager - The scope of this source code.
      * @param {Object|null} textOrConfig.visitorKeys - The visitor keys to traverse AST.
      * @param {ASTNode} [astIfNoConfig] - The Program node of the AST representing the code. This AST should be created from the text that BOM was stripped.
@@ -316,6 +316,7 @@ class SourceCode extends TokenStore {
      * @returns {Token|null} The Block comment token containing the JSDoc comment
      *      for the given node or null if not found.
      * @public
+     * @deprecated
      */
     getJSDocComment(node) {
 
diff --git a/messages/all-files-ignored.txt b/messages/all-files-ignored.txt
index 3b741a03e..3f4c8ced4 100644
--- a/messages/all-files-ignored.txt
+++ b/messages/all-files-ignored.txt
@@ -1,4 +1,4 @@
-All of the files matching the glob pattern "<%= pattern %>" are ignored.
+You are linting "<%= pattern %>", but all of the files matching the glob pattern "<%= pattern %>" are ignored.
 
 If you don't want to lint these files, remove the pattern "<%= pattern %>" from the list of arguments passed to ESLint.
 
diff --git a/package.json b/package.json
index c64318d0b..441828725 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": "^4.0.0",
+    "espree": "^5.0.0",
     "esquery": "^1.0.1",
     "esutils": "^2.0.2",
     "file-entry-cache": "^2.0.0",
@@ -54,7 +54,6 @@
     "ignore": "^4.0.6",
     "imurmurhash": "^0.1.4",
     "inquirer": "^6.1.0",
-    "is-resolvable": "^1.1.0",
     "js-yaml": "^3.12.0",
     "json-stable-stringify-without-jsonify": "^1.0.1",
     "levn": "^0.3.0",
diff --git a/packages/eslint-config-eslint/default.yml b/packages/eslint-config-eslint/default.yml
index 30444d640..42ce7b1ec 100644
--- a/packages/eslint-config-eslint/default.yml
+++ b/packages/eslint-config-eslint/default.yml
@@ -181,6 +181,7 @@ rules:
             "String": "string",
             "Number": "number",
             "Boolean": "boolean",
+            "array": "Array",
             "object": "Object",
             "function": "Function"
         }


Test patch:
diff --git a/tests/lib/cli-engine.js b/tests/lib/cli-engine.js
index d5b0b3728..9a57e86df 100644
--- a/tests/lib/cli-engine.js
+++ b/tests/lib/cli-engine.js
@@ -733,6 +733,7 @@ describe("CLIEngine", () => {
         it("should warn when deprecated rules are found in a config", () => {
             engine = new CLIEngine({
                 cwd: originalDir,
+                useEslintrc: false,
                 configFile: "tests/fixtures/cli-engine/deprecated-rule-config/.eslintrc.yml"
             });
 
@@ -1530,7 +1531,11 @@ describe("CLIEngine", () => {
 
             assert.deepStrictEqual(
                 report.usedDeprecatedRules,
-                [{ ruleId: "indent-legacy", replacedBy: ["indent"] }]
+                [
+                    { ruleId: "indent-legacy", replacedBy: ["indent"] },
+                    { ruleId: "require-jsdoc", replacedBy: [] },
+                    { ruleId: "valid-jsdoc", replacedBy: [] }
+                ]
             );
         });
 
@@ -1538,7 +1543,7 @@ describe("CLIEngine", () => {
             engine = new CLIEngine({
                 cwd: originalDir,
                 configFile: ".eslintrc.js",
-                rules: { indent: 1 }
+                rules: { indent: 1, "valid-jsdoc": 0, "require-jsdoc": 0 }
             });
 
             const report = engine.executeOnFiles(["lib/cli*.js"]);
@@ -1549,7 +1554,8 @@ describe("CLIEngine", () => {
         it("should warn when deprecated rules are found in a config", () => {
             engine = new CLIEngine({
                 cwd: originalDir,
-                configFile: "tests/fixtures/cli-engine/deprecated-rule-config/.eslintrc.yml"
+                configFile: "tests/fixtures/cli-engine/deprecated-rule-config/.eslintrc.yml",
+                useEslintrc: false
             });
 
             const report = engine.executeOnFiles(["lib/cli*.js"]);
diff --git a/tests/lib/rules/camelcase.js b/tests/lib/rules/camelcase.js
index 3d2b7516c..d1ce3b3fd 100644
--- a/tests/lib/rules/camelcase.js
+++ b/tests/lib/rules/camelcase.js
@@ -193,6 +193,10 @@ ruleTester.run("camelcase", rule, {
         {
             code: "user_id = 0;",
             options: [{ allow: ["_id$"] }]
+        },
+        {
+            code: "__option_foo__ = 0;",
+            options: [{ allow: ["__option_foo__"] }]
         }
     ],
     invalid: [
diff --git a/tests/lib/rules/comma-style.js b/tests/lib/rules/comma-style.js
index 83a1ca2c9..a63d80ae8 100644
--- a/tests/lib/rules/comma-style.js
+++ b/tests/lib/rules/comma-style.js
@@ -612,6 +612,13 @@ ruleTester.run("comma-style", rule, {
             code: "[\n[foo(3)],\n,\nbar\n];",
             output: "[\n[foo(3)],,\nbar\n];",
             errors: [{ messageId: "unexpectedLineBeforeAndAfterComma" }]
+        },
+        {
+
+            // https://github.com/eslint/eslint/issues/10632
+            code: "[foo//\n,/*block\ncomment*/];",
+            output: "[foo,//\n/*block\ncomment*/];",
+            errors: [{ messageId: "unexpectedLineBeforeAndAfterComma" }]
         }
     ]
 });
diff --git a/tests/lib/rules/indent-legacy.js b/tests/lib/rules/indent-legacy.js
index 17a1f62a4..3e3a21684 100644
--- a/tests/lib/rules/indent-legacy.js
+++ b/tests/lib/rules/indent-legacy.js
@@ -24,7 +24,7 @@ const fixedFixture = fs.readFileSync(path.join(__dirname, "../../fixtures/rules/
 /**
  * Create error message object for failure cases with a single 'found' indentation type
  * @param {string} providedIndentType indent type of string or tab
- * @param {array} providedErrors error info
+ * @param {Array} providedErrors error info
  * @returns {Object} returns the error messages collection
  * @private
  */
diff --git a/tests/lib/rules/indent.js b/tests/lib/rules/indent.js
index b25e25949..8f20a8ea8 100644
--- a/tests/lib/rules/indent.js
+++ b/tests/lib/rules/indent.js
@@ -25,7 +25,7 @@ const parser = require("../../fixtures/fixture-parser");
 /**
  * Create error message object for failure cases with a single 'found' indentation type
  * @param {string} providedIndentType indent type of string or tab
- * @param {array} providedErrors error info
+ * @param {Array} providedErrors error info
  * @returns {Object} returns the error messages collection
  * @private
  */
@@ -271,6 +271,17 @@ ruleTester.run("indent", rule, {
             `,
             options: [4]
         },
+        {
+
+            // https://github.com/eslint/eslint/issues/11802
+            code: unIndent`
+                import foo from "foo"
+
+                ;(() => {})()
+            `,
+            options: [4],
+            parserOptions: { sourceType: "module" }
+        },
         {
             code: unIndent`
                 function test() {
diff --git a/tests/lib/rules/keyword-spacing.js b/tests/lib/rules/keyword-spacing.js
index 33a9d5068..cebd16367 100644
--- a/tests/lib/rules/keyword-spacing.js
+++ b/tests/lib/rules/keyword-spacing.js
@@ -2023,6 +2023,12 @@ ruleTester.run("keyword-spacing", rule, {
             parserOptions: { sourceType: "module" },
             errors: expectedBefore("export")
         },
+        {
+            code: "export default{a}",
+            output: "export default {a}",
+            parserOptions: { sourceType: "module" },
+            errors: expectedAfter("default")
+        },
         {
             code: "{}export* from \"a\"",
             output: "{} export * from \"a\"",
diff --git a/tests/lib/rules/no-empty-function.js b/tests/lib/rules/no-empty-function.js
index 416a47da6..21f1bdae0 100644
--- a/tests/lib/rules/no-empty-function.js
+++ b/tests/lib/rules/no-empty-function.js
@@ -31,9 +31,9 @@ const ALLOW_OPTIONS = Object.freeze([
  * Folds test items to `{valid: [], invalid: []}`.
  * One item would be converted to 4 valid patterns and 8 invalid patterns.
  *
- * @param {{valid: object[], invalid: object[]}} patterns - The result.
+ * @param {{valid: Object[], invalid: Object[]}} patterns - The result.
  * @param {{code: string, message: string, allow: string}} item - A test item.
- * @returns {{valid: object[], invalid: object[]}} The result.
+ * @returns {{valid: Object[], invalid: Object[]}} The result.
  */
 function toValidInvalid(patterns, item) {
 
diff --git a/tests/lib/util/config-comment-parser.js b/tests/lib/util/config-comment-parser.js
new file mode 100644
index 000000000..6dbe9381a
--- /dev/null
+++ b/tests/lib/util/config-comment-parser.js
@@ -0,0 +1,229 @@
+/**
+ * @fileoverview Tests for ConfigCommentParser object.
+ * @author Nicholas C. Zakas
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const assert = require("chai").assert,
+    ConfigCommentParser = require("../../../lib/util/config-comment-parser");
+
+//------------------------------------------------------------------------------
+// Tests
+//------------------------------------------------------------------------------
+
+describe("ConfigCommentParser", () => {
+
+    let commentParser;
+    const location = {
+        start: {
+            line: 1,
+            column: 0
+        }
+    };
+
+    beforeEach(() => {
+        commentParser = new ConfigCommentParser();
+    });
+
+    describe("parseJsonConfig", () => {
+
+        it("should parse JSON config with one item", () => {
+            const code = "no-alert:0";
+            const result = commentParser.parseJsonConfig(code, location);
+
+
+            assert.deepStrictEqual(result, {
+                success: true,
+                config: {
+                    "no-alert": 0
+                }
+            });
+        });
+
+        it("should parse JSON config with two items", () => {
+            const code = "no-alert:0 semi: 2";
+            const result = commentParser.parseJsonConfig(code, location);
+
+
+            assert.deepStrictEqual(result, {
+                success: true,
+                config: {
+                    "no-alert": 0,
+                    semi: 2
+                }
+            });
+        });
+
+        it("should parse JSON config with two comma-separated items", () => {
+            const code = "no-alert:0,semi: 2";
+            const result = commentParser.parseJsonConfig(code, location);
+
+
+            assert.deepStrictEqual(result, {
+                success: true,
+                config: {
+                    "no-alert": 0,
+                    semi: 2
+                }
+            });
+        });
+
+        it("should parse JSON config with two items and a string severity", () => {
+            const code = "no-alert:off,semi: 2";
+            const result = commentParser.parseJsonConfig(code, location);
+
+
+            assert.deepStrictEqual(result, {
+                success: true,
+                config: {
+                    "no-alert": "off",
+                    semi: 2
+                }
+            });
+        });
+
+        it("should parse JSON config with two items and options", () => {
+            const code = "no-alert:off, semi: [2, always]";
+            const result = commentParser.parseJsonConfig(code, location);
+
+
+            assert.deepStrictEqual(result, {
+                success: true,
+                config: {
+                    "no-alert": "off",
+                    semi: [2, "always"]
+                }
+            });
+        });
+
+        it("should parse JSON config with two items and options from plugins", () => {
+            const code = "plugin/no-alert:off, plugin/semi: [2, always]";
+            const result = commentParser.parseJsonConfig(code, location);
+
+            assert.deepStrictEqual(result, {
+                success: true,
+                config: {
+                    "plugin/no-alert": "off",
+                    "plugin/semi": [2, "always"]
+                }
+            });
+        });
+
+
+    });
+
+    describe("parseBooleanConfig", () => {
+
+        const comment = {};
+
+        it("should parse Boolean config with one item", () => {
+            const code = "a: true";
+            const result = commentParser.parseBooleanConfig(code, comment);
+
+            assert.deepStrictEqual(result, {
+                a: {
+                    value: true,
+                    comment
+                }
+            });
+        });
+
+        it("should parse Boolean config with one item and no value", () => {
+            const code = "a";
+            const result = commentParser.parseBooleanConfig(code, comment);
+
+            assert.deepStrictEqual(result, {
+                a: {
+                    value: false,
+                    comment
+                }
+            });
+        });
+
+        it("should parse Boolean config with two items", () => {
+            const code = "a: true b:false";
+            const result = commentParser.parseBooleanConfig(code, comment);
+
+            assert.deepStrictEqual(result, {
+                a: {
+                    value: true,
+                    comment
+                },
+                b: {
+                    value: false,
+                    comment
+                }
+            });
+        });
+
+        it("should parse Boolean config with two comma-separated items", () => {
+            const code = "a: true, b:false";
+            const result = commentParser.parseBooleanConfig(code, comment);
+
+            assert.deepStrictEqual(result, {
+                a: {
+                    value: true,
+                    comment
+                },
+                b: {
+                    value: false,
+                    comment
+                }
+            });
+        });
+
+        it("should parse Boolean config with two comma-separated items and no values", () => {
+            const code = "a , b";
+            const result = commentParser.parseBooleanConfig(code, comment);
+
+            assert.deepStrictEqual(result, {
+                a: {
+                    value: false,
+                    comment
+                },
+                b: {
+                    value: false,
+                    comment
+                }
+            });
+        });
+    });
+
+    describe("parseListConfig", () => {
+
+        it("should parse list config with one item", () => {
+            const code = "a";
+            const result = commentParser.parseListConfig(code);
+
+            assert.deepStrictEqual(result, {
+                a: true
+            });
+        });
+
+        it("should parse list config with two items", () => {
+            const code = "a, b";
+            const result = commentParser.parseListConfig(code);
+
+            assert.deepStrictEqual(result, {
+                a: true,
+                b: true
+            });
+        });
+
+        it("should parse list config with two items and exta whitespace", () => {
+            const code = "  a , b  ";
+            const result = commentParser.parseListConfig(code);
+
+            assert.deepStrictEqual(result, {
+                a: true,
+                b: true
+            });
+        });
+    });
+
+});
diff --git a/tests/lib/ignored-paths.js b/tests/lib/util/ignored-paths.js
similarity index 99%
rename from tests/lib/ignored-paths.js
rename to tests/lib/util/ignored-paths.js
index b03314e61..acf007b18 100644
--- a/tests/lib/ignored-paths.js
+++ b/tests/lib/util/ignored-paths.js
@@ -12,7 +12,7 @@
 const assert = require("chai").assert,
     path = require("path"),
     os = require("os"),
-    IgnoredPaths = require("../../lib/ignored-paths.js"),
+    IgnoredPaths = require("../../../lib/util/ignored-paths.js"),
     sinon = require("sinon"),
     fs = require("fs"),
     includes = require("lodash").includes;
@@ -29,7 +29,7 @@ let fixtureDir;
 
 /**
  * get raw rules from IgnorePaths instance
- * @param {IgnoredPaths} ignoredPaths, instance of IgnoredPaths
+ * @param {IgnoredPaths} ignoredPaths instance of IgnoredPaths
  * @returns {string[]} raw ignore rules
  */
 function getIgnoreRules(ignoredPaths) {
@@ -78,7 +78,7 @@ function getIgnorePatterns(ignoredPaths) {
 
 /**
  * count the number of default patterns applied to IgnoredPaths instance
- * @param {IgnoredPaths} ignoredPaths, instance of IgnoredPaths
+ * @param {IgnoredPaths} ignoredPaths instance of IgnoredPaths
  * @returns {integer} count of default patterns
  */
 function countDefaultPatterns(ignoredPaths) {
diff --git a/tests/lib/util/npm-utils.js b/tests/lib/util/npm-utils.js
index 1b07f3715..5c8e4cc84 100644
--- a/tests/lib/util/npm-utils.js
+++ b/tests/lib/util/npm-utils.js
@@ -162,8 +162,15 @@ describe("npmUtils", () => {
         });
 
         it("should return false if package.json does not exist", () => {
-            mockFs({});
-            assert.strictEqual(npmUtils.checkPackageJson(), false);
+
+            /*
+             * Checking local file system directly, which does not
+             * contains package.json. This is necessary because mock-fs
+             * doesn't work in Node.js 11: it throws an error when
+             * a file is missing rather than returning false.
+             * TODO: Find a replacement for mock-fs that works in Node 11.
+             */
+            assert.strictEqual(npmUtils.checkPackageJson("/"), false);
         });
     });
 
diff --git a/tests/lib/report-translator.js b/tests/lib/util/report-translator.js
similarity index 99%
rename from tests/lib/report-translator.js
rename to tests/lib/util/report-translator.js
index e009e4e82..cd600934d 100644
--- a/tests/lib/report-translator.js
+++ b/tests/lib/util/report-translator.js
@@ -9,9 +9,9 @@
 //------------------------------------------------------------------------------
 
 const assert = require("chai").assert;
-const SourceCode = require("../../lib/util/source-code");
+const SourceCode = require("../../../lib/util/source-code");
 const espree = require("espree");
-const createReportTranslator = require("../../lib/report-translator");
+const createReportTranslator = require("../../../lib/util/report-translator");
 
 //------------------------------------------------------------------------------
 // Tests