Repository: eslint/eslint
Pull request #12613 (2019-11-27 22:15:41)

Update: no-void add an option to allow void as a statement
<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

**What is the purpose of this pull request?**
Changes an existing rule

<!--
    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.)
-->

**What rule do you want to change?**
`no-void`

**Does this change cause the rule to produce more or fewer warnings?**
Fewer, when the option is turned on

**How will the change be implemented? (New option, new default behavior, etc.)?**
New option

**Please provide some example code that this change will affect:**
Code that will now be valid, when the option is turned on:
```js
/*eslint no-void: ["error", { "allowAsStatement": true }]*/

void foo;
void someFunction();
```

**What does the rule currently do for this code?**
Errors for all `void` operator usage, regardless of context

**What will the rule do after it's changed?**
When the option is on, it will allow the `void` when used as a statement.

**Why?**
A common usage pattern I've seen out in the world is to use the `void` operator to mark promises as "consumed" without awaiting them.
I.e. it's a way for users to say "I am intentionally not awaiting this promise".

```ts
async function returnsPromise(): Promise<void> {}

void returnsPromise();
```

This pattern works well with our rule [`@typescript-eslint/no-floating-promises`](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-floating-promises.md), which would otherwise error on the above promise if the `void` operator was omitted.

Feel free to push back, we could potentially extend this rule within `@typescript-eslint`, and make it type aware to only allow it for thenable values, but I thought I'd see if you guys thought there was value in this before forking.


