Repository: eslint/eslint
Pull request #12118 (2019-08-19 00:02:02)

Fix: quotes autofix produces syntax error with octal escape sequences
<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

**What is the purpose of this pull request? (put an "X" next to item)**

[X] Bug fix

<!--
    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.)
-->
**Tell us about your environment**

* **ESLint Version:** 6.2.0
* **Node Version:** 10.16.0
* **npm Version:** 6.9.0

**What parser (default, Babel-ESLint, etc.) are you using?**

default

**Please show your full configuration:**

<details>
<summary>Configuration</summary>

<!-- Paste your configuration below: -->
```js
module.exports = {
  parserOptions: {
    ecmaVersion: 2015,
  },
};
```

</details>

**What did you do? Please include the actual source code causing the issue.**

```js
/*eslint quotes: ["error", "backtick"]*/

var foo = '\1';
```

**What did you expect to happen?**

Given how `prefer-template` works in similar situations, to report a warning but without the auto-fix.

**What actually happened? Please include the actual, raw output from ESLint.**

Fixed to:

```js
/*eslint quotes: ["error", "backtick"]*/

var foo = `\1`;
```

```
3:12  error  Parsing error: Octal literal in template string
```

<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->

**What changes did you make? (Give an overview)**

Prevent fix to a template literal if the source string contains an octal escape sequence.

An alternative would be to not report that string at all.

**Is there anything you'd like reviewers to focus on?**



platinumazure: Is there an equivalent escape sequence that is allowed in templates? (Ideally in octal but other radix is good too)

To be clear, I'm not trying to suggest a complicated fix. I'm trying to establish if there is no way for the user to fix the issue (in which case, best not to report at all), or if there is a way they could change the code to get the same value.
mdjermanovic: I think there are only 'hex' (`\xXX`) and 'unicode' (`\uXXXX` or `\u{...}`) which is also hex notation, but there is no octal, unlike number literals which have `0oXX...`. 

So, there is a way to manually fix, but the user would be forced to convert octal -> hex. On the other hand octal escapes shouldn't be used anyway, as far as I know it's a legacy feature and is forbidden in strict mode.