Patch:
diff --git a/.azure-pipelines/job.yml b/.azure-pipelines/job.yml
deleted file mode 100644
index 2f8a55373..000000000
--- a/.azure-pipelines/job.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-parameters:
-  name: ""
-  displayName: ""
-  vmImage: ""
-  nodeVersion: ""
-
-jobs:
-  - job: ${{parameters.name}}
-    displayName: ${{parameters.displayName}}
-    pool:
-      vmImage: ${{parameters.vmImage}}
-    steps:
-      - task: NodeTool@0
-        displayName: Install Node.js
-        inputs:
-          versionSpec: ${{parameters.nodeVersion}}
-
-      - script: npm install
-        displayName: Install Packages
-
-      - script: npm test
-        displayName: Test
-
-      - task: PublishTestResults@2
-        displayName: Process Test Results
-        condition: succeededOrFailed()
-        inputs:
-          testRunner: JUnit
-          testResultsFiles: $(System.DefaultWorkingDirectory)/test-results.xml
-
-      - task: PublishCodeCoverageResults@1
-        displayName: Process Coverage Results
-        condition: succeededOrFailed()
-        inputs: 
-          codeCoverageTool: Cobertura
-          summaryFileLocation: $(System.DefaultWorkingDirectory)/coverage/cobertura-coverage.xml
-          reportDirectory: $(System.DefaultWorkingDirectory)/coverage
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d46edfd5d..645258a56 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,42 @@
+v6.8.0 - December 20, 2019
+
+* [`c5c7086`](https://github.com/eslint/eslint/commit/c5c708666b450fb69522a55aa375626f9297dc6f) Fix: ignore aligning single line in key-spacing (fixes #11414) (#12652) (YeonJuan)
+* [`9986d9e`](https://github.com/eslint/eslint/commit/9986d9e0baed0d3586bbee472fe2fae2ed625f5d) Chore: add object option test cases in yield-star-spacing (#12679) (YeonJuan)
+* [`1713d07`](https://github.com/eslint/eslint/commit/1713d0758b083f3840d724505f997a7cb20ff384) New: Add no-error-on-unmatched-pattern flag (fixes #10587) (#12377) (ncraley)
+* [`5c25a26`](https://github.com/eslint/eslint/commit/5c25a26608fbd9a1d0127c9a3653609aa4b63e86) Update: autofix bug in lines-between-class-members (fixes #12391) (#12632) (YeonJuan)
+* [`4b3cc5c`](https://github.com/eslint/eslint/commit/4b3cc5cd2459f04eae149faea0651785d7f9db0b) Chore: enable prefer-regex-literals in eslint codebase (#12268) (薛定谔的猫)
+* [`05faebb`](https://github.com/eslint/eslint/commit/05faebb943456ad2b20117f3c8b3eccbe2e2fb03) Update: improve suggestion testing experience (#12602) (Brad Zacher)
+* [`05f7dd5`](https://github.com/eslint/eslint/commit/05f7dd53ed91a6e3be9eb40825fb6d2207f82209) Update: Add suggestions for no-unsafe-negation (fixes #12591) (#12609) (Milos Djermanovic)
+* [`d3e43f1`](https://github.com/eslint/eslint/commit/d3e43f1c10c5e19f40e7b3d3944b87f1b0c9c075) Docs: Update no-multi-assign explanation (#12615) (Yuping Zuo)
+* [`272e4db`](https://github.com/eslint/eslint/commit/272e4db6074283bc01cc6ec72c9e396bb3c110e6) Fix: no-multiple-empty-lines: Adjust reported `loc` (#12594) (Tobias Bieniek)
+* [`a258039`](https://github.com/eslint/eslint/commit/a258039e556075d7d1f955a79d094ea103ec165a) Fix: no-restricted-imports schema allows multiple paths/patterns objects (#12639) (Milos Djermanovic)
+* [`51f9620`](https://github.com/eslint/eslint/commit/51f9620cc55cc091fe38dbe68e4633de06297b8c) Fix: improve report location for array-bracket-spacing (#12653) (Milos Djermanovic)
+* [`45364af`](https://github.com/eslint/eslint/commit/45364afc9c7f0251348cd1a7a13656c3816435d7) Fix: prefer-numeric-literals doesn't check types of literal arguments (#12655) (Milos Djermanovic)
+* [`e3c570e`](https://github.com/eslint/eslint/commit/e3c570eaf3d1d44fb57bf42f1870887856e4c5a0) Docs: Add example for expression option (#12694) (Arnaud Barré)
+* [`6b774ef`](https://github.com/eslint/eslint/commit/6b774ef0d849ccf5c1127b25e1fe7c3e438d586b) Docs: Add spacing in comments for no-console rule (#12696) (Nikki Nikkhoui)
+* [`7171fca`](https://github.com/eslint/eslint/commit/7171fca6ef4e0e8f267658fc7d8f603f00eddd84) Chore: refactor regex in config comment parser (#12662) (Milos Djermanovic)
+* [`1600648`](https://github.com/eslint/eslint/commit/1600648d2880ffb1e9e414b31ff0f66ead7167f9) Update: Allow $schema in config (#12612) (Yordis Prieto)
+* [`acc0e47`](https://github.com/eslint/eslint/commit/acc0e47572a9390292b4e313b4a4bf360d236358) Update: support .eslintrc.cjs (refs eslint/rfcs#43) (#12321) (Evan Plaice)
+* [`49c1658`](https://github.com/eslint/eslint/commit/49c1658544ace24b9aaaa301af0fc07a2ef3bf30) Chore: remove bundling of ESLint during release (#12676) (Kai Cataldo)
+* [`257f3d6`](https://github.com/eslint/eslint/commit/257f3d67905a52bf8602a5a5707c893cc90d7ca7) Chore: complete to move to GitHub Actions (#12625) (Toru Nagashima)
+* [`ab912f0`](https://github.com/eslint/eslint/commit/ab912f0ef709a916ab9a27ea09d9d7adf046fb2d) Docs: 1tbs with allowSingleLine edge cases (refs #12284) (#12314) (Ari Kardasis)
+* [`dd1c30e`](https://github.com/eslint/eslint/commit/dd1c30e35f05ed332e2abbd3d4d53635efde74b8) Sponsors: Sync README with website (ESLint Jenkins)
+* [`a230f84`](https://github.com/eslint/eslint/commit/a230f8404e4f2423dd79378b065d24c12776775b) Update: include node version in cache (#12582) (Eric Wang)
+* [`8b65f17`](https://github.com/eslint/eslint/commit/8b65f175dfb4fac11ed7184537be400ed14996fb) Chore: remove references to parser demo (#12644) (Kai Cataldo)
+* [`e9cef99`](https://github.com/eslint/eslint/commit/e9cef99e6ebec1faefdb576ca597e81ae4f04afd) Docs: wrap {{}} in raw liquid tags to prevent interpolation (#12643) (Kai Cataldo)
+* [`e707453`](https://github.com/eslint/eslint/commit/e70745325ff9e085acc6843dd8bfae5550645d4f) Docs: Fix configuration example in no-restricted-imports (fixes #11717) (#12638) (Milos Djermanovic)
+* [`19194ce`](https://github.com/eslint/eslint/commit/19194cec724e016df02376bbeae31171be6f0bdf) Chore: Add tests to cover default object options in comma-dangle (#12627) (YeonJuan)
+* [`6e36d12`](https://github.com/eslint/eslint/commit/6e36d12d95e76022172fd0ec8a5e85c22fde6a8a) Update: do not recommend require-atomic-updates (refs #11899) (#12599) (Kai Cataldo)
+
+v6.7.2 - November 30, 2019
+
+* [`bc435a9`](https://github.com/eslint/eslint/commit/bc435a93afd6ba4def1b53993ef7cf8220f3f070) Fix: isSpaceBetweenTokens() recognizes spaces in JSXText (fixes #12614) (#12616) (Toru Nagashima)
+* [`4928d51`](https://github.com/eslint/eslint/commit/4928d513b4fe716c7ed958c294a10ef8517be25e) Fix: don't ignore the entry directory (fixes #12604) (#12607) (Toru Nagashima)
+* [`b41677a`](https://github.com/eslint/eslint/commit/b41677ae2a143790b19b0e70391a46ec6c8f5de1) Docs: Clarify suggestion's data in Working with Rules (refs #12606) (#12617) (Milos Djermanovic)
+* [`ea16de4`](https://github.com/eslint/eslint/commit/ea16de4e7c6f661398b0b7843f95e5f307c89551) Fix: Support tagged template literal generics in no-unexpected-multiline (#11698) (Brad Zacher)
+* [`fa6415d`](https://github.com/eslint/eslint/commit/fa6415d5b877370374a6a530a5190ab5a411b4dc) Sponsors: Sync README with website (ESLint Jenkins)
+* [`e1e158b`](https://github.com/eslint/eslint/commit/e1e158b4d7bd61e812723b378d2c391295da43a5) Sponsors: Sync README with website (ESLint Jenkins)
+
 v6.7.1 - November 24, 2019
 
 * [`dd1e9f4`](https://github.com/eslint/eslint/commit/dd1e9f4df2103c43509a54b0ad5f9106557997f9) Fix: revert changes to key-spacing due to regression (#12598) (Kai Cataldo)
diff --git a/Makefile.js b/Makefile.js
index 1b241c1ae..2dc8547f3 100644
--- a/Makefile.js
+++ b/Makefile.js
@@ -560,7 +560,7 @@ target.mocha = () => {
 target.karma = () => {
     echo("Running unit tests on browsers");
 
-    target.webpack();
+    target.webpack("production");
 
     const browserFileLintOutput = new CLIEngine({
         useEslintrc: false,
@@ -775,17 +775,7 @@ target.gensite = function(prereleaseVersion) {
     echo("> Removing the temporary directory (Step 12)");
     rm("-rf", TEMP_DIR);
 
-    // 13. Update demos, but only for non-prereleases
-    if (!prereleaseVersion) {
-        echo("> Updating the demos (Step 13)");
-        target.webpack("production");
-        cp("-f", "build/eslint.js", `${SITE_DIR}src/js/eslint.js`);
-        cp("-f", "build/espree.js", `${SITE_DIR}src/js/espree.js`);
-    } else {
-        echo("> Skipped updating the demos (Step 13)");
-    }
-
-    // 14. Create Example Formatter Output Page
+    // 13. Create Example Formatter Output Page
     echo("> Creating the formatter examples (Step 14)");
     generateFormatterExamples(getFormatterResults(), prereleaseVersion);
 
diff --git a/README.md b/README.md
index 0e574e5b2..0cde09fc6 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,4 @@
 [![NPM version][npm-image]][npm-url]
-[![Build Status](https://dev.azure.com/eslint/eslint/_apis/build/status/eslint.eslint?branchName=master)](https://dev.azure.com/eslint/eslint/_build/latest?definitionId=1&branchName=master)
 [![Build Status](https://github.com/eslint/eslint/workflows/CI/badge.svg)](https://github.com/eslint/eslint/actions)
 [![Downloads][downloads-image]][downloads-url]
 [![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=282608)](https://www.bountysource.com/trackers/282608-eslint?utm_source=282608&utm_medium=shield&utm_campaign=TRACKER_BADGE)
@@ -265,7 +264,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
 <h3>Gold Sponsors</h3>
 <p><a href="https://www.shopify.com"><img src="https://images.opencollective.com/shopify/eeb91aa/logo.png" alt="Shopify" height="96"></a> <a href="http://engineering.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://badoo.com/team?utm_source=eslint"><img src="https://images.opencollective.com/badoo/2826a3b/logo.png" alt="Badoo" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a> <a href="https://opensource.facebook.com"><img src="https://images.opencollective.com/fbopensource/fbb8a5b/logo.png" alt="Facebook Open Source" height="96"></a></p><h3>Silver Sponsors</h3>
 <p><a href="https://www.ampproject.org/"><img src="https://images.opencollective.com/amp/c8a3b25/logo.png" alt="AMP Project" height="64"></a></p><h3>Bronze Sponsors</h3>
-<p><a href="https://uxplanet.org/top-ui-ux-design-agencies-user-experience-firms-8c54697e290"><img src="https://images.opencollective.com/ui-ux-design-agencies/cae5dfe/logo.png" alt="UI UX Design Agencies" height="32"></a> <a href="https://edubirdie.com/"><img src="https://images.opencollective.com/edubirdie2/b1d51ab/logo.png" alt="EduBirdie" height="32"></a> <a href="https://www.crosswordsolver.com"><img src="https://images.opencollective.com/crosswordsolver/d4481d6/logo.png" alt="Crosswordsolver" height="32"></a> <a href="https://www.codacy.com/?utm_source=eslint&utm_medium=cpm&utm_campaign=eslint-sponsorship"><img src="https://images.opencollective.com/codacy/ed22716/logo.png" alt="Codacy" height="32"></a> <a href="https://mixpanel.com"><img src="https://images.opencollective.com/mixpanel/cd682f7/logo.png" alt="Mixpanel" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/0b37d14/logo.png" alt="Free Icons by Icons8" height="32"></a> <a href="https://www.bugsnag.com/platforms?utm_source=Open Collective&utm_medium=Website&utm_content=open-source&utm_campaign=2019-community&utm_term="><img src="https://images.opencollective.com/bugsnag-stability-monitoring/c2cef36/logo.png" alt="Bugsnag Stability Monitoring" height="32"></a> <a href="https://clay.global"><img src="https://images.opencollective.com/clayglobal/2468f34/logo.png" alt="clay" height="32"></a> <a href="https://discordapp.com"><img src="https://images.opencollective.com/discordapp/7e3d9a9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://tekhattan.com"><img src="https://images.opencollective.com/tekhattan/bc73c28/logo.png" alt="TekHattan" height="32"></a> <a href="https://www.marfeel.com/"><img src="https://images.opencollective.com/marfeel/4b88e30/logo.png" alt="Marfeel" height="32"></a> <a href="http://www.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a> <a href="https://jsheroes.io/"><img src="https://images.opencollective.com/jsheroes1/9fedf0b/logo.png" alt="JSHeroes " height="32"></a></p>
+<p><a href="https://uxplanet.org/top-ui-ux-design-agencies-user-experience-firms-8c54697e290"><img src="https://images.opencollective.com/ui-ux-design-agencies/cae5dfe/logo.png" alt="UI UX Design Agencies" height="32"></a> <a href="https://medium.com/@niksundin/best-web-design-companies-1872e445775f"><img src="https://images.opencollective.com/top-web-design-agencies/d92d747/logo.png" alt="Top Web Design Agencies" height="32"></a> <a href="https://www.bugsnag.com/platforms?utm_source=Open Collective&utm_medium=Website&utm_content=open-source&utm_campaign=2019-community&utm_term="><img src="https://images.opencollective.com/bugsnag-stability-monitoring/c2cef36/logo.png" alt="Bugsnag Stability Monitoring" height="32"></a> <a href="https://www.crosswordsolver.com"><img src="https://images.opencollective.com/crosswordsolver/d4481d6/logo.png" alt="Crosswordsolver" height="32"></a> <a href="https://www.codacy.com/?utm_source=eslint&utm_medium=cpm&utm_campaign=eslint-sponsorship"><img src="https://images.opencollective.com/codacy/ed22716/logo.png" alt="Codacy" height="32"></a> <a href="https://mixpanel.com"><img src="https://images.opencollective.com/mixpanel/cd682f7/logo.png" alt="Mixpanel" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/0b37d14/logo.png" alt="Free Icons by Icons8" height="32"></a> <a href="https://edubirdie.com/"><img src="https://images.opencollective.com/edubirdie2/b1d51ab/logo.png" alt="EduBirdie" height="32"></a> <a href="https://clay.global"><img src="https://images.opencollective.com/clayglobal/2468f34/logo.png" alt="clay" height="32"></a> <a href="https://discordapp.com"><img src="https://images.opencollective.com/discordapp/7e3d9a9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://tekhattan.com"><img src="https://images.opencollective.com/tekhattan/bc73c28/logo.png" alt="TekHattan" height="32"></a> <a href="https://www.marfeel.com/"><img src="https://images.opencollective.com/marfeel/4b88e30/logo.png" alt="Marfeel" height="32"></a> <a href="http://www.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a> <a href="https://jsheroes.io/"><img src="https://images.opencollective.com/jsheroes1/9fedf0b/logo.png" alt="JSHeroes " height="32"></a></p>
 <!--sponsorsend-->
 
 ## <a name="technology-sponsors"></a>Technology Sponsors
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
deleted file mode 100644
index 13a2f38c4..000000000
--- a/azure-pipelines.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-trigger:
-  - master
-
-jobs:
-  - template: .azure-pipelines/job.yml
-    parameters:
-      name: test_on_linux_node12
-      displayName: Test on Node.js 12 (Linux)
-      vmImage: Ubuntu-16.04
-      nodeVersion: 12.x
-
-  - template: .azure-pipelines/job.yml
-    parameters:
-      name: test_on_linux_node10
-      displayName: Test on Node.js 10 (Linux)
-      vmImage: Ubuntu-16.04
-      nodeVersion: 10.x
-
-  - template: .azure-pipelines/job.yml
-    parameters:
-      name: test_on_linux_node8
-      displayName: Test on Node.js 8 (Linux)
-      vmImage: Ubuntu-16.04
-      nodeVersion: 8.x
-
-  - template: .azure-pipelines/job.yml
-    parameters:
-      name: test_on_windows_node12
-      displayName: Test on Node.js 12 (Windows)
-      vmImage: Windows-2019
-      nodeVersion: 12.x
-
-  - template: .azure-pipelines/job.yml
-    parameters:
-      name: test_on_macos_node12
-      displayName: Test on Node.js 12 (macOS)
-      vmImage: macOS-10.14
-      nodeVersion: 12.x
diff --git a/conf/config-schema.js b/conf/config-schema.js
index 83addff87..712fc4235 100644
--- a/conf/config-schema.js
+++ b/conf/config-schema.js
@@ -6,6 +6,7 @@
 "use strict";
 
 const baseConfigProperties = {
+    $schema: { type: "string" },
     env: { type: "object" },
     extends: { $ref: "#/definitions/stringOrStrings" },
     globals: { type: "object" },
diff --git a/conf/eslint-recommended.js b/conf/eslint-recommended.js
index 7cc6e0165..e915ec449 100644
--- a/conf/eslint-recommended.js
+++ b/conf/eslint-recommended.js
@@ -62,7 +62,6 @@ module.exports = {
         "no-useless-catch": "error",
         "no-useless-escape": "error",
         "no-with": "error",
-        "require-atomic-updates": "error",
         "require-yield": "error",
         "use-isnan": "error",
         "valid-typeof": "error"
diff --git a/docs/developer-guide/working-with-rules.md b/docs/developer-guide/working-with-rules.md
index 945061f1f..deac450b0 100644
--- a/docs/developer-guide/working-with-rules.md
+++ b/docs/developer-guide/working-with-rules.md
@@ -352,6 +352,7 @@ In some cases fixes aren't appropriate to be automatically applied, for example,
 In order to provide suggestions, use the `suggest` key in the report argument with an array of suggestion objects. The suggestion objects represent individual suggestions that could be applied and require either a `desc` key string that describes what applying the suggestion would do or a `messageId` key (see [below](#suggestion-messageids)), and a `fix` key that is a function defining the suggestion result. This `fix` function follows the same API as regular fixes (described above in [applying fixes](#applying-fixes)).
 
 ```js
+{% raw %}
 context.report({
     node: node,
     message: "Unnecessary escape character: \\{{character}}.",
@@ -371,6 +372,7 @@ context.report({
         }
     ]
 });
+{% endraw %}
 ```
 
 Note: Suggestions will be applied as a stand-alone change, without triggering multipass fixes. Each suggestion should focus on a singular change in the code and should not try to conform to user defined styles. For example, if a suggestion is adding a new statement into the codebase, it should not try to match correct indentation, or confirm to user preferences on presence/absence of semicolumns. All of those things can be corrected by multipass autofix when the user triggers it.
@@ -385,6 +387,7 @@ Best practices for suggestions:
 Instead of using a `desc` key for suggestions a `messageId` can be used instead. This works the same way as `messageId`s for the overall error (see [messageIds](#messageIds)). Here is an example of how to use it in a rule:
 
 ```js
+{% raw %}
 module.exports = {
     meta: {
         messages: {
@@ -416,6 +419,43 @@ module.exports = {
         });
     }
 };
+{% endraw %}
+```
+
+#### Placeholders in suggestion messages
+
+You can also use placeholders in the suggestion message. This works the same way as placeholders for the overall error (see [using message placeholders](#using-message-placeholders)).
+
+Please note that you have to provide `data` on the suggestion's object. Suggestion messages cannot use properties from the overall error's `data`.
+
+```js
+{% raw %}
+module.exports = {
+    meta: {
+        messages: {
+            unnecessaryEscape: "Unnecessary escape character: \\{{character}}.",
+            removeEscape: "Remove `\\` before {{character}}.",
+        }
+    },
+    create: function(context) {
+        // ...
+        context.report({
+            node: node,
+            messageId: "unnecessaryEscape",
+            data: { character }, // data for the unnecessaryEscape overall message
+            suggest: [
+                {
+                    messageId: "removeEscape",
+                    data: { character }, // data for the removeEscape suggestion message
+                    fix: function(fixer) {
+                        return fixer.removeRange(range);
+                    }
+                }
+            ]
+        });
+    }
+};
+{% endraw %}
 ```
 
 ### context.options
diff --git a/docs/rules/brace-style.md b/docs/rules/brace-style.md
index 37098b1cd..dce2d9649 100644
--- a/docs/rules/brace-style.md
+++ b/docs/rules/brace-style.md
@@ -129,6 +129,27 @@ if (foo) { bar(); }
 if (foo) { bar(); } else { baz(); }
 
 try { somethingRisky(); } catch(e) { handleError(); }
+
+if (foo) { baz(); } else {
+  boom();
+}
+
+if (foo) { baz(); } else if (bar) {
+  boom();
+}
+
+if (foo) { baz(); } else
+if (bar) {
+  boom();
+}
+
+if (foo) { baz); } else if (bar) {
+  boom();
+}
+
+try { somethingRisky(); } catch(e) {
+  handleError();
+}
 ```
 
 ### stroustrup
diff --git a/docs/rules/comma-style.md b/docs/rules/comma-style.md
index 2a55dbf58..24b551574 100644
--- a/docs/rules/comma-style.md
+++ b/docs/rules/comma-style.md
@@ -39,7 +39,7 @@ This rule also accepts an additional `exceptions` object:
     * `"VariableDeclaration": true` ignores comma style in variable declarations
     * `"NewExpression": true` ignores comma style in the parameters of constructor expressions
 
-A way to determine the node types as defined by [ESTree](https://github.com/estree/estree) is to use the [online demo](https://eslint.org/parser).
+A way to determine the node types as defined by [ESTree](https://github.com/estree/estree) is to use [AST Explorer](https://astexplorer.net/) with the espree parser.
 
 ### last
 
diff --git a/docs/rules/func-style.md b/docs/rules/func-style.md
index 14f01b0c4..e17fecf8f 100644
--- a/docs/rules/func-style.md
+++ b/docs/rules/func-style.md
@@ -77,6 +77,8 @@ Examples of **correct** code for this rule with the default `"expression"` optio
 var foo = function() {
     // ...
 };
+
+var foo = () => {};
 ```
 
 ### declaration
diff --git a/docs/rules/indent.md b/docs/rules/indent.md
index 0e58352fc..8d7f9d059 100644
--- a/docs/rules/indent.md
+++ b/docs/rules/indent.md
@@ -84,6 +84,7 @@ This rule has an object option:
 * `"ObjectExpression"` (default: 1) enforces indentation level for properties in objects. It can be set to the string `"first"`, indicating that all properties in the object should be aligned with the first property. This can also be set to `"off"` to disable checking for object properties.
 * `"ImportDeclaration"` (default: 1) enforces indentation level for import statements. It can be set to the string `"first"`, indicating that all imported members from a module should be aligned with the first member in the list. This can also be set to `"off"` to disable checking for imported module members.
 * `"flatTernaryExpressions": true` (`false` by default) requires no indentation for ternary expressions which are nested in other ternary expressions.
+* `"offsetTernaryExpressions": true` (`false` by default) requires indentation for values of ternary expressions.
 * `"ignoredNodes"` accepts an array of [selectors](/docs/developer-guide/selectors.md). If an AST node is matched by any of the selectors, the indentation of tokens which are direct children of that node will be ignored. This can be used as an escape hatch to relax the rule if you disagree with the indentation that it enforces for a particular syntactic pattern.
 * `"ignoreComments"` (default: false) can be used when comments do not need to be aligned with nodes on the previous or next line.
 
@@ -643,6 +644,76 @@ var a =
     boop;
 ```
 
+### offsetTernaryExpressions
+
+Examples of **incorrect** code for this rule with the default `2, { "offsetTernaryExpressions": false }` option:
+
+```js
+/*eslint indent: ["error", 2, { "offsetTernaryExpressions": false }]*/
+
+condition
+  ? () => {
+      return true
+    }
+  : () => {
+      false
+    }
+```
+
+Examples of **correct** code for this rule with the default `2, { "offsetTernaryExpressions": false }` option:
+
+```js
+/*eslint indent: ["error", 2, { "offsetTernaryExpressions": false }]*/
+
+condition
+  ? () => {
+    return true
+  }
+  : condition2
+    ? () => {
+      return true
+    }
+    : () => {
+      return false
+    }
+```
+
+Examples of **incorrect** code for this rule with the `2, { "offsetTernaryExpressions": true }` option:
+
+```js
+/*eslint indent: ["error", 2, { "offsetTernaryExpressions": true }]*/
+
+condition
+  ? () => {
+    return true
+  }
+  : condition2
+    ? () => {
+      return true
+    }
+    : () => {
+      return false
+    }
+```
+
+Examples of **correct** code for this rule with the `2, { "offsetTernaryExpressions": true }` option:
+
+```js
+/*eslint indent: ["error", 2, { "offsetTernaryExpressions": true }]*/
+
+condition
+  ? () => {
+      return true
+    }
+  : condition2
+    ? () => {
+        return true
+      }
+    : () => {
+        return false
+      }
+```
+
 ### ignoredNodes
 
 The following configuration ignores the indentation of `ConditionalExpression` ("ternary expression") nodes:
diff --git a/docs/rules/no-console.md b/docs/rules/no-console.md
index bc163b937..f2fb79ec4 100644
--- a/docs/rules/no-console.md
+++ b/docs/rules/no-console.md
@@ -14,7 +14,7 @@ This rule disallows calls to methods of the `console` object.
 Examples of **incorrect** code for this rule:
 
 ```js
-/*eslint no-console: "error"*/
+/* eslint no-console: "error" */
 
 console.log("Log a debug level message.");
 console.warn("Log a warn level message.");
@@ -24,7 +24,7 @@ console.error("Log an error level message.");
 Examples of **correct** code for this rule:
 
 ```js
-/*eslint no-console: "error"*/
+/* eslint no-console: "error" */
 
 // custom console
 Console.log("Hello world!");
@@ -39,7 +39,7 @@ This rule has an object option for exceptions:
 Examples of additional **correct** code for this rule with a sample `{ "allow": ["warn", "error"] }` option:
 
 ```js
-/*eslint no-console: ["error", { allow: ["warn", "error"] }] */
+/* eslint no-console: ["error", { allow: ["warn", "error"] }] */
 
 console.warn("Log a warn level message.");
 console.error("Log an error level message.");
@@ -52,7 +52,7 @@ If you're using Node.js, however, `console` is used to output information to the
 Another case where you might not use this rule is if you want to enforce console calls and not console overwrites. For example:
 
 ```js
-/*eslint no-console: ["error", { allow: ["warn"] }] */
+/* eslint no-console: ["error", { allow: ["warn"] }] */
 console.error = function (message) {
   throw new Error(message);
 };
diff --git a/docs/rules/no-multi-assign.md b/docs/rules/no-multi-assign.md
index 2da09ba07..41bba9ad6 100644
--- a/docs/rules/no-multi-assign.md
+++ b/docs/rules/no-multi-assign.md
@@ -3,7 +3,11 @@
 Chaining the assignment of variables can lead to unexpected results and be difficult to read.
 
 ```js
-a = b = c = d;
+(function() {
+    const foo = bar = 0; // Did you mean `foo = bar == 0`?
+    bar = 1;             // This will not fail since `bar` is not constant.
+})();
+console.log(bar);        // This will output 1 since `bar` is not scoped.
 ```
 
 ## Rule Details
@@ -17,9 +21,9 @@ Examples of **incorrect** code for this rule:
 
 var a = b = c = 5;
 
-var foo = bar = "baz";
+const foo = bar = "baz";
 
-var a =
+let a =
     b =
     c;
 ```
@@ -32,11 +36,11 @@ var a = 5;
 var b = 5;
 var c = 5;
 
-var foo = "baz";
-var bar = "baz";
+const foo = "baz";
+const bar = "baz";
 
-var a = c;
-var b = c;
+let a = c;
+let b = c;
 ```
 
 ## Related Rules
diff --git a/docs/rules/no-multi-spaces.md b/docs/rules/no-multi-spaces.md
index 07cd0e901..c4b12e938 100644
--- a/docs/rules/no-multi-spaces.md
+++ b/docs/rules/no-multi-spaces.md
@@ -102,7 +102,7 @@ var x = 5;      /* multiline
 
 To avoid contradictions with other rules that require multiple spaces, this rule has an `exceptions` option to ignore certain nodes.
 
-This option is an object that expects property names to be AST node types as defined by [ESTree](https://github.com/estree/estree). The easiest way to determine the node types for `exceptions` is to use the [online demo](https://eslint.org/parser).
+This option is an object that expects property names to be AST node types as defined by [ESTree](https://github.com/estree/estree). The easiest way to determine the node types for `exceptions` is to use [AST Explorer](https://astexplorer.net/) with the espree parser.
 
 Only the `Property` node type is ignored by default, because for the [key-spacing](key-spacing.md) rule some alignment options require multiple spaces in properties of object literals.
 
diff --git a/docs/rules/no-param-reassign.md b/docs/rules/no-param-reassign.md
index 2ee312c2b..47a7af3cb 100644
--- a/docs/rules/no-param-reassign.md
+++ b/docs/rules/no-param-reassign.md
@@ -129,17 +129,25 @@ Examples of **correct** code for the `{ "props": true }` option with `"ignorePro
 ```js
 /*eslint no-param-reassign: ["error", { "props": true, "ignorePropertyModificationsForRegex": ["^bar"] }]*/
 
-function foo(bar) {
+function foo(barVar) {
     barVar.prop = "value";
 }
 
-function foo(bar) {
+function foo(barrito) {
     delete barrito.aaa;
 }
 
-function foo(bar) {
+function foo(bar_) {
     bar_.aaa++;
 }
+
+function foo(barBaz) {
+    for (barBaz.aaa in baz) {}
+}
+
+function foo(barBaz) {
+    for (barBaz.aaa of baz) {}
+}
 ```
 
 
diff --git a/docs/rules/no-restricted-imports.md b/docs/rules/no-restricted-imports.md
index 62747ebce..e86544d2e 100644
--- a/docs/rules/no-restricted-imports.md
+++ b/docs/rules/no-restricted-imports.md
@@ -38,20 +38,26 @@ When using the object form, you can also specify an array of gitignore-style pat
 You may also specify a custom message for any paths you want to restrict as follows:
 
 ```json
-"no-restricted-imports": ["error", [{
-  "name": "import-foo",
-  "message": "Please use import-bar instead."
-}]]
+"no-restricted-imports": ["error", {
+    "name": "import-foo",
+    "message": "Please use import-bar instead."
+}, {
+    "name": "import-baz",
+    "message": "Please use import-quux instead."
+}]
 ```
 
 or like this:
 
 ```json
 "no-restricted-imports": ["error", {
-  "paths": [{
-    "name": "import-foo",
-    "message": "Please use import-bar instead."
-  }]
+    "paths": [{
+        "name": "import-foo",
+        "message": "Please use import-bar instead."
+    }, {
+        "name": "import-baz",
+        "message": "Please use import-quux instead."
+    }]
 }]
 ```
 
diff --git a/docs/rules/no-restricted-syntax.md b/docs/rules/no-restricted-syntax.md
index 37dbe8f01..066516721 100644
--- a/docs/rules/no-restricted-syntax.md
+++ b/docs/rules/no-restricted-syntax.md
@@ -2,7 +2,7 @@
 
 JavaScript has a lot of language features, and not everyone likes all of them. As a result, some projects choose to disallow the use of certain language features altogether. For instance, you might decide to disallow the use of `try-catch` or `class`, or you might decide to disallow the use of the `in` operator.
 
-Rather than creating separate rules for every language feature you want to turn off, this rule allows you to configure the syntax elements you want to restrict use of. These elements are represented by their [ESTree](https://github.com/estree/estree) node types. For example, a function declaration is represented by `FunctionDeclaration` and the `with` statement is represented by `WithStatement`. You may find the full list of AST node names you can use [on GitHub](https://github.com/eslint/espree/blob/master/lib/ast-node-types.js) and use the [online parser](https://eslint.org/parser/) to see what type of nodes your code consists of.
+Rather than creating separate rules for every language feature you want to turn off, this rule allows you to configure the syntax elements you want to restrict use of. These elements are represented by their [ESTree](https://github.com/estree/estree) node types. For example, a function declaration is represented by `FunctionDeclaration` and the `with` statement is represented by `WithStatement`. You may find the full list of AST node names you can use [on GitHub](https://github.com/eslint/espree/blob/master/lib/ast-node-types.js) and use [AST Explorer](https://astexplorer.net/) with the espree parser to see what type of nodes your code consists of.
 
 You can also specify [AST selectors](../developer-guide/selectors) to restrict, allowing much more precise control over syntax patterns.
 
diff --git a/docs/rules/no-void.md b/docs/rules/no-void.md
index 856c934c6..6b7774805 100644
--- a/docs/rules/no-void.md
+++ b/docs/rules/no-void.md
@@ -54,8 +54,42 @@ Examples of **incorrect** code for this rule:
 /*eslint no-void: "error"*/
 
 void foo
+void someFunction();
 
 var foo = void bar();
+function baz() {
+    return void 0;
+}
+```
+
+## Options
+
+This rule has an object option:
+
+* `allowAsStatement` set to `true` allows the void operator to be used as a statement (Default `false`).
+
+### allowAsStatement
+
+When `allowAsStatement` is set to true, the rule will not error on cases that the void operator is used as a statement, i.e. when it's not used in an expression position, like in a variable assignment or a function return.
+
+Examples of **incorrect** code for `{ "allowAsStatement": true }`:
+
+```js
+/*eslint no-void: ["error", { "allowAsStatement": true }]*/
+
+var foo = void bar();
+function baz() {
+    return void 0;
+}
+```
+
+Examples of **correct** code for `{ "allowAsStatement": true }`:
+
+```js
+/*eslint no-void: ["error", { "allowAsStatement": true }]*/
+
+void foo;
+void someFunction();
 ```
 
 ## When Not To Use It
diff --git a/docs/user-guide/command-line-interface.md b/docs/user-guide/command-line-interface.md
index c8871b07d..89f42744e 100644
--- a/docs/user-guide/command-line-interface.md
+++ b/docs/user-guide/command-line-interface.md
@@ -79,6 +79,7 @@ Caching:
 Miscellaneous:
   --init                         Run config initialization wizard - default: false
   --env-info                     Output execution environment information - default: false
+  --no-error-on-unmatched-pattern  Prevent errors when pattern is unmatched - default: false
   --debug                        Output debugging information
   -h, --help                     Show help
   -v, --version                  Output the version number
@@ -451,6 +452,10 @@ The resulting configuration file will be created in the current directory.
 
 This option outputs information about the execution environment, including the version of Node, npm, and local and global installations of ESLint. The ESLint team may ask for this information to help solve bugs.
 
+#### `--no-error-on-unmatched-pattern`
+
+This option prevents errors when a quoted glob pattern or `--ext` is unmatched. This will not prevent errors when your shell can't match a glob.
+
 #### `--debug`
 
 This option outputs debugging information to the console. This information is useful when you're seeing a problem and having a hard time pinpointing it. The ESLint team may ask for this debugging information to help solve bugs.
diff --git a/docs/user-guide/configuring.md b/docs/user-guide/configuring.md
index 5022fc44d..2a47a3e9e 100644
--- a/docs/user-guide/configuring.md
+++ b/docs/user-guide/configuring.md
@@ -664,6 +664,7 @@ In each case, the settings in the configuration file override default settings.
 ESLint supports configuration files in several formats:
 
 * **JavaScript** - use `.eslintrc.js` and export an object containing your configuration.
+* **JavaScript (ESM)** - use `.eslintrc.cjs` when running ESLint in JavaScript packages that specify `"type":"module"` in their `package.json`. Note that ESLint does not support ESM configuration at this time.
 * **YAML** - use `.eslintrc.yaml` or `.eslintrc.yml` to define the configuration structure.
 * **JSON** - use `.eslintrc.json` to define the configuration structure. ESLint's JSON files also allow JavaScript-style comments.
 * **Deprecated** - use `.eslintrc`, which can be either JSON or YAML.
@@ -672,13 +673,13 @@ ESLint supports configuration files in several formats:
 If there are multiple configuration files in the same directory, ESLint will only use one. The priority order is:
 
 1. `.eslintrc.js`
+1. `.eslintrc.cjs`
 1. `.eslintrc.yaml`
 1. `.eslintrc.yml`
 1. `.eslintrc.json`
 1. `.eslintrc`
 1. `package.json`
 
-
 ## Configuration Cascading and Hierarchy
 
 When using `.eslintrc.*` and `package.json` files for configuration, you can take advantage of configuration cascading. For instance, suppose you have the following structure:
diff --git a/lib/cli-engine/cli-engine.js b/lib/cli-engine/cli-engine.js
index 0b1c76bac..22336a91d 100644
--- a/lib/cli-engine/cli-engine.js
+++ b/lib/cli-engine/cli-engine.js
@@ -576,6 +576,7 @@ class CLIEngine {
             cwd: options.cwd,
             extensions: options.extensions,
             globInputPaths: options.globInputPaths,
+            errorOnUnmatchedPattern: options.errorOnUnmatchedPattern,
             ignore: options.ignore
         });
         const lintResultCache =
diff --git a/lib/cli-engine/config-array-factory.js b/lib/cli-engine/config-array-factory.js
index c444031bc..76c4ccd70 100644
--- a/lib/cli-engine/config-array-factory.js
+++ b/lib/cli-engine/config-array-factory.js
@@ -62,6 +62,7 @@ const eslintRecommendedPath = path.resolve(__dirname, "../../conf/eslint-recomme
 const eslintAllPath = path.resolve(__dirname, "../../conf/eslint-all.js");
 const configFilenames = [
     ".eslintrc.js",
+    ".eslintrc.cjs",
     ".eslintrc.yaml",
     ".eslintrc.yml",
     ".eslintrc.json",
@@ -279,6 +280,7 @@ function configMissingError(configName, importerName) {
 function loadConfigFile(filePath) {
     switch (path.extname(filePath)) {
         case ".js":
+        case ".cjs":
             return loadJSConfigFile(filePath);
 
         case ".json":
diff --git a/lib/cli-engine/file-enumerator.js b/lib/cli-engine/file-enumerator.js
index 700f8009c..c67e01aef 100644
--- a/lib/cli-engine/file-enumerator.js
+++ b/lib/cli-engine/file-enumerator.js
@@ -190,6 +190,7 @@ class FileEnumerator {
         configArrayFactory = new CascadingConfigArrayFactory({ cwd }),
         extensions = [".js"],
         globInputPaths = true,
+        errorOnUnmatchedPattern = true,
         ignore = true
     } = {}) {
         internalSlotsMap.set(this, {
@@ -208,6 +209,7 @@ class FileEnumerator {
                 "u"
             ),
             globInputPaths,
+            errorOnUnmatchedPattern,
             ignoreFlag: ignore
         });
     }
@@ -226,7 +228,7 @@ class FileEnumerator {
      * @returns {IterableIterator<FileAndConfig>} The found files.
      */
     *iterateFiles(patternOrPatterns) {
-        const { globInputPaths } = internalSlotsMap.get(this);
+        const { globInputPaths, errorOnUnmatchedPattern } = internalSlotsMap.get(this);
         const patterns = Array.isArray(patternOrPatterns)
             ? patternOrPatterns
             : [patternOrPatterns];
@@ -265,14 +267,16 @@ class FileEnumerator {
             }
 
             // Raise an error if any files were not found.
-            if (!foundRegardlessOfIgnored) {
-                throw new NoFilesFoundError(
-                    pattern,
-                    !globInputPaths && isGlob(pattern)
-                );
-            }
-            if (!found) {
-                throw new AllFilesIgnoredError(pattern);
+            if (errorOnUnmatchedPattern) {
+                if (!foundRegardlessOfIgnored) {
+                    throw new NoFilesFoundError(
+                        pattern,
+                        !globInputPaths && isGlob(pattern)
+                    );
+                }
+                if (!found) {
+                    throw new AllFilesIgnoredError(pattern);
+                }
             }
         }
 
@@ -375,9 +379,6 @@ class FileEnumerator {
      * @private
      */
     *_iterateFilesRecursive(directoryPath, options) {
-        if (this._isIgnoredFile(directoryPath + path.sep, options)) {
-            return;
-        }
         debug(`Enter the directory: ${directoryPath}`);
         const { configArrayFactory, extensionRegExp } = internalSlotsMap.get(this);
 
@@ -426,7 +427,20 @@ class FileEnumerator {
 
             // Dive into the sub directory.
             } else if (options.recursive && stat && stat.isDirectory()) {
-                yield* this._iterateFilesRecursive(filePath, options);
+                if (!config) {
+                    config = configArrayFactory.getConfigArrayForFile(
+                        filePath,
+                        { ignoreNotFoundError: true }
+                    );
+                }
+                const ignored = this._isIgnoredFile(
+                    filePath + path.sep,
+                    { ...options, config }
+                );
+
+                if (!ignored) {
+                    yield* this._iterateFilesRecursive(filePath, options);
+                }
             }
         }
 
diff --git a/lib/cli-engine/lint-result-cache.js b/lib/cli-engine/lint-result-cache.js
index 14e19d9e5..23a142097 100644
--- a/lib/cli-engine/lint-result-cache.js
+++ b/lib/cli-engine/lint-result-cache.js
@@ -20,6 +20,7 @@ const hash = require("./hash");
 //-----------------------------------------------------------------------------
 
 const configHashCache = new WeakMap();
+const nodeVersion = process && process.version;
 
 /**
  * Calculates the hash of the config
@@ -28,7 +29,7 @@ const configHashCache = new WeakMap();
  */
 function hashOfConfigFor(config) {
     if (!configHashCache.has(config)) {
-        configHashCache.set(config, hash(`${pkg.version}_${stringify(config)}`));
+        configHashCache.set(config, hash(`${pkg.version}_${nodeVersion}_${stringify(config)}`));
     }
 
     return configHashCache.get(config);
diff --git a/lib/cli.js b/lib/cli.js
index 18a917cf0..944b4b793 100644
--- a/lib/cli.js
+++ b/lib/cli.js
@@ -68,7 +68,8 @@ function translateOptions(cliOptions) {
         fixTypes: cliOptions.fixType,
         allowInlineConfig: cliOptions.inlineConfig,
         reportUnusedDisableDirectives: cliOptions.reportUnusedDisableDirectives,
-        resolvePluginsRelativeTo: cliOptions.resolvePluginsRelativeTo
+        resolvePluginsRelativeTo: cliOptions.resolvePluginsRelativeTo,
+        errorOnUnmatchedPattern: cliOptions.errorOnUnmatchedPattern
     };
 }
 
diff --git a/lib/linter/config-comment-parser.js b/lib/linter/config-comment-parser.js
index d0e24c594..35862315d 100644
--- a/lib/linter/config-comment-parser.js
+++ b/lib/linter/config-comment-parser.js
@@ -90,7 +90,7 @@ module.exports = class ConfigCommentParser {
          * But we are supporting that. So this is a fallback for that.
          */
         items = {};
-        const normalizedString = string.replace(/([a-zA-Z0-9\-/]+):/gu, "\"$1\":").replace(/(\]|[0-9])\s+(?=")/u, "$1,");
+        const normalizedString = string.replace(/([-a-zA-Z0-9/]+):/gu, "\"$1\":").replace(/(\]|[0-9])\s+(?=")/u, "$1,");
 
         try {
             items = JSON.parse(`{${normalizedString}}`);
diff --git a/lib/options.js b/lib/options.js
index 83bf9afc2..98dc04b6e 100644
--- a/lib/options.js
+++ b/lib/options.js
@@ -230,6 +230,12 @@ module.exports = optionator({
             default: "false",
             description: "Output execution environment information"
         },
+        {
+            option: "error-on-unmatched-pattern",
+            type: "Boolean",
+            default: "true",
+            description: "Prevent errors when pattern is unmatched"
+        },
         {
             option: "debug",
             type: "Boolean",
diff --git a/lib/rules/array-bracket-spacing.js b/lib/rules/array-bracket-spacing.js
index 2510159ee..c2b77a641 100644
--- a/lib/rules/array-bracket-spacing.js
+++ b/lib/rules/array-bracket-spacing.js
@@ -84,16 +84,16 @@ module.exports = {
          * @returns {void}
          */
         function reportNoBeginningSpace(node, token) {
+            const nextToken = sourceCode.getTokenAfter(token);
+
             context.report({
                 node,
-                loc: token.loc.start,
+                loc: { start: token.loc.end, end: nextToken.loc.start },
                 messageId: "unexpectedSpaceAfter",
                 data: {
                     tokenValue: token.value
                 },
                 fix(fixer) {
-                    const nextToken = sourceCode.getTokenAfter(token);
-
                     return fixer.removeRange([token.range[1], nextToken.range[0]]);
                 }
             });
@@ -106,16 +106,16 @@ module.exports = {
          * @returns {void}
          */
         function reportNoEndingSpace(node, token) {
+            const previousToken = sourceCode.getTokenBefore(token);
+
             context.report({
                 node,
-                loc: token.loc.start,
+                loc: { start: previousToken.loc.end, end: token.loc.start },
                 messageId: "unexpectedSpaceBefore",
                 data: {
                     tokenValue: token.value
                 },
                 fix(fixer) {
-                    const previousToken = sourceCode.getTokenBefore(token);
-
                     return fixer.removeRange([previousToken.range[1], token.range[0]]);
                 }
             });
@@ -130,7 +130,7 @@ module.exports = {
         function reportRequiredBeginningSpace(node, token) {
             context.report({
                 node,
-                loc: token.loc.start,
+                loc: token.loc,
                 messageId: "missingSpaceAfter",
                 data: {
                     tokenValue: token.value
@@ -150,7 +150,7 @@ module.exports = {
         function reportRequiredEndingSpace(node, token) {
             context.report({
                 node,
-                loc: token.loc.start,
+                loc: token.loc,
                 messageId: "missingSpaceBefore",
                 data: {
                     tokenValue: token.value
diff --git a/lib/rules/indent.js b/lib/rules/indent.js
index 694cf7d9e..9fa62c84a 100644
--- a/lib/rules/indent.js
+++ b/lib/rules/indent.js
@@ -590,6 +590,10 @@ module.exports = {
                         type: "boolean",
                         default: false
                     },
+                    offsetTernaryExpressions: {
+                        type: "boolean",
+                        default: false
+                    },
                     ignoredNodes: {
                         type: "array",
                         items: {
@@ -1142,7 +1146,8 @@ module.exports = {
                     offsets.setDesiredOffset(questionMarkToken, firstToken, 1);
                     offsets.setDesiredOffset(colonToken, firstToken, 1);
 
-                    offsets.setDesiredOffset(firstConsequentToken, firstToken, 1);
+                    offsets.setDesiredOffset(firstConsequentToken, firstToken,
+                        options.offsetTernaryExpressions ? 2 : 1);
 
                     /*
                      * The alternate and the consequent should usually have the same indentation.
@@ -1167,7 +1172,9 @@ module.exports = {
                          * If `baz` were aligned with `bar` rather than being offset by 1 from `foo`, `baz` would end up
                          * having no expected indentation.
                          */
-                        offsets.setDesiredOffset(firstAlternateToken, firstToken, 1);
+                        offsets.setDesiredOffset(firstAlternateToken, firstToken,
+                            firstAlternateToken.type === "Punctuator" &&
+                            options.offsetTernaryExpressions ? 2 : 1);
                     }
                 }
             },
diff --git a/lib/rules/key-spacing.js b/lib/rules/key-spacing.js
index 994c35627..6d1b9121c 100644
--- a/lib/rules/key-spacing.js
+++ b/lib/rules/key-spacing.js
@@ -42,6 +42,18 @@ function isSingleLine(node) {
     return (node.loc.end.line === node.loc.start.line);
 }
 
+/**
+ * Checks whether the properties on a single line.
+ * @param {ASTNode[]} properties List of Property AST nodes.
+ * @returns {boolean} True if all properies is on a single line.
+ */
+function isSingleLineProperties(properties) {
+    const [firstProp] = properties,
+        lastProp = last(properties);
+
+    return firstProp.loc.start.line === lastProp.loc.end.line;
+}
+
 /**
  * Initializes a single option property from the configuration with defaults for undefined values
  * @param {Object} toOptions Object to be initialized
@@ -583,17 +595,6 @@ module.exports = {
             }
         }
 
-        /**
-         * Verifies vertical alignment, taking into account groups of properties.
-         * @param  {ASTNode} node ObjectExpression node being evaluated.
-         * @returns {void}
-         */
-        function verifyAlignment(node) {
-            createGroups(node).forEach(group => {
-                verifyGroupAlignment(group.filter(isKeyValueProperty));
-            });
-        }
-
         /**
          * Verifies spacing of property conforms to specified options.
          * @param  {ASTNode} node Property node being evaluated.
@@ -611,17 +612,35 @@ module.exports = {
 
         /**
          * Verifies spacing of each property in a list.
-         * @param  {ASTNode[]} properties List of Property AST nodes.
+         * @param {ASTNode[]} properties List of Property AST nodes.
+         * @param {Object} lineOptions Configured singleLine or multiLine options
          * @returns {void}
          */
-        function verifyListSpacing(properties) {
+        function verifyListSpacing(properties, lineOptions) {
             const length = properties.length;
 
             for (let i = 0; i < length; i++) {
-                verifySpacing(properties[i], singleLineOptions);
+                verifySpacing(properties[i], lineOptions);
             }
         }
 
+        /**
+         * Verifies vertical alignment, taking into account groups of properties.
+         * @param  {ASTNode} node ObjectExpression node being evaluated.
+         * @returns {void}
+         */
+        function verifyAlignment(node) {
+            createGroups(node).forEach(group => {
+                const properties = group.filter(isKeyValueProperty);
+
+                if (properties.length > 0 && isSingleLineProperties(properties)) {
+                    verifyListSpacing(properties, multiLineOptions);
+                } else {
+                    verifyGroupAlignment(properties);
+                }
+            });
+        }
+
         //--------------------------------------------------------------------------
         // Public API
         //--------------------------------------------------------------------------
@@ -631,7 +650,7 @@ module.exports = {
             return {
                 ObjectExpression(node) {
                     if (isSingleLine(node)) {
-                        verifyListSpacing(node.properties.filter(isKeyValueProperty));
+                        verifyListSpacing(node.properties.filter(isKeyValueProperty), singleLineOptions);
                     } else {
                         verifyAlignment(node);
                     }
diff --git a/lib/rules/lines-between-class-members.js b/lib/rules/lines-between-class-members.js
index 60332a1b3..972353036 100644
--- a/lib/rules/lines-between-class-members.js
+++ b/lib/rules/lines-between-class-members.js
@@ -54,62 +54,45 @@ module.exports = {
         const sourceCode = context.getSourceCode();
 
         /**
-         * Checks if there is padding between two tokens
-         * @param {Token} first The first token
-         * @param {Token} second The second token
-         * @returns {boolean} True if there is at least a line between the tokens
+         * Return the last token among the consecutive tokens that have no exceed max line difference in between, before the first token in the next member.
+         * @param {Token} prevLastToken The last token in the previous member node.
+         * @param {Token} nextFirstToken The first token in the next member node.
+         * @param {number} maxLine The maximum number of allowed line difference between consecutive tokens.
+         * @returns {Token} The last token among the consecutive tokens.
          */
-        function isPaddingBetweenTokens(first, second) {
-            const comments = sourceCode.getCommentsBefore(second);
-            const len = comments.length;
+        function findLastConsecutiveTokenAfter(prevLastToken, nextFirstToken, maxLine) {
+            const after = sourceCode.getTokenAfter(prevLastToken, { includeComments: true });
 
-            // If there is no comments
-            if (len === 0) {
-                const linesBetweenFstAndSnd = second.loc.start.line - first.loc.end.line - 1;
-
-                return linesBetweenFstAndSnd >= 1;
-            }
-
-
-            // If there are comments
-            let sumOfCommentLines = 0; // the numbers of lines of comments
-            let prevCommentLineNum = -1; // line number of the end of the previous comment
-
-            for (let i = 0; i < len; i++) {
-                const commentLinesOfThisComment = comments[i].loc.end.line - comments[i].loc.start.line + 1;
-
-                sumOfCommentLines += commentLinesOfThisComment;
-
-                /*
-                 * If this comment and the previous comment are in the same line,
-                 * the count of comment lines is duplicated. So decrement sumOfCommentLines.
-                 */
-                if (prevCommentLineNum === comments[i].loc.start.line) {
-                    sumOfCommentLines -= 1;
-                }
-
-                prevCommentLineNum = comments[i].loc.end.line;
+            if (after !== nextFirstToken && after.loc.start.line - prevLastToken.loc.end.line <= maxLine) {
+                return findLastConsecutiveTokenAfter(after, nextFirstToken, maxLine);
             }
+            return prevLastToken;
+        }
 
-            /*
-             * If the first block and the first comment are in the same line,
-             * the count of comment lines is duplicated. So decrement sumOfCommentLines.
-             */
-            if (first.loc.end.line === comments[0].loc.start.line) {
-                sumOfCommentLines -= 1;
-            }
+        /**
+         * Return the first token among the consecutive tokens that have no exceed max line difference in between, after the last token in the previous member.
+         * @param {Token} nextFirstToken The first token in the next member node.
+         * @param {Token} prevLastToken The last token in the previous member node.
+         * @param {number} maxLine The maximum number of allowed line difference between consecutive tokens.
+         * @returns {Token} The first token among the consecutive tokens.
+         */
+        function findFirstConsecutiveTokenBefore(nextFirstToken, prevLastToken, maxLine) {
+            const before = sourceCode.getTokenBefore(nextFirstToken, { includeComments: true });
 
-            /*
-             * If the last comment and the second block are in the same line,
-             * the count of comment lines is duplicated. So decrement sumOfCommentLines.
-             */
-            if (comments[len - 1].loc.end.line === second.loc.start.line) {
-                sumOfCommentLines -= 1;
+            if (before !== prevLastToken && nextFirstToken.loc.start.line - before.loc.end.line <= maxLine) {
+                return findFirstConsecutiveTokenBefore(before, prevLastToken, maxLine);
             }
+            return nextFirstToken;
+        }
 
-            const linesBetweenFstAndSnd = second.loc.start.line - first.loc.end.line - 1;
-
-            return linesBetweenFstAndSnd - sumOfCommentLines >= 1;
+        /**
+         * Checks if there is a token or comment between two tokens.
+         * @param {Token} before The token before.
+         * @param {Token} after The token after.
+         * @returns {boolean} True if there is a token or comment between two tokens.
+         */
+        function hasTokenOrCommentBetween(before, after) {
+            return sourceCode.getTokensBetween(before, after, { includeComments: true }).length !== 0;
         }
 
         return {
@@ -120,10 +103,13 @@ module.exports = {
                     const curFirst = sourceCode.getFirstToken(body[i]);
                     const curLast = sourceCode.getLastToken(body[i]);
                     const nextFirst = sourceCode.getFirstToken(body[i + 1]);
-                    const isPadded = isPaddingBetweenTokens(curLast, nextFirst);
                     const isMulti = !astUtils.isTokenOnSameLine(curFirst, curLast);
                     const skip = !isMulti && options[1].exceptAfterSingleLine;
-
+                    const beforePadding = findLastConsecutiveTokenAfter(curLast, nextFirst, 1);
+                    const afterPadding = findFirstConsecutiveTokenBefore(nextFirst, curLast, 1);
+                    const isPadded = afterPadding.loc.start.line - beforePadding.loc.end.line > 1;
+                    const hasTokenInPadding = hasTokenOrCommentBetween(beforePadding, afterPadding);
+                    const curLineLastToken = findLastConsecutiveTokenAfter(curLast, nextFirst, 0);
 
                     if ((options[0] === "always" && !skip && !isPadded) ||
                         (options[0] === "never" && isPadded)) {
@@ -131,9 +117,12 @@ module.exports = {
                             node: body[i + 1],
                             messageId: isPadded ? "never" : "always",
                             fix(fixer) {
+                                if (hasTokenInPadding) {
+                                    return null;
+                                }
                                 return isPadded
-                                    ? fixer.replaceTextRange([curLast.range[1], nextFirst.range[0]], "\n")
-                                    : fixer.insertTextAfter(curLast, "\n");
+                                    ? fixer.replaceTextRange([beforePadding.range[1], afterPadding.range[0]], "\n")
+                                    : fixer.insertTextAfter(curLineLastToken, "\n");
                             }
                         });
                     }
diff --git a/lib/rules/no-multiple-empty-lines.js b/lib/rules/no-multiple-empty-lines.js
index f945cfeff..41e6be3a2 100644
--- a/lib/rules/no-multiple-empty-lines.js
+++ b/lib/rules/no-multiple-empty-lines.js
@@ -110,7 +110,7 @@ module.exports = {
                         if (lineNumber - lastLineNumber - 1 > maxAllowed) {
                             context.report({
                                 node,
-                                loc: { start: { line: lastLineNumber + 1, column: 0 }, end: { line: lineNumber, column: 0 } },
+                                loc: { start: { line: lastLineNumber + maxAllowed + 1, column: 0 }, end: { line: lineNumber, column: 0 } },
                                 message,
                                 data: { max: maxAllowed, pluralizedLines: maxAllowed === 1 ? "line" : "lines" },
                                 fix(fixer) {
diff --git a/lib/rules/no-restricted-imports.js b/lib/rules/no-restricted-imports.js
index bed9c2432..ec0696f99 100644
--- a/lib/rules/no-restricted-imports.js
+++ b/lib/rules/no-restricted-imports.js
@@ -72,14 +72,14 @@ module.exports = {
                 arrayOfStringsOrObjects,
                 {
                     type: "array",
-                    items: {
+                    items: [{
                         type: "object",
                         properties: {
                             paths: arrayOfStringsOrObjects,
                             patterns: arrayOfStrings
                         },
                         additionalProperties: false
-                    },
+                    }],
                     additionalItems: false
                 }
             ]
diff --git a/lib/rules/no-unsafe-negation.js b/lib/rules/no-unsafe-negation.js
index 5c8f569d7..a9c2ee74f 100644
--- a/lib/rules/no-unsafe-negation.js
+++ b/lib/rules/no-unsafe-negation.js
@@ -54,7 +54,8 @@ module.exports = {
             description: "disallow negating the left operand of relational operators",
             category: "Possible Errors",
             recommended: true,
-            url: "https://eslint.org/docs/rules/no-unsafe-negation"
+            url: "https://eslint.org/docs/rules/no-unsafe-negation",
+            suggestion: true
         },
 
         schema: [
@@ -69,9 +70,13 @@ module.exports = {
                 additionalProperties: false
             }
         ],
+
         fixable: null,
+
         messages: {
-            unexpected: "Unexpected negating the left operand of '{{operator}}' operator."
+            unexpected: "Unexpected negating the left operand of '{{operator}}' operator.",
+            suggestNegatedExpression: "Negate '{{operator}}' expression instead of its left operand. This changes the current behavior.",
+            suggestParenthesisedNegation: "Wrap negation in '()' to make the intention explicit. This preserves the current behavior."
         }
     },
 
@@ -82,10 +87,11 @@ module.exports = {
 
         return {
             BinaryExpression(node) {
-                const orderingRelationRuleApplies = enforceForOrderingRelations && isOrderingRelationalOperator(node.operator);
+                const operator = node.operator;
+                const orderingRelationRuleApplies = enforceForOrderingRelations && isOrderingRelationalOperator(operator);
 
                 if (
-                    (isInOrInstanceOfOperator(node.operator) || orderingRelationRuleApplies) &&
+                    (isInOrInstanceOfOperator(operator) || orderingRelationRuleApplies) &&
                     isNegation(node.left) &&
                     !astUtils.isParenthesised(sourceCode, node.left)
                 ) {
@@ -93,7 +99,26 @@ module.exports = {
                         node,
                         loc: node.left.loc,
                         messageId: "unexpected",
-                        data: { operator: node.operator }
+                        data: { operator },
+                        suggest: [
+                            {
+                                messageId: "suggestNegatedExpression",
+                                data: { operator },
+                                fix(fixer) {
+                                    const negationToken = sourceCode.getFirstToken(node.left);
+                                    const fixRange = [negationToken.range[1], node.range[1]];
+                                    const text = sourceCode.text.slice(fixRange[0], fixRange[1]);
+
+                                    return fixer.replaceTextRange(fixRange, `(${text})`);
+                                }
+                            },
+                            {
+                                messageId: "suggestParenthesisedNegation",
+                                fix(fixer) {
+                                    return fixer.replaceText(node.left, `(${sourceCode.getText(node.left)})`);
+                                }
+                            }
+                        ]
                     });
                 }
             }
diff --git a/lib/rules/no-void.js b/lib/rules/no-void.js
index d2b5d2f96..99c837855 100644
--- a/lib/rules/no-void.js
+++ b/lib/rules/no-void.js
@@ -19,22 +19,46 @@ module.exports = {
             url: "https://eslint.org/docs/rules/no-void"
         },
 
-        schema: []
+        messages: {
+            noVoid: "Expected 'undefined' and instead saw 'void'."
+        },
+
+        schema: [
+            {
+                type: "object",
+                properties: {
+                    allowAsStatement: {
+                        type: "boolean",
+                        default: false
+                    }
+                },
+                additionalProperties: false
+            }
+        ]
     },
 
     create(context) {
+        const allowAsStatement =
+            context.options[0] && context.options[0].allowAsStatement;
 
         //--------------------------------------------------------------------------
         // Public
         //--------------------------------------------------------------------------
 
         return {
-            UnaryExpression(node) {
-                if (node.operator === "void") {
-                    context.report({ node, message: "Expected 'undefined' and instead saw 'void'." });
+            'UnaryExpression[operator="void"]'(node) {
+                if (
+                    allowAsStatement &&
+                    node.parent &&
+                    node.parent.type === "ExpressionStatement"
+                ) {
+                    return;
                 }
+                context.report({
+                    node,
+                    messageId: "noVoid"
+                });
             }
         };
-
     }
 };
diff --git a/lib/rules/prefer-numeric-literals.js b/lib/rules/prefer-numeric-literals.js
index 672d9bcaa..c352d88dc 100644
--- a/lib/rules/prefer-numeric-literals.js
+++ b/lib/rules/prefer-numeric-literals.js
@@ -15,6 +15,12 @@ const astUtils = require("./utils/ast-utils");
 // Helpers
 //------------------------------------------------------------------------------
 
+const radixMap = new Map([
+    [2, { system: "binary", literalPrefix: "0b" }],
+    [8, { system: "octal", literalPrefix: "0o" }],
+    [16, { system: "hexadecimal", literalPrefix: "0x" }]
+]);
+
 /**
  * Checks to see if a CallExpression's callee node is `parseInt` or
  * `Number.parseInt`.
@@ -54,49 +60,44 @@ module.exports = {
         },
 
         schema: [],
+
+        messages: {
+            useLiteral: "Use {{system}} literals instead of {{functionName}}()."
+        },
+
         fixable: "code"
     },
 
     create(context) {
         const sourceCode = context.getSourceCode();
 
-        const radixMap = {
-            2: "binary",
-            8: "octal",
-            16: "hexadecimal"
-        };
-
-        const prefixMap = {
-            2: "0b",
-            8: "0o",
-            16: "0x"
-        };
-
         //----------------------------------------------------------------------
         // Public
         //----------------------------------------------------------------------
 
         return {
 
-            CallExpression(node) {
-
-                // doesn't check parseInt() if it doesn't have a radix argument
-                if (node.arguments.length !== 2) {
-                    return;
-                }
+            "CallExpression[arguments.length=2]"(node) {
+                const [strNode, radixNode] = node.arguments,
+                    str = strNode.value,
+                    radix = radixNode.value;
+
+                if (
+                    strNode.type === "Literal" &&
+                    radixNode.type === "Literal" &&
+                    typeof str === "string" &&
+                    typeof radix === "number" &&
+                    radixMap.has(radix) &&
+                    isParseInt(node.callee)
+                ) {
 
-                // only error if the radix is 2, 8, or 16
-                const radixName = radixMap[node.arguments[1].value];
+                    const { system, literalPrefix } = radixMap.get(radix);
 
-                if (isParseInt(node.callee) &&
-                    radixName &&
-                    node.arguments[0].type === "Literal"
-                ) {
                     context.report({
                         node,
-                        message: "Use {{radixName}} literals instead of {{functionName}}().",
+                        messageId: "useLiteral",
                         data: {
-                            radixName,
+                            system,
                             functionName: sourceCode.getText(node.callee)
                         },
                         fix(fixer) {
@@ -104,9 +105,9 @@ module.exports = {
                                 return null;
                             }
 
-                            const replacement = `${prefixMap[node.arguments[1].value]}${node.arguments[0].value}`;
+                            const replacement = `${literalPrefix}${str}`;
 
-                            if (+replacement !== parseInt(node.arguments[0].value, node.arguments[1].value)) {
+                            if (+replacement !== parseInt(str, radix)) {
 
                                 /*
                                  * If the newly-produced literal would be invalid, (e.g. 0b1234),
diff --git a/lib/rules/require-atomic-updates.js b/lib/rules/require-atomic-updates.js
index 3912ad86c..bdd6d81eb 100644
--- a/lib/rules/require-atomic-updates.js
+++ b/lib/rules/require-atomic-updates.js
@@ -162,7 +162,7 @@ module.exports = {
         docs: {
             description: "disallow assignments that can lead to race conditions due to usage of `await` or `yield`",
             category: "Possible Errors",
-            recommended: true,
+            recommended: false,
             url: "https://eslint.org/docs/rules/require-atomic-updates"
         },
 
diff --git a/lib/source-code/source-code.js b/lib/source-code/source-code.js
index 20b442f23..30b4e9ab5 100644
--- a/lib/source-code/source-code.js
+++ b/lib/source-code/source-code.js
@@ -90,6 +90,56 @@ function nodesOrTokensOverlap(first, second) {
         (second.range[0] <= first.range[0] && second.range[1] >= first.range[0]);
 }
 
+/**
+ * Determines if two nodes or tokens have at least one whitespace character
+ * between them. Order does not matter. Returns false if the given nodes or
+ * tokens overlap.
+ * @param {SourceCode} sourceCode The source code object.
+ * @param {ASTNode|Token} first The first node or token to check between.
+ * @param {ASTNode|Token} second The second node or token to check between.
+ * @param {boolean} checkInsideOfJSXText If `true` is present, check inside of JSXText tokens for backward compatibility.
+ * @returns {boolean} True if there is a whitespace character between
+ * any of the tokens found between the two given nodes or tokens.
+ * @public
+ */
+function isSpaceBetween(sourceCode, first, second, checkInsideOfJSXText) {
+    if (nodesOrTokensOverlap(first, second)) {
+        return false;
+    }
+
+    const [startingNodeOrToken, endingNodeOrToken] = first.range[1] <= second.range[0]
+        ? [first, second]
+        : [second, first];
+    const firstToken = sourceCode.getLastToken(startingNodeOrToken) || startingNodeOrToken;
+    const finalToken = sourceCode.getFirstToken(endingNodeOrToken) || endingNodeOrToken;
+    let currentToken = firstToken;
+
+    while (currentToken !== finalToken) {
+        const nextToken = sourceCode.getTokenAfter(currentToken, { includeComments: true });
+
+        if (
+            currentToken.range[1] !== nextToken.range[0] ||
+
+                /*
+                 * For backward compatibility, check speces in JSXText.
+                 * https://github.com/eslint/eslint/issues/12614
+                 */
+                (
+                    checkInsideOfJSXText &&
+                    nextToken !== finalToken &&
+                    nextToken.type === "JSXText" &&
+                    /\s/u.test(nextToken.value)
+                )
+        ) {
+            return true;
+        }
+
+        currentToken = nextToken;
+    }
+
+    return false;
+}
+
 //------------------------------------------------------------------------------
 // Public Interface
 //------------------------------------------------------------------------------
@@ -433,42 +483,24 @@ class SourceCode extends TokenStore {
      * @public
      */
     isSpaceBetween(first, second) {
-        if (nodesOrTokensOverlap(first, second)) {
-            return false;
-        }
-
-        const [startingNodeOrToken, endingNodeOrToken] = first.range[1] <= second.range[0]
-            ? [first, second]
-            : [second, first];
-        const firstToken = this.getLastToken(startingNodeOrToken) || startingNodeOrToken;
-        const finalToken = this.getFirstToken(endingNodeOrToken) || endingNodeOrToken;
-        let currentToken = firstToken;
-
-        while (currentToken !== finalToken) {
-            const nextToken = this.getTokenAfter(currentToken, { includeComments: true });
-
-            if (currentToken.range[1] !== nextToken.range[0]) {
-                return true;
-            }
-
-            currentToken = nextToken;
-        }
-
-        return false;
+        return isSpaceBetween(this, first, second, false);
     }
 
     /**
      * Determines if two nodes or tokens have at least one whitespace character
      * between them. Order does not matter. Returns false if the given nodes or
      * tokens overlap.
-     * @param {...ASTNode|Token} args The nodes or tokens to check between.
+     * For backward compatibility, this method returns true if there are
+     * `JSXText` tokens that contain whitespaces between the two.
+     * @param {ASTNode|Token} first The first node or token to check between.
+     * @param {ASTNode|Token} second The second node or token to check between.
      * @returns {boolean} True if there is a whitespace character between
      * any of the tokens found between the two given nodes or tokens.
      * @deprecated in favor of isSpaceBetween().
      * @public
      */
-    isSpaceBetweenTokens(...args) {
-        return this.isSpaceBetween(...args);
+    isSpaceBetweenTokens(first, second) {
+        return isSpaceBetween(this, first, second, true);
     }
 
     /**
diff --git a/package.json b/package.json
index b0563edf1..ccb76c18b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint",
-  "version": "6.7.1",
+  "version": "6.8.0",
   "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
   "description": "An AST-based pattern checker for JavaScript.",
   "bin": {
diff --git a/packages/eslint-config-eslint/default.yml b/packages/eslint-config-eslint/default.yml
index a1fd92ff9..8f3ed3125 100644
--- a/packages/eslint-config-eslint/default.yml
+++ b/packages/eslint-config-eslint/default.yml
@@ -175,6 +175,7 @@ rules:
     prefer-const: "error"
     prefer-numeric-literals: "error"
     prefer-promise-reject-errors: "error"
+    prefer-regex-literals: "error"
     prefer-rest-params: "error"
     prefer-spread: "error"
     prefer-template: "error"
diff --git a/packages/eslint-config-eslint/package.json b/packages/eslint-config-eslint/package.json
index 48bfb65f5..afbe4f558 100644
--- a/packages/eslint-config-eslint/package.json
+++ b/packages/eslint-config-eslint/package.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint-config-eslint",
-  "version": "5.0.1",
+  "version": "6.0.0",
   "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
   "description": "Default ESLint configuration for ESLint projects.",
   "scripts": {
diff --git a/webpack.config.js b/webpack.config.js
index 1630cef97..6a43ac755 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -3,8 +3,7 @@
 module.exports = {
     mode: "none",
     entry: {
-        eslint: ["core-js/stable", "regenerator-runtime/runtime", "./lib/linter/linter.js"],
-        espree: ["core-js/stable", "regenerator-runtime/runtime", "espree"]
+        eslint: ["core-js/stable", "regenerator-runtime/runtime", "./lib/linter/linter.js"]
     },
     output: {
         filename: "[name].js",


Test patch:
diff --git a/lib/rule-tester/rule-tester.js b/lib/rule-tester/rule-tester.js
index b4b3b2bec..44e01dadf 100644
--- a/lib/rule-tester/rule-tester.js
+++ b/lib/rule-tester/rule-tester.js
@@ -596,8 +596,10 @@ class RuleTester {
                         if (hasOwnProperty(error, "suggestions")) {
 
                             // Support asserting there are no suggestions
-                            if (!error.suggestions) {
-                                assert.strictEqual(message.suggestions, error.suggestions, `Error should have no suggestions on error with message: "${message.message}"`);
+                            if (!error.suggestions || (Array.isArray(error.suggestions) && error.suggestions.length === 0)) {
+                                if (Array.isArray(message.suggestions) && message.suggestions.length > 0) {
+                                    assert.fail(`Error should have no suggestions on error with message: "${message.message}"`);
+                                }
                             } else {
                                 assert.strictEqual(Array.isArray(message.suggestions), true, `Error should have an array of suggestions. Instead received "${message.suggestions}" on error with message: "${message.message}"`);
                                 assert.strictEqual(message.suggestions.length, error.suggestions.length, `Error should have ${error.suggestions.length} suggestions. Instead found ${message.suggestions.length} suggestions`);
diff --git a/tests/fixtures/config-file/cjs/.eslintrc.cjs b/tests/fixtures/config-file/cjs/.eslintrc.cjs
new file mode 100644
index 000000000..b3100591d
--- /dev/null
+++ b/tests/fixtures/config-file/cjs/.eslintrc.cjs
@@ -0,0 +1,5 @@
+module.exports = {
+    rules: {
+        semi: [2, "always"]
+    }
+};
diff --git a/tests/fixtures/unmatched-patterns/failing.js b/tests/fixtures/unmatched-patterns/failing.js
new file mode 100644
index 000000000..e24993ff6
--- /dev/null
+++ b/tests/fixtures/unmatched-patterns/failing.js
@@ -0,0 +1,3 @@
+var foo = "bar";
+if (foo) {
+    foo = "bar2";
diff --git a/tests/fixtures/unmatched-patterns/passing.js2 b/tests/fixtures/unmatched-patterns/passing.js2
new file mode 100644
index 000000000..425be7cea
--- /dev/null
+++ b/tests/fixtures/unmatched-patterns/passing.js2
@@ -0,0 +1,5 @@
+let foo = "bar";
+
+if (foo) {
+    foo = "bar2";
+}
diff --git a/tests/lib/cli-engine/cli-engine.js b/tests/lib/cli-engine/cli-engine.js
index 1d9bef090..1c2411c97 100644
--- a/tests/lib/cli-engine/cli-engine.js
+++ b/tests/lib/cli-engine/cli-engine.js
@@ -1288,7 +1288,7 @@ describe("CLIEngine", () => {
 
             assert.throws(() => {
                 engine.executeOnFiles(["./tests/fixtures/cli-engine/"]);
-            }, "No files matching './tests/fixtures/cli-engine/' were found.");
+            }, "All files matched by './tests/fixtures/cli-engine/' are ignored.");
         });
 
         it("should throw an error when all given files are ignored via ignore-pattern", () => {
@@ -3628,6 +3628,55 @@ describe("CLIEngine", () => {
                 assert.strictEqual(messages[0].ruleId, "no-console");
             });
         });
+
+        describe("don't ignore the entry directory.", () => {
+            const root = getFixturePath("cli-engine/dont-ignore-entry-dir");
+
+            it("'executeOnFiles(\".\")' should not load config files from outside of \".\".", () => {
+                CLIEngine = defineCLIEngineWithInMemoryFileSystem({
+                    cwd: () => root,
+                    files: {
+                        "../.eslintrc.json": "BROKEN FILE",
+                        ".eslintrc.json": JSON.stringify({ root: true }),
+                        "index.js": "console.log(\"hello\")"
+                    }
+                }).CLIEngine;
+                engine = new CLIEngine();
+
+                // Don't throw "failed to load config file" error.
+                engine.executeOnFiles(".");
+            });
+
+            it("'executeOnFiles(\".\")' should not ignore '.' even if 'ignorePatterns' contains it.", () => {
+                CLIEngine = defineCLIEngineWithInMemoryFileSystem({
+                    cwd: () => root,
+                    files: {
+                        "../.eslintrc.json": JSON.stringify({ ignorePatterns: ["/dont-ignore-entry-dir"] }),
+                        ".eslintrc.json": JSON.stringify({ root: true }),
+                        "index.js": "console.log(\"hello\")"
+                    }
+                }).CLIEngine;
+                engine = new CLIEngine();
+
+                // Don't throw "file not found" error.
+                engine.executeOnFiles(".");
+            });
+
+            it("'executeOnFiles(\"subdir\")' should not ignore './subdir' even if 'ignorePatterns' contains it.", () => {
+                CLIEngine = defineCLIEngineWithInMemoryFileSystem({
+                    cwd: () => root,
+                    files: {
+                        ".eslintrc.json": JSON.stringify({ ignorePatterns: ["/subdir"] }),
+                        "subdir/.eslintrc.json": JSON.stringify({ root: true }),
+                        "subdir/index.js": "console.log(\"hello\")"
+                    }
+                }).CLIEngine;
+                engine = new CLIEngine();
+
+                // Don't throw "file not found" error.
+                engine.executeOnFiles("subdir");
+            });
+        });
     });
 
     describe("getConfigForFile", () => {
diff --git a/tests/lib/cli-engine/config-array-factory.js b/tests/lib/cli-engine/config-array-factory.js
index 4f3ade1e6..1fb5661fb 100644
--- a/tests/lib/cli-engine/config-array-factory.js
+++ b/tests/lib/cli-engine/config-array-factory.js
@@ -171,6 +171,7 @@ describe("ConfigArrayFactory", () => {
     describe("'loadFile(filePath, options)' method should load a config file.", () => {
         const basicFiles = {
             "js/.eslintrc.js": "exports.settings = { name: 'js/.eslintrc.js' }",
+            "cjs/.eslintrc.cjs": "exports.settings = { name: 'cjs/.eslintrc.cjs' }",
             "json/.eslintrc.json": "{ \"settings\": { \"name\": \"json/.eslintrc.json\" } }",
             "legacy-json/.eslintrc": "{ \"settings\": { \"name\": \"legacy-json/.eslintrc\" } }",
             "legacy-yml/.eslintrc": "settings:\n  name: legacy-yml/.eslintrc",
@@ -288,6 +289,7 @@ describe("ConfigArrayFactory", () => {
     describe("'loadInDirectory(directoryPath, options)' method should load the config file of a directory.", () => {
         const basicFiles = {
             "js/.eslintrc.js": "exports.settings = { name: 'js/.eslintrc.js' }",
+            "cjs/.eslintrc.cjs": "exports.settings = { name: 'cjs/.eslintrc.cjs' }",
             "json/.eslintrc.json": "{ \"settings\": { \"name\": \"json/.eslintrc.json\" } }",
             "legacy-json/.eslintrc": "{ \"settings\": { \"name\": \"legacy-json/.eslintrc\" } }",
             "legacy-yml/.eslintrc": "settings:\n  name: legacy-yml/.eslintrc",
@@ -1497,6 +1499,7 @@ describe("ConfigArrayFactory", () => {
             "node_modules/eslint-plugin-invalid-parser/index.js": "exports.configs = { foo: { parser: 'nonexistent-parser' } }",
             "node_modules/eslint-plugin-invalid-config/index.js": "exports.configs = { foo: {} }",
             "js/.eslintrc.js": "module.exports = { rules: { semi: [2, 'always'] } };",
+            "cjs/.eslintrc.cjs": "module.exports = { rules: { semi: [2, 'always'] } };",
             "json/.eslintrc.json": "{ \"rules\": { \"quotes\": [2, \"double\"] } }",
             "package-json/package.json": "{ \"eslintConfig\": { \"env\": { \"es6\": true } } }",
             "yaml/.eslintrc.yaml": "env:\n    browser: true"
@@ -1747,6 +1750,22 @@ describe("ConfigArrayFactory", () => {
             });
         });
 
+        it("should load information from a JavaScript file with a .cjs extension", () => {
+            const { ConfigArrayFactory } = defineConfigArrayFactoryWithInMemoryFileSystem({
+                files: {
+                    "cjs/.eslintrc.cjs": "module.exports = { rules: { semi: [2, 'always'] } };"
+                }
+            });
+            const factory = new ConfigArrayFactory();
+            const config = load(factory, "cjs/.eslintrc.cjs");
+
+            assertConfig(config, {
+                rules: {
+                    semi: [2, "always"]
+                }
+            });
+        });
+
         it("should throw error when loading invalid JavaScript file", () => {
             const { ConfigArrayFactory } = defineConfigArrayFactoryWithInMemoryFileSystem({
                 files: {
diff --git a/tests/lib/cli-engine/file-enumerator.js b/tests/lib/cli-engine/file-enumerator.js
index 3d05f63ab..c62578c91 100644
--- a/tests/lib/cli-engine/file-enumerator.js
+++ b/tests/lib/cli-engine/file-enumerator.js
@@ -380,7 +380,7 @@ describe("FileEnumerator", () => {
 
                     assert.throws(() => {
                         listFiles(patterns);
-                    }, `No files matching '${patterns[0]}' were found.`);
+                    }, `All files matched by '${patterns[0]}' are ignored.`);
                 });
 
                 it("should return an ignored file, if ignore option is turned off", () => {
diff --git a/tests/lib/cli-engine/lint-result-cache.js b/tests/lib/cli-engine/lint-result-cache.js
index 7c5cc20a1..a3b6ee3ab 100644
--- a/tests/lib/cli-engine/lint-result-cache.js
+++ b/tests/lib/cli-engine/lint-result-cache.js
@@ -120,6 +120,35 @@ describe("LintResultCache", () => {
             lintResultsCache = new LintResultCache(cacheFileLocation);
         });
 
+        describe("when calculating the hashing", () => {
+            it("contains eslint version during hashing", () => {
+                const version = "eslint-=-version";
+                const NewLintResultCache = proxyquire("../../../lib/cli-engine/lint-result-cache.js", {
+                    "../../package.json": { version },
+                    "./hash": hashStub
+                });
+                const newLintResultCache = new NewLintResultCache(cacheFileLocation);
+
+                newLintResultCache.getCachedLintResults(filePath, fakeConfig);
+                assert.ok(hashStub.calledOnce);
+                assert.ok(hashStub.calledWithMatch(version));
+            });
+
+            it("contains node version during hashing", () => {
+                const version = "node-=-version";
+
+                sinon.stub(process, "version").value(version);
+                const NewLintResultCache = proxyquire("../../../lib/cli-engine/lint-result-cache.js", {
+                    "./hash": hashStub
+                });
+                const newLintResultCache = new NewLintResultCache(cacheFileLocation);
+
+                newLintResultCache.getCachedLintResults(filePath, fakeConfig);
+                assert.ok(hashStub.calledOnce);
+                assert.ok(hashStub.calledWithMatch(version));
+            });
+        });
+
         describe("When file is changed", () => {
             beforeEach(() => {
                 hashStub.returns(hashOfConfig);
diff --git a/tests/lib/cli.js b/tests/lib/cli.js
index e0f10d5ae..6af3b5c83 100644
--- a/tests/lib/cli.js
+++ b/tests/lib/cli.js
@@ -347,6 +347,74 @@ describe("cli", () => {
         });
     });
 
+    describe("when executing without no-error-on-unmatched-pattern flag", () => {
+        it("should throw an error on unmatched glob pattern", () => {
+            const filePath = getFixturePath("unmatched-patterns");
+            const globPattern = "*.js3";
+
+            assert.throws(() => {
+                cli.execute(`"${filePath}/${globPattern}"`);
+            }, `No files matching '${filePath}/${globPattern}' were found.`);
+        });
+
+        it("should throw an error on unmatched --ext", () => {
+            const filePath = getFixturePath("unmatched-patterns");
+            const extension = ".js3";
+
+            assert.throws(() => {
+                cli.execute(`--ext ${extension} ${filePath}`);
+            }, `No files matching '${filePath}' were found`);
+        });
+    });
+
+    describe("when executing with no-error-on-unmatched-pattern flag", () => {
+        it("should not throw an error on unmatched node glob syntax patterns", () => {
+            const filePath = getFixturePath("unmatched-patterns");
+            const exit = cli.execute(`--no-error-on-unmatched-pattern "${filePath}/*.js3"`);
+
+            assert.strictEqual(exit, 0);
+        });
+
+        it("should not throw an error on unmatched --ext", () => {
+            const filePath = getFixturePath("unmatched-patterns");
+            const exit = cli.execute(`--no-error-on-unmatched-pattern --ext .js3 ${filePath}`);
+
+            assert.strictEqual(exit, 0);
+        });
+    });
+
+    describe("when executing with no-error-on-unmatched-pattern flag and multiple patterns", () => {
+        it("should not throw an error on multiple unmatched node glob syntax patterns", () => {
+            const filePath = getFixturePath("unmatched-patterns");
+            const exit = cli.execute(`--no-error-on-unmatched-pattern ${filePath}/*.js3 ${filePath}/*.js4`);
+
+            assert.strictEqual(exit, 0);
+        });
+
+        it("should still throw an error on when a matched pattern has lint errors", () => {
+            const filePath = getFixturePath("unmatched-patterns");
+            const exit = cli.execute(`--no-error-on-unmatched-pattern ${filePath}/*.js3 ${filePath}/*.js`);
+
+            assert.strictEqual(exit, 1);
+        });
+    });
+
+    describe("when executing with no-error-on-unmatched-pattern flag and multiple --ext arguments", () => {
+        it("should not throw an error on multiple unmatched --ext arguments", () => {
+            const filePath = getFixturePath("unmatched-patterns");
+            const exit = cli.execute(`--no-error-on-unmatched-pattern --ext .js3 --ext .js4 ${filePath}`);
+
+            assert.strictEqual(exit, 0);
+        });
+
+        it("should still throw an error on when a matched pattern has lint errors", () => {
+            const filePath = getFixturePath("unmatched-patterns");
+            const exit = cli.execute(`--no-error-on-unmatched-pattern --ext .js3 --ext .js ${filePath}`);
+
+            assert.strictEqual(exit, 1);
+        });
+    });
+
     describe("when executing with help flag", () => {
         it("should print out help", () => {
             assert.strictEqual(cli.execute("-h"), 0);
diff --git a/tests/lib/rule-tester/rule-tester.js b/tests/lib/rule-tester/rule-tester.js
index 6ab341ccc..4abb053ab 100644
--- a/tests/lib/rule-tester/rule-tester.js
+++ b/tests/lib/rule-tester/rule-tester.js
@@ -1018,29 +1018,33 @@ describe("RuleTester", () => {
         });
 
         it("should support explicitly expecting no suggestions", () => {
-            ruleTester.run("suggestions-basic", require("../../fixtures/testers/rule-tester/no-eval"), {
-                valid: [],
-                invalid: [{
-                    code: "eval('var foo');",
-                    errors: [{
-                        suggestions: void 0
-                    }]
-                }]
-            });
-        });
-
-        it("should fail when expecting no suggestions and there are suggestions", () => {
-            assert.throws(() => {
-                ruleTester.run("suggestions-basic", require("../../fixtures/testers/rule-tester/suggestions").basic, {
+            [void 0, null, false, []].forEach(suggestions => {
+                ruleTester.run("suggestions-basic", require("../../fixtures/testers/rule-tester/no-eval"), {
                     valid: [],
                     invalid: [{
-                        code: "var foo;",
+                        code: "eval('var foo');",
                         errors: [{
-                            suggestions: void 0
+                            suggestions
                         }]
                     }]
                 });
-            }, "Error should have no suggestions on error with message: \"Avoid using identifiers named 'foo'.\"");
+            });
+        });
+
+        it("should fail when expecting no suggestions and there are suggestions", () => {
+            [void 0, null, false, []].forEach(suggestions => {
+                assert.throws(() => {
+                    ruleTester.run("suggestions-basic", require("../../fixtures/testers/rule-tester/suggestions").basic, {
+                        valid: [],
+                        invalid: [{
+                            code: "var foo;",
+                            errors: [{
+                                suggestions
+                            }]
+                        }]
+                    });
+                }, "Error should have no suggestions on error with message: \"Avoid using identifiers named 'foo'.\"");
+            });
         });
 
         it("should fail when testing for suggestions that don't exist", () => {
diff --git a/tests/lib/rules/array-bracket-spacing.js b/tests/lib/rules/array-bracket-spacing.js
index 120c90501..33caf0889 100644
--- a/tests/lib/rules/array-bracket-spacing.js
+++ b/tests/lib/rules/array-bracket-spacing.js
@@ -190,7 +190,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 }
             ]
         },
@@ -208,7 +210,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 },
                 {
                     messageId: "missingSpaceBefore",
@@ -217,7 +221,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 36
+                    column: 36,
+                    endLine: 1,
+                    endColumn: 37
                 }
             ]
         },
@@ -233,7 +239,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 11,
+                    endLine: 1,
+                    endColumn: 12
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
@@ -242,7 +250,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 35
+                    column: 34,
+                    endLine: 1,
+                    endColumn: 35
                 }
             ]
         },
@@ -258,7 +268,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
@@ -267,7 +279,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 50
+                    column: 49,
+                    endLine: 1,
+                    endColumn: 50
                 }
             ]
         },
@@ -285,7 +299,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
@@ -294,7 +310,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 19
+                    column: 18,
+                    endLine: 1,
+                    endColumn: 19
                 }
             ]
         },
@@ -310,7 +328,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 18
+                    column: 17,
+                    endLine: 1,
+                    endColumn: 18
                 }
             ]
         },
@@ -326,7 +346,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 11,
+                    endLine: 1,
+                    endColumn: 12
                 },
                 {
                     messageId: "missingSpaceBefore",
@@ -335,7 +357,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 17
+                    column: 17,
+                    endLine: 1,
+                    endColumn: 18
                 }
             ]
         },
@@ -353,7 +377,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 }
             ]
         },
@@ -369,7 +395,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 31
+                    column: 30,
+                    endLine: 1,
+                    endColumn: 31
                 }
             ]
         },
@@ -385,7 +413,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 34
+                    column: 33,
+                    endLine: 1,
+                    endColumn: 34
                 }
             ]
         },
@@ -401,7 +431,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 }
             ]
         },
@@ -417,7 +449,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
@@ -426,7 +460,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 35
+                    column: 34,
+                    endLine: 1,
+                    endColumn: 35
                 }
             ]
         },
@@ -444,7 +480,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 5
+                column: 5,
+                endLine: 1,
+                endColumn: 6
             },
             {
                 messageId: "missingSpaceBefore",
@@ -453,7 +491,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 9
+                column: 9,
+                endLine: 1,
+                endColumn: 10
             }]
         },
         {
@@ -468,7 +508,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 5
+                column: 5,
+                endLine: 1,
+                endColumn: 6
             }]
         },
         {
@@ -483,7 +525,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 5
+                column: 5,
+                endLine: 1,
+                endColumn: 6
             },
             {
                 messageId: "missingSpaceBefore",
@@ -492,7 +536,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 12
+                column: 12,
+                endLine: 1,
+                endColumn: 13
             }]
         },
         {
@@ -507,7 +553,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 13
+                column: 13,
+                endLine: 1,
+                endColumn: 14
             }]
         },
         {
@@ -522,7 +570,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 5
+                column: 5,
+                endLine: 1,
+                endColumn: 6
             },
             {
                 messageId: "missingSpaceBefore",
@@ -531,7 +581,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 14
+                column: 14,
+                endLine: 1,
+                endColumn: 15
             }]
         },
         {
@@ -546,7 +598,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 5
+                column: 5,
+                endLine: 1,
+                endColumn: 6
             }]
         },
         {
@@ -561,7 +615,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 5
+                column: 6,
+                endLine: 1,
+                endColumn: 7
             }]
         },
         {
@@ -576,7 +632,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 1
+                column: 2,
+                endLine: 1,
+                endColumn: 3
             }]
         },
         {
@@ -591,7 +649,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                 },
                 type: "ArrayPattern",
                 line: 1,
-                column: 15
+                column: 14,
+                endLine: 1,
+                endColumn: 15
             }]
         },
 
@@ -608,7 +668,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 11,
+                    endLine: 1,
+                    endColumn: 12
                 },
                 {
                     messageId: "missingSpaceBefore",
@@ -617,7 +679,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 29
+                    column: 29,
+                    endLine: 1,
+                    endColumn: 30
                 }
             ]
         },
@@ -633,7 +697,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 }
             ]
         },
@@ -651,7 +717,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 }
             ]
         },
@@ -669,7 +737,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 11,
+                    endLine: 1,
+                    endColumn: 12
                 },
                 {
                     messageId: "missingSpaceBefore",
@@ -678,7 +748,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 22
+                    column: 22,
+                    endLine: 1,
+                    endColumn: 23
                 }
             ]
         },
@@ -694,7 +766,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 11,
+                    endLine: 1,
+                    endColumn: 12
                 }
             ]
         },
@@ -710,7 +784,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 23
+                    column: 23,
+                    endLine: 1,
+                    endColumn: 24
                 }
             ]
         },
@@ -728,7 +804,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
@@ -737,7 +815,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 24
+                    column: 23,
+                    endLine: 1,
+                    endColumn: 24
                 }
             ]
         },
@@ -753,7 +833,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 23
+                    column: 22,
+                    endLine: 1,
+                    endColumn: 23
                 }
             ]
         },
@@ -769,7 +851,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 }
             ]
         },
@@ -785,7 +869,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 11
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
                 },
                 {
                     messageId: "unexpectedSpaceAfter",
@@ -794,7 +880,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 13
+                    column: 14,
+                    endLine: 1,
+                    endColumn: 15
                 }
             ]
         },
@@ -810,7 +898,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 15
+                    column: 14,
+                    endLine: 1,
+                    endColumn: 15
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
@@ -819,7 +909,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayExpression",
                     line: 1,
-                    column: 26
+                    column: 25,
+                    endLine: 1,
+                    endColumn: 26
                 }
             ]
         },
@@ -841,7 +933,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayPattern",
                     line: 1,
-                    column: 2
+                    column: 3,
+                    endLine: 1,
+                    endColumn: 4
                 },
                 {
                     messageId: "unexpectedSpaceBefore",
@@ -850,7 +944,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayPattern",
                     line: 1,
-                    column: 9
+                    column: 8,
+                    endLine: 1,
+                    endColumn: 9
                 }
             ]
         },
@@ -870,7 +966,9 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayPattern",
                     line: 1,
-                    column: 2
+                    column: 2,
+                    endLine: 1,
+                    endColumn: 3
                 },
                 {
                     messageId: "missingSpaceBefore",
@@ -879,7 +977,152 @@ ruleTester.run("array-bracket-spacing", rule, {
                     },
                     type: "ArrayPattern",
                     line: 1,
-                    column: 7
+                    column: 7,
+                    endLine: 1,
+                    endColumn: 8
+                }
+            ]
+        },
+
+        // multiple spaces
+        {
+            code: "var arr = [  1, 2   ];",
+            output: "var arr = [1, 2];",
+            options: ["never"],
+            errors: [
+                {
+                    messageId: "unexpectedSpaceAfter",
+                    data: {
+                        tokenValue: "["
+                    },
+                    type: "ArrayExpression",
+                    line: 1,
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 14
+                },
+                {
+                    messageId: "unexpectedSpaceBefore",
+                    data: {
+                        tokenValue: "]"
+                    },
+                    type: "ArrayExpression",
+                    line: 1,
+                    column: 18,
+                    endLine: 1,
+                    endColumn: 21
+                }
+            ]
+        },
+        {
+            code: "function f( [   a, b  ] ) {}",
+            output: "function f( [a, b] ) {}",
+            options: ["never"],
+            parserOptions: {
+                ecmaVersion: 6
+            },
+            errors: [
+                {
+                    messageId: "unexpectedSpaceAfter",
+                    data: {
+                        tokenValue: "["
+                    },
+                    type: "ArrayPattern",
+                    line: 1,
+                    column: 14,
+                    endLine: 1,
+                    endColumn: 17
+                },
+                {
+                    messageId: "unexpectedSpaceBefore",
+                    data: {
+                        tokenValue: "]"
+                    },
+                    type: "ArrayPattern",
+                    line: 1,
+                    column: 21,
+                    endLine: 1,
+                    endColumn: 23
+                }
+            ]
+        },
+        {
+            code: "var arr = [ 1,\n   2   ];",
+            output: "var arr = [1,\n   2];",
+            options: ["never"],
+            errors: [
+                {
+                    messageId: "unexpectedSpaceAfter",
+                    data: {
+                        tokenValue: "["
+                    },
+                    type: "ArrayExpression",
+                    line: 1,
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 13
+                },
+                {
+                    messageId: "unexpectedSpaceBefore",
+                    data: {
+                        tokenValue: "]"
+                    },
+                    type: "ArrayExpression",
+                    line: 2,
+                    column: 5,
+                    endLine: 2,
+                    endColumn: 8
+                }
+            ]
+        },
+        {
+            code: "var arr = [  1, [ 2, 3  ] ];",
+            output: "var arr = [1, [2, 3]];",
+            options: ["never"],
+            errors: [
+                {
+                    messageId: "unexpectedSpaceAfter",
+                    data: {
+                        tokenValue: "["
+                    },
+                    type: "ArrayExpression",
+                    line: 1,
+                    column: 12,
+                    endLine: 1,
+                    endColumn: 14
+                },
+                {
+                    messageId: "unexpectedSpaceAfter",
+                    data: {
+                        tokenValue: "["
+                    },
+                    type: "ArrayExpression",
+                    line: 1,
+                    column: 18,
+                    endLine: 1,
+                    endColumn: 19
+                },
+                {
+                    messageId: "unexpectedSpaceBefore",
+                    data: {
+                        tokenValue: "]"
+                    },
+                    type: "ArrayExpression",
+                    line: 1,
+                    column: 23,
+                    endLine: 1,
+                    endColumn: 25
+                },
+                {
+                    messageId: "unexpectedSpaceBefore",
+                    data: {
+                        tokenValue: "]"
+                    },
+                    type: "ArrayExpression",
+                    line: 1,
+                    column: 26,
+                    endLine: 1,
+                    endColumn: 27
                 }
             ]
         }
diff --git a/tests/lib/rules/brace-style.js b/tests/lib/rules/brace-style.js
index 4444863b6..70211608b 100644
--- a/tests/lib/rules/brace-style.js
+++ b/tests/lib/rules/brace-style.js
@@ -82,6 +82,22 @@ ruleTester.run("brace-style", rule, {
         { code: "if (foo) {}\nelse {}", options: ["allman", { allowSingleLine: true }] },
         { code: "try {  bar(); }\ncatch (e) { baz();  }", options: ["allman", { allowSingleLine: true }] },
         { code: "var foo = () => { return; }", options: ["allman", { allowSingleLine: true }], parserOptions: { ecmaVersion: 6 } },
+        {
+            code: "if (foo) { baz(); } else {\n  boom();\n}",
+            options: ["1tbs", { allowSingleLine: true }]
+        },
+        {
+            code: "if (foo) { baz(); } else if (bar) {\n  boom();\n}",
+            options: ["1tbs", { allowSingleLine: true }]
+        },
+        {
+            code: "if (foo) { baz(); } else\nif (bar) {\n  boom();\n}",
+            options: ["1tbs", { allowSingleLine: true }]
+        },
+        {
+            code: "try { somethingRisky(); } catch(e) {\n  handleError();\n}",
+            options: ["1tbs", { allowSingleLine: true }]
+        },
         {
             code: "if (tag === 1) fontstack.name = pbf.readString(); \nelse if (tag === 2) fontstack.range = pbf.readString(); \nelse if (tag === 3) {\n var glyph = pbf.readMessage(readGlyph, {});\n fontstack.glyphs[glyph.id] = glyph; \n}",
             options: ["1tbs"]
diff --git a/tests/lib/rules/comma-dangle.js b/tests/lib/rules/comma-dangle.js
index 9225b4341..3a4f0aa73 100644
--- a/tests/lib/rules/comma-dangle.js
+++ b/tests/lib/rules/comma-dangle.js
@@ -359,6 +359,16 @@ ruleTester.run("comma-dangle", rule, {
         },
 
         // trailing comma in functions
+        {
+            code: "function foo(a) {} ",
+            options: [{}],
+            parserOptions: { ecmaVersion: 8 }
+        },
+        {
+            code: "foo(a)",
+            options: [{}],
+            parserOptions: { ecmaVersion: 8 }
+        },
         {
             code: "function foo(a) {} ",
             options: [{ functions: "never" }],
diff --git a/tests/lib/rules/for-direction.js b/tests/lib/rules/for-direction.js
index 4dd4f8a99..a04b10e11 100644
--- a/tests/lib/rules/for-direction.js
+++ b/tests/lib/rules/for-direction.js
@@ -53,7 +53,13 @@ ruleTester.run("for-direction", rule, {
         "for(var i = 10; i >= 0; i %= 2){}",
         "for(var i = 0; i < MAX; i += STEP_SIZE);",
         "for(var i = 0; i < MAX; i -= STEP_SIZE);",
-        "for(var i = 10; i > 0; i += STEP_SIZE);"
+        "for(var i = 10; i > 0; i += STEP_SIZE);",
+
+        // other cond-expressions.
+        "for(var i = 0; i !== 10; i+=1){}",
+        "for(var i = 0; i === 10; i+=1){}",
+        "for(var i = 0; i == 10; i+=1){}",
+        "for(var i = 0; i != 10; i+=1){}"
     ],
     invalid: [
 
diff --git a/tests/lib/rules/indent.js b/tests/lib/rules/indent.js
index 249f9bc91..93ebb2824 100644
--- a/tests/lib/rules/indent.js
+++ b/tests/lib/rules/indent.js
@@ -2097,6 +2097,86 @@ ruleTester.run("indent", rule, {
             `,
             options: [2]
         },
+        {
+            code: unIndent`
+              condition
+                ? () => {
+                  return true
+                }
+                : condition2
+                  ? () => {
+                    return true
+                  }
+                  : () => {
+                    return false
+                  }
+            `,
+            options: [2]
+        },
+        {
+            code: unIndent`
+              condition
+                ? () => {
+                  return true
+                }
+                : condition2
+                  ? () => {
+                    return true
+                  }
+                  : () => {
+                    return false
+                  }
+            `,
+            options: [2, { offsetTernaryExpressions: false }]
+        },
+        {
+            code: unIndent`
+              condition
+                ? () => {
+                    return true
+                  }
+                : condition2
+                  ? () => {
+                      return true
+                    }
+                  : () => {
+                      return false
+                    }
+            `,
+            options: [2, { offsetTernaryExpressions: true }]
+        },
+        {
+            code: unIndent`
+              condition
+                  ? () => {
+                          return true
+                      }
+                  : condition2
+                      ? () => {
+                              return true
+                          }
+                      : () => {
+                              return false
+                          }
+            `,
+            options: [4, { offsetTernaryExpressions: true }]
+        },
+        {
+            code: unIndent`
+              condition
+              \t? () => {
+              \t\t\treturn true
+              \t\t}
+              \t: condition2
+              \t\t? () => {
+              \t\t\t\treturn true
+              \t\t\t}
+              \t\t: () => {
+              \t\t\t\treturn false
+              \t\t\t}
+            `,
+            options: ["tab", { offsetTernaryExpressions: true }]
+        },
         unIndent`
             [
                 foo ?
@@ -7705,6 +7785,88 @@ ruleTester.run("indent", rule, {
             `,
             errors: expectedErrors([5, 4, 8, "Identifier"])
         },
+        {
+            code: unIndent`
+              condition
+              ? () => {
+              return true
+              }
+              : condition2
+              ? () => {
+              return true
+              }
+              : () => {
+              return false
+              }
+            `,
+            output: unIndent`
+              condition
+                ? () => {
+                    return true
+                  }
+                : condition2
+                  ? () => {
+                      return true
+                    }
+                  : () => {
+                      return false
+                    }
+            `,
+            options: [2, { offsetTernaryExpressions: true }],
+            errors: expectedErrors([
+                [2, 2, 0, "Punctuator"],
+                [3, 6, 0, "Keyword"],
+                [4, 4, 0, "Punctuator"],
+                [5, 2, 0, "Punctuator"],
+                [6, 4, 0, "Punctuator"],
+                [7, 8, 0, "Keyword"],
+                [8, 6, 0, "Punctuator"],
+                [9, 4, 0, "Punctuator"],
+                [10, 8, 0, "Keyword"],
+                [11, 6, 0, "Punctuator"]
+            ])
+        },
+        {
+            code: unIndent`
+              condition
+              ? () => {
+              return true
+              }
+              : condition2
+              ? () => {
+              return true
+              }
+              : () => {
+              return false
+              }
+            `,
+            output: unIndent`
+              condition
+                ? () => {
+                  return true
+                }
+                : condition2
+                  ? () => {
+                    return true
+                  }
+                  : () => {
+                    return false
+                  }
+            `,
+            options: [2, { offsetTernaryExpressions: false }],
+            errors: expectedErrors([
+                [2, 2, 0, "Punctuator"],
+                [3, 4, 0, "Keyword"],
+                [4, 2, 0, "Punctuator"],
+                [5, 2, 0, "Punctuator"],
+                [6, 4, 0, "Punctuator"],
+                [7, 6, 0, "Keyword"],
+                [8, 4, 0, "Punctuator"],
+                [9, 4, 0, "Punctuator"],
+                [10, 6, 0, "Keyword"],
+                [11, 4, 0, "Punctuator"]
+            ])
+        },
         {
 
             /*
diff --git a/tests/lib/rules/key-spacing.js b/tests/lib/rules/key-spacing.js
index a9ed53374..29bbbe857 100644
--- a/tests/lib/rules/key-spacing.js
+++ b/tests/lib/rules/key-spacing.js
@@ -757,6 +757,141 @@ ruleTester.run("key-spacing", rule, {
             }
         }],
         parserOptions: { ecmaVersion: 6 }
+    }, {
+        code: [
+            "var obj = {",
+            "    foo : 1, 'bar' : 2, baz : 3, longlonglong : 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            multiLine: {
+                beforeColon: true,
+                afterColon: true,
+                align: "colon"
+            }
+        }]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo: 1, 'bar': 2, baz: 3",
+            "}"
+        ].join("\n"),
+        options: [{
+            multiLine: {
+                align: "value"
+            }
+        }]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo: 1",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            multiLine: {
+                align: "value"
+            }
+        }]
+    }, {
+        code: [
+            "foo({",
+            "    bar: 1",
+            "})"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "colon"
+            }
+        }]
+    }, {
+        code: "var obj = { foo:1, 'bar':2, baz:3, longlonglong:4 }",
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "colon"
+            }
+        }]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo         : 1,",
+            "    'bar'       : 2, baz         : 3, longlonglong: 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "colon"
+            }
+        }]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo:          1,",
+            "    'bar':        2, baz:          3, longlonglong: 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "value"
+            }
+        }]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo         : 1,",
+            "    'bar'       : 2, baz         : 3,",
+            "    longlonglong: 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "colon"
+            }
+        }]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo:          1,",
+            "    'bar':        2, baz:          3,",
+            "    longlonglong: 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "value"
+            }
+        }]
     }],
 
     invalid: [{
@@ -1769,5 +1904,206 @@ ruleTester.run("key-spacing", rule, {
             { messageId: "missingKey", data: { computed: "", key: "foo" }, line: 1, column: 7, type: "Identifier" },
             { messageId: "missingValue", data: { computed: "", key: "foo" }, line: 1, column: 19, type: "Identifier" }
         ]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo:1, 'bar':2, baz:3",
+            "}"
+        ].join("\n"),
+        output: [
+            "var obj = {",
+            "    foo : 1, 'bar' : 2, baz : 3",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            multiLine: {
+                beforeColon: true,
+                afterColon: true,
+                align: "colon"
+            }
+        }],
+        errors: [
+            { messageId: "missingKey", data: { computed: "", key: "foo" }, line: 2, column: 5, type: "Identifier" },
+            { messageId: "missingValue", data: { computed: "", key: "foo" }, line: 2, column: 9, type: "Literal" },
+            { messageId: "missingKey", data: { computed: "", key: "bar" }, line: 2, column: 12, type: "Literal" },
+            { messageId: "missingValue", data: { computed: "", key: "bar" }, line: 2, column: 18, type: "Literal" },
+            { messageId: "missingKey", data: { computed: "", key: "baz" }, line: 2, column: 21, type: "Identifier" },
+            { messageId: "missingValue", data: { computed: "", key: "baz" }, line: 2, column: 25, type: "Literal" }
+        ]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo : 1, 'bar' : 2, baz : 3, longlonglong : 4",
+            "}"
+        ].join("\n"),
+        output: [
+            "var obj = {",
+            "    foo: 1, 'bar': 2, baz: 3, longlonglong: 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            multiLine: {
+                align: "value"
+            }
+        }],
+        errors: [
+            { messageId: "extraKey", data: { computed: "", key: "foo" }, line: 2, column: 5, type: "Identifier" },
+            { messageId: "extraKey", data: { computed: "", key: "bar" }, line: 2, column: 14, type: "Literal" },
+            { messageId: "extraKey", data: { computed: "", key: "baz" }, line: 2, column: 25, type: "Identifier" },
+            { messageId: "extraKey", data: { computed: "", key: "longlonglong" }, line: 2, column: 34, type: "Identifier" }
+        ]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo:1",
+            "}"
+        ].join("\n"),
+        output: [
+            "var obj = {",
+            "    foo: 1",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            multiLine: {
+                align: "value"
+            }
+        }],
+        errors: [
+            { messageId: "missingValue", data: { computed: "", key: "foo" }, line: 2, column: 9, type: "Literal" }
+        ]
+    }, {
+        code: [
+            "foo({",
+            "    bar:1",
+            "})"
+        ].join("\n"),
+        output: [
+            "foo({",
+            "    bar: 1",
+            "})"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "colon"
+            }
+        }],
+        errors: [
+            { messageId: "missingValue", data: { computed: "", key: "bar" }, line: 2, column: 9, type: "Literal" }
+        ]
+    }, {
+        code: "var obj = { foo: 1, 'bar': 2, baz :3, longlonglong :4 }",
+        output: "var obj = { foo:1, 'bar':2, baz:3, longlonglong:4 }",
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "colon"
+            }
+        }],
+        errors: [
+            { messageId: "extraValue", data: { computed: "", key: "foo" }, line: 1, column: 18, type: "Literal" },
+            { messageId: "extraValue", data: { computed: "", key: "bar" }, line: 1, column: 28, type: "Literal" },
+            { messageId: "extraKey", data: { computed: "", key: "baz" }, line: 1, column: 31, type: "Identifier" },
+            { messageId: "extraKey", data: { computed: "", key: "longlonglong" }, line: 1, column: 39, type: "Identifier" }
+        ]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo: 1,",
+            "    'bar': 2, baz: 3, longlonglong: 4",
+            "}"
+        ].join("\n"),
+        output: [
+            "var obj = {",
+            "    foo         : 1,",
+            "    'bar'       : 2, baz         : 3, longlonglong: 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "colon"
+            }
+        }],
+        errors: [
+            { messageId: "missingKey", data: { computed: "", key: "foo" }, line: 2, column: 5, type: "Identifier" },
+            { messageId: "missingKey", data: { computed: "", key: "bar" }, line: 3, column: 5, type: "Literal" },
+            { messageId: "missingKey", data: { computed: "", key: "baz" }, line: 3, column: 15, type: "Identifier" }
+        ]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo : 1,",
+            "    'bar' : 2, baz : 3,",
+            "    longlonglong: 4",
+            "}"
+        ].join("\n"),
+        output: [
+            "var obj = {",
+            "    foo         : 1,",
+            "    'bar'       : 2, baz         : 3,",
+            "    longlonglong: 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "colon"
+            }
+        }],
+        errors: [
+            { messageId: "missingKey", data: { computed: "", key: "foo" }, line: 2, column: 5, type: "Identifier" },
+            { messageId: "missingKey", data: { computed: "", key: "bar" }, line: 3, column: 5, type: "Literal" },
+            { messageId: "missingKey", data: { computed: "", key: "baz" }, line: 3, column: 16, type: "Identifier" }
+        ]
+    }, {
+        code: [
+            "var obj = {",
+            "    foo: 1,",
+            "    'bar': 2, baz: 3,",
+            "    longlonglong: 4",
+            "}"
+        ].join("\n"),
+        output: [
+            "var obj = {",
+            "    foo:          1,",
+            "    'bar':        2, baz:          3,",
+            "    longlonglong: 4",
+            "}"
+        ].join("\n"),
+        options: [{
+            singleLine: {
+                beforeColon: false,
+                afterColon: false
+            },
+            align: {
+                on: "value"
+            }
+        }],
+        errors: [
+            { messageId: "missingValue", data: { computed: "", key: "foo" }, line: 2, column: 10, type: "Literal" },
+            { messageId: "missingValue", data: { computed: "", key: "bar" }, line: 3, column: 12, type: "Literal" },
+            { messageId: "missingValue", data: { computed: "", key: "baz" }, line: 3, column: 20, type: "Literal" }
+        ]
     }]
 });
diff --git a/tests/lib/rules/lines-between-class-members.js b/tests/lib/rules/lines-between-class-members.js
index d1aa8607c..e4b1c0c09 100644
--- a/tests/lib/rules/lines-between-class-members.js
+++ b/tests/lib/rules/lines-between-class-members.js
@@ -40,6 +40,9 @@ ruleTester.run("lines-between-class-members", rule, {
         "class A{ foo() {}\n/* a */ /* b */\n\nbar() {}}",
         "class A{ foo() {}/* a */ \n\n /* b */bar() {}}",
 
+        "class A {\nfoo() {}\n/* comment */;\n;\n\nbar() {}\n}",
+        "class A {\nfoo() {}\n// comment\n\n;\n;\nbar() {}\n}",
+
         "class foo{ bar(){}\n\n;;baz(){}}",
         "class foo{ bar(){};\n\nbaz(){}}",
 
@@ -73,6 +76,71 @@ ruleTester.run("lines-between-class-members", rule, {
             output: "class foo{ bar(){\n}\n\nbaz(){}}",
             options: ["always", { exceptAfterSingleLine: true }],
             errors: [alwaysError]
+        }, {
+            code: "class foo{ bar(){\n}\n/* comment */\nbaz(){}}",
+            output: "class foo{ bar(){\n}\n\n/* comment */\nbaz(){}}",
+            options: ["always", { exceptAfterSingleLine: true }],
+            errors: [alwaysError]
+        }, {
+            code: "class foo{ bar(){}\n\n// comment\nbaz(){}}",
+            output: "class foo{ bar(){}\n// comment\nbaz(){}}",
+            options: ["never"],
+            errors: [neverError]
+        }, {
+            code: "class foo{ bar(){}\n\n/* comment */\nbaz(){}}",
+            output: "class foo{ bar(){}\n/* comment */\nbaz(){}}",
+            options: ["never"],
+            errors: [neverError]
+        }, {
+            code: "class foo{ bar(){}\n/* comment-1 */\n\n/* comment-2 */\nbaz(){}}",
+            output: "class foo{ bar(){}\n/* comment-1 */\n/* comment-2 */\nbaz(){}}",
+            options: ["never"],
+            errors: [neverError]
+        }, {
+            code: "class foo{ bar(){}\n\n/* comment */\n\nbaz(){}}",
+            output: null,
+            options: ["never"],
+            errors: [neverError]
+        }, {
+            code: "class foo{ bar(){}\n\n// comment\n\nbaz(){}}",
+            output: null,
+            options: ["never"],
+            errors: [neverError]
+        }, {
+            code: "class foo{ bar(){}\n/* comment-1 */\n\n/* comment-2 */\n\n/* comment-3 */\nbaz(){}}",
+            output: null,
+            options: ["never"],
+            errors: [neverError]
+        }, {
+            code: "class foo{ bar(){}\n/* comment-1 */\n\n;\n\n/* comment-3 */\nbaz(){}}",
+            output: null,
+            options: ["never"],
+            errors: [neverError]
+        }, {
+            code: "class A {\nfoo() {}// comment\n;\n/* comment */\nbar() {}\n}",
+            output: "class A {\nfoo() {}// comment\n\n;\n/* comment */\nbar() {}\n}",
+            options: ["always"],
+            errors: [alwaysError]
+        }, {
+            code: "class A {\nfoo() {}\n/* comment */;\n;\n/* comment */\nbar() {}\n}",
+            output: "class A {\nfoo() {}\n\n/* comment */;\n;\n/* comment */\nbar() {}\n}",
+            options: ["always"],
+            errors: [alwaysError]
+        }, {
+            code: "class foo{ bar(){};\nbaz(){}}",
+            output: "class foo{ bar(){};\n\nbaz(){}}",
+            options: ["always"],
+            errors: [alwaysError]
+        }, {
+            code: "class foo{ bar(){} // comment \nbaz(){}}",
+            output: "class foo{ bar(){} // comment \n\nbaz(){}}",
+            options: ["always"],
+            errors: [alwaysError]
+        }, {
+            code: "class A {\nfoo() {}\n/* comment */;\n;\nbar() {}\n}",
+            output: "class A {\nfoo() {}\n\n/* comment */;\n;\nbar() {}\n}",
+            options: ["always"],
+            errors: [alwaysError]
         }
     ]
 });
diff --git a/tests/lib/rules/no-multiple-empty-lines.js b/tests/lib/rules/no-multiple-empty-lines.js
index 5c51dd811..7b14f75ae 100644
--- a/tests/lib/rules/no-multiple-empty-lines.js
+++ b/tests/lib/rules/no-multiple-empty-lines.js
@@ -316,6 +316,32 @@ ruleTester.run("no-multiple-empty-lines", rule, {
             output: "foo\n",
             options: [{ max: 1, maxEOF: 0 }],
             errors: [getExpectedErrorEOF(0)]
+        },
+        {
+
+            // https://github.com/eslint/eslint/pull/12594
+            code: "var a;\n\n\n\n\nvar b;",
+            output: "var a;\n\nvar b;",
+            options: [{ max: 1 }],
+            errors: [{
+                message: "More than 1 blank line not allowed.",
+                type: "Program",
+                line: 3,
+                column: 1
+            }]
+        },
+        {
+
+            // https://github.com/eslint/eslint/pull/12594
+            code: "var a;\n\n\n\n\nvar b;",
+            output: "var a;\n\n\nvar b;",
+            options: [{ max: 2 }],
+            errors: [{
+                message: "More than 2 blank lines not allowed.",
+                type: "Program",
+                line: 4,
+                column: 1
+            }]
         }
     ]
 });
diff --git a/tests/lib/rules/no-param-reassign.js b/tests/lib/rules/no-param-reassign.js
index 5bb70e6aa..6985cabb8 100644
--- a/tests/lib/rules/no-param-reassign.js
+++ b/tests/lib/rules/no-param-reassign.js
@@ -91,6 +91,14 @@ ruleTester.run("no-param-reassign", rule, {
             code: "function foo(a) { for (bar of baz) a.b; }",
             options: [{ props: true }],
             parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "function foo(bar, baz) { bar.a = true; baz.b = false; }",
+            options: [{
+                props: true,
+                ignorePropertyModificationsForRegex: ["^(foo|bar)$"],
+                ignorePropertyModificationsFor: ["baz"]
+            }]
         }
     ],
 
diff --git a/tests/lib/rules/no-restricted-imports.js b/tests/lib/rules/no-restricted-imports.js
index ac97bc137..15ee089b2 100644
--- a/tests/lib/rules/no-restricted-imports.js
+++ b/tests/lib/rules/no-restricted-imports.js
@@ -20,6 +20,7 @@ const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6, sourceType:
 
 ruleTester.run("no-restricted-imports", rule, {
     valid: [
+        "import os from \"os\";",
         { code: "import os from \"os\";", options: ["osx"] },
         { code: "import fs from \"fs\";", options: ["crypto"] },
         { code: "import path from \"path\";", options: ["crypto", "stream", "os"] },
diff --git a/tests/lib/rules/no-unsafe-negation.js b/tests/lib/rules/no-unsafe-negation.js
index 9493bbb72..23e6cd5ce 100644
--- a/tests/lib/rules/no-unsafe-negation.js
+++ b/tests/lib/rules/no-unsafe-negation.js
@@ -17,27 +17,6 @@ const rule = require("../../../lib/rules/no-unsafe-negation"),
 //------------------------------------------------------------------------------
 
 const ruleTester = new RuleTester();
-const unexpectedInError = { messageId: "unexpected", data: { operator: "in" } };
-const unexpectedInstanceofError = {
-    messageId: "unexpected",
-    data: { operator: "instanceof" }
-};
-const unexpectedLessThanOperatorError = {
-    messageId: "unexpected",
-    data: { operator: "<" }
-};
-const unexpectedMoreThanOperatorError = {
-    messageId: "unexpected",
-    data: { operator: ">" }
-};
-const unexpectedMoreThanOrEqualOperatorError = {
-    messageId: "unexpected",
-    data: { operator: ">=" }
-};
-const unexpectedLessThanOrEqualOperatorError = {
-    messageId: "unexpected",
-    data: { operator: "<=" }
-};
 
 ruleTester.run("no-unsafe-negation", rule, {
     valid: [
@@ -83,52 +62,194 @@ ruleTester.run("no-unsafe-negation", rule, {
     invalid: [
         {
             code: "!a in b",
-            errors: [unexpectedInError]
+            errors: [{
+                message: "Unexpected negating the left operand of 'in' operator.",
+                suggestions: [
+                    {
+                        desc: "Negate 'in' expression instead of its left operand. This changes the current behavior.",
+                        output: "!(a in b)"
+                    },
+                    {
+                        desc: "Wrap negation in '()' to make the intention explicit. This preserves the current behavior.",
+                        output: "(!a) in b"
+                    }
+                ]
+            }]
         },
         {
             code: "(!a in b)",
-            errors: [unexpectedInError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: "in" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "(!(a in b))"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "((!a) in b)"
+                    }
+                ]
+            }]
         },
         {
             code: "!(a) in b",
-            errors: [unexpectedInError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: "in" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "!((a) in b)"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "(!(a)) in b"
+                    }
+                ]
+            }]
         },
         {
             code: "!a instanceof b",
-            errors: [unexpectedInstanceofError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: "instanceof" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "!(a instanceof b)"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "(!a) instanceof b"
+                    }
+                ]
+            }]
         },
         {
             code: "(!a instanceof b)",
-            errors: [unexpectedInstanceofError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: "instanceof" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "(!(a instanceof b))"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "((!a) instanceof b)"
+                    }
+                ]
+            }]
         },
         {
             code: "!(a) instanceof b",
-            errors: [unexpectedInstanceofError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: "instanceof" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "!((a) instanceof b)"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "(!(a)) instanceof b"
+                    }
+                ]
+            }]
         },
         {
             code: "if (! a < b) {}",
             options: [{ enforceForOrderingRelations: true }],
-            errors: [unexpectedLessThanOperatorError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: "<" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "if (!( a < b)) {}"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "if ((! a) < b) {}"
+                    }
+                ]
+            }]
         },
         {
             code: "while (! a > b) {}",
             options: [{ enforceForOrderingRelations: true }],
-            errors: [unexpectedMoreThanOperatorError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: ">" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "while (!( a > b)) {}"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "while ((! a) > b) {}"
+                    }
+                ]
+            }]
         },
         {
             code: "foo = ! a <= b;",
             options: [{ enforceForOrderingRelations: true }],
-            errors: [unexpectedLessThanOrEqualOperatorError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: "<=" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "foo = !( a <= b);"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "foo = (! a) <= b;"
+                    }
+                ]
+            }]
         },
         {
             code: "foo = ! a >= b;",
             options: [{ enforceForOrderingRelations: true }],
-            errors: [unexpectedMoreThanOrEqualOperatorError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: ">=" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "foo = !( a >= b);"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "foo = (! a) >= b;"
+                    }
+                ]
+            }]
         },
         {
             code: "! a <= b",
             options: [{ enforceForOrderingRelations: true }],
-            errors: [unexpectedLessThanOrEqualOperatorError]
+            errors: [{
+                messageId: "unexpected",
+                data: { operator: "<=" },
+                suggestions: [
+                    {
+                        messageId: "suggestNegatedExpression",
+                        output: "!( a <= b)"
+                    },
+                    {
+                        messageId: "suggestParenthesisedNegation",
+                        output: "(! a) <= b"
+                    }
+                ]
+            }]
         }
     ]
 });
diff --git a/tests/lib/rules/no-void.js b/tests/lib/rules/no-void.js
index 2d12718d8..2a1ee1d9a 100644
--- a/tests/lib/rules/no-void.js
+++ b/tests/lib/rules/no-void.js
@@ -8,8 +8,8 @@
 // Requirements
 //------------------------------------------------------------------------------
 
-const rule = require("../../../lib/rules/no-void"),
-    { RuleTester } = require("../../../lib/rule-tester");
+const rule = require("../../../lib/rules/no-void");
+const { RuleTester } = require("../../../lib/rule-tester");
 
 //------------------------------------------------------------------------------
 // Tests
@@ -18,32 +18,48 @@ const rule = require("../../../lib/rules/no-void"),
 const ruleTester = new RuleTester();
 
 ruleTester.run("no-void", rule, {
-
     valid: [
         "var foo = bar()",
         "foo.void()",
         "foo.void = bar",
-        "delete foo;"
+        "delete foo;",
+        {
+            code: "void 0",
+            options: [{ allowAsStatement: true }]
+        },
+        {
+            code: "void(0)",
+            options: [{ allowAsStatement: true }]
+        }
     ],
 
     invalid: [
         {
             code: "void 0",
-            errors: [{
-                message: "Expected 'undefined' and instead saw 'void'."
-            }]
+            errors: [{ messageId: "noVoid" }]
+        },
+        {
+            code: "void 0",
+            options: [{}],
+            errors: [{ messageId: "noVoid" }]
+        },
+        {
+            code: "void 0",
+            options: [{ allowAsStatement: false }],
+            errors: [{ messageId: "noVoid" }]
         },
         {
             code: "void(0)",
-            errors: [{
-                message: "Expected 'undefined' and instead saw 'void'."
-            }]
+            errors: [{ messageId: "noVoid" }]
+        },
+        {
+            code: "var foo = void 0",
+            errors: [{ messageId: "noVoid" }]
         },
         {
             code: "var foo = void 0",
-            errors: [{
-                message: "Expected 'undefined' and instead saw 'void'."
-            }]
+            options: [{ allowAsStatement: true }],
+            errors: [{ messageId: "noVoid" }]
         }
     ]
 });
diff --git a/tests/lib/rules/prefer-numeric-literals.js b/tests/lib/rules/prefer-numeric-literals.js
index ddd6e36c8..4d3037f44 100644
--- a/tests/lib/rules/prefer-numeric-literals.js
+++ b/tests/lib/rules/prefer-numeric-literals.js
@@ -31,7 +31,28 @@ ruleTester.run("prefer-numeric-literals", rule, {
         "parseInt(foo);",
         "parseInt(foo, 2);",
         "Number.parseInt(foo);",
-        "Number.parseInt(foo, 2);"
+        "Number.parseInt(foo, 2);",
+        "parseInt(11, 2);",
+        "Number.parseInt(1, 8);",
+        "parseInt(1e5, 16);",
+        "parseInt('11', '2');",
+        "Number.parseInt('11', '8');",
+        {
+            code: "parseInt('11', 2n);",
+            parserOptions: { ecmaVersion: 2020 }
+        },
+        {
+            code: "Number.parseInt('11', 8n);",
+            parserOptions: { ecmaVersion: 2020 }
+        },
+        {
+            code: "parseInt('11', 16n);",
+            parserOptions: { ecmaVersion: 2020 }
+        },
+        {
+            code: "parseInt(1n, 2);",
+            parserOptions: { ecmaVersion: 2020 }
+        }
     ],
     invalid: [
         {
diff --git a/tests/lib/rules/yield-star-spacing.js b/tests/lib/rules/yield-star-spacing.js
index 0665f648e..9c8aaff95 100644
--- a/tests/lib/rules/yield-star-spacing.js
+++ b/tests/lib/rules/yield-star-spacing.js
@@ -137,6 +137,24 @@ ruleTester.run("yield-star-spacing", rule, {
         {
             code: "function *foo(){ var result = yield*foo(); }",
             options: ["neither"]
+        },
+
+        // object option
+        {
+            code: "function *foo(){ yield* foo; }",
+            options: [{ before: false, after: true }]
+        },
+        {
+            code: "function *foo(){ yield *foo; }",
+            options: [{ before: true, after: false }]
+        },
+        {
+            code: "function *foo(){ yield * foo; }",
+            options: [{ before: true, after: true }]
+        },
+        {
+            code: "function *foo(){ yield*foo; }",
+            options: [{ before: false, after: false }]
         }
     ],
 
@@ -227,6 +245,32 @@ ruleTester.run("yield-star-spacing", rule, {
             output: "function *foo(){ yield*foo; }",
             options: ["neither"],
             errors: [unexpectedBeforeError, unexpectedAfterError]
+        },
+
+        // object option
+        {
+            code: "function *foo(){ yield*foo; }",
+            output: "function *foo(){ yield* foo; }",
+            options: [{ before: false, after: true }],
+            errors: [missingAfterError]
+        },
+        {
+            code: "function *foo(){ yield * foo; }",
+            output: "function *foo(){ yield *foo; }",
+            options: [{ before: true, after: false }],
+            errors: [unexpectedAfterError]
+        },
+        {
+            code: "function *foo(){ yield*foo; }",
+            output: "function *foo(){ yield * foo; }",
+            options: [{ before: true, after: true }],
+            errors: [missingBeforeError, missingAfterError]
+        },
+        {
+            code: "function *foo(){ yield * foo; }",
+            output: "function *foo(){ yield*foo; }",
+            options: [{ before: false, after: false }],
+            errors: [unexpectedBeforeError, unexpectedAfterError]
         }
     ]
 
diff --git a/tests/lib/shared/config-validator.js b/tests/lib/shared/config-validator.js
index 1c4cfe895..95976fc9f 100644
--- a/tests/lib/shared/config-validator.js
+++ b/tests/lib/shared/config-validator.js
@@ -114,6 +114,7 @@ describe("Validator", () => {
         it("should do nothing with a valid eslint config", () => {
             validator.validate(
                 {
+                    $schema: "http://json.schemastore.org/eslintrc",
                     root: true,
                     globals: { globalFoo: "readonly" },
                     parser: "parserFoo",
diff --git a/tests/lib/source-code/source-code.js b/tests/lib/source-code/source-code.js
index 29dbf1d6f..e89f9a328 100644
--- a/tests/lib/source-code/source-code.js
+++ b/tests/lib/source-code/source-code.js
@@ -2076,6 +2076,69 @@ describe("SourceCode", () => {
                     });
                 });
             });
+
+            it("JSXText tokens that contain only whitespaces should NOT be handled as space", () => {
+                const code = "let jsx = <div>\n   {content}\n</div>";
+                const ast = espree.parse(code, { ...DEFAULT_CONFIG, ecmaFeatures: { jsx: true } });
+                const sourceCode = new SourceCode(code, ast);
+                const jsx = ast.body[0].declarations[0].init;
+                const interpolation = jsx.children[1];
+
+                assert.strictEqual(
+                    sourceCode.isSpaceBetween(jsx.openingElement, interpolation),
+                    false
+                );
+                assert.strictEqual(
+                    sourceCode.isSpaceBetween(interpolation, jsx.closingElement),
+                    false
+                );
+
+                // Reversed order
+                assert.strictEqual(
+                    sourceCode.isSpaceBetween(interpolation, jsx.openingElement),
+                    false
+                );
+                assert.strictEqual(
+                    sourceCode.isSpaceBetween(jsx.closingElement, interpolation),
+                    false
+                );
+            });
+
+            it("JSXText tokens that contain both letters and whitespaces should NOT be handled as space", () => {
+                const code = "let jsx = <div>\n   Hello\n</div>";
+                const ast = espree.parse(code, { ...DEFAULT_CONFIG, ecmaFeatures: { jsx: true } });
+                const sourceCode = new SourceCode(code, ast);
+                const jsx = ast.body[0].declarations[0].init;
+
+                assert.strictEqual(
+                    sourceCode.isSpaceBetween(jsx.openingElement, jsx.closingElement),
+                    false
+                );
+
+                // Reversed order
+                assert.strictEqual(
+                    sourceCode.isSpaceBetween(jsx.closingElement, jsx.openingElement),
+                    false
+                );
+            });
+
+            it("JSXText tokens that contain only letters should NOT be handled as space", () => {
+                const code = "let jsx = <div>Hello</div>";
+                const ast = espree.parse(code, { ...DEFAULT_CONFIG, ecmaFeatures: { jsx: true } });
+                const sourceCode = new SourceCode(code, ast);
+                const jsx = ast.body[0].declarations[0].init;
+
+                assert.strictEqual(
+                    sourceCode.isSpaceBetween(jsx.openingElement, jsx.closingElement),
+                    false
+                );
+
+                // Reversed order
+                assert.strictEqual(
+                    sourceCode.isSpaceBetween(jsx.closingElement, jsx.openingElement),
+                    false
+                );
+            });
         });
 
         describe("should return false either of the arguments' location is inside the other one", () => {
@@ -2409,6 +2472,69 @@ describe("SourceCode", () => {
                     });
                 });
             });
+
+            it("JSXText tokens that contain only whitespaces should be handled as space", () => {
+                const code = "let jsx = <div>\n   {content}\n</div>";
+                const ast = espree.parse(code, { ...DEFAULT_CONFIG, ecmaFeatures: { jsx: true } });
+                const sourceCode = new SourceCode(code, ast);
+                const jsx = ast.body[0].declarations[0].init;
+                const interpolation = jsx.children[1];
+
+                assert.strictEqual(
+                    sourceCode.isSpaceBetweenTokens(jsx.openingElement, interpolation),
+                    true
+                );
+                assert.strictEqual(
+                    sourceCode.isSpaceBetweenTokens(interpolation, jsx.closingElement),
+                    true
+                );
+
+                // Reversed order
+                assert.strictEqual(
+                    sourceCode.isSpaceBetweenTokens(interpolation, jsx.openingElement),
+                    true
+                );
+                assert.strictEqual(
+                    sourceCode.isSpaceBetweenTokens(jsx.closingElement, interpolation),
+                    true
+                );
+            });
+
+            it("JSXText tokens that contain both letters and whitespaces should be handled as space", () => {
+                const code = "let jsx = <div>\n   Hello\n</div>";
+                const ast = espree.parse(code, { ...DEFAULT_CONFIG, ecmaFeatures: { jsx: true } });
+                const sourceCode = new SourceCode(code, ast);
+                const jsx = ast.body[0].declarations[0].init;
+
+                assert.strictEqual(
+                    sourceCode.isSpaceBetweenTokens(jsx.openingElement, jsx.closingElement),
+                    true
+                );
+
+                // Reversed order
+                assert.strictEqual(
+                    sourceCode.isSpaceBetweenTokens(jsx.closingElement, jsx.openingElement),
+                    true
+                );
+            });
+
+            it("JSXText tokens that contain only letters should NOT be handled as space", () => {
+                const code = "let jsx = <div>Hello</div>";
+                const ast = espree.parse(code, { ...DEFAULT_CONFIG, ecmaFeatures: { jsx: true } });
+                const sourceCode = new SourceCode(code, ast);
+                const jsx = ast.body[0].declarations[0].init;
+
+                assert.strictEqual(
+                    sourceCode.isSpaceBetweenTokens(jsx.openingElement, jsx.closingElement),
+                    false
+                );
+
+                // Reversed order
+                assert.strictEqual(
+                    sourceCode.isSpaceBetweenTokens(jsx.closingElement, jsx.openingElement),
+                    false
+                );
+            });
         });
 
         describe("should return false either of the arguments' location is inside the other one", () => {