Re the auto-fix, it might be not even too complicated, but I guess that rules such as `no-octal-escape`, `no-octal` and even `no-useless-escape`  don't have fixer although it wouldn't change behavior, because such literal might be a mistake rather than intention, and it could be better not to silently fix it.



Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 000000000..0667729f8
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,63 @@
+name: CI
+on:
+  push:
+    branches: [master]
+  pull_request:
+    branches: [master]
+
+jobs:
+  verify_files:
+    name: Verify Files
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - uses: actions/setup-node@v1
+    - name: Install Packages
+      run: npm install
+    - name: Lint Files
+      run: node Makefile lint
+    - name: Check Rule Files
+      run: node Makefile checkRuleFiles
+    - name: Check Licenses
+      run: node Makefile checkLicenses
+
+  test_on_node:
+    name: Test
+    strategy:
+      matrix:
+        os: [ubuntu-latest, windows-latest, macOS-latest]
+        node: [8.x, 10.x, 12.x]
+        exclude:
+        - os: windows-latest
+          node: 8.x
+        - os: windows-latest
+          node: 10.x
+        - os: macOS-latest
+          node: 8.x
+        - os: macOS-latest
+          node: 10.x
+    runs-on: ${{ matrix.os }}
+    steps:
+    - uses: actions/checkout@v1
+    - uses: actions/setup-node@v1
+      with:
+        version: ${{ matrix.node }}
+    - name: Install Packages
+      run: npm install
+    - name: Test
+      run: node Makefile mocha
+    - name: Fuzz Test
+      run: node Makefile fuzz
+
+  test_on_browser:
+    name: Browser Test
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v1
+    - uses: actions/setup-node@v1
+    - name: Install Packages
+      run: npm install
+    - name: Test
+      run: node Makefile karma
+    - name: Fuzz Test
+      run: node Makefile fuzz
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6ec977f6d..8e35b1451 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,36 @@
+v6.3.0 - August 30, 2019
+
+* [`0acdefb`](https://github.com/eslint/eslint/commit/0acdefb97f35bb09db2910540c70dc377a01ad62) Chore: refactor code (#12113) (James George)
+* [`52e2cf5`](https://github.com/eslint/eslint/commit/52e2cf50b35d57fb8466e0bcd0581eff1590fb4c) New: reportUnusedDisableDirectives in config (refs eslint/rfcs#22) (#12151) (Toru Nagashima)
+* [`020f952`](https://github.com/eslint/eslint/commit/020f9526b618a191566acea3e17e20815d484c58) Update: enforceForSequenceExpressions to no-extra-parens (fixes #11916) (#12142) (Milos Djermanovic)
+* [`aab1b84`](https://github.com/eslint/eslint/commit/aab1b840f9cffb2a76a5c9fe1852961be71dc184) Fix: reset to the default color (#12174) (Ricardo Gobbo de Souza)
+* [`4009d39`](https://github.com/eslint/eslint/commit/4009d39aa59451510aa24911e758d664f216289a) Fix: yoda rule produces invalid autofix with preceding yield (#12166) (Milos Djermanovic)
+* [`febb660`](https://github.com/eslint/eslint/commit/febb6605d350c936d64cb73e694482cfbb20b29c) Fix: no-extra-boolean-cast invalid autofix with yield before negation (#12164) (Milos Djermanovic)
+* [`4c0b70b`](https://github.com/eslint/eslint/commit/4c0b70b869c16647f7af6de9d5c5479fc19f49db) New: support TypeScript at config initializer (fixes #11789) (#12172) (Pig Fang)
+* [`94e39d9`](https://github.com/eslint/eslint/commit/94e39d9f782f45db86a079e07508d63040118ef1) Chore: use GitHub Actions (#12144) (Toru Nagashima)
+* [`e88f305`](https://github.com/eslint/eslint/commit/e88f305df9d454868624c559fd93b981a680c215) Chore: support es2020 in fuzz (#12180) (薛定谔的猫)
+* [`00d2c5b`](https://github.com/eslint/eslint/commit/00d2c5be9a89efd90135c4368a9589f33df3f7ba) Docs: corrected class extension example (#12176) (Marius M)
+* [`31e5428`](https://github.com/eslint/eslint/commit/31e542819967b2aa1191e1abaa1c4a49fddbe3cf) Chore: Fix wrong error object keys in test files (#12162) (Milos Djermanovic)
+* [`197f443`](https://github.com/eslint/eslint/commit/197f4432fca70a574028e5568c48afad12213224) Fix: func-name-matching crash on descriptor-like arguments (#12100) (Milos Djermanovic)
+* [`644ce33`](https://github.com/eslint/eslint/commit/644ce3306748a33b74fc6a94be0267c2c9f19348) Fix: no-self-assign false positive with rest and spread in array (#12099) (Milos Djermanovic)
+* [`a81d263`](https://github.com/eslint/eslint/commit/a81d2636ce41fb34d6826c2e9857814e11cb9c30) Fix: fix message of function-paren-newline (#12136) (Pig Fang)
+* [`77f8ed1`](https://github.com/eslint/eslint/commit/77f8ed1ad9656c526217ce54a6717fa232d522c8) Chore: update blogpost template (#12154) (Toru Nagashima)
+* [`6abc7b7`](https://github.com/eslint/eslint/commit/6abc7b72dfb824a372379708ca39340b2c7abc03) Docs: Document the exception in no-unsafe-negation (#12161) (Milos Djermanovic)
+
+v6.2.2 - August 23, 2019
+
+* [`0e0b784`](https://github.com/eslint/eslint/commit/0e0b784b922051c2a1d39dd8160382114b645800) Upgrade: espree@^6.1.1 (#12158) (Kevin Partington)
+* [`04e859f`](https://github.com/eslint/eslint/commit/04e859f228d081efd3af6edb22563dbc775f8d1d) Sponsors: Sync README with website (ESLint Jenkins)
+* [`34783d1`](https://github.com/eslint/eslint/commit/34783d10ff9b58a3c1e39a36e10864caeb9f66e0) Sponsors: Sync README with website (ESLint Jenkins)
+* [`b809e72`](https://github.com/eslint/eslint/commit/b809e72221bc658e5a42bfd4b8723d3771571f9e) Docs: Update README team and sponsors (ESLint Jenkins)
+
+v6.2.1 - August 20, 2019
+
+* [`8c021b5`](https://github.com/eslint/eslint/commit/8c021b5917b3aa3c578ffe3972106d0a6bcf0838) Upgrade: eslint-utils 1.4.2 (#12131) (Toru Nagashima)
+* [`e82388b`](https://github.com/eslint/eslint/commit/e82388bd87717430200ec554634cc08806e38d3c) Sponsors: Sync README with website (ESLint Jenkins)
+* [`4aeeeed`](https://github.com/eslint/eslint/commit/4aeeeedb656ee3519ea82ebf0cb41ca801215046) Docs: update docs for ecmaVersion 2020 (#12120) (silverwind)
+* [`6886148`](https://github.com/eslint/eslint/commit/6886148d1f528659ec3e125f61ef7a5f4c67556d) Docs: Add duplicate keys limitation to accessor-pairs (#12124) (Milos Djermanovic)
+
 v6.2.0 - August 18, 2019
 
 * [`fee6acb`](https://github.com/eslint/eslint/commit/fee6acbe13cecd4c028e681e185fc6a6d6ba9452) Update: support bigint and dynamic import (refs #11803) (#11983) (Toru Nagashima)
diff --git a/Makefile.js b/Makefile.js
index 02386d2f4..a01d13bde 100644
--- a/Makefile.js
+++ b/Makefile.js
@@ -497,7 +497,7 @@ target.lint = function() {
     }
 };
 
-target.fuzz = function({ amount = process.env.CI ? 1000 : 300, fuzzBrokenAutofixes = true } = {}) {
+target.fuzz = function({ amount = 1000, fuzzBrokenAutofixes = false } = {}) {
     const fuzzerRunner = require("./tools/fuzzer-runner");
     const fuzzResults = fuzzerRunner.run({ amount, fuzzBrokenAutofixes });
 
@@ -536,18 +536,13 @@ target.fuzz = function({ amount = process.env.CI ? 1000 : 300, fuzzBrokenAutofix
     }
 };
 
-target.test = function() {
-    target.lint();
-    target.checkRuleFiles();
+target.mocha = () => {
     let errors = 0,
         lastReturn;
 
     echo("Running unit tests");
 
-    // In CI (Azure Pipelines), use JUnit reporter.
-    const reporter = process.env.TF_BUILD ? "mocha-junit-reporter" : "progress";
-
-    lastReturn = exec(`${getBinFile("nyc")} -- ${MOCHA} -R ${reporter} -t ${MOCHA_TIMEOUT} -c ${TEST_FILES}`);
+    lastReturn = exec(`${getBinFile("nyc")} -- ${MOCHA} -R progress -t ${MOCHA_TIMEOUT} -c ${TEST_FILES}`);
     if (lastReturn.code !== 0) {
         errors++;
     }
@@ -557,6 +552,14 @@ target.test = function() {
         errors++;
     }
 
+    if (errors) {
+        exit(1);
+    }
+};
+
+target.karma = () => {
+    echo("Running unit tests on browsers");
+
     target.webpack();
 
     const browserFileLintOutput = new CLIEngine({
@@ -569,20 +572,22 @@ target.test = function() {
     if (browserFileLintOutput.errorCount > 0) {
         echo(`error: Failed to lint ${BUILD_DIR}/eslint.js as ES5 code`);
         echo(CLIEngine.getFormatter("stylish")(browserFileLintOutput.results));
-        errors++;
+        exit(1);
     }
 
-    lastReturn = exec(`${getBinFile("karma")} start karma.conf.js`);
-    if (lastReturn.code !== 0) {
-        errors++;
-    }
+    const lastReturn = exec(`${getBinFile("karma")} start karma.conf.js`);
 
-    if (errors) {
+    if (lastReturn.code !== 0) {
         exit(1);
     }
+};
 
+target.test = function() {
+    target.lint();
+    target.checkRuleFiles();
+    target.mocha();
+    target.karma();
     target.fuzz({ amount: 150, fuzzBrokenAutofixes: false });
-
     target.checkLicenses();
 };
 
diff --git a/README.md b/README.md
index 061eafefc..134c991d8 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,6 @@
 [![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)
 [![Join the chat at https://gitter.im/eslint/eslint](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/eslint/eslint?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@@ -244,6 +245,11 @@ The people who review and fix bugs and help triage issues.
 <img src="https://github.com/g-plane.png?s=75" width="75" height="75"><br />
 Pig Fang
 </a>
+</td><td align="center" valign="top" width="11%">
+<a href="https://github.com/mdjermanovic">
+<img src="https://github.com/mdjermanovic.png?s=75" width="75" height="75"><br />
+Milos Djermanovic
+</a>
 </td></tr></tbody></table>
 
 
@@ -256,9 +262,9 @@ The following companies, organizations, and individuals support ESLint's ongoing
 <!-- NOTE: This section is autogenerated. Do not manually edit.-->
 <!--sponsorsstart-->
 <h3>Gold Sponsors</h3>
-<p><a href="https://www.shopify.com"><img src="https://images.opencollective.com/shopify/eeb91aa/logo.png" alt="Shopify" height="96"></a> <a href="http://salesforce.com"><img src="https://images.opencollective.com/salesforce/853ecef/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/001a341/logo.png" alt="Airbnb" height="96"></a> <a href="https://code.facebook.com/projects/"><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.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/d1b37c4/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/001a341/logo.png" alt="Airbnb" height="96"></a> <a href="https://code.facebook.com/projects/"><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://icons8.com"><img src="https://images.opencollective.com/icons8/0b37d14/logo.png" alt="Free Icons by Icons8" height="32"></a> <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://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/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> <a href="https://faithlife.com/ref/about"><img src="https://images.opencollective.com/faithlife/534b832/logo.png" alt="Faithlife" height="32"></a></p>
+<p><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://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://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/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/conf/config-schema.js b/conf/config-schema.js
index d89bf0f58..164f0b421 100644
--- a/conf/config-schema.js
+++ b/conf/config-schema.js
@@ -21,6 +21,7 @@ const baseConfigProperties = {
     rules: { type: "object" },
     settings: { type: "object" },
     noInlineConfig: { type: "boolean" },
+    reportUnusedDisableDirectives: { type: "boolean" },
 
     ecmaFeatures: { type: "object" } // deprecated; logs a warning when used
 };
diff --git a/conf/default-cli-options.js b/conf/default-cli-options.js
index 9670a14b0..abbd9184e 100644
--- a/conf/default-cli-options.js
+++ b/conf/default-cli-options.js
@@ -26,6 +26,6 @@ module.exports = {
     cacheFile: ".eslintcache",
     fix: false,
     allowInlineConfig: true,
-    reportUnusedDisableDirectives: false,
+    reportUnusedDisableDirectives: void 0,
     globInputPaths: true
 };
diff --git a/docs/rules/accessor-pairs.md b/docs/rules/accessor-pairs.md
index 207eedeac..183bc42b6 100644
--- a/docs/rules/accessor-pairs.md
+++ b/docs/rules/accessor-pairs.md
@@ -164,6 +164,28 @@ var o = {
 };
 ```
 
+Also, this rule does not disallow duplicate keys in object literals, and in certain cases with duplicate keys
+might not report a missing pair for a getter/setter, like in the following example:
+
+```js
+/*eslint accessor-pairs: "error"*/
+
+// no warnings
+var o = {
+    get a() {
+        return this.val;
+    },
+    a: 1,
+    set a(value) {
+        this.val = value;
+    }
+};
+```
+
+The code above creates an object with just a setter for the property `"a"`.
+
+See [no-dupe-keys](no-dupe-keys.md) if you also want to disallow duplicate keys in object literals.
+
 ## When Not To Use It
 
 You can turn this rule off if you are not concerned with the simultaneous presence of setters and getters on objects.
diff --git a/docs/rules/no-extra-parens.md b/docs/rules/no-extra-parens.md
index 61fb50dc3..1896d0a9e 100644
--- a/docs/rules/no-extra-parens.md
+++ b/docs/rules/no-extra-parens.md
@@ -24,6 +24,7 @@ This rule has an object option for exceptions to the `"all"` option:
 * `"nestedBinaryExpressions": false` allows extra parentheses in nested binary expressions
 * `"ignoreJSX": "none|all|multi-line|single-line"` allows extra parentheses around no/all/multi-line/single-line JSX components. Defaults to `none`.
 * `"enforceForArrowConditionals": false` allows extra parentheses around ternary expressions which are the body of an arrow function
+* `"enforceForSequenceExpressions": false` allows extra parentheses around sequence expressions
 
 ### all
 
@@ -192,6 +193,20 @@ const b = a => 1 ? 2 : 3;
 const d = c => (1 ? 2 : 3);
 ```
 
+### enforceForSequenceExpressions
+
+Examples of **correct** code for this rule with the `"all"` and `{ "enforceForSequenceExpressions": false }` options:
+
+```js
+/* eslint no-extra-parens: ["error", "all", { "enforceForSequenceExpressions": false }] */
+
+(a, b);
+
+if ((val = foo(), val < 10)) {}
+
+while ((val = foo(), val < 10));
+```
+
 ### functions
 
 Examples of **incorrect** code for this rule with the `"functions"` option:
diff --git a/docs/rules/no-unsafe-negation.md b/docs/rules/no-unsafe-negation.md
index 8e1428ea9..880e9f644 100644
--- a/docs/rules/no-unsafe-negation.md
+++ b/docs/rules/no-unsafe-negation.md
@@ -39,10 +39,36 @@ if (!(key in object)) {
 if (!(obj instanceof Ctor)) {
     // obj is not an instance of Ctor
 }
+```
+
+### Exception
+
+For rare situations when negating the left operand is intended, this rule allows an exception.
+If the whole negation is explicitly wrapped in parentheses, the rule will not report a problem.
+
+Examples of **correct** code for this rule:
+
+```js
+/*eslint no-unsafe-negation: "error"*/
+
+if ((!foo) in object) {
+    // allowed, because the negation is explicitly wrapped in parentheses
+    // it is equivalent to (foo ? "false" : "true") in object
+    // this is allowed as an exception for rare situations when that is the intended meaning
+}
+
+if(("" + !foo) in object) {
+    // you can also make the intention more explicit, with type conversion
+}
+```
+
+Examples of **incorrect** code for this rule:
+
+```js
+/*eslint no-unsafe-negation: "error"*/
 
-if(("" + !key) in object) {
-    // make operator precedence and type conversion explicit
-    // in a rare situation when that is the intended meaning
+if (!(foo) in object) {
+    // this is not an allowed exception
 }
 ```
 
diff --git a/docs/rules/no-useless-constructor.md b/docs/rules/no-useless-constructor.md
index dbc0d8bce..cdfe5052f 100644
--- a/docs/rules/no-useless-constructor.md
+++ b/docs/rules/no-useless-constructor.md
@@ -8,7 +8,7 @@ class A {
     }
 }
 
-class A extends B {
+class B extends A {
     constructor (value) {
       super(value);
     }
@@ -32,7 +32,7 @@ class A {
     }
 }
 
-class A extends B {
+class B extends A {
     constructor (...args) {
       super(...args);
     }
@@ -52,13 +52,13 @@ class A {
     }
 }
 
-class A extends B {
+class B extends A {
     constructor() {
         super('foo');
     }
 }
 
-class A extends B {
+class B extends A {
     constructor() {
         super();
         doSomething();
diff --git a/docs/user-guide/configuring.md b/docs/user-guide/configuring.md
index 6132c46bf..0818f85e2 100644
--- a/docs/user-guide/configuring.md
+++ b/docs/user-guide/configuring.md
@@ -26,7 +26,7 @@ For ES6 syntax, use `{ "parserOptions": { "ecmaVersion": 6 } }`; for new ES6 glo
 { "es6": true } }`. `{ "env": { "es6": true } }` enables ES6 syntax automatically, but `{ "parserOptions": { "ecmaVersion": 6 } }` does not enable ES6 globals automatically.
 Parser options are set in your `.eslintrc.*` file by using the `parserOptions` property. The available options are:
 
-* `ecmaVersion` - set to 3, 5 (default), 6, 7, 8, 9, or 10 to specify the version of ECMAScript syntax you want to use. You can also set to 2015 (same as 6), 2016 (same as 7), 2017 (same as 8), 2018 (same as 9), or 2019 (same as 10) to use the year-based naming.
+* `ecmaVersion` - set to 3, 5 (default), 6, 7, 8, 9, 10 or 11 to specify the version of ECMAScript syntax you want to use. You can also set to 2015 (same as 6), 2016 (same as 7), 2017 (same as 8), 2018 (same as 9), 2019 (same as 10) or 2020 (same as 11) to use the year-based naming.
 * `sourceType` - set to `"script"` (default) or `"module"` if your code is in ECMAScript modules.
 * `ecmaFeatures` - an object indicating which additional language features you'd like to use:
     * `globalReturn` - allow `return` statements in the global scope
@@ -530,6 +530,34 @@ To disable rules inside of a configuration file for a group of files, use the `o
 }
 ```
 
+## Configuring Inline Comment Behaviors
+
+### Disabling Inline Comments
+
+To disable all inline config comments, use `noInlineConfig` setting. For example:
+
+```json
+{
+  "rules": {...},
+  "noInlineConfig": true
+}
+```
+
+This setting is similar to [--no-inline-config](./command-line-interface.md#--no-inline-config) CLI option.
+
+### Report Unused `eslint-disable` Comments
+
+To report unused `eslint-disable` comments, use `reportUnusedDisableDirectives` setting. For example:
+
+```json
+{
+  "rules": {...},
+  "reportUnusedDisableDirectives": true
+}
+```
+
+This setting is similar to [--report-unused-disable-directives](./command-line-interface.md#--report-unused-disable-directives) CLI option, but doesn't fail linting (reports as `"warn"` severity).
+
 ## Adding Shared Settings
 
 ESLint supports adding shared settings into configuration file. You can add `settings` object to ESLint configuration file and it will be supplied to every rule that will be executed. This may be useful if you are adding custom rules and want them to have access to the same information and be easily configurable.
diff --git a/lib/cli-engine/config-array-factory.js b/lib/cli-engine/config-array-factory.js
index 0b2ed07b6..6e1ba1e02 100644
--- a/lib/cli-engine/config-array-factory.js
+++ b/lib/cli-engine/config-array-factory.js
@@ -531,6 +531,7 @@ class ConfigArrayFactory {
             parserOptions,
             plugins: pluginList,
             processor,
+            reportUnusedDisableDirectives,
             root,
             rules,
             settings,
@@ -573,6 +574,7 @@ class ConfigArrayFactory {
             parserOptions,
             plugins,
             processor,
+            reportUnusedDisableDirectives,
             root,
             rules,
             settings
diff --git a/lib/cli-engine/config-array/config-array.js b/lib/cli-engine/config-array/config-array.js
index 0859868d8..6383c0211 100644
--- a/lib/cli-engine/config-array/config-array.js
+++ b/lib/cli-engine/config-array/config-array.js
@@ -59,6 +59,7 @@ const { ExtractedConfig } = require("./extracted-config");
  * @property {Object|undefined} parserOptions The parser options.
  * @property {Record<string, DependentPlugin>|undefined} plugins The plugin loaders.
  * @property {string|undefined} processor The processor name to refer plugin's processor.
+ * @property {boolean|undefined} reportUnusedDisableDirectives The flag to report unused `eslint-disable` comments.
  * @property {boolean|undefined} root The flag to express root.
  * @property {Record<string, RuleConf>|undefined} rules The rule settings
  * @property {Object|undefined} settings The shared settings.
@@ -257,6 +258,11 @@ function createConfig(instance, indices) {
             config.configNameOfNoInlineConfig = element.name;
         }
 
+        // Adopt the reportUnusedDisableDirectives which was found at first.
+        if (config.reportUnusedDisableDirectives === void 0 && element.reportUnusedDisableDirectives !== void 0) {
+            config.reportUnusedDisableDirectives = element.reportUnusedDisableDirectives;
+        }
+
         // Merge others.
         mergeWithoutOverwrite(config.env, element.env);
         mergeWithoutOverwrite(config.globals, element.globals);
diff --git a/lib/cli-engine/config-array/extracted-config.js b/lib/cli-engine/config-array/extracted-config.js
index 53208c16e..66858313b 100644
--- a/lib/cli-engine/config-array/extracted-config.js
+++ b/lib/cli-engine/config-array/extracted-config.js
@@ -77,6 +77,12 @@ class ExtractedConfig {
          */
         this.processor = null;
 
+        /**
+         * The flag that reports unused `eslint-disable` directive comments.
+         * @type {boolean|undefined}
+         */
+        this.reportUnusedDisableDirectives = void 0;
+
         /**
          * Rule settings.
          * @type {Record<string, [SeverityConf, ...any[]]>}
diff --git a/lib/cli-engine/formatters/stylish.js b/lib/cli-engine/formatters/stylish.js
index ca132ffa8..a808448b6 100644
--- a/lib/cli-engine/formatters/stylish.js
+++ b/lib/cli-engine/formatters/stylish.js
@@ -96,5 +96,6 @@ module.exports = function(results) {
         }
     }
 
-    return total > 0 ? output : "";
+    // Resets output color, for prevent change on top level
+    return total > 0 ? chalk.reset(output) : "";
 };
diff --git a/lib/init/config-initializer.js b/lib/init/config-initializer.js
index 17aa96505..2e47e902c 100644
--- a/lib/init/config-initializer.js
+++ b/lib/init/config-initializer.js
@@ -120,6 +120,12 @@ function getModulesList(config, installESLint) {
         }
     }
 
+    const parser = config.parser || (config.parserOptions && config.parserOptions.parser);
+
+    if (parser) {
+        modules[parser] = "latest";
+    }
+
     if (installESLint === false) {
         delete modules.eslint;
     } else {
@@ -291,6 +297,20 @@ function processAnswers(answers) {
         config.extends.push("plugin:vue/essential");
     }
 
+    if (answers.typescript) {
+        if (answers.framework === "vue") {
+            config.parserOptions.parser = "@typescript-eslint/parser";
+        } else {
+            config.parser = "@typescript-eslint/parser";
+        }
+
+        if (Array.isArray(config.plugins)) {
+            config.plugins.push("@typescript-eslint");
+        } else {
+            config.plugins = ["@typescript-eslint"];
+        }
+    }
+
     // setup rules based on problems/style enforcement preferences
     if (answers.purpose === "problems") {
         config.extends.unshift("eslint:recommended");
@@ -306,6 +326,9 @@ function processAnswers(answers) {
             config = autoconfig.extendFromRecommended(config);
         }
     }
+    if (answers.typescript && config.extends.includes("eslint:recommended")) {
+        config.extends.push("plugin:@typescript-eslint/eslint-recommended");
+    }
 
     // normalize extends
     if (config.extends.length === 0) {
@@ -465,6 +488,12 @@ function promptUser() {
                 { name: "None of these", value: "none" }
             ]
         },
+        {
+            type: "confirm",
+            name: "typescript",
+            message: "Does your project use TypeScript?",
+            default: false
+        },
         {
             type: "checkbox",
             name: "env",
diff --git a/lib/init/npm-utils.js b/lib/init/npm-utils.js
index 3a680aae9..7fe7c6e7d 100644
--- a/lib/init/npm-utils.js
+++ b/lib/init/npm-utils.js
@@ -98,7 +98,7 @@ function fetchPeerDependencies(packageName) {
  *                                        and values are booleans indicating installation.
  */
 function check(packages, opt) {
-    let deps = [];
+    const deps = new Set();
     const pkgJson = (opt) ? findPackageJson(opt.startDir) : findPackageJson();
     let fileJson;
 
@@ -119,14 +119,14 @@ function check(packages, opt) {
         throw error;
     }
 
-    if (opt.devDependencies && typeof fileJson.devDependencies === "object") {
-        deps = deps.concat(Object.keys(fileJson.devDependencies));
-    }
-    if (opt.dependencies && typeof fileJson.dependencies === "object") {
-        deps = deps.concat(Object.keys(fileJson.dependencies));
-    }
+    ["dependencies", "devDependencies"].forEach(key => {
+        if (opt[key] && typeof fileJson[key] === "object") {
+            Object.keys(fileJson[key]).forEach(dep => deps.add(dep));
+        }
+    });
+
     return packages.reduce((status, pkg) => {
-        status[pkg] = deps.indexOf(pkg) !== -1;
+        status[pkg] = deps.has(pkg);
         return status;
     }, {});
 }
diff --git a/lib/linter/apply-disable-directives.js b/lib/linter/apply-disable-directives.js
index c764a9b70..41d6934ab 100644
--- a/lib/linter/apply-disable-directives.js
+++ b/lib/linter/apply-disable-directives.js
@@ -93,7 +93,7 @@ function applyDirectives(options) {
                 : "Unused eslint-disable directive (no problems were reported).",
             line: directive.unprocessedDirective.line,
             column: directive.unprocessedDirective.column,
-            severity: 2,
+            severity: options.reportUnusedDisableDirectives === "warn" ? 1 : 2,
             nodeType: null
         }));
 
@@ -114,17 +114,17 @@ function applyDirectives(options) {
  * comment for two different rules is represented as two directives).
  * @param {{ruleId: (string|null), line: number, column: number}[]} options.problems
  * A list of problems reported by rules, sorted by increasing location in the file, with one-based columns.
- * @param {boolean} options.reportUnusedDisableDirectives If `true`, adds additional problems for unused directives
+ * @param {"off" | "warn" | "error"} options.reportUnusedDisableDirectives If `"warn"` or `"error"`, adds additional problems for unused directives
  * @returns {{ruleId: (string|null), line: number, column: number}[]}
  * A list of reported problems that were not disabled by the directive comments.
  */
-module.exports = options => {
-    const blockDirectives = options.directives
+module.exports = ({ directives, problems, reportUnusedDisableDirectives = "off" }) => {
+    const blockDirectives = directives
         .filter(directive => directive.type === "disable" || directive.type === "enable")
         .map(directive => Object.assign({}, directive, { unprocessedDirective: directive }))
         .sort(compareLocations);
 
-    const lineDirectives = lodash.flatMap(options.directives, directive => {
+    const lineDirectives = lodash.flatMap(directives, directive => {
         switch (directive.type) {
             case "disable":
             case "enable":
@@ -147,10 +147,18 @@ module.exports = options => {
         }
     }).sort(compareLocations);
 
-    const blockDirectivesResult = applyDirectives({ problems: options.problems, directives: blockDirectives });
-    const lineDirectivesResult = applyDirectives({ problems: blockDirectivesResult.problems, directives: lineDirectives });
-
-    return options.reportUnusedDisableDirectives
+    const blockDirectivesResult = applyDirectives({
+        problems,
+        directives: blockDirectives,
+        reportUnusedDisableDirectives
+    });
+    const lineDirectivesResult = applyDirectives({
+        problems: blockDirectivesResult.problems,
+        directives: lineDirectives,
+        reportUnusedDisableDirectives
+    });
+
+    return reportUnusedDisableDirectives !== "off"
         ? lineDirectivesResult.problems
             .concat(blockDirectivesResult.unusedDisableDirectives)
             .concat(lineDirectivesResult.unusedDisableDirectives)
diff --git a/lib/linter/linter.js b/lib/linter/linter.js
index d367cef6c..7d1dc8c8c 100644
--- a/lib/linter/linter.js
+++ b/lib/linter/linter.js
@@ -54,6 +54,11 @@ const DEFAULT_ERROR_LOC = { start: { line: 1, column: 0 }, end: { line: 1, colum
 /** @typedef {import("../shared/types").Processor} Processor */
 /** @typedef {import("../shared/types").Rule} Rule */
 
+/**
+ * @template T
+ * @typedef {{ [P in keyof T]-?: T[P] }} Required
+ */
+
 /**
  * @typedef {Object} DisableDirective
  * @property {("disable"|"enable"|"disable-line"|"disable-next-line")} type
@@ -79,7 +84,7 @@ const DEFAULT_ERROR_LOC = { start: { line: 1, column: 0 }, end: { line: 1, colum
  * @property {boolean} [disableFixes] if `true` then the linter doesn't make `fix`
  *      properties into the lint result.
  * @property {string} [filename] the filename of the source code.
- * @property {boolean} [reportUnusedDisableDirectives] Adds reported errors for
+ * @property {boolean | "off" | "warn" | "error"} [reportUnusedDisableDirectives] Adds reported errors for
  *      unused `eslint-disable` directives.
  */
 
@@ -103,6 +108,12 @@ const DEFAULT_ERROR_LOC = { start: { line: 1, column: 0 }, end: { line: 1, colum
  *      whether fixes should be applied.
  */
 
+/**
+ * @typedef {Object} InternalOptions
+ * @property {string | null} warnInlineConfig The config name what `noInlineConfig` setting came from. If `noInlineConfig` setting didn't exist, this is null. If this is a config name, then the linter warns directive comments.
+ * @property {"off" | "warn" | "error"} reportUnusedDisableDirectives (boolean values were normalized)
+ */
+
 //------------------------------------------------------------------------------
 // Helpers
 //------------------------------------------------------------------------------
@@ -467,7 +478,7 @@ function normalizeFilename(filename) {
  * consistent shape.
  * @param {VerifyOptions} providedOptions Options
  * @param {ConfigData} config Config.
- * @returns {Required<VerifyOptions> & { warnInlineConfig: string|null }} Normalized options
+ * @returns {Required<VerifyOptions> & InternalOptions} Normalized options
  */
 function normalizeVerifyOptions(providedOptions, config) {
     const disableInlineConfig = config.noInlineConfig === true;
@@ -476,13 +487,22 @@ function normalizeVerifyOptions(providedOptions, config) {
         ? ` (${config.configNameOfNoInlineConfig})`
         : "";
 
+    let reportUnusedDisableDirectives = providedOptions.reportUnusedDisableDirectives;
+
+    if (typeof reportUnusedDisableDirectives === "boolean") {
+        reportUnusedDisableDirectives = reportUnusedDisableDirectives ? "error" : "off";
+    }
+    if (typeof reportUnusedDisableDirectives !== "string") {
+        reportUnusedDisableDirectives = config.reportUnusedDisableDirectives ? "warn" : "off";
+    }
+
     return {
         filename: normalizeFilename(providedOptions.filename || "<input>"),
         allowInlineConfig: !ignoreInlineConfig,
         warnInlineConfig: disableInlineConfig && !ignoreInlineConfig
             ? `your config${configNameOfNoInlineConfig}`
             : null,
-        reportUnusedDisableDirectives: Boolean(providedOptions.reportUnusedDisableDirectives),
+        reportUnusedDisableDirectives,
         disableFixes: Boolean(providedOptions.disableFixes)
     };
 }
diff --git a/lib/options.js b/lib/options.js
index be4c09b8e..440773a84 100644
--- a/lib/options.js
+++ b/lib/options.js
@@ -192,7 +192,7 @@ module.exports = optionator({
         {
             option: "report-unused-disable-directives",
             type: "Boolean",
-            default: false,
+            default: void 0,
             description: "Adds reported errors for unused eslint-disable directives"
         },
         {
diff --git a/lib/rules/func-name-matching.js b/lib/rules/func-name-matching.js
index 3c4ee510d..83430ffad 100644
--- a/lib/rules/func-name-matching.js
+++ b/lib/rules/func-name-matching.js
@@ -118,6 +118,7 @@ module.exports = {
                 return false;
             }
             return node.type === "CallExpression" &&
+                node.callee.type === "MemberExpression" &&
                 node.callee.object.name === objName &&
                 node.callee.property.name === funcName;
         }
diff --git a/lib/rules/function-paren-newline.js b/lib/rules/function-paren-newline.js
index c9f09fdef..894c8e331 100644
--- a/lib/rules/function-paren-newline.js
+++ b/lib/rules/function-paren-newline.js
@@ -51,8 +51,8 @@ module.exports = {
             expectedBefore: "Expected newline before ')'.",
             expectedAfter: "Expected newline after '('.",
             expectedBetween: "Expected newline between arguments/params.",
-            unexpectedBefore: "Unexpected newline before '('.",
-            unexpectedAfter: "Unexpected newline after ')'."
+            unexpectedBefore: "Unexpected newline before ')'.",
+            unexpectedAfter: "Unexpected newline after '('."
         }
     },
 
diff --git a/lib/rules/no-extra-boolean-cast.js b/lib/rules/no-extra-boolean-cast.js
index 9ae9b5be6..9bbd5546e 100644
--- a/lib/rules/no-extra-boolean-cast.js
+++ b/lib/rules/no-extra-boolean-cast.js
@@ -102,7 +102,17 @@ module.exports = {
                             if (hasCommentsInside(parent)) {
                                 return null;
                             }
-                            return fixer.replaceText(parent, sourceCode.getText(node.argument));
+
+                            let prefix = "";
+                            const tokenBefore = sourceCode.getTokenBefore(parent);
+                            const firstReplacementToken = sourceCode.getFirstToken(node.argument);
+
+                            if (tokenBefore && tokenBefore.range[1] === parent.range[0] &&
+                                    !astUtils.canTokensBeAdjacent(tokenBefore, firstReplacementToken)) {
+                                prefix = " ";
+                            }
+
+                            return fixer.replaceText(parent, prefix + sourceCode.getText(node.argument));
                         }
                     });
                 }
diff --git a/lib/rules/no-extra-parens.js b/lib/rules/no-extra-parens.js
index aa455c6a2..c5cf79047 100644
--- a/lib/rules/no-extra-parens.js
+++ b/lib/rules/no-extra-parens.js
@@ -49,7 +49,8 @@ module.exports = {
                                 nestedBinaryExpressions: { type: "boolean" },
                                 returnAssign: { type: "boolean" },
                                 ignoreJSX: { enum: ["none", "all", "single-line", "multi-line"] },
-                                enforceForArrowConditionals: { type: "boolean" }
+                                enforceForArrowConditionals: { type: "boolean" },
+                                enforceForSequenceExpressions: { type: "boolean" }
                             },
                             additionalProperties: false
                         }
@@ -77,6 +78,8 @@ module.exports = {
         const IGNORE_JSX = ALL_NODES && context.options[1] && context.options[1].ignoreJSX;
         const IGNORE_ARROW_CONDITIONALS = ALL_NODES && context.options[1] &&
             context.options[1].enforceForArrowConditionals === false;
+        const IGNORE_SEQUENCE_EXPRESSIONS = ALL_NODES && context.options[1] &&
+            context.options[1].enforceForSequenceExpressions === false;
 
         const PRECEDENCE_OF_ASSIGNMENT_EXPR = precedence({ type: "AssignmentExpression" });
         const PRECEDENCE_OF_UPDATE_EXPR = precedence({ type: "UpdateExpression" });
@@ -115,6 +118,10 @@ module.exports = {
                 }
             }
 
+            if (node.type === "SequenceExpression" && IGNORE_SEQUENCE_EXPRESSIONS) {
+                return false;
+            }
+
             return ALL_NODES || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
         }
 
diff --git a/lib/rules/no-self-assign.js b/lib/rules/no-self-assign.js
index 79fb50770..dc8bf9014 100644
--- a/lib/rules/no-self-assign.js
+++ b/lib/rules/no-self-assign.js
@@ -94,9 +94,19 @@ function eachSelfAssignment(left, right, props, report) {
         const end = Math.min(left.elements.length, right.elements.length);
 
         for (let i = 0; i < end; ++i) {
+            const leftElement = left.elements[i];
             const rightElement = right.elements[i];
 
-            eachSelfAssignment(left.elements[i], rightElement, props, report);
+            // Avoid cases such as [...a] = [...a, 1]
+            if (
+                leftElement &&
+                leftElement.type === "RestElement" &&
+                i < right.elements.length - 1
+            ) {
+                break;
+            }
+
+            eachSelfAssignment(leftElement, rightElement, props, report);
 
             // After a spread element, those indices are unknown.
             if (rightElement && rightElement.type === "SpreadElement") {
diff --git a/lib/rules/quotes.js b/lib/rules/quotes.js
index 28b20af29..5f260e55f 100644
--- a/lib/rules/quotes.js
+++ b/lib/rules/quotes.js
@@ -279,6 +279,12 @@ module.exports = {
                                 description: settings.description
                             },
                             fix(fixer) {
+                                if (quoteOption === "backtick" && astUtils.hasOctalEscapeSequence(rawVal)) {
+
+                                    // An octal escape sequence in a template literal would produce syntax error, even in non-strict mode.
+                                    return null;
+                                }
+
                                 return fixer.replaceText(node, settings.convert(node.raw));
                             }
                         });
diff --git a/lib/rules/yoda.js b/lib/rules/yoda.js
index 89c4a8afd..b00acf82c 100644
--- a/lib/rules/yoda.js
+++ b/lib/rules/yoda.js
@@ -274,13 +274,22 @@ module.exports = {
          * @returns {string} A string representation of the node with the sides and operator flipped
          */
         function getFlippedString(node) {
+            const tokenBefore = sourceCode.getTokenBefore(node);
             const operatorToken = sourceCode.getFirstTokenBetween(node.left, node.right, token => token.value === node.operator);
             const textBeforeOperator = sourceCode.getText().slice(sourceCode.getTokenBefore(operatorToken).range[1], operatorToken.range[0]);
             const textAfterOperator = sourceCode.getText().slice(operatorToken.range[1], sourceCode.getTokenAfter(operatorToken).range[0]);
             const leftText = sourceCode.getText().slice(node.range[0], sourceCode.getTokenBefore(operatorToken).range[1]);
-            const rightText = sourceCode.getText().slice(sourceCode.getTokenAfter(operatorToken).range[0], node.range[1]);
+            const firstRightToken = sourceCode.getTokenAfter(operatorToken);
+            const rightText = sourceCode.getText().slice(firstRightToken.range[0], node.range[1]);
 
-            return rightText + textBeforeOperator + OPERATOR_FLIP_MAP[operatorToken.value] + textAfterOperator + leftText;
+            let prefix = "";
+
+            if (tokenBefore && tokenBefore.range[1] === node.range[0] &&
+                    !astUtils.canTokensBeAdjacent(tokenBefore, firstRightToken)) {
+                prefix = " ";
+            }
+
+            return prefix + rightText + textBeforeOperator + OPERATOR_FLIP_MAP[operatorToken.value] + textAfterOperator + leftText;
         }
 
         //--------------------------------------------------------------------------
diff --git a/lib/shared/types.js b/lib/shared/types.js
index 8a889d21d..12bd0aed8 100644
--- a/lib/shared/types.js
+++ b/lib/shared/types.js
@@ -36,6 +36,7 @@ module.exports = {};
  * @property {ParserOptions} [parserOptions] The parser options.
  * @property {string[]} [plugins] The plugin specifiers.
  * @property {string} [processor] The processor specifier.
+ * @property {boolean|undefined} reportUnusedDisableDirectives The flag to report unused `eslint-disable` comments.
  * @property {boolean} [root] The root flag.
  * @property {Record<string, RuleConf>} [rules] The rule settings.
  * @property {Object} [settings] The shared settings.
@@ -54,6 +55,7 @@ module.exports = {};
  * @property {ParserOptions} [parserOptions] The parser options.
  * @property {string[]} [plugins] The plugin specifiers.
  * @property {string} [processor] The processor specifier.
+ * @property {boolean|undefined} reportUnusedDisableDirectives The flag to report unused `eslint-disable` comments.
  * @property {Record<string, RuleConf>} [rules] The rule settings.
  * @property {Object} [settings] The shared settings.
  */
diff --git a/package.json b/package.json
index 782d29c4f..b1490aeed 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint",
-  "version": "6.2.0",
+  "version": "6.3.0",
   "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
   "description": "An AST-based pattern checker for JavaScript.",
   "bin": {
@@ -50,9 +50,9 @@
     "debug": "^4.0.1",
     "doctrine": "^3.0.0",
     "eslint-scope": "^5.0.0",
-    "eslint-utils": "^1.4.0",
+    "eslint-utils": "^1.4.2",
     "eslint-visitor-keys": "^1.1.0",
-    "espree": "^6.1.0",
+    "espree": "^6.1.1",
     "esquery": "^1.0.1",
     "esutils": "^2.0.2",
     "file-entry-cache": "^5.0.1",
diff --git a/templates/blogpost.md.ejs b/templates/blogpost.md.ejs
index bbaa09fd6..a812a79d9 100644
--- a/templates/blogpost.md.ejs
+++ b/templates/blogpost.md.ejs
@@ -14,7 +14,7 @@ const RULE_REGEX = new RegExp(`\`?\\b(${ruleList.join("|")})\\b\`?`, "g");
 
 function linkify(line) {
     return line
-        .replace(/#(\d+)/g, "[#$1](https://github.com/eslint/eslint/issues/$1)")
+        .replace(/([^\s/]+[/][^\s/]+)?#(\d+)/g, (_, repo, num) => `[${repo || ""}#${num}](https://github.com/${repo || "eslint/eslint"}/issues/${num})`)
         .replace(RULE_REGEX, "[$&](/docs/rules/$1)");
 }
 
diff --git a/tools/eslint-fuzzer.js b/tools/eslint-fuzzer.js
index dce2b2352..dc0a65a8e 100644
--- a/tools/eslint-fuzzer.js
+++ b/tools/eslint-fuzzer.js
@@ -129,7 +129,7 @@ function fuzz(options) {
         const text = codeGenerator({ sourceType });
         const config = {
             rules: lodash.mapValues(ruleConfigs, lodash.sample),
-            parserOptions: { sourceType, ecmaVersion: 2018 }
+            parserOptions: { sourceType, ecmaVersion: 2020 }
         };
 
         let autofixResult;


Test patch:
diff --git a/tests/lib/cli-engine/cli-engine.js b/tests/lib/cli-engine/cli-engine.js
index dc42cfa68..d8591788f 100644
--- a/tests/lib/cli-engine/cli-engine.js
+++ b/tests/lib/cli-engine/cli-engine.js
@@ -3534,6 +3534,64 @@ describe("CLIEngine", () => {
                 assert.strictEqual(messages[0].message, "'/*globals*/' has no effect because you have 'noInlineConfig' setting in your config (.eslintrc.yml » eslint-config-foo).");
             });
         });
+
+        describe("with 'reportUnusedDisableDirectives' setting", () => {
+            const root = getFixturePath("cli-engine/reportUnusedDisableDirectives");
+
+            it("should warn unused 'eslint-disable' comments if 'reportUnusedDisableDirectives' was given.", () => {
+                CLIEngine = defineCLIEngineWithInMemoryFileSystem({
+                    cwd: () => root,
+                    files: {
+                        "test.js": "/* eslint-disable eqeqeq */",
+                        ".eslintrc.yml": "reportUnusedDisableDirectives: true"
+                    }
+                }).CLIEngine;
+                engine = new CLIEngine();
+
+                const { results } = engine.executeOnFiles(["test.js"]);
+                const messages = results[0].messages;
+
+                assert.strictEqual(messages.length, 1);
+                assert.strictEqual(messages[0].severity, 1);
+                assert.strictEqual(messages[0].message, "Unused eslint-disable directive (no problems were reported from 'eqeqeq').");
+            });
+
+            describe("the runtime option overrides config files.", () => {
+                it("should not warn unused 'eslint-disable' comments if 'reportUnusedDisableDirectives=off' was given in runtime.", () => {
+                    CLIEngine = defineCLIEngineWithInMemoryFileSystem({
+                        cwd: () => root,
+                        files: {
+                            "test.js": "/* eslint-disable eqeqeq */",
+                            ".eslintrc.yml": "reportUnusedDisableDirectives: true"
+                        }
+                    }).CLIEngine;
+                    engine = new CLIEngine({ reportUnusedDisableDirectives: "off" });
+
+                    const { results } = engine.executeOnFiles(["test.js"]);
+                    const messages = results[0].messages;
+
+                    assert.strictEqual(messages.length, 0);
+                });
+
+                it("should warn unused 'eslint-disable' comments as error if 'reportUnusedDisableDirectives=error' was given in runtime.", () => {
+                    CLIEngine = defineCLIEngineWithInMemoryFileSystem({
+                        cwd: () => root,
+                        files: {
+                            "test.js": "/* eslint-disable eqeqeq */",
+                            ".eslintrc.yml": "reportUnusedDisableDirectives: true"
+                        }
+                    }).CLIEngine;
+                    engine = new CLIEngine({ reportUnusedDisableDirectives: "error" });
+
+                    const { results } = engine.executeOnFiles(["test.js"]);
+                    const messages = results[0].messages;
+
+                    assert.strictEqual(messages.length, 1);
+                    assert.strictEqual(messages[0].severity, 2);
+                    assert.strictEqual(messages[0].message, "Unused eslint-disable directive (no problems were reported from 'eqeqeq').");
+                });
+            });
+        });
     });
 
     describe("getConfigForFile", () => {
diff --git a/tests/lib/cli-engine/config-array-factory.js b/tests/lib/cli-engine/config-array-factory.js
index b9f404dca..8b86b0f84 100644
--- a/tests/lib/cli-engine/config-array-factory.js
+++ b/tests/lib/cli-engine/config-array-factory.js
@@ -35,6 +35,7 @@ function assertConfigArrayElement(actual, providedExpected) {
         parserOptions: void 0,
         plugins: void 0,
         processor: void 0,
+        reportUnusedDisableDirectives: void 0,
         root: void 0,
         rules: void 0,
         settings: void 0,
@@ -58,6 +59,7 @@ function assertConfig(actual, providedExpected) {
         parser: null,
         parserOptions: {},
         plugins: [],
+        reportUnusedDisableDirectives: void 0,
         rules: {},
         settings: {},
         ...providedExpected
diff --git a/tests/lib/cli-engine/config-array/config-array.js b/tests/lib/cli-engine/config-array/config-array.js
index 82f3e7507..4e248af9f 100644
--- a/tests/lib/cli-engine/config-array/config-array.js
+++ b/tests/lib/cli-engine/config-array/config-array.js
@@ -436,6 +436,7 @@ describe("ConfigArray", () => {
                 },
                 plugins: {},
                 processor: null,
+                reportUnusedDisableDirectives: void 0,
                 rules: {},
                 settings: {}
             });
@@ -466,6 +467,7 @@ describe("ConfigArray", () => {
                 },
                 plugins: {},
                 processor: null,
+                reportUnusedDisableDirectives: void 0,
                 rules: {},
                 settings: {}
             });
@@ -607,7 +609,8 @@ describe("ConfigArray", () => {
                 },
                 settings: {},
                 processor: null,
-                noInlineConfig: void 0
+                noInlineConfig: void 0,
+                reportUnusedDisableDirectives: void 0
             });
             assert.deepStrictEqual(config[0], {
                 rules: {
diff --git a/tests/lib/cli-engine/formatters/stylish.js b/tests/lib/cli-engine/formatters/stylish.js
index b336df54b..54e66fbc1 100644
--- a/tests/lib/cli-engine/formatters/stylish.js
+++ b/tests/lib/cli-engine/formatters/stylish.js
@@ -19,6 +19,12 @@ const assert = require("chai").assert,
  * for Sinon to work.
  */
 const chalkStub = Object.create(chalk, {
+    reset: {
+        value(str) {
+            return chalk.reset(str);
+        },
+        writable: true
+    },
     yellow: {
         value(str) {
             return chalk.yellow(str);
@@ -47,6 +53,7 @@ describe("formatter:stylish", () => {
 
     beforeEach(() => {
         chalk.enabled = false;
+        sinon.spy(chalkStub, "reset");
         sinon.spy(chalkStub.yellow, "bold");
         sinon.spy(chalkStub.red, "bold");
     });
@@ -68,6 +75,7 @@ describe("formatter:stylish", () => {
             const result = formatter(code);
 
             assert.strictEqual(result, "");
+            assert.strictEqual(chalkStub.reset.callCount, 0);
             assert.strictEqual(chalkStub.yellow.bold.callCount, 0);
             assert.strictEqual(chalkStub.red.bold.callCount, 0);
         });
@@ -93,8 +101,10 @@ describe("formatter:stylish", () => {
             const result = formatter(code);
 
             assert.strictEqual(result, "\nfoo.js\n  5:10  error  Unexpected foo  foo\n\n\u2716 1 problem (1 error, 0 warnings)\n");
+            assert.strictEqual(chalkStub.reset.callCount, 1);
             assert.strictEqual(chalkStub.yellow.bold.callCount, 0);
             assert.strictEqual(chalkStub.red.bold.callCount, 1);
+
         });
 
         describe("when the error is fixable", () => {
@@ -106,6 +116,7 @@ describe("formatter:stylish", () => {
                 const result = formatter(code);
 
                 assert.strictEqual(result, "\nfoo.js\n  5:10  error  Unexpected foo  foo\n\n\u2716 1 problem (1 error, 0 warnings)\n  1 error and 0 warnings potentially fixable with the `--fix` option.\n");
+                assert.strictEqual(chalkStub.reset.callCount, 1);
                 assert.strictEqual(chalkStub.yellow.bold.callCount, 0);
                 assert.strictEqual(chalkStub.red.bold.callCount, 2);
             });
@@ -132,6 +143,7 @@ describe("formatter:stylish", () => {
             const result = formatter(code);
 
             assert.strictEqual(result, "\nfoo.js\n  5:10  warning  Unexpected foo  foo\n\n\u2716 1 problem (0 errors, 1 warning)\n");
+            assert.strictEqual(chalkStub.reset.callCount, 1);
             assert.strictEqual(chalkStub.yellow.bold.callCount, 1);
             assert.strictEqual(chalkStub.red.bold.callCount, 0);
         });
@@ -145,6 +157,7 @@ describe("formatter:stylish", () => {
                 const result = formatter(code);
 
                 assert.strictEqual(result, "\nfoo.js\n  5:10  warning  Unexpected foo  foo\n\n\u2716 1 problem (0 errors, 1 warning)\n  0 errors and 1 warning potentially fixable with the `--fix` option.\n");
+                assert.strictEqual(chalkStub.reset.callCount, 1);
                 assert.strictEqual(chalkStub.yellow.bold.callCount, 2);
                 assert.strictEqual(chalkStub.red.bold.callCount, 0);
             });
@@ -172,6 +185,7 @@ describe("formatter:stylish", () => {
             const result = formatter(code);
 
             assert.strictEqual(result, "\nfoo.js\n  5:10  warning  Unexpected .  foo\n\n\u2716 1 problem (0 errors, 1 warning)\n");
+            assert.strictEqual(chalkStub.reset.callCount, 1);
             assert.strictEqual(chalkStub.yellow.bold.callCount, 1);
             assert.strictEqual(chalkStub.red.bold.callCount, 0);
         });
@@ -195,6 +209,7 @@ describe("formatter:stylish", () => {
             const result = formatter(code);
 
             assert.strictEqual(result, "\nfoo.js\n  5:10  error  Unexpected foo  foo\n\n\u2716 1 problem (1 error, 0 warnings)\n");
+            assert.strictEqual(chalkStub.reset.callCount, 1);
             assert.strictEqual(chalkStub.yellow.bold.callCount, 0);
             assert.strictEqual(chalkStub.red.bold.callCount, 1);
         });
@@ -224,6 +239,7 @@ describe("formatter:stylish", () => {
             const result = formatter(code);
 
             assert.strictEqual(result, "\nfoo.js\n  5:10  error    Unexpected foo  foo\n  6:11  warning  Unexpected bar  bar\n\n\u2716 2 problems (1 error, 1 warning)\n");
+            assert.strictEqual(chalkStub.reset.callCount, 1);
             assert.strictEqual(chalkStub.yellow.bold.callCount, 0);
             assert.strictEqual(chalkStub.red.bold.callCount, 1);
         });
@@ -258,6 +274,7 @@ describe("formatter:stylish", () => {
             const result = formatter(code);
 
             assert.strictEqual(result, "\nfoo.js\n  5:10  error  Unexpected foo  foo\n\nbar.js\n  6:11  warning  Unexpected bar  bar\n\n\u2716 2 problems (1 error, 1 warning)\n");
+            assert.strictEqual(chalkStub.reset.callCount, 1);
             assert.strictEqual(chalkStub.yellow.bold.callCount, 0);
             assert.strictEqual(chalkStub.red.bold.callCount, 1);
         });
@@ -271,6 +288,7 @@ describe("formatter:stylish", () => {
             const result = formatter(code);
 
             assert.strictEqual(result, "\nfoo.js\n  5:10  error  Unexpected foo  foo\n\nbar.js\n  6:11  warning  Unexpected bar  bar\n\n\u2716 2 problems (2 errors, 0 warnings)\n");
+            assert.strictEqual(chalkStub.reset.callCount, 1);
             assert.strictEqual(chalkStub.yellow.bold.callCount, 0);
             assert.strictEqual(chalkStub.red.bold.callCount, 1);
         });
@@ -284,6 +302,7 @@ describe("formatter:stylish", () => {
             const result = formatter(code);
 
             assert.strictEqual(result, "\nfoo.js\n  5:10  error  Unexpected foo  foo\n\nbar.js\n  6:11  warning  Unexpected bar  bar\n\n\u2716 2 problems (0 errors, 2 warnings)\n");
+            assert.strictEqual(chalkStub.reset.callCount, 1);
             assert.strictEqual(chalkStub.yellow.bold.callCount, 0);
             assert.strictEqual(chalkStub.red.bold.callCount, 1);
         });
@@ -304,6 +323,7 @@ describe("formatter:stylish", () => {
             const result = formatter(code);
 
             assert.strictEqual(result, "\nfoo.js\n  0:0  error  Couldn't find foo.js\n\n\u2716 1 problem (1 error, 0 warnings)\n");
+            assert.strictEqual(chalkStub.reset.callCount, 1);
             assert.strictEqual(chalkStub.yellow.bold.callCount, 0);
             assert.strictEqual(chalkStub.red.bold.callCount, 1);
         });
diff --git a/tests/lib/init/config-initializer.js b/tests/lib/init/config-initializer.js
index 4ee6ff6b7..ed2388fd5 100644
--- a/tests/lib/init/config-initializer.js
+++ b/tests/lib/init/config-initializer.js
@@ -168,6 +168,24 @@ describe("configInitializer", () => {
                 assert.deepStrictEqual(config.extends, ["eslint:recommended", "plugin:vue/essential"]);
             });
 
+            it("should enable typescript parser and plugin", () => {
+                answers.typescript = true;
+                const config = init.processAnswers(answers);
+
+                assert.strictEqual(config.parser, "@typescript-eslint/parser");
+                assert.deepStrictEqual(config.plugins, ["@typescript-eslint"]);
+                assert.deepStrictEqual(config.extends, ["eslint:recommended", "plugin:@typescript-eslint/eslint-recommended"]);
+            });
+
+            it("should enable typescript parser and plugin with vue", () => {
+                answers.framework = "vue";
+                answers.typescript = true;
+                const config = init.processAnswers(answers);
+
+                assert.strictEqual(config.parserOptions.parser, "@typescript-eslint/parser");
+                assert.deepStrictEqual(config.plugins, ["vue", "@typescript-eslint"]);
+            });
+
             it("should extend eslint:recommended", () => {
                 const config = init.processAnswers(answers);
 
@@ -317,6 +335,28 @@ describe("configInitializer", () => {
                 assert.include(modules, "eslint-plugin-vue@latest");
                 assert.include(modules, "eslint-config-standard@latest");
             });
+
+            it("should support custom parser", () => {
+                const config = {
+                    parser: "@typescript-eslint/parser"
+                };
+                const modules = init.getModulesList(config);
+
+                assert.include(modules, "@typescript-eslint/parser@latest");
+            });
+
+            it("should support custom parser with Vue.js", () => {
+                const config = {
+
+                    // We should declare the parser at `parserOptions` when using with `eslint-plugin-vue`.
+                    parserOptions: {
+                        parser: "@typescript-eslint/parser"
+                    }
+                };
+                const modules = init.getModulesList(config);
+
+                assert.include(modules, "@typescript-eslint/parser@latest");
+            });
         });
 
         describe("auto", () => {
diff --git a/tests/lib/linter/apply-disable-directives.js b/tests/lib/linter/apply-disable-directives.js
index 440b2810f..84dddcba4 100644
--- a/tests/lib/linter/apply-disable-directives.js
+++ b/tests/lib/linter/apply-disable-directives.js
@@ -431,7 +431,7 @@ describe("apply-disable-directives", () => {
                 applyDisableDirectives({
                     directives: [{ type: "disable", line: 1, column: 5 }],
                     problems: [],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 [
                     {
@@ -451,7 +451,7 @@ describe("apply-disable-directives", () => {
                 applyDisableDirectives({
                     directives: [{ type: "disable", line: 1, column: 5, ruleId: null }],
                     problems: [{ line: 2, column: 1, ruleId: "foo" }],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 []
             );
@@ -462,7 +462,7 @@ describe("apply-disable-directives", () => {
                 applyDisableDirectives({
                     directives: [{ type: "disable", line: 1, column: 5, ruleId: "foo" }],
                     problems: [],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 [
                     {
@@ -482,7 +482,7 @@ describe("apply-disable-directives", () => {
                 applyDisableDirectives({
                     directives: [{ type: "disable", line: 1, column: 5, ruleId: "foo" }],
                     problems: [{ line: 1, column: 20, ruleId: "not-foo" }],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 [
                     {
@@ -510,7 +510,7 @@ describe("apply-disable-directives", () => {
                         { type: "enable", line: 1, column: 6, ruleId: "foo" }
                     ],
                     problems: [{ line: 1, column: 2, ruleId: "foo" }],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 [
                     {
@@ -538,7 +538,7 @@ describe("apply-disable-directives", () => {
                         { type: "enable", line: 1, column: 6, ruleId: null }
                     ],
                     problems: [],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 [
                     {
@@ -561,7 +561,7 @@ describe("apply-disable-directives", () => {
                         { type: "disable", line: 2, column: 1, ruleId: null }
                     ],
                     problems: [],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 [
                     {
@@ -592,7 +592,7 @@ describe("apply-disable-directives", () => {
                         { type: "disable", line: 2, column: 1, ruleId: null }
                     ],
                     problems: [{ line: 3, column: 1, ruleId: "foo" }],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 [
                     {
@@ -615,7 +615,7 @@ describe("apply-disable-directives", () => {
                         { type: "disable", line: 2, column: 1, ruleId: null }
                     ],
                     problems: [{ line: 3, column: 1, ruleId: "foo" }],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 [
                     {
@@ -635,7 +635,7 @@ describe("apply-disable-directives", () => {
                 applyDisableDirectives({
                     directives: [{ type: "disable", line: 1, column: 5, ruleId: "foo" }],
                     problems: [{ line: 1, column: 6, ruleId: "foo" }],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 []
             );
@@ -649,7 +649,7 @@ describe("apply-disable-directives", () => {
                         { type: "disable", line: 2, column: 1, ruleId: "foo" }
                     ],
                     problems: [{ line: 3, column: 1, ruleId: "foo" }],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 [
                     {
@@ -672,7 +672,7 @@ describe("apply-disable-directives", () => {
                         { type: "disable", line: 2, column: 1, ruleId: "foo" }
                     ],
                     problems: [{ line: 3, column: 1, ruleId: "bar" }],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 [
                     {
@@ -695,7 +695,7 @@ describe("apply-disable-directives", () => {
                         { type: "enable", line: 1, column: 8, ruleId: "foo" }
                     ],
                     problems: [{ line: 1, column: 10, ruleId: "foo" }],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 [
                     {
@@ -723,7 +723,7 @@ describe("apply-disable-directives", () => {
                         { type: "enable", line: 1, column: 8, ruleId: null }
                     ],
                     problems: [{ line: 1, column: 10, ruleId: "foo" }],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 [
                     {
@@ -752,7 +752,7 @@ describe("apply-disable-directives", () => {
                         { type: "enable", line: 3, column: 1, ruleId: "foo" }
                     ],
                     problems: [{ line: 4, column: 1, ruleId: "foo" }],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 [
                     {
@@ -786,7 +786,7 @@ describe("apply-disable-directives", () => {
                 applyDisableDirectives({
                     directives: [{ type: "disable-line", line: 1, column: 5, ruleId: null }],
                     problems: [],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 [
                     {
@@ -807,7 +807,7 @@ describe("apply-disable-directives", () => {
                 applyDisableDirectives({
                     directives: [{ type: "disable-line", line: 1, column: 5, ruleId: null }],
                     problems: [{ line: 1, column: 10, ruleId: "foo" }],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 []
             );
@@ -818,7 +818,7 @@ describe("apply-disable-directives", () => {
                 applyDisableDirectives({
                     directives: [{ type: "disable-next-line", line: 1, column: 5, ruleId: null }],
                     problems: [],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 [
                     {
@@ -838,7 +838,7 @@ describe("apply-disable-directives", () => {
                 applyDisableDirectives({
                     directives: [{ type: "disable-next-line", line: 1, column: 5, ruleId: null }],
                     problems: [{ line: 2, column: 10, ruleId: "foo" }],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 []
             );
@@ -852,7 +852,7 @@ describe("apply-disable-directives", () => {
                         { type: "disable-line", line: 1, column: 5, ruleId: null }
                     ],
                     problems: [],
-                    reportUnusedDisableDirectives: true
+                    reportUnusedDisableDirectives: "error"
                 }),
                 [
                     {
@@ -875,12 +875,12 @@ describe("apply-disable-directives", () => {
             );
         });
 
-        it("Does not add problems when reportUnusedDisableDirectives: false is used", () => {
+        it("Does not add problems when reportUnusedDisableDirectives: \"off\" is used", () => {
             assert.deepStrictEqual(
                 applyDisableDirectives({
                     directives: [{ type: "disable-next-line", line: 1, column: 5, ruleId: null }],
                     problems: [],
-                    reportUnusedDisableDirectives: false
+                    reportUnusedDisableDirectives: "off"
                 }),
                 []
             );
diff --git a/tests/lib/linter/linter.js b/tests/lib/linter/linter.js
index b1b621935..baadf43ca 100644
--- a/tests/lib/linter/linter.js
+++ b/tests/lib/linter/linter.js
@@ -3211,6 +3211,54 @@ describe("Linter", () => {
                 ]
             );
         });
+
+        it("reports problems for unused eslint-disable comments (error)", () => {
+            assert.deepStrictEqual(
+                linter.verify("/* eslint-disable */", {}, { reportUnusedDisableDirectives: "error" }),
+                [
+                    {
+                        ruleId: null,
+                        message: "Unused eslint-disable directive (no problems were reported).",
+                        line: 1,
+                        column: 1,
+                        severity: 2,
+                        nodeType: null
+                    }
+                ]
+            );
+        });
+
+        it("reports problems for unused eslint-disable comments (warn)", () => {
+            assert.deepStrictEqual(
+                linter.verify("/* eslint-disable */", {}, { reportUnusedDisableDirectives: "warn" }),
+                [
+                    {
+                        ruleId: null,
+                        message: "Unused eslint-disable directive (no problems were reported).",
+                        line: 1,
+                        column: 1,
+                        severity: 1,
+                        nodeType: null
+                    }
+                ]
+            );
+        });
+
+        it("reports problems for unused eslint-disable comments (in config)", () => {
+            assert.deepStrictEqual(
+                linter.verify("/* eslint-disable */", { reportUnusedDisableDirectives: true }),
+                [
+                    {
+                        ruleId: null,
+                        message: "Unused eslint-disable directive (no problems were reported).",
+                        line: 1,
+                        column: 1,
+                        severity: 1,
+                        nodeType: null
+                    }
+                ]
+            );
+        });
     });
 
     describe("when evaluating code with comments to change config when allowInlineConfig is disabled", () => {
diff --git a/tests/lib/rules/callback-return.js b/tests/lib/rules/callback-return.js
index 1d5e29a63..1f17ef6cc 100644
--- a/tests/lib/rules/callback-return.js
+++ b/tests/lib/rules/callback-return.js
@@ -159,7 +159,7 @@ ruleTester.run("callback-return", rule, {
                 messageId: "missingReturn",
                 line: 1,
                 column: 30,
-                nodeType: "CallExpression"
+                type: "CallExpression"
             }]
         },
         {
@@ -168,7 +168,7 @@ ruleTester.run("callback-return", rule, {
                 messageId: "missingReturn",
                 line: 1,
                 column: 63,
-                nodeType: "CallExpression"
+                type: "CallExpression"
             }]
         },
         {
@@ -177,7 +177,7 @@ ruleTester.run("callback-return", rule, {
                 messageId: "missingReturn",
                 line: 1,
                 column: 61,
-                nodeType: "CallExpression"
+                type: "CallExpression"
             }]
         },
         {
@@ -186,7 +186,7 @@ ruleTester.run("callback-return", rule, {
                 messageId: "missingReturn",
                 line: 1,
                 column: 35,
-                nodeType: "CallExpression"
+                type: "CallExpression"
             }]
         },
         {
@@ -196,7 +196,7 @@ ruleTester.run("callback-return", rule, {
                 messageId: "missingReturn",
                 line: 1,
                 column: 31,
-                nodeType: "CallExpression"
+                type: "CallExpression"
             }]
         },
         {
@@ -206,7 +206,7 @@ ruleTester.run("callback-return", rule, {
                 messageId: "missingReturn",
                 line: 1,
                 column: 31,
-                nodeType: "CallExpression"
+                type: "CallExpression"
             }]
         },
         {
@@ -215,7 +215,7 @@ ruleTester.run("callback-return", rule, {
                 messageId: "missingReturn",
                 line: 3,
                 column: 2,
-                nodeType: "CallExpression"
+                type: "CallExpression"
             }]
         },
         {
@@ -225,7 +225,7 @@ ruleTester.run("callback-return", rule, {
                 messageId: "missingReturn",
                 line: 1,
                 column: 43,
-                nodeType: "CallExpression"
+                type: "CallExpression"
             }]
         },
         {
@@ -234,7 +234,7 @@ ruleTester.run("callback-return", rule, {
                 messageId: "missingReturn",
                 line: 1,
                 column: 19,
-                nodeType: "CallExpression"
+                type: "CallExpression"
             }]
         },
         {
@@ -243,7 +243,7 @@ ruleTester.run("callback-return", rule, {
                 messageId: "missingReturn",
                 line: 1,
                 column: 19,
-                nodeType: "CallExpression"
+                type: "CallExpression"
             }]
         },
         {
@@ -252,7 +252,7 @@ ruleTester.run("callback-return", rule, {
                 messageId: "missingReturn",
                 line: 1,
                 column: 30,
-                nodeType: "CallExpression"
+                type: "CallExpression"
             }]
         },
         {
@@ -262,7 +262,7 @@ ruleTester.run("callback-return", rule, {
                 messageId: "missingReturn",
                 line: 1,
                 column: 20,
-                nodeType: "CallExpression"
+                type: "CallExpression"
             }]
         },
         {
@@ -271,7 +271,7 @@ ruleTester.run("callback-return", rule, {
                 messageId: "missingReturn",
                 line: 1,
                 column: 30,
-                nodeType: "CallExpression"
+                type: "CallExpression"
             }]
         },
         {
@@ -280,7 +280,7 @@ ruleTester.run("callback-return", rule, {
                 messageId: "missingReturn",
                 line: 3,
                 column: 1,
-                nodeType: "CallExpression"
+                type: "CallExpression"
 
             }]
         },
@@ -291,7 +291,7 @@ ruleTester.run("callback-return", rule, {
                 messageId: "missingReturn",
                 line: 1,
                 column: 32,
-                nodeType: "CallExpression"
+                type: "CallExpression"
             }]
         },
 
@@ -303,12 +303,12 @@ ruleTester.run("callback-return", rule, {
                 messageId: "missingReturn",
                 line: 1,
                 column: 30,
-                nodeType: "CallExpression"
+                type: "CallExpression"
             }, {
                 messageId: "missingReturn",
                 line: 1,
                 column: 50,
-                nodeType: "CallExpression"
+                type: "CallExpression"
             }]
         },
         {
@@ -318,7 +318,7 @@ ruleTester.run("callback-return", rule, {
                     messageId: "missingReturn",
                     line: 1,
                     column: 52,
-                    nodeType: "CallExpression"
+                    type: "CallExpression"
                 }
             ]
         },
@@ -330,7 +330,7 @@ ruleTester.run("callback-return", rule, {
                     messageId: "missingReturn",
                     line: 1,
                     column: 18,
-                    nodeType: "CallExpression"
+                    type: "CallExpression"
                 }
             ]
         },
@@ -341,7 +341,7 @@ ruleTester.run("callback-return", rule, {
                     messageId: "missingReturn",
                     line: 1,
                     column: 42,
-                    nodeType: "CallExpression"
+                    type: "CallExpression"
                 }
             ]
         },
@@ -353,7 +353,7 @@ ruleTester.run("callback-return", rule, {
                     messageId: "missingReturn",
                     line: 1,
                     column: 42,
-                    nodeType: "CallExpression"
+                    type: "CallExpression"
                 }
             ]
         },
@@ -367,7 +367,7 @@ ruleTester.run("callback-return", rule, {
                     messageId: "missingReturn",
                     line: 1,
                     column: 33,
-                    nodeType: "CallExpression"
+                    type: "CallExpression"
                 }
             ]
         },
@@ -379,7 +379,7 @@ ruleTester.run("callback-return", rule, {
                     messageId: "missingReturn",
                     line: 1,
                     column: 47,
-                    nodeType: "CallExpression"
+                    type: "CallExpression"
                 }
             ]
         },
@@ -391,7 +391,7 @@ ruleTester.run("callback-return", rule, {
                     messageId: "missingReturn",
                     line: 1,
                     column: 51,
-                    nodeType: "CallExpression"
+                    type: "CallExpression"
                 }
             ]
         },
@@ -403,7 +403,7 @@ ruleTester.run("callback-return", rule, {
                     messageId: "missingReturn",
                     line: 1,
                     column: 30,
-                    nodeType: "CallExpression"
+                    type: "CallExpression"
                 }
             ]
         },
@@ -415,7 +415,7 @@ ruleTester.run("callback-return", rule, {
                     messageId: "missingReturn",
                     line: 1,
                     column: 30,
-                    nodeType: "CallExpression"
+                    type: "CallExpression"
                 }
             ]
         },
@@ -427,7 +427,7 @@ ruleTester.run("callback-return", rule, {
                     messageId: "missingReturn",
                     line: 1,
                     column: 30,
-                    nodeType: "CallExpression"
+                    type: "CallExpression"
                 }
             ]
         },
@@ -439,7 +439,7 @@ ruleTester.run("callback-return", rule, {
                     messageId: "missingReturn",
                     line: 1,
                     column: 41,
-                    nodeType: "CallExpression"
+                    type: "CallExpression"
                 }
             ]
         },
@@ -451,7 +451,7 @@ ruleTester.run("callback-return", rule, {
                     messageId: "missingReturn",
                     line: 2,
                     column: 1,
-                    nodeType: "CallExpression"
+                    type: "CallExpression"
                 }
             ]
         },
@@ -463,7 +463,7 @@ ruleTester.run("callback-return", rule, {
                     messageId: "missingReturn",
                     line: 1,
                     column: 30,
-                    nodeType: "CallExpression"
+                    type: "CallExpression"
                 }
             ]
         },
@@ -475,7 +475,7 @@ ruleTester.run("callback-return", rule, {
                     messageId: "missingReturn",
                     line: 1,
                     column: 30,
-                    nodeType: "CallExpression"
+                    type: "CallExpression"
                 }
             ]
         }
diff --git a/tests/lib/rules/func-name-matching.js b/tests/lib/rules/func-name-matching.js
index efb7987d4..72ee66b41 100644
--- a/tests/lib/rules/func-name-matching.js
+++ b/tests/lib/rules/func-name-matching.js
@@ -255,6 +255,10 @@ ruleTester.run("func-name-matching", rule, {
             code: "Reflect.defineProperty(foo, 'bar', { value() {} })",
             options: ["never", { considerPropertyDescriptor: true }],
             parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "foo({ value: function value() {} })",
+            options: ["always", { considerPropertyDescriptor: true }]
         }
     ],
     invalid: [
@@ -446,6 +450,13 @@ ruleTester.run("func-name-matching", rule, {
             errors: [
                 { messageId: "notMatchProperty", data: { funcName: "bar", name: "bar" } }
             ]
+        },
+        {
+            code: "foo({ value: function bar() {} })",
+            options: ["always", { considerPropertyDescriptor: true }],
+            errors: [
+                { messageId: "matchProperty", data: { funcName: "bar", name: "value" } }
+            ]
         }
     ]
 });
diff --git a/tests/lib/rules/no-extra-boolean-cast.js b/tests/lib/rules/no-extra-boolean-cast.js
index 129329ff0..1de914ca5 100644
--- a/tests/lib/rules/no-extra-boolean-cast.js
+++ b/tests/lib/rules/no-extra-boolean-cast.js
@@ -270,6 +270,68 @@ ruleTester.run("no-extra-boolean-cast", rule, {
         },
 
         // Adjacent tokens tests
+        {
+            code: "function *foo() { yield!!a ? b : c }",
+            output: "function *foo() { yield a ? b : c }",
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [{
+                messageId: "unexpectedNegation",
+                type: "UnaryExpression"
+            }]
+        },
+        {
+            code: "function *foo() { yield!! a ? b : c }",
+            output: "function *foo() { yield a ? b : c }",
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [{
+                messageId: "unexpectedNegation",
+                type: "UnaryExpression"
+            }]
+        },
+        {
+            code: "function *foo() { yield! !a ? b : c }",
+            output: "function *foo() { yield a ? b : c }",
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [{
+                messageId: "unexpectedNegation",
+                type: "UnaryExpression"
+            }]
+        },
+        {
+            code: "function *foo() { yield !!a ? b : c }",
+            output: "function *foo() { yield a ? b : c }",
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [{
+                messageId: "unexpectedNegation",
+                type: "UnaryExpression"
+            }]
+        },
+        {
+            code: "function *foo() { yield(!!a) ? b : c }",
+            output: "function *foo() { yield(a) ? b : c }",
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [{
+                messageId: "unexpectedNegation",
+                type: "UnaryExpression"
+            }]
+        },
+        {
+            code: "function *foo() { yield/**/!!a ? b : c }",
+            output: "function *foo() { yield/**/a ? b : c }",
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [{
+                messageId: "unexpectedNegation",
+                type: "UnaryExpression"
+            }]
+        },
+        {
+            code: "x=!!a ? b : c ",
+            output: "x=a ? b : c ",
+            errors: [{
+                messageId: "unexpectedNegation",
+                type: "UnaryExpression"
+            }]
+        },
         {
             code: "void!Boolean()",
             output: "void true",
diff --git a/tests/lib/rules/no-extra-parens.js b/tests/lib/rules/no-extra-parens.js
index 2b20f20f6..788823e04 100644
--- a/tests/lib/rules/no-extra-parens.js
+++ b/tests/lib/rules/no-extra-parens.js
@@ -439,6 +439,12 @@ ruleTester.run("no-extra-parens", rule, {
         { code: "var a = b => 1 ? 2 : 3", options: ["all", { enforceForArrowConditionals: false }] },
         { code: "var a = (b) => (1 ? 2 : 3)", options: ["all", { enforceForArrowConditionals: false }] },
 
+        // ["all", { enforceForSequenceExpressions: false }]
+        { code: "(a, b)", options: ["all", { enforceForSequenceExpressions: false }] },
+        { code: "(foo(), bar());", options: ["all", { enforceForSequenceExpressions: false }] },
+        { code: "if((a, b)){}", options: ["all", { enforceForSequenceExpressions: false }] },
+        { code: "while ((val = foo(), val < 10));", options: ["all", { enforceForSequenceExpressions: false }] },
+
         "let a = [ ...b ]",
         "let a = { ...b }",
         {
@@ -836,7 +842,7 @@ ruleTester.run("no-extra-parens", rule, {
             options: ["all", { returnAssign: false }],
             errors: [
                 {
-                    messgeId: "unexpected",
+                    messageId: "unexpected",
                     type: "LogicalExpression"
                 }
             ]
@@ -846,7 +852,7 @@ ruleTester.run("no-extra-parens", rule, {
             output: "function a(b) { return (b = c) || (d = e); }",
             errors: [
                 {
-                    messgeId: "unexpected",
+                    messageId: "unexpected",
                     type: "LogicalExpression"
                 }
             ]
@@ -856,7 +862,7 @@ ruleTester.run("no-extra-parens", rule, {
             output: "function a(b) { return b = 1; }",
             errors: [
                 {
-                    messgeId: "unexpected",
+                    messageId: "unexpected",
                     type: "AssignmentExpression"
                 }
             ]
@@ -866,11 +872,11 @@ ruleTester.run("no-extra-parens", rule, {
             output: "function a(b) { return c ? d = b : e = b; }",
             errors: [
                 {
-                    messgeId: "unexpected",
+                    messageId: "unexpected",
                     type: "AssignmentExpression"
                 },
                 {
-                    messgeId: "unexpected",
+                    messageId: "unexpected",
                     type: "AssignmentExpression"
                 }
             ]
@@ -882,7 +888,7 @@ ruleTester.run("no-extra-parens", rule, {
 
             errors: [
                 {
-                    messgeId: "unexpected",
+                    messageId: "unexpected",
                     type: "LogicalExpression"
                 }
             ]
@@ -892,7 +898,7 @@ ruleTester.run("no-extra-parens", rule, {
             output: "b => (b = c) || (d = e);",
             errors: [
                 {
-                    messgeId: "unexpected",
+                    messageId: "unexpected",
                     type: "LogicalExpression"
                 }
             ]
@@ -902,7 +908,7 @@ ruleTester.run("no-extra-parens", rule, {
             output: "b => b = 1;",
             errors: [
                 {
-                    messgeId: "unexpected",
+                    messageId: "unexpected",
                     type: "AssignmentExpression"
                 }
             ]
@@ -912,11 +918,11 @@ ruleTester.run("no-extra-parens", rule, {
             output: "b => c ? d = b : e = b;",
             errors: [
                 {
-                    messgeId: "unexpected",
+                    messageId: "unexpected",
                     type: "AssignmentExpression"
                 },
                 {
-                    messgeId: "unexpected",
+                    messageId: "unexpected",
                     type: "AssignmentExpression"
                 }
             ]
@@ -927,7 +933,7 @@ ruleTester.run("no-extra-parens", rule, {
             options: ["all", { returnAssign: false }],
             errors: [
                 {
-                    messgeId: "unexpected",
+                    messageId: "unexpected",
                     type: "LogicalExpression"
                 }
             ]
@@ -937,7 +943,7 @@ ruleTester.run("no-extra-parens", rule, {
             output: "b => { return (b = c) || (d = e) };",
             errors: [
                 {
-                    messgeId: "unexpected",
+                    messageId: "unexpected",
                     type: "LogicalExpression"
                 }
             ]
@@ -947,7 +953,7 @@ ruleTester.run("no-extra-parens", rule, {
             output: "b => { return b = 1 };",
             errors: [
                 {
-                    messgeId: "unexpected",
+                    messageId: "unexpected",
                     type: "AssignmentExpression"
                 }
             ]
@@ -957,11 +963,11 @@ ruleTester.run("no-extra-parens", rule, {
             output: "b => { return c ? d = b : e = b; }",
             errors: [
                 {
-                    messgeId: "unexpected",
+                    messageId: "unexpected",
                     type: "AssignmentExpression"
                 },
                 {
-                    messgeId: "unexpected",
+                    messageId: "unexpected",
                     type: "AssignmentExpression"
                 }
             ]
@@ -973,11 +979,11 @@ ruleTester.run("no-extra-parens", rule, {
             output: "async function a() { await a + await b; }",
             errors: [
                 {
-                    messgeId: "unexpected",
+                    messageId: "unexpected",
                     type: "AwaitExpression"
                 },
                 {
-                    messgeId: "unexpected",
+                    messageId: "unexpected",
                     type: "AwaitExpression"
                 }
             ]
@@ -1058,7 +1064,7 @@ ruleTester.run("no-extra-parens", rule, {
             options: ["all", { enforceForArrowConditionals: true }],
             errors: [
                 {
-                    messgeId: "unexpected"
+                    messageId: "unexpected"
                 }
             ]
         },
@@ -1070,7 +1076,75 @@ ruleTester.run("no-extra-parens", rule, {
             options: ["all", { enforceForArrowConditionals: false }],
             errors: [
                 {
-                    messgeId: "unexpected"
+                    messageId: "unexpected"
+                }
+            ]
+        },
+
+        // ["all", { enforceForSequenceExpressions: true }]
+        {
+            code: "(a, b)",
+            output: "a, b",
+            options: ["all"],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "SequenceExpression"
+                }
+            ]
+        },
+        {
+            code: "(a, b)",
+            output: "a, b",
+            options: ["all", {}],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "SequenceExpression"
+                }
+            ]
+        },
+        {
+            code: "(a, b)",
+            output: "a, b",
+            options: ["all", { enforceForSequenceExpressions: true }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "SequenceExpression"
+                }
+            ]
+        },
+        {
+            code: "(foo(), bar());",
+            output: "foo(), bar();",
+            options: ["all", { enforceForSequenceExpressions: true }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "SequenceExpression"
+                }
+            ]
+        },
+        {
+            code: "if((a, b)){}",
+            output: "if(a, b){}",
+            options: ["all", { enforceForSequenceExpressions: true }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "SequenceExpression"
+                }
+            ]
+        },
+        {
+            code: "while ((val = foo(), val < 10));",
+            output: "while (val = foo(), val < 10);",
+            options: ["all", { enforceForSequenceExpressions: true }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "SequenceExpression"
                 }
             ]
         },
@@ -1360,6 +1434,15 @@ ruleTester.run("no-extra-parens", rule, {
                 }
             ]
         },
+        {
+            code: "for (let [a = (b in c)] = []; ;);",
+            output: "for (let [a = b in c] = []; ;);",
+            errors: [
+                {
+                    messageId: "unexpected"
+                }
+            ]
+        },
         {
             code: "for (let [a = b && (c in d)] = []; ;);",
             output: "for (let [a = b && c in d] = []; ;);",
@@ -1414,6 +1497,15 @@ ruleTester.run("no-extra-parens", rule, {
                 }
             ]
         },
+        {
+            code: "for (let { a = (b in c) } = {}; ;);",
+            output: "for (let { a = b in c } = {}; ;);",
+            errors: [
+                {
+                    messageId: "unexpected"
+                }
+            ]
+        },
         {
             code: "for (let { a = b && (c in d) } = {}; ;);",
             output: "for (let { a = b && c in d } = {}; ;);",
@@ -1432,6 +1524,15 @@ ruleTester.run("no-extra-parens", rule, {
                 }
             ]
         },
+        {
+            code: "for (let a = `${(a in b)}`; ;);",
+            output: "for (let a = `${a in b}`; ;);",
+            errors: [
+                {
+                    messageId: "unexpected"
+                }
+            ]
+        },
         {
             code: "for (let a = `${a && (b in c)}`; ;);",
             output: "for (let a = `${a && b in c}`; ;);",
@@ -1441,6 +1542,15 @@ ruleTester.run("no-extra-parens", rule, {
                 }
             ]
         },
+        {
+            code: "for (let a = (b = (c in d)) => {}; ;);",
+            output: "for (let a = (b = c in d) => {}; ;);",
+            errors: [
+                {
+                    messageId: "unexpected"
+                }
+            ]
+        },
         {
             code: "for (let a = (b = c && (d in e)) => {}; ;);",
             output: "for (let a = (b = c && d in e) => {}; ;);",
@@ -1703,8 +1813,6 @@ ruleTester.run("no-extra-parens", rule, {
             )
         },
 
-        // TODO: Add '`in` inside a for-loop' first level tests for AssignmentPattern (param, obj, ary) and TemplateLiteral when these become supported.
-
         // https://github.com/eslint/eslint/issues/11706 regression tests (also in valid[])
         {
             code: "for (let a = (b); a > (b); a = (b)) a = (b); a = (b);",
diff --git a/tests/lib/rules/no-extra-semi.js b/tests/lib/rules/no-extra-semi.js
index f9e103bb5..913290aaf 100644
--- a/tests/lib/rules/no-extra-semi.js
+++ b/tests/lib/rules/no-extra-semi.js
@@ -47,68 +47,68 @@ ruleTester.run("no-extra-semi", rule, {
         {
             code: "var x = 5;;",
             output: "var x = 5;",
-            errors: [{ messgeId: "unexpected", type: "EmptyStatement" }]
+            errors: [{ messageId: "unexpected", type: "EmptyStatement" }]
         },
         {
             code: "function foo(){};",
             output: "function foo(){}",
-            errors: [{ messgeId: "unexpected", type: "EmptyStatement" }]
+            errors: [{ messageId: "unexpected", type: "EmptyStatement" }]
         },
         {
             code: "for(;;);;",
             output: "for(;;);",
-            errors: [{ messgeId: "unexpected", type: "EmptyStatement" }]
+            errors: [{ messageId: "unexpected", type: "EmptyStatement" }]
         },
         {
             code: "while(0);;",
             output: "while(0);",
-            errors: [{ messgeId: "unexpected", type: "EmptyStatement" }]
+            errors: [{ messageId: "unexpected", type: "EmptyStatement" }]
         },
         {
             code: "do;while(0);;",
             output: "do;while(0);",
-            errors: [{ messgeId: "unexpected", type: "EmptyStatement" }]
+            errors: [{ messageId: "unexpected", type: "EmptyStatement" }]
         },
         {
             code: "for(a in b);;",
             output: "for(a in b);",
-            errors: [{ messgeId: "unexpected", type: "EmptyStatement" }]
+            errors: [{ messageId: "unexpected", type: "EmptyStatement" }]
         },
         {
             code: "for(a of b);;",
             output: "for(a of b);",
             parserOptions: { ecmaVersion: 6 },
-            errors: [{ messgeId: "unexpected", type: "EmptyStatement" }]
+            errors: [{ messageId: "unexpected", type: "EmptyStatement" }]
         },
         {
             code: "if(true);;",
             output: "if(true);",
-            errors: [{ messgeId: "unexpected", type: "EmptyStatement" }]
+            errors: [{ messageId: "unexpected", type: "EmptyStatement" }]
         },
         {
             code: "if(true){} else;;",
             output: "if(true){} else;",
-            errors: [{ messgeId: "unexpected", type: "EmptyStatement" }]
+            errors: [{ messageId: "unexpected", type: "EmptyStatement" }]
         },
         {
             code: "if(true){;} else {;}",
             output: "if(true){} else {}",
-            errors: [{ messgeId: "unexpected", type: "EmptyStatement" }, { messgeId: "unexpected", type: "EmptyStatement" }]
+            errors: [{ messageId: "unexpected", type: "EmptyStatement" }, { messageId: "unexpected", type: "EmptyStatement" }]
         },
         {
             code: "foo:;;",
             output: "foo:;",
-            errors: [{ messgeId: "unexpected", type: "EmptyStatement" }]
+            errors: [{ messageId: "unexpected", type: "EmptyStatement" }]
         },
         {
             code: "with(foo);;",
             output: "with(foo);",
-            errors: [{ messgeId: "unexpected", type: "EmptyStatement" }]
+            errors: [{ messageId: "unexpected", type: "EmptyStatement" }]
         },
         {
             code: "with(foo){;}",
             output: "with(foo){}",
-            errors: [{ messgeId: "unexpected", type: "EmptyStatement" }]
+            errors: [{ messageId: "unexpected", type: "EmptyStatement" }]
         },
 
         // Class body.
@@ -116,47 +116,47 @@ ruleTester.run("no-extra-semi", rule, {
             code: "class A { ; }",
             output: "class A {  }",
             parserOptions: { ecmaVersion: 6 },
-            errors: [{ messgeId: "unexpected", type: "Punctuator", column: 11 }]
+            errors: [{ messageId: "unexpected", type: "Punctuator", column: 11 }]
         },
         {
             code: "class A { /*a*/; }",
             output: "class A { /*a*/ }",
             parserOptions: { ecmaVersion: 6 },
-            errors: [{ messgeId: "unexpected", type: "Punctuator", column: 16 }]
+            errors: [{ messageId: "unexpected", type: "Punctuator", column: 16 }]
         },
         {
             code: "class A { ; a() {} }",
             output: "class A {  a() {} }",
             parserOptions: { ecmaVersion: 6 },
-            errors: [{ messgeId: "unexpected", type: "Punctuator", column: 11 }]
+            errors: [{ messageId: "unexpected", type: "Punctuator", column: 11 }]
         },
         {
             code: "class A { a() {}; }",
             output: "class A { a() {} }",
             parserOptions: { ecmaVersion: 6 },
-            errors: [{ messgeId: "unexpected", type: "Punctuator", column: 17 }]
+            errors: [{ messageId: "unexpected", type: "Punctuator", column: 17 }]
         },
         {
             code: "class A { a() {}; b() {} }",
             output: "class A { a() {} b() {} }",
             parserOptions: { ecmaVersion: 6 },
-            errors: [{ messgeId: "unexpected", type: "Punctuator", column: 17 }]
+            errors: [{ messageId: "unexpected", type: "Punctuator", column: 17 }]
         },
         {
             code: "class A {; a() {}; b() {}; }",
             output: "class A { a() {} b() {} }",
             parserOptions: { ecmaVersion: 6 },
             errors: [
-                { messgeId: "unexpected", type: "Punctuator", column: 10 },
-                { messgeId: "unexpected", type: "Punctuator", column: 18 },
-                { messgeId: "unexpected", type: "Punctuator", column: 26 }
+                { messageId: "unexpected", type: "Punctuator", column: 10 },
+                { messageId: "unexpected", type: "Punctuator", column: 18 },
+                { messageId: "unexpected", type: "Punctuator", column: 26 }
             ]
         },
         {
             code: "class A { a() {}; get b() {} }",
             output: "class A { a() {} get b() {} }",
             parserOptions: { ecmaVersion: 6 },
-            errors: [{ messgeId: "unexpected", type: "Punctuator", column: 17 }]
+            errors: [{ messageId: "unexpected", type: "Punctuator", column: 17 }]
         }
     ]
 });
diff --git a/tests/lib/rules/no-inline-comments.js b/tests/lib/rules/no-inline-comments.js
index 916c83657..6af30d12b 100644
--- a/tests/lib/rules/no-inline-comments.js
+++ b/tests/lib/rules/no-inline-comments.js
@@ -17,11 +17,11 @@ const rule = require("../../../lib/rules/no-inline-comments"),
 
 const ruleTester = new RuleTester(),
     lineError = {
-        messsage: "Unexpected comment inline with code.",
+        message: "Unexpected comment inline with code.",
         type: "Line"
     },
     blockError = {
-        messsage: "Unexpected comment inline with code.",
+        message: "Unexpected comment inline with code.",
         type: "Block"
     };
 
diff --git a/tests/lib/rules/no-self-assign.js b/tests/lib/rules/no-self-assign.js
index a344e8084..fbf52dcba 100644
--- a/tests/lib/rules/no-self-assign.js
+++ b/tests/lib/rules/no-self-assign.js
@@ -32,6 +32,8 @@ ruleTester.run("no-self-assign", rule, {
         { code: "[a, b] = [b, a]", parserOptions: { ecmaVersion: 6 } },
         { code: "[a,, b] = [, b, a]", parserOptions: { ecmaVersion: 6 } },
         { code: "[x, a] = [...x, a]", parserOptions: { ecmaVersion: 6 } },
+        { code: "[...a] = [...a, 1]", parserOptions: { ecmaVersion: 6 } },
+        { code: "[a, ...b] = [0, ...b, 1]", parserOptions: { ecmaVersion: 6 } },
         { code: "[a, b] = {a, b}", parserOptions: { ecmaVersion: 6 } },
         { code: "({a} = a)", parserOptions: { ecmaVersion: 6 } },
         { code: "({a = 1} = {a})", parserOptions: { ecmaVersion: 6 } },
diff --git a/tests/lib/rules/quotes.js b/tests/lib/rules/quotes.js
index 3245c7454..5a12ad0fb 100644
--- a/tests/lib/rules/quotes.js
+++ b/tests/lib/rules/quotes.js
@@ -328,6 +328,96 @@ ruleTester.run("quotes", rule, {
             output: "\"\"``",
             parserOptions: { ecmaVersion: 6 },
             errors: [{ message: "Strings must use doublequote.", type: "TemplateLiteral", line: 1, column: 1 }]
+        },
+
+        // Strings containing octal escape sequences. Don't autofix to backticks.
+        {
+            code: "var foo = \"\\1\"",
+            output: "var foo = '\\1'",
+            options: ["single"],
+            errors: [
+                { message: "Strings must use singlequote.", type: "Literal" }
+            ]
+        },
+        {
+            code: "var foo = '\\1'",
+            output: "var foo = \"\\1\"",
+            options: ["double"],
+            errors: [
+                { message: "Strings must use doublequote.", type: "Literal" }
+            ]
+        },
+        {
+            code: "var notoctal = '\\0'",
+            output: "var notoctal = `\\0`",
+            options: ["backtick"],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                { message: "Strings must use backtick.", type: "Literal" }
+            ]
+        },
+        {
+            code: "var foo = '\\1'",
+            output: null,
+            options: ["backtick"],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                { message: "Strings must use backtick.", type: "Literal" }
+            ]
+        },
+        {
+            code: "var foo = \"\\1\"",
+            output: null,
+            options: ["backtick"],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                { message: "Strings must use backtick.", type: "Literal" }
+            ]
+        },
+        {
+            code: "var foo = '\\01'",
+            output: null,
+            options: ["backtick"],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                { message: "Strings must use backtick.", type: "Literal" }
+            ]
+        },
+        {
+            code: "var foo = '\\0\\1'",
+            output: null,
+            options: ["backtick"],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                { message: "Strings must use backtick.", type: "Literal" }
+            ]
+        },
+        {
+            code: "var foo = '\\08'",
+            output: null,
+            options: ["backtick"],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                { message: "Strings must use backtick.", type: "Literal" }
+            ]
+        },
+        {
+            code: "var foo = 'prefix \\33'",
+            output: null,
+            options: ["backtick"],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                { message: "Strings must use backtick.", type: "Literal" }
+            ]
+        },
+        {
+            code: "var foo = 'prefix \\75 sufix'",
+            output: null,
+            options: ["backtick"],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                { message: "Strings must use backtick.", type: "Literal" }
+            ]
         }
     ]
 });
diff --git a/tests/lib/rules/require-unicode-regexp.js b/tests/lib/rules/require-unicode-regexp.js
index 38a125096..18f5fb25c 100644
--- a/tests/lib/rules/require-unicode-regexp.js
+++ b/tests/lib/rules/require-unicode-regexp.js
@@ -30,7 +30,7 @@ ruleTester.run("require-unicode-regexp", rule, {
         "new RegExp('', 'gimuy')",
         "const flags = 'u'; new RegExp('', flags)",
         "const flags = 'g'; new RegExp('', flags + 'u')",
-        "const flags = 'gimu'; new RegExp('foo', flags.slice(1))",
+        "const flags = 'gimu'; new RegExp('foo', flags[3])",
         "new RegExp('', flags)",
         "function f(flags) { return new RegExp('', flags) }",
         "function f(RegExp) { return new RegExp('foo') }"
@@ -73,7 +73,7 @@ ruleTester.run("require-unicode-regexp", rule, {
             errors: [{ messageId: "requireUFlag" }]
         },
         {
-            code: "const flags = 'gimu'; new RegExp('foo', flags.slice(0, -1))",
+            code: "const flags = 'gimu'; new RegExp('foo', flags[0])",
             errors: [{ messageId: "requireUFlag" }]
         },
         {
diff --git a/tests/lib/rules/space-infix-ops.js b/tests/lib/rules/space-infix-ops.js
index e94d6fe32..85d61d449 100644
--- a/tests/lib/rules/space-infix-ops.js
+++ b/tests/lib/rules/space-infix-ops.js
@@ -312,12 +312,12 @@ ruleTester.run("space-infix-ops", rule, {
                 message: "Operator '=' must be spaced.",
                 line: 1,
                 column: 7,
-                nodeType: "AssignmentPattern"
+                type: "AssignmentPattern"
             }, {
                 message: "Operator '=' must be spaced.",
                 line: 1,
                 column: 10,
-                nodeType: "VariableDeclarator"
+                type: "VariableDeclarator"
             }]
         },
         {
@@ -328,7 +328,7 @@ ruleTester.run("space-infix-ops", rule, {
                 message: "Operator '=' must be spaced.",
                 line: 1,
                 column: 15,
-                nodeType: "AssignmentPattern"
+                type: "AssignmentPattern"
             }]
         },
         {
@@ -339,7 +339,7 @@ ruleTester.run("space-infix-ops", rule, {
                 message: "Operator '**' must be spaced.",
                 line: 1,
                 column: 2,
-                nodeType: "BinaryExpression"
+                type: "BinaryExpression"
             }]
         },
         {
@@ -349,7 +349,7 @@ ruleTester.run("space-infix-ops", rule, {
                 message: "Operator 'in' must be spaced.",
                 line: 1,
                 column: 6,
-                nodeType: "BinaryExpression"
+                type: "BinaryExpression"
             }]
         },
         {
@@ -359,7 +359,7 @@ ruleTester.run("space-infix-ops", rule, {
                 message: "Operator 'instanceof' must be spaced.",
                 line: 1,
                 column: 6,
-                nodeType: "BinaryExpression"
+                type: "BinaryExpression"
             }]
         },
 
@@ -385,7 +385,7 @@ ruleTester.run("space-infix-ops", rule, {
                 message: "Operator '=' must be spaced.",
                 line: 1,
                 column: 23,
-                nodeType: "AssignmentPattern"
+                type: "AssignmentPattern"
             }]
         }
     ]
diff --git a/tests/lib/rules/spaced-comment.js b/tests/lib/rules/spaced-comment.js
index c4c729b2e..fd6b2e510 100644
--- a/tests/lib/rules/spaced-comment.js
+++ b/tests/lib/rules/spaced-comment.js
@@ -313,7 +313,7 @@ ruleTester.run("spaced-comment", rule, {
             output: "// An invalid comment NOT starting with space\nvar a = 1;",
             options: ["always"],
             errors: [{
-                messsage: "Expected space or tab after '//' in comment.",
+                message: "Expected space or tab after '//' in comment.",
                 type: "Line"
             }]
         },
diff --git a/tests/lib/rules/switch-colon-spacing.js b/tests/lib/rules/switch-colon-spacing.js
index dfaf357b7..8ceb3bdf7 100644
--- a/tests/lib/rules/switch-colon-spacing.js
+++ b/tests/lib/rules/switch-colon-spacing.js
@@ -18,10 +18,10 @@ const rule = require("../../../lib/rules/switch-colon-spacing"),
 
 const ruleTester = new RuleTester();
 
-const expectedBeforeError = { messagesId: "expectedBefore" };
-const expectedAfterError = { messagesId: "expectedAfter" };
-const unexpectedBeforeError = { messagesId: "unexpectedBefore" };
-const unexpectedAfterError = { messagesId: "unexpectedAfter" };
+const expectedBeforeError = { messageId: "expectedBefore" };
+const expectedAfterError = { messageId: "expectedAfter" };
+const unexpectedBeforeError = { messageId: "unexpectedBefore" };
+const unexpectedAfterError = { messageId: "unexpectedAfter" };
 
 ruleTester.run("switch-colon-spacing", rule, {
     valid: [
diff --git a/tests/lib/rules/yoda.js b/tests/lib/rules/yoda.js
index d2c183477..7908499d8 100644
--- a/tests/lib/rules/yoda.js
+++ b/tests/lib/rules/yoda.js
@@ -568,6 +568,175 @@ ruleTester.run("yoda", rule, {
                     type: "BinaryExpression"
                 }
             ]
+        },
+
+        // Adjacent tokens tests
+        {
+            code: "function *foo() { yield(1) < a }",
+            output: "function *foo() { yield a > (1) }",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [
+                {
+                    messageId: "expected",
+                    data: { expectedSide: "right", operator: "<" },
+                    type: "BinaryExpression"
+                }
+            ]
+        },
+        {
+            code: "function *foo() { yield((1)) < a }",
+            output: "function *foo() { yield a > ((1)) }",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [
+                {
+                    messageId: "expected",
+                    data: { expectedSide: "right", operator: "<" },
+                    type: "BinaryExpression"
+                }
+            ]
+        },
+        {
+            code: "function *foo() { yield 1 < a }",
+            output: "function *foo() { yield a > 1 }",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [
+                {
+                    messageId: "expected",
+                    data: { expectedSide: "right", operator: "<" },
+                    type: "BinaryExpression"
+                }
+            ]
+        },
+        {
+            code: "function *foo() { yield/**/1 < a }",
+            output: "function *foo() { yield/**/a > 1 }",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [
+                {
+                    messageId: "expected",
+                    data: { expectedSide: "right", operator: "<" },
+                    type: "BinaryExpression"
+                }
+            ]
+        },
+        {
+            code: "function *foo() { yield(1) < ++a }",
+            output: "function *foo() { yield++a > (1) }",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [
+                {
+                    messageId: "expected",
+                    data: { expectedSide: "right", operator: "<" },
+                    type: "BinaryExpression"
+                }
+            ]
+        },
+        {
+            code: "function *foo() { yield(1) < (a) }",
+            output: "function *foo() { yield(a) > (1) }",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [
+                {
+                    messageId: "expected",
+                    data: { expectedSide: "right", operator: "<" },
+                    type: "BinaryExpression"
+                }
+            ]
+        },
+        {
+            code: "x=1 < a",
+            output: "x=a > 1",
+            options: ["never"],
+            errors: [
+                {
+                    messageId: "expected",
+                    data: { expectedSide: "right", operator: "<" },
+                    type: "BinaryExpression"
+                }
+            ]
+        },
+        {
+            code: "function *foo() { yield++a < 1 }",
+            output: "function *foo() { yield 1 > ++a }",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [
+                {
+                    messageId: "expected",
+                    data: { expectedSide: "left", operator: "<" },
+                    type: "BinaryExpression"
+                }
+            ]
+        },
+        {
+            code: "function *foo() { yield(a) < 1 }",
+            output: "function *foo() { yield 1 > (a) }",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [
+                {
+                    messageId: "expected",
+                    data: { expectedSide: "left", operator: "<" },
+                    type: "BinaryExpression"
+                }
+            ]
+        },
+        {
+            code: "function *foo() { yield a < 1 }",
+            output: "function *foo() { yield 1 > a }",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [
+                {
+                    messageId: "expected",
+                    data: { expectedSide: "left", operator: "<" },
+                    type: "BinaryExpression"
+                }
+            ]
+        },
+        {
+            code: "function *foo() { yield/**/a < 1 }",
+            output: "function *foo() { yield/**/1 > a }",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [
+                {
+                    messageId: "expected",
+                    data: { expectedSide: "left", operator: "<" },
+                    type: "BinaryExpression"
+                }
+            ]
+        },
+        {
+            code: "function *foo() { yield++a < (1) }",
+            output: "function *foo() { yield(1) > ++a }",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [
+                {
+                    messageId: "expected",
+                    data: { expectedSide: "left", operator: "<" },
+                    type: "BinaryExpression"
+                }
+            ]
+        },
+        {
+            code: "x=a < 1",
+            output: "x=1 > a",
+            options: ["always"],
+            errors: [
+                {
+                    messageId: "expected",
+                    data: { expectedSide: "left", operator: "<" },
+                    type: "BinaryExpression"
+                }
+            ]
         }
     ]
 });