Repository: eslint/eslint
Pull request #15326 (2021-11-17 16:38:36)

feat: Treat Class/New Expressions as truthy in no-constant-condition
In working on #15296 I discovered a few constant expressions that that were not covered in `no-constant-condition`, so I figured I'd propose adding them here.

<!--
    Thank you for contributing!

    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

#### Prerequisites checklist

- [X] I have read the [contributing guidelines](https://github.com/eslint/eslint/blob/HEAD/CONTRIBUTING.md).

#### What is the purpose of this pull request? (put an "X" next to an item)

<!--
    The following template is intentionally not a markdown checkbox list for the reasons
    explained in https://github.com/eslint/eslint/pull/12848#issuecomment-580302888
-->

[X] Changes an existing rule ([template](https://raw.githubusercontent.com/eslint/eslint/HEAD/templates/rule-change-proposal.md))

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->

<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->

#### What changes did you make? (Give an overview)

In working on #15296 I discovered a few constant expressions that that were not covered in `no-constant-condition`, so I figured I'd propose adding them here. This change add the ability to detect `ClassExpression` and `NewExpression`s as always truthy. I especially like that it catches the unintuitive fact that boxed primitives are always truthy.

These will now report errors:

```
if(new Foo()) {
  // ...
}

if(new Number(x)) {
  // ...
}

if(class {}) {
  // ...
}
```
#### Is there anything you'd like reviewers to focus on?

There's some overlap here with [`no-new-wrappers`](https://eslint.org/docs/rules/no-new-wrappers) but I think it's sensible since this detects an actual bug that results from primitive boxing.



eslint-github-bot[bot]: Hi @captbaritone!, thanks for the Pull Request

The first commit message isn't properly formatted. We ask that you update the message to match this format, as we use it to generate changelogs and automate releases.

- The length of the commit message must be less than or equal to 72

Read more about contributing to ESLint [here](https://eslint.org/docs/developer-guide/contributing/)

eslint-github-bot[bot]: Hi @captbaritone!, thanks for the Pull Request

The first commit message isn't properly formatted. We ask that you update the message to match this format, as we use it to generate changelogs and automate releases.

- The length of the commit message must be less than or equal to 72

Read more about contributing to ESLint [here](https://eslint.org/docs/developer-guide/contributing/)

captbaritone: I've added an example of each error to the docs. The class expression seems obscure enough that it might not be worth inclusion. Happy to remove it if others feel the same way.

Patch:
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index e15677ead..e2d756628 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -19,7 +19,7 @@
 [ ] Bug fix ([template](https://raw.githubusercontent.com/eslint/eslint/HEAD/templates/bug-report.md))
 [ ] New rule ([template](https://raw.githubusercontent.com/eslint/eslint/HEAD/templates/rule-proposal.md))
 [ ] Changes an existing rule ([template](https://raw.githubusercontent.com/eslint/eslint/HEAD/templates/rule-change-proposal.md))
-[ ] Add autofixing to a rule
+[ ] Add autofix to a rule
 [ ] Add a CLI option
 [ ] Add something to the core
 [ ] Other, please explain:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d6baaa970..1087ab4e4 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -13,7 +13,7 @@ jobs:
     - uses: actions/checkout@v2
     - uses: actions/setup-node@v2
       with:
-        node-version: '14.x'
+        node-version: '16.x'
     - name: Install Packages
       run: npm install
     - name: Lint Files
diff --git a/.markdownlint.yml b/.markdownlint.yml
index 975106df0..c37cf77fb 100644
--- a/.markdownlint.yml
+++ b/.markdownlint.yml
@@ -1,11 +1,9 @@
 default: true
 
 # Exclusions for deliberate/widespread violations
-MD001: false     # Header levels should only increment by one level at a time
 MD002: false     # First header should be a h1 header
 MD007:           # Unordered list indentation
     indent: 4
-MD012: false     # Multiple consecutive blank lines
 MD013: false     # Line length
 MD014: false     # Dollar signs used before commands without showing output
 MD019: false     # Multiple spaces after hash on atx style header
@@ -15,7 +13,5 @@ MD026: false     # Trailing punctuation in header
 MD029: false     # Ordered list item prefix
 MD030: false     # Spaces after list markers
 MD033: false     # Allow inline HTML
-MD034: false     # Bare URL used
-MD040: false     # Fenced code blocks should have a language specified
 MD041: false     # First line in file should be a top level header
 MD046: false     # Code block style
diff --git a/.markdownlintignore b/.markdownlintignore
index 1b763b1ba..251c083e0 100644
--- a/.markdownlintignore
+++ b/.markdownlintignore
@@ -1,1 +1,3 @@
 CHANGELOG.md
+node_modules
+tmp
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 9260dfefa..8f2246f3b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -24,4 +24,4 @@ Please sign our [Contributor License Agreement](https://cla.js.foundation/eslint
 ## Full Documentation
 
 Our full contribution guidelines can be found at:
-https://eslint.org/docs/developer-guide/contributing/
+<https://eslint.org/docs/developer-guide/contributing/>
diff --git a/README.md b/README.md
index 94378a513..e8b005d7d 100644
--- a/README.md
+++ b/README.md
@@ -47,19 +47,19 @@ Prerequisites: [Node.js](https://nodejs.org/) (`^12.22.0`, `^14.17.0`, or `>=16.
 
 You can install ESLint using npm:
 
-```
+```sh
 $ npm install eslint --save-dev
 ```
 
 You should then set up a configuration file:
 
-```
+```sh
 $ ./node_modules/.bin/eslint --init
 ```
 
 After that, you can run ESLint on any file or directory like this:
 
-```
+```sh
 $ ./node_modules/.bin/eslint yourfile.js
 ```
 
@@ -207,8 +207,6 @@ These folks keep the project moving and are resources for help.
 
 <!-- NOTE: This section is autogenerated. Do not manually edit.-->
 
-
-
 <!--teamstart-->
 
 ### Technical Steering Committee (TSC)
@@ -232,7 +230,6 @@ Milos Djermanovic
 </a>
 </td></tr></tbody></table>
 
-
 ### Reviewers
 
 The people who review and implement new features.
@@ -249,9 +246,6 @@ Toru Nagashima
 </a>
 </td></tr></tbody></table>
 
-
-
-
 ### Committers
 
 The people who review and fix bugs and help triage issues.
@@ -288,12 +282,8 @@ Nitin Kumar
 </a>
 </td></tr></tbody></table>
 
-
 <!--teamend-->
 
-
-
-
 ## <a name="sponsors"></a>Sponsors
 
 The following companies, organizations, and individuals support ESLint's ongoing maintenance and development. [Become a Sponsor](https://opencollective.com/eslint) to get your logo on our README and website.
@@ -304,7 +294,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
 <p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="undefined"></a></p><h3>Gold Sponsors</h3>
 <p><a href="https://contra.com"><img src="https://images.opencollective.com/contra1/c70f93f/logo.png" alt="Contra" height="96"></a> <a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" height="96"></a> <a href="https://google.com/chrome"><img src="https://images.opencollective.com/chrome/dc55bd4/logo.png" alt="Chrome's Web Framework & Tools Performance Fund" height="96"></a> <a href="https://www.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a> <a href="https://coinbase.com"><img src="https://avatars.githubusercontent.com/u/1885080?v=4" alt="Coinbase" height="96"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301?v=4" alt="American Express" height="96"></a> <a href="https://substack.com/"><img src="https://avatars.githubusercontent.com/u/53023767?v=4" alt="Substack" height="96"></a></p><h3>Silver Sponsors</h3>
 <p><a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a></p><h3>Bronze Sponsors</h3>
-<p><a href="https://sumatosoft.com/"><img src="https://images.opencollective.com/sumatosoft1/cab6013/logo.png" alt="SumatoSoft" height="32"></a> <a href="https://launchdarkly.com"><img src="https://images.opencollective.com/launchdarkly/574bb9e/logo.png" alt="launchdarkly" height="32"></a> <a href="https://troypoint.com"><img src="https://images.opencollective.com/troypoint/080f96f/avatar.png" alt="TROYPOINT" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8: free icons, photos, illustrations, and music" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://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://www.practiceignition.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Practice Ignition" height="32"></a></p>
+<p><a href="https://sumatosoft.com/"><img src="https://images.opencollective.com/sumatosoft1/cab6013/logo.png" alt="SumatoSoft" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8: free icons, photos, illustrations, and music" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://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://www.practiceignition.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Practice Ignition" height="32"></a></p>
 <!--sponsorsend-->
 
 ## <a name="technology-sponsors"></a>Technology Sponsors
diff --git a/docs/developer-guide/code-path-analysis.md b/docs/developer-guide/code-path-analysis.md
index f22eb8f34..2b01bc77e 100644
--- a/docs/developer-guide/code-path-analysis.md
+++ b/docs/developer-guide/code-path-analysis.md
@@ -189,8 +189,6 @@ bar();
 
    ![Loop Event's Example 5](./code-path-analysis/loop-event-example-for-5.svg)
 
-
-
 ## Usage Examples
 
 ### To check whether or not this is reachable
diff --git a/docs/developer-guide/contributing/pull-requests.md b/docs/developer-guide/contributing/pull-requests.md
index dde1c3144..58fe6f9c0 100644
--- a/docs/developer-guide/contributing/pull-requests.md
+++ b/docs/developer-guide/contributing/pull-requests.md
@@ -30,7 +30,7 @@ Details about each step are found below.
 
 The first step to sending a pull request is to create a new branch in your ESLint fork. Give the branch a descriptive name that describes what it is you're fixing, such as:
 
-```
+```sh
 $ git checkout -b issue1234
 ```
 
@@ -42,14 +42,14 @@ You should do all of your development for the issue in this branch.
 
 Make the changes to the code and tests, following the [code conventions](../code-conventions.md) as you go. Once you have finished, commit the changes to your branch:
 
-```
+```sh
 $ git add -A
 $ git commit
 ```
 
 All ESLint projects follow [Conventional Commits](https://www.conventionalcommits.org/) for our commit messages. Here's an example commit message:
 
-```
+```pt
 tag: Short description of what you did
 
 Longer description here if necessary
@@ -79,7 +79,7 @@ The message summary should be a one-sentence description of the change, and it m
 
 Here are some good commit message summary examples:
 
-```
+```pt
 build: Update Travis to only test Node 0.10
 fix: Semi rule incorrectly flagging extra semicolon
 chore: Upgrade Esprima to 1.2, switch to using comment attachment
@@ -91,7 +91,7 @@ The commit message format is important because these messages are used to create
 
 Before you send the pull request, be sure to rebase onto the upstream source. This ensures your code is running on the latest available code.
 
-```
+```sh
 git fetch upstream
 git rebase upstream/main
 ```
@@ -100,7 +100,7 @@ git rebase upstream/main
 
 After rebasing, be sure to run all of the tests once again to make sure nothing broke:
 
-```
+```sh
 npm test
 ```
 
@@ -123,13 +123,13 @@ With your code ready to go, this is a good time to double-check your submission
 
 Next, push your changes to your clone:
 
-```
+```sh
 git push origin issue1234
 ```
 
 If you are unable to push because some references are old, do a forced push instead:
 
-```
+```sh
 git push -f origin issue1234
 ```
 
@@ -149,13 +149,13 @@ Once your pull request is sent, it's time for the team to review it. As such, pl
 
 If your commit message is in the incorrect format, you'll be asked to update it. You can do so via:
 
-```
+```sh
 $ git commit --amend
 ```
 
 This will open up your editor so you can make changes. After that, you'll need to do a forced push to your branch:
 
-```
+```sh
 $ git push origin issue1234 -f
 ```
 
@@ -163,7 +163,7 @@ $ git push origin issue1234 -f
 
 If we ask you to make code changes, there's no need to close the pull request and create a new one. Just go back to the branch on your fork and make your changes. Then, when you're ready, you can add your changes into the branch:
 
-```
+```sh
 $ git add -A
 $ git commit
 $ git push origin issue1234
@@ -177,13 +177,13 @@ The commit messages in subsequent commits do not need to be in any specific form
 
 If your code is out-of-date, we might ask you to rebase. That means we want you to apply your changes on top of the latest upstream code. Make sure you have set up a [development environment](../development-environment.md) and then you can rebase using these commands:
 
-```
+```sh
 $ git fetch upstream
 $ git rebase upstream/main
 ```
 
 You might find that there are merge conflicts when you attempt to rebase. Please [resolve the conflicts](https://help.github.com/articles/resolving-merge-conflicts-after-a-git-rebase/) and then do a forced push to your branch:
 
-```
+```sh
 $ git push origin issue1234 -f
 ```
diff --git a/docs/developer-guide/development-environment.md b/docs/developer-guide/development-environment.md
index 7981c66e6..4828476aa 100644
--- a/docs/developer-guide/development-environment.md
+++ b/docs/developer-guide/development-environment.md
@@ -14,7 +14,7 @@ Go to <https://github.com/eslint/eslint> and click the "Fork" button. Follow the
 
 Once you've cloned the repository, run `npm install` to get all the necessary dependencies:
 
-```
+```sh
 $ cd eslint
 $ npm install
 ```
@@ -27,7 +27,7 @@ The *upstream source* is the main ESLint repository where active development hap
 
 To add the upstream source for ESLint, run the following in your repository:
 
-```
+```sh
 git remote add upstream git@github.com:eslint/eslint.git
 ```
 
@@ -49,7 +49,7 @@ Please see the [generator documentation](https://github.com/eslint/generator-esl
 
 Running the tests is the best way to ensure you have correctly set up your development environment. Make sure you're in the `eslint` directory and run:
 
-```
+```sh
 npm test
 ```
 
diff --git a/docs/developer-guide/nodejs-api.md b/docs/developer-guide/nodejs-api.md
index e4a3a1e42..ca07415cd 100644
--- a/docs/developer-guide/nodejs-api.md
+++ b/docs/developer-guide/nodejs-api.md
@@ -473,7 +473,7 @@ const linter2 = new Linter();
 ```
 
 In this example, rules run on `linter1` will get `path/to/project` when calling `context.getCwd()`.
-Those run on `linter2` will get `process.cwd()` if the global `process` object is defined or `undefined` otherwise (e.g. on the browser https://eslint.org/demo).
+Those run on `linter2` will get `process.cwd()` if the global `process` object is defined or `undefined` otherwise (e.g. on the browser <https://eslint.org/demo>).
 
 ### Linter#verify
 
@@ -783,7 +783,7 @@ Any additional properties of a test case will be passed directly to the linter a
 
 If a valid test case only uses the `code` property, it can optionally be provided as a string containing the code, rather than an object with a `code` key.
 
-#### Testing errors with `messageId`
+### Testing errors with `messageId`
 
 If the rule under test uses `messageId`s, you can use `messageId` property in a test case to assert reported error's `messageId` instead of its `message`.
 
@@ -805,7 +805,7 @@ For messages with placeholders, a test case can also use `data` property to addi
 
 Please note that `data` in a test case does not assert `data` passed to `context.report`. Instead, it is used to form the expected message text which is then compared with the received `message`.
 
-#### Testing Suggestions
+### Testing Suggestions
 
 Suggestions can be tested by defining a `suggestions` key on an errors object. The options to check for the suggestions are the following (all are optional):
 
diff --git a/docs/developer-guide/shareable-configs.md b/docs/developer-guide/shareable-configs.md
index 7b57f3fbf..15032d9e7 100644
--- a/docs/developer-guide/shareable-configs.md
+++ b/docs/developer-guide/shareable-configs.md
@@ -32,9 +32,11 @@ Once your shareable config is ready, you can [publish to npm](https://docs.npmjs
 
 You should declare your dependency on ESLint in `package.json` using the [peerDependencies](https://docs.npmjs.com/files/package.json#peerdependencies) field. The recommended way to declare a dependency for future proof compatibility is with the ">=" range syntax, using the lowest required ESLint version. For example:
 
-```
-"peerDependencies": {
-    "eslint": ">= 3"
+```json
+{
+    "peerDependencies": {
+        "eslint": ">= 3"
+    }
 }
 ```
 
@@ -76,7 +78,6 @@ You can also omit the `eslint-config-` and it will be automatically assumed by E
 
 npm [scoped modules](https://docs.npmjs.com/misc/scope) are also supported in a number of ways.
 
-
 By using the module name:
 
 ```json
diff --git a/docs/developer-guide/working-with-custom-formatters.md b/docs/developer-guide/working-with-custom-formatters.md
index 181aa69ce..54db66328 100644
--- a/docs/developer-guide/working-with-custom-formatters.md
+++ b/docs/developer-guide/working-with-custom-formatters.md
@@ -6,7 +6,7 @@ Each formatter is just a function that receives a `results` object and returns a
 
 ```js
 //my-awesome-formatter.js
-module.exports = function(results) {
+module.exports = function(results, context) {
     return JSON.stringify(results, null, 2);
 };
 ```
@@ -29,35 +29,6 @@ eslint -f ./my-awesome-formatter.js src/
 
 In order to use a local file as a custom formatter, you must begin the filename with a dot (such as `./my-awesome-formatter.js` or `../formatters/my-awesome-formatter.js`).
 
-### The `data` Argument
-
-The exported function receives an optional second argument named `data`. The `data` object provides extended information related to the analysis results. Currently, the `data` object consists of a single property named `rulesMeta`. This property is a dictionary of rule metadata, keyed with `ruleId`. The value for each entry is the `meta` property from the corresponding rule object. The dictionary contains an entry for each rule that was run during the analysis.
-
-Here's what the `data` object would look like if one rule, `no-extra-semi`, had been run:
-
-```js
-{
-    rulesMeta: {
-        "no-extra-semi": {
-            type: "suggestion",
-            docs: {
-                description: "disallow unnecessary semicolons",
-                category: "Possible Errors",
-                recommended: true,
-                url: "https://eslint.org/docs/rules/no-extra-semi"
-            },
-            fixable: "code",
-            schema: [],
-            messages: {
-                unexpected: "Unnecessary semicolon."
-            }
-        }
-    }
-}
-```
-
-The [Using Rule metadata](#using-rule-metadata) example shows how to use the `data` object in a custom formatter. See the [Working with Rules](https://eslint.org/docs/developer-guide/working-with-rules) page for more information about rules.
-
 ## Packaging the Custom Formatter
 
 Custom formatters can also be distributed through npm packages. To do so, create an npm package with a name in the format of `eslint-formatter-*`, where `*` is the name of your formatter (such as `eslint-formatter-awesome`). Projects should then install the package and can use the custom formatter with the `-f` (or `--format`) flag like this:
@@ -78,14 +49,14 @@ Tips for `package.json`:
 
 See all [formatters on npm](https://www.npmjs.com/search?q=eslint-formatter);
 
-## The `results` Object
+## The `results` Argument
 
 The `results` object passed into a formatter is an array of objects containing the lint results for individual files. Here's some example output:
 
 ```js
 [
     {
-        filePath: "path/to/file.js",
+        filePath: "/path/to/a/file.js",
         messages: [
             {
                 ruleId: "curly",
@@ -112,7 +83,7 @@ The `results` object passed into a formatter is an array of objects containing t
             "var err = doStuff();\nif (err) console.log('failed tests: ' + err);\nprocess.exit(1);\n"
     },
     {
-        filePath: "Gruntfile.js",
+        filePath: "/path/to/Gruntfile.js",
         messages: [],
         errorCount: 0,
         warningCount: 0,
@@ -147,6 +118,38 @@ Each `message` object contains information about the ESLint rule that was trigge
 *   **column**: the column where the issue is located.
 *   **nodeType**: the type of the node in the [AST](https://github.com/estree/estree/blob/master/spec.md#node-objects)
 
+## The `context` Argument
+
+The formatter function receives an object as the second argument. The object has two properties:
+
+* `cwd` ... The current working directory. This value comes from the `cwd` constructor option of the [ESLint](nodejs-api.md#-new-eslintoptions) class.
+* `rulesMeta` ... The `meta` property values of rules. See the [Working with Rules](working-with-rules.md) page for more information about rules.
+
+For example, here's what the object would look like if one rule, `no-extra-semi`, had been run:
+
+```js
+{
+    cwd: "/path/to/cwd",
+    rulesMeta: {
+        "no-extra-semi": {
+            type: "suggestion",
+            docs: {
+                description: "disallow unnecessary semicolons",
+                recommended: true,
+                url: "https://eslint.org/docs/rules/no-extra-semi"
+            },
+            fixable: "code",
+            schema: [],
+            messages: {
+                unexpected: "Unnecessary semicolon."
+            }
+        }
+    }
+}
+```
+
+**Note:** if a linting is executed by deprecated `CLIEngine` class, the `context` argument may be a different value because it is up to the API users. Please check whether the `context` argument is an expected value or not if you want to support legacy environments.
+
 ## Examples
 
 ### Summary formatter
@@ -154,7 +157,7 @@ Each `message` object contains information about the ESLint rule that was trigge
 A formatter that only cares about the total count of errors and warnings will look like this:
 
 ```javascript
-module.exports = function(results) {
+module.exports = function(results, context) {
     // accumulate the errors and warnings
     var summary = results.reduce(
         function(seq, current) {
@@ -196,7 +199,7 @@ Errors: 2, Warnings: 4
 A more complex report will look something like this:
 
 ```javascript
-module.exports = function(results, data) {
+module.exports = function(results, context) {
     var results = results || [];
 
     var summary = results.reduce(
@@ -205,7 +208,7 @@ module.exports = function(results, data) {
                 var logMessage = {
                     filePath: current.filePath,
                     ruleId: msg.ruleId,
-                    ruleUrl: data.rulesMeta[msg.ruleId].docs.url,
+                    ruleUrl: context.rulesMeta[msg.ruleId].docs.url,
                     message: msg.message,
                     line: msg.line,
                     column: msg.column
@@ -358,7 +361,6 @@ error semi
   src/configs/bundler.js:6:10
 ```
 
-
 ### Complex Argument Passing
 
 If you find the custom formatter pattern doesn't provide enough options for the way you'd like to format ESLint results, the best option is to use ESLint's built-in [JSON formatter](https://eslint.org/docs/user-guide/formatters/) and pipe the output to a second program. For example:
diff --git a/docs/rules/accessor-pairs.md b/docs/rules/accessor-pairs.md
index 25028d9ef..22cf28ab9 100644
--- a/docs/rules/accessor-pairs.md
+++ b/docs/rules/accessor-pairs.md
@@ -232,7 +232,6 @@ const Quux = class {
 }
 ```
 
-
 ## Known Limitations
 
 Due to the limits of static analysis, this rule does not account for possible side effects and in certain cases
diff --git a/docs/rules/array-bracket-newline.md b/docs/rules/array-bracket-newline.md
index eed32295f..bb990c75b 100644
--- a/docs/rules/array-bracket-newline.md
+++ b/docs/rules/array-bracket-newline.md
@@ -267,7 +267,6 @@ var e = [
 ];
 ```
 
-
 ## When Not To Use It
 
 If you don't want to enforce line breaks after opening and before closing array brackets, don't enable this rule.
diff --git a/docs/rules/array-callback-return.md b/docs/rules/array-callback-return.md
index 84bf0e771..568e014cd 100644
--- a/docs/rules/array-callback-return.md
+++ b/docs/rules/array-callback-return.md
@@ -144,7 +144,6 @@ myArray.forEach(item => {
 });
 ```
 
-
 ## Known Limitations
 
 This rule checks callback functions of methods with the given names, *even if* the object which has the method is *not* an array.
diff --git a/docs/rules/arrow-parens.md b/docs/rules/arrow-parens.md
index 144ebdf07..8a133cdf4 100644
--- a/docs/rules/arrow-parens.md
+++ b/docs/rules/arrow-parens.md
@@ -20,7 +20,6 @@ a => {}
 Following this style will help you find arrow functions (`=>`) which may be mistakenly included in a condition
 when a comparison such as `>=` was the intent.
 
-
 ```js
 /*eslint-env es6*/
 
diff --git a/docs/rules/callback-return.md b/docs/rules/callback-return.md
index f425ccd3f..c4e7277c4 100644
--- a/docs/rules/callback-return.md
+++ b/docs/rules/callback-return.md
@@ -165,7 +165,6 @@ There are some cases where you might want to call a callback function more than
  may lead to incorrect behavior. In those cases you may want to reserve a special name for those callbacks and
  not include that in the list of callbacks that trigger warnings.
 
-
 ## Further Reading
 
 * [The Art Of Node: Callbacks](https://github.com/maxogden/art-of-node#callbacks)
diff --git a/docs/rules/class-methods-use-this.md b/docs/rules/class-methods-use-this.md
index 73efc9dba..7e25b069a 100644
--- a/docs/rules/class-methods-use-this.md
+++ b/docs/rules/class-methods-use-this.md
@@ -99,7 +99,7 @@ This rule has two options:
 
 ### exceptMethods
 
-```
+```js
 "class-methods-use-this": [<enabled>, { "exceptMethods": [<...exceptions>] }]
 ```
 
@@ -131,7 +131,7 @@ class A {
 
 ## enforceForClassFields
 
-```
+```js
 "class-methods-use-this": [<enabled>, { "enforceForClassFields": true | false }]
 ```
 
diff --git a/docs/rules/comma-spacing.md b/docs/rules/comma-spacing.md
index 23107719a..3160f86a8 100644
--- a/docs/rules/comma-spacing.md
+++ b/docs/rules/comma-spacing.md
@@ -110,13 +110,11 @@ var arr = [,2 ,3]
 
 If your project will not be following a consistent comma-spacing pattern, turn this rule off.
 
-
 ## Further Reading
 
 * [JavaScript](http://javascript.crockford.com/code.html)
 * [Dojo Style Guide](https://dojotoolkit.org/reference-guide/1.9/developer/styleguide.html)
 
-
 ## Related Rules
 
 * [array-bracket-spacing](array-bracket-spacing.md)
diff --git a/docs/rules/comma-style.md b/docs/rules/comma-style.md
index 24b551574..f71e3105a 100644
--- a/docs/rules/comma-style.md
+++ b/docs/rules/comma-style.md
@@ -157,7 +157,6 @@ var o = {fst:1,
 
 This rule can safely be turned off if your project does not care about enforcing a consistent comma style.
 
-
 ## Further Reading
 
 For more information on the Comma First style:
@@ -165,7 +164,6 @@ For more information on the Comma First style:
 * [A better coding convention for lists and object literals in JavaScript by isaacs](https://gist.github.com/isaacs/357981)
 * [npm coding style guideline](https://docs.npmjs.com/misc/coding-style)
 
-
 ## Related Rules
 
 * [operator-linebreak](operator-linebreak.md)
diff --git a/docs/rules/function-call-argument-newline.md b/docs/rules/function-call-argument-newline.md
index 01c1ff426..abe0d4956 100644
--- a/docs/rules/function-call-argument-newline.md
+++ b/docs/rules/function-call-argument-newline.md
@@ -14,7 +14,6 @@ This rule has a string option:
 * `"never"` disallows line breaks between arguments
 * `"consistent"` requires consistent usage of line breaks between arguments
 
-
 ### always
 
 Examples of **incorrect** code for this rule with the default `"always"` option:
@@ -69,7 +68,6 @@ baz(
 );
 ```
 
-
 ### never
 
 Examples of **incorrect** code for this rule with the `"never"` option:
@@ -189,7 +187,6 @@ baz(
 );
 ```
 
-
 ## When Not To Use It
 
 If you don't want to enforce line breaks between arguments, don't enable this rule.
diff --git a/docs/rules/getter-return.md b/docs/rules/getter-return.md
index c49f39dd2..631de8059 100644
--- a/docs/rules/getter-return.md
+++ b/docs/rules/getter-return.md
@@ -3,17 +3,17 @@
 The get syntax binds an object property to a function that will be called when that property is looked up. It was first introduced in ECMAScript 5:
 
 ```js
-    var p = {
-        get name(){
-            return "nicholas";
-        }
-    };
-
-    Object.defineProperty(p, "age", {
-        get: function (){
-            return 17;
-        }
-    });
+var p = {
+    get name(){
+        return "nicholas";
+    }
+};
+
+Object.defineProperty(p, "age", {
+    get: function (){
+        return 17;
+    }
+});
 ```
 
 Note that every `getter` is expected to return a value.
diff --git a/docs/rules/indent.md b/docs/rules/indent.md
index 74fb0e7e2..bd4e86ea9 100644
--- a/docs/rules/indent.md
+++ b/docs/rules/indent.md
@@ -842,7 +842,6 @@ if (foo) {
 }
 ```
 
-
 ## Compatibility
 
 * **JSHint**: `indent`
diff --git a/docs/rules/line-comment-position.md b/docs/rules/line-comment-position.md
index 734453411..2e0eef853 100644
--- a/docs/rules/line-comment-position.md
+++ b/docs/rules/line-comment-position.md
@@ -11,7 +11,6 @@ var foo = "bar";  // beside comment
 
 This rule enforces consistent position of line comments. Block comments are not affected by this rule. By default, this rule ignores comments starting with the following words: `eslint`, `jshint`, `jslint`, `istanbul`, `global`, `exported`, `jscs`, `falls through`.
 
-
 ## Options
 
 This rule takes one argument, which can be a string or an object. The string settings are the same as those of the `position` property (explained below). The object option has the following properties:
@@ -33,7 +32,6 @@ Examples of **correct** code for the `{ "position": "above" }` option:
 1 + 1;
 ```
 
-
 Examples of **incorrect** code for the `{ "position": "above" }` option:
 
 ```js
@@ -50,7 +48,6 @@ Examples of **correct** code for the `{ "position": "beside" }` option:
 1 + 1; // valid comment
 ```
 
-
 Examples of **incorrect** code for the `{ "position": "beside" }` option:
 
 ```js
diff --git a/docs/rules/linebreak-style.md b/docs/rules/linebreak-style.md
index d2aa5a1aa..a4eb620ac 100644
--- a/docs/rules/linebreak-style.md
+++ b/docs/rules/linebreak-style.md
@@ -19,7 +19,6 @@ This rule has a string option:
 * `"unix"` (default) enforces the usage of Unix line endings: `\n` for LF.
 * `"windows"` enforces the usage of Windows line endings: `\r\n` for CRLF.
 
-
 ### unix
 
 Examples of **incorrect** code for this rule with the default `"unix"` option:
@@ -73,7 +72,7 @@ Version control systems sometimes have special behavior for linebreaks. To make
 
 For example, the default behavior of [git](https://git-scm.com/) on Windows systems is to convert LF linebreaks to CRLF when checking out files, but to store the linebreaks as LF when committing a change. This will cause the `linebreak-style` rule to report errors if configured with the `"unix"` setting, because the files that ESLint sees will have CRLF linebreaks. If you use git, you may want to add a line to your [`.gitattributes` file](https://git-scm.com/docs/gitattributes) to prevent git from converting linebreaks in `.js` files:
 
-```
+```pt
 *.js text eol=lf
 ```
 
diff --git a/docs/rules/lines-around-comment.md b/docs/rules/lines-around-comment.md
index fb0161102..b13d52532 100644
--- a/docs/rules/lines-around-comment.md
+++ b/docs/rules/lines-around-comment.md
@@ -26,7 +26,6 @@ This rule has an object option:
 * `"applyDefaultIgnorePatterns"` enables or disables the default comment patterns to be ignored by the rule
 * `"ignorePattern"` custom patterns to be ignored by the rule
 
-
 ### beforeBlockComment
 
 Examples of **incorrect** code for this rule with the default `{ "beforeBlockComment": true }` option:
@@ -515,7 +514,6 @@ const [
 ] = ["great", "not great"];
 ```
 
-
 ### ignorePattern
 
 By default this rule ignores comments starting with the following words: `eslint`, `jshint`, `jslint`, `istanbul`, `global`, `exported`, `jscs`. To ignore more comments in addition to the defaults, set the `ignorePattern` option to a string pattern that will be passed to the [`RegExp` constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/RegExp).
@@ -568,7 +566,6 @@ foo();
 
 ```
 
-
 ## When Not To Use It
 
 Many people enjoy a terser code style and don't mind comments bumping up against code. If you fall into that category this rule is not for you.
diff --git a/docs/rules/max-lines-per-function.md b/docs/rules/max-lines-per-function.md
index d3b13615b..f2af93b8d 100644
--- a/docs/rules/max-lines-per-function.md
+++ b/docs/rules/max-lines-per-function.md
@@ -10,7 +10,7 @@ This rule enforces a maximum number of lines per function, in order to aid in ma
 
 Nested long method chains like the below example are often broken onto separate lines for readability:
 
-```
+```js
 function() {
     return m("div", [
         m("table", {className: "table table-striped latest-data"}, [
diff --git a/docs/rules/no-compare-neg-zero.md b/docs/rules/no-compare-neg-zero.md
index e9de786e8..cfbe545e2 100644
--- a/docs/rules/no-compare-neg-zero.md
+++ b/docs/rules/no-compare-neg-zero.md
@@ -31,5 +31,3 @@ if (Object.is(x, -0)) {
     // doSomething()...
 }
 ```
-
-
diff --git a/docs/rules/no-constant-condition.md b/docs/rules/no-constant-condition.md
index 036bbb786..8de5e69f3 100644
--- a/docs/rules/no-constant-condition.md
+++ b/docs/rules/no-constant-condition.md
@@ -32,6 +32,14 @@ if (x &&= false) {
     doSomethingNever();
 }
 
+if (class {}) {
+    doSomethingAlways();
+}
+
+if (new Boolean(x)) {
+    doSomethingAlways();
+}
+
 if (x ||= true) {
     doSomethingAlways();
 }
diff --git a/docs/rules/no-empty-function.md b/docs/rules/no-empty-function.md
index 0f8691c82..19110312a 100644
--- a/docs/rules/no-empty-function.md
+++ b/docs/rules/no-empty-function.md
@@ -180,7 +180,7 @@ This rule has an option to allow specific kinds of functions to be empty.
     * `"asyncFunctions"` - Async functions.
     * `"asyncMethods"` - Async class methods and method shorthands of object literals.
 
-#### allow: functions
+### allow: functions
 
 Examples of **correct** code for the `{ "allow": ["functions"] }` option:
 
@@ -196,7 +196,7 @@ var obj = {
 };
 ```
 
-#### allow: arrowFunctions
+### allow: arrowFunctions
 
 Examples of **correct** code for the `{ "allow": ["arrowFunctions"] }` option:
 
@@ -207,7 +207,7 @@ Examples of **correct** code for the `{ "allow": ["arrowFunctions"] }` option:
 var foo = () => {};
 ```
 
-#### allow: generatorFunctions
+### allow: generatorFunctions
 
 Examples of **correct** code for the `{ "allow": ["generatorFunctions"] }` option:
 
@@ -224,7 +224,7 @@ var obj = {
 };
 ```
 
-#### allow: methods
+### allow: methods
 
 Examples of **correct** code for the `{ "allow": ["methods"] }` option:
 
@@ -242,7 +242,7 @@ class A {
 }
 ```
 
-#### allow: generatorMethods
+### allow: generatorMethods
 
 Examples of **correct** code for the `{ "allow": ["generatorMethods"] }` option:
 
@@ -260,7 +260,7 @@ class A {
 }
 ```
 
-#### allow: getters
+### allow: getters
 
 Examples of **correct** code for the `{ "allow": ["getters"] }` option:
 
@@ -278,7 +278,7 @@ class A {
 }
 ```
 
-#### allow: setters
+### allow: setters
 
 Examples of **correct** code for the `{ "allow": ["setters"] }` option:
 
@@ -296,7 +296,7 @@ class A {
 }
 ```
 
-#### allow: constructors
+### allow: constructors
 
 Examples of **correct** code for the `{ "allow": ["constructors"] }` option:
 
@@ -309,7 +309,7 @@ class A {
 }
 ```
 
-#### allow: asyncFunctions
+### allow: asyncFunctions
 
 Examples of **correct** code for the `{ "allow": ["asyncFunctions"] }` options:
 
@@ -320,7 +320,7 @@ Examples of **correct** code for the `{ "allow": ["asyncFunctions"] }` options:
 async function a(){}
 ```
 
-#### allow: asyncMethods
+### allow: asyncMethods
 
 Examples of **correct** code for the `{ "allow": ["asyncMethods"] }` options:
 
diff --git a/docs/rules/no-empty-label.md b/docs/rules/no-empty-label.md
index 3f8850199..b887c87a5 100644
--- a/docs/rules/no-empty-label.md
+++ b/docs/rules/no-empty-label.md
@@ -4,7 +4,6 @@
 
 Labeled statements are only used in conjunction with labeled break and continue statements. ECMAScript has no goto statement.
 
-
 ## Rule Details
 
 This error occurs when a label is used to mark a statement that is not an iteration or switch
diff --git a/docs/rules/no-implied-eval.md b/docs/rules/no-implied-eval.md
index d300ff61d..cbf7c67c2 100644
--- a/docs/rules/no-implied-eval.md
+++ b/docs/rules/no-implied-eval.md
@@ -19,7 +19,6 @@ setTimeout(function() {
 
 The best practice is to always use a function for the first argument of `setTimeout()` and `setInterval()` (and avoid `execScript()`).
 
-
 ## Rule Details
 
 This rule aims to eliminate implied `eval()` through the use of `setTimeout()`, `setInterval()` or `execScript()`. As such, it will warn when either function is used with a string as the first argument.
diff --git a/docs/rules/no-loop-func.md b/docs/rules/no-loop-func.md
index 65c753278..f39b868e5 100644
--- a/docs/rules/no-loop-func.md
+++ b/docs/rules/no-loop-func.md
@@ -26,7 +26,6 @@ for (let i = 0; i < 10; i++) {
 
 In this case, each function created within the loop returns a different number as expected.
 
-
 ## Rule Details
 
 This error is raised to highlight a piece of code that may not work as you expect it to and could also indicate a misunderstanding of how the language works. Your code may run without any problems if you do not fix this error, but in some situations it could behave unexpectedly.
diff --git a/docs/rules/no-mixed-operators.md b/docs/rules/no-mixed-operators.md
index 33ce7f658..1dca581e8 100644
--- a/docs/rules/no-mixed-operators.md
+++ b/docs/rules/no-mixed-operators.md
@@ -36,7 +36,6 @@ will generate
 1:18  Unexpected mix of '&&' and '?:'. (no-mixed-operators)
 ```
 
-
 ## Rule Details
 
 This rule checks `BinaryExpression`, `LogicalExpression` and `ConditionalExpression`.
diff --git a/docs/rules/no-mixed-spaces-and-tabs.md b/docs/rules/no-mixed-spaces-and-tabs.md
index ba34dbe49..9f156bb2b 100644
--- a/docs/rules/no-mixed-spaces-and-tabs.md
+++ b/docs/rules/no-mixed-spaces-and-tabs.md
@@ -59,7 +59,6 @@ function main() {
 }
 ```
 
-
 ## Further Reading
 
 * [Smart Tabs](https://www.emacswiki.org/emacs/SmartTabs)
diff --git a/docs/rules/no-multiple-empty-lines.md b/docs/rules/no-multiple-empty-lines.md
index aff6c2e6f..1a0484182 100644
--- a/docs/rules/no-multiple-empty-lines.md
+++ b/docs/rules/no-multiple-empty-lines.md
@@ -69,7 +69,7 @@ var bar = 3;
 
 **Incorrect**:
 
-```
+```js
 1    /*eslint no-multiple-empty-lines: ["error", { "max": 2, "maxEOF": 0 }]*/⏎
 2    ⏎
 3    var foo = 5;⏎
@@ -82,7 +82,7 @@ var bar = 3;
 
 **Correct**:
 
-```
+```js
 1    /*eslint no-multiple-empty-lines: ["error", { "max": 2, "maxEOF": 0 }]*/⏎
 2    ⏎
 3    var foo = 5;⏎
diff --git a/docs/rules/no-param-reassign.md b/docs/rules/no-param-reassign.md
index 47a7af3cb..29952c370 100644
--- a/docs/rules/no-param-reassign.md
+++ b/docs/rules/no-param-reassign.md
@@ -150,7 +150,6 @@ function foo(barBaz) {
 }
 ```
 
-
 ## When Not To Use It
 
 If you want to allow assignment to function parameters, then you can safely disable this rule.
diff --git a/docs/rules/no-process-env.md b/docs/rules/no-process-env.md
index 83bfa6d02..4655e965e 100644
--- a/docs/rules/no-process-env.md
+++ b/docs/rules/no-process-env.md
@@ -4,7 +4,6 @@ This rule was **deprecated** in ESLint v7.0.0. Please use the corresponding rule
 
 The `process.env` object in Node.js is used to store deployment/configuration parameters. Littering it through out a project could lead to maintenance issues as it's another kind of global dependency. As such, it could lead to merge conflicts in a multi-user setup and deployment issues in a multi-server setup. Instead, one of the best practices is to define all those parameters in a single configuration/settings file which could be accessed throughout the project.
 
-
 ## Rule Details
 
 This rule is aimed at discouraging use of `process.env` to avoid global dependencies. As such, it will warn whenever `process.env` is used.
diff --git a/docs/rules/no-restricted-imports.md b/docs/rules/no-restricted-imports.md
index f1577d7d8..d8e06101b 100644
--- a/docs/rules/no-restricted-imports.md
+++ b/docs/rules/no-restricted-imports.md
@@ -91,7 +91,7 @@ or like this if you want to apply a custom message to pattern matches:
 
 The custom message will be appended to the default error message.
 
-To restrict the use of all Node.js core imports (via https://github.com/nodejs/node/tree/master/lib):
+To restrict the use of all Node.js core imports (via <https://github.com/nodejs/node/tree/master/lib>):
 
 ```json
     "no-restricted-imports": ["error",
diff --git a/docs/rules/no-restricted-modules.md b/docs/rules/no-restricted-modules.md
index 3fc412fe5..3bce05804 100644
--- a/docs/rules/no-restricted-modules.md
+++ b/docs/rules/no-restricted-modules.md
@@ -57,8 +57,7 @@ or like this:
 
 The custom message will be appended to the default error message. Please note that you may not specify custom error messages for restricted patterns as a particular module may match more than one pattern.
 
-
-To restrict the use of all Node.js core modules (via https://github.com/nodejs/node/tree/master/lib):
+To restrict the use of all Node.js core modules (via <https://github.com/nodejs/node/tree/master/lib>):
 
 ```json
 {
diff --git a/docs/rules/no-restricted-properties.md b/docs/rules/no-restricted-properties.md
index e1824d579..468d0b36a 100644
--- a/docs/rules/no-restricted-properties.md
+++ b/docs/rules/no-restricted-properties.md
@@ -2,7 +2,6 @@
 
 Certain properties on objects may be disallowed in a codebase. This is useful for deprecating an API or restricting usage of a module's methods. For example, you may want to disallow using `describe.only` when using Mocha or telling people to use `Object.assign` instead of `_.extend`.
 
-
 ## Rule Details
 
 This rule looks for accessing a given property key on a given object name, either when reading the property's value or invoking it as a function. You may specify an optional message to indicate an alternative API or a reason for the restriction.
diff --git a/docs/rules/no-template-curly-in-string.md b/docs/rules/no-template-curly-in-string.md
index 9c03b67a6..68a237de9 100644
--- a/docs/rules/no-template-curly-in-string.md
+++ b/docs/rules/no-template-curly-in-string.md
@@ -2,7 +2,6 @@
 
 ECMAScript 6 allows programmers to create strings containing variable or expressions using template literals, instead of string concatenation, by writing expressions like `${variable}` between two backtick quotes (\`). It can be easy to use the wrong quotes when wanting to use template literals, by writing `"${variable}"`, and end up with the literal value `"${variable}"` instead of a string containing the value of the injected expressions.
 
-
 ## Rule Details
 
 This rule aims to warn when a regular string contains what looks like a template literal placeholder. It will warn when it finds a string containing the template literal placeholder (`${something}`) that uses either `"` or `'` for the quotes.
diff --git a/docs/rules/no-undef-init.md b/docs/rules/no-undef-init.md
index 0cf99c192..10bde7769 100644
--- a/docs/rules/no-undef-init.md
+++ b/docs/rules/no-undef-init.md
@@ -16,7 +16,6 @@ var foo = undefined;
 
 It's considered a best practice to avoid initializing variables to `undefined`.
 
-
 ## Rule Details
 
 This rule aims to eliminate `var` and `let` variable declarations that initialize to `undefined`.
diff --git a/docs/rules/no-undefined.md b/docs/rules/no-undefined.md
index 0e183f266..0e67c21fd 100644
--- a/docs/rules/no-undefined.md
+++ b/docs/rules/no-undefined.md
@@ -22,7 +22,6 @@ Because `undefined` can be overwritten or shadowed, reading `undefined` can give
 
 As an alternative, you can use the [no-global-assign](no-global-assign.md) and [no-shadow-restricted-names](no-shadow-restricted-names.md) rules to prevent `undefined` from being shadowed or assigned a different value. This ensures that `undefined` will always hold its original, expected value.
 
-
 ## Rule Details
 
 This rule aims to eliminate the use of `undefined`, and as such, generates a warning whenever it is used.
diff --git a/docs/rules/no-unused-vars.md b/docs/rules/no-unused-vars.md
index 30647031e..24eb337c6 100644
--- a/docs/rules/no-unused-vars.md
+++ b/docs/rules/no-unused-vars.md
@@ -293,7 +293,6 @@ try {
 }
 ```
 
-
 ## When Not To Use It
 
 If you don't want to be notified about unused variables or function arguments, you can safely turn this rule off.
diff --git a/docs/rules/no-void.md b/docs/rules/no-void.md
index 6b7774805..3f7837622 100644
--- a/docs/rules/no-void.md
+++ b/docs/rules/no-void.md
@@ -38,7 +38,7 @@ void function(){ foo = 1; }() // will assign foo a value of 1
 +function(){ foo = 1; }() // same as above
 ```
 
-```
+```js
 function(){ foo = 1; }() // will throw SyntaxError
 ```
 
diff --git a/docs/rules/no-wrap-func.md b/docs/rules/no-wrap-func.md
index 6732c9242..5193d79ec 100644
--- a/docs/rules/no-wrap-func.md
+++ b/docs/rules/no-wrap-func.md
@@ -2,7 +2,6 @@
 
 (removed) This rule was **removed** in ESLint v1.0 and **replaced** by the [no-extra-parens](no-extra-parens.md) rule. The `"functions"` option in the new rule is equivalent to the removed rule.
 
-
 Although it's possible to wrap functions in parentheses, this can be confusing when the code also contains immediately-invoked function expressions (IIFEs) since parentheses are often used to make this distinction. For example:
 
 ```js
diff --git a/docs/rules/object-shorthand.md b/docs/rules/object-shorthand.md
index 79e76655c..fee0e62f4 100644
--- a/docs/rules/object-shorthand.md
+++ b/docs/rules/object-shorthand.md
@@ -43,7 +43,6 @@ properties defined where the key name matches name of the assigned variable.
 
 Each of the following properties would warn:
 
-
 ```js
 /*eslint object-shorthand: "error"*/
 /*eslint-env es6*/
diff --git a/docs/rules/prefer-destructuring.md b/docs/rules/prefer-destructuring.md
index 64e914fce..b0f887c13 100644
--- a/docs/rules/prefer-destructuring.md
+++ b/docs/rules/prefer-destructuring.md
@@ -179,7 +179,6 @@ var foo = $('body')[0];
 var [bar] = $('body'); // fails with a TypeError
 ```
 
-
 ## Further Reading
 
 If you want to learn more about destructuring, check out the links below:
diff --git a/docs/rules/prefer-named-capture-group.md b/docs/rules/prefer-named-capture-group.md
index 2caf9518e..f48ec8003 100644
--- a/docs/rules/prefer-named-capture-group.md
+++ b/docs/rules/prefer-named-capture-group.md
@@ -1,6 +1,5 @@
 # Suggest using named capture group in regular expression (prefer-named-capture-group)
 
-
 ## Rule Details
 
 With the landing of ECMAScript 2018, named capture groups can be used in regular expressions, which can improve their readability.
diff --git a/docs/rules/prefer-promise-reject-errors.md b/docs/rules/prefer-promise-reject-errors.md
index ac0a227d1..9740bc975 100644
--- a/docs/rules/prefer-promise-reject-errors.md
+++ b/docs/rules/prefer-promise-reject-errors.md
@@ -2,7 +2,6 @@
 
 It is considered good practice to only pass instances of the built-in `Error` object to the `reject()` function for user-defined errors in Promises. `Error` objects automatically store a stack trace, which can be used to debug an error by determining where it came from. If a Promise is rejected with a non-`Error` value, it can be difficult to determine where the rejection occurred.
 
-
 ## Rule Details
 
 This rule aims to ensure that Promises are only rejected with `Error` objects.
diff --git a/docs/rules/prefer-reflect.md b/docs/rules/prefer-reflect.md
index 55bc1bbbe..af0838efb 100644
--- a/docs/rules/prefer-reflect.md
+++ b/docs/rules/prefer-reflect.md
@@ -19,7 +19,7 @@ The prefer-reflect rule will flag usage of any older method, suggesting to inste
 
 ### Exceptions
 
-```
+```js
 "prefer-reflect": [<enabled>, { "exceptions": [<...exceptions>] }]
 ```
 
diff --git a/docs/rules/radix.md b/docs/rules/radix.md
index da3196c85..4453a648f 100644
--- a/docs/rules/radix.md
+++ b/docs/rules/radix.md
@@ -29,7 +29,6 @@ There are two options for this rule:
 * `"always"` enforces providing a radix (default)
 * `"as-needed"` disallows providing the `10` radix
 
-
 ### always
 
 Examples of **incorrect** code for the default `"always"` option:
diff --git a/docs/rules/require-await.md b/docs/rules/require-await.md
index 595d0acbf..9c84d4393 100644
--- a/docs/rules/require-await.md
+++ b/docs/rules/require-await.md
@@ -81,7 +81,6 @@ In this case, the `fail()` function throws an error that is intended to be caugh
 
 If you are throwing an error inside of an asynchronous function for this purpose, then you may want to disable this rule.
 
-
 ## Related Rules
 
 * [require-yield](require-yield.md)
diff --git a/docs/rules/sort-imports.md b/docs/rules/sort-imports.md
index 637c9fcf3..08c2cf366 100644
--- a/docs/rules/sort-imports.md
+++ b/docs/rules/sort-imports.md
@@ -22,7 +22,6 @@ import "my-module.js"
 
 When declaring multiple imports, a sorted list of import declarations make it easier for developers to read the code and find necessary imports later. This rule is purely a matter of style.
 
-
 ## Rule Details
 
 This rule checks all import declarations and verifies that all imports are first sorted by the used member syntax and then alphabetically by the first member or alias name.
diff --git a/docs/rules/space-after-function-name.md b/docs/rules/space-after-function-name.md
index 4607ff4a1..6cceaab12 100644
--- a/docs/rules/space-after-function-name.md
+++ b/docs/rules/space-after-function-name.md
@@ -20,7 +20,6 @@ Some style guides may require a consistent spacing for function names.
 
 This rule aims to enforce a consistent spacing after function names. It takes one argument. If it is `"always"` then all function names must be followed by at least one space. If `"never"` then there should be no spaces between the name and the parameter list. The default is `"never"`.
 
-
 Examples of **incorrect** code for this rule:
 
 ```js
diff --git a/docs/rules/space-in-brackets.md b/docs/rules/space-in-brackets.md
index 9bb247727..330609acd 100644
--- a/docs/rules/space-in-brackets.md
+++ b/docs/rules/space-in-brackets.md
@@ -232,7 +232,6 @@ var arr = [ {
 
 Examples of **correct** code when `"objectsInArrays"` is set to `false`:
 
-
 ```js
 var arr = [{ 'foo': 'bar' }];
 var arr = [{
diff --git a/docs/rules/spaced-comment.md b/docs/rules/spaced-comment.md
index 5a885f982..66f8f7086 100644
--- a/docs/rules/spaced-comment.md
+++ b/docs/rules/spaced-comment.md
@@ -24,7 +24,7 @@ The rule takes two options.
     * The `"exceptions"` value is an array of string patterns which are considered exceptions to the rule. The rule will not warn when the pattern starts from the beginning of the comment and repeats until the end of the line or `*/` if the comment is a single line comment.
     Please note that exceptions are ignored if the first argument is `"never"`.
 
-    ```
+    ```js
     "spaced-comment": ["error", "always", { "exceptions": ["-", "+"] }]
     ```
 
@@ -32,7 +32,7 @@ The rule takes two options.
     such as an additional `/`, used to denote documentation read by doxygen, vsdoc, etc. which must have additional characters.
     The `"markers"` array will apply regardless of the value of the first argument, e.g. `"always"` or `"never"`.
 
-    ```
+    ```js
     "spaced-comment": ["error", "always", { "markers": ["/"] }]
     ```
 
@@ -281,7 +281,6 @@ subsequent lines are ignored
 /*global ABC*/
 ```
 
-
 ## Related Rules
 
 * [spaced-line-comment](spaced-line-comment.md)
diff --git a/docs/rules/spaced-line-comment.md b/docs/rules/spaced-line-comment.md
index b50404b74..aaaa27a18 100644
--- a/docs/rules/spaced-line-comment.md
+++ b/docs/rules/spaced-line-comment.md
@@ -6,7 +6,6 @@ Some style guides require or disallow a whitespace immediately after the initial
 Whitespace after the `//` makes it easier to read text in comments.
 On the other hand, commenting out code is easier without having to put a whitespace right after the `//`.
 
-
 ## Rule Details
 
 This rule will enforce consistency of spacing after the start of a line comment `//`.
diff --git a/docs/rules/switch-colon-spacing.md b/docs/rules/switch-colon-spacing.md
index bd469ea77..b9872c2ad 100644
--- a/docs/rules/switch-colon-spacing.md
+++ b/docs/rules/switch-colon-spacing.md
@@ -20,7 +20,6 @@ This rule has 2 options that are boolean value.
 - `"before": true` requires one or more spaces before colons.
 - `"before": false` (Default) disallows before colons.
 
-
 Examples of **incorrect** code for this rule:
 
 ```js
diff --git a/docs/rules/symbol-description.md b/docs/rules/symbol-description.md
index 61be8767e..7743867d2 100644
--- a/docs/rules/symbol-description.md
+++ b/docs/rules/symbol-description.md
@@ -9,7 +9,6 @@ var someString = "some description";
 var bar = Symbol(someString);
 ```
 
-
 Using `description` promotes easier debugging: when a symbol is logged the description is used:
 
 ```js
@@ -21,12 +20,10 @@ var foo = Symbol("some description");
 
 It may facilitate identifying symbols when one is observed during debugging.
 
-
 ## Rule Details
 
 This rules requires a description when creating symbols.
 
-
 ## Examples
 
 Examples of **incorrect** code for this rule:
@@ -50,7 +47,6 @@ var someString = "some description";
 var bar = Symbol(someString);
 ```
 
-
 ## When Not To Use It
 
 This rule should not be used in ES3/5 environments.
diff --git a/docs/user-guide/command-line-interface.md b/docs/user-guide/command-line-interface.md
index ad84c37b6..6f350d485 100644
--- a/docs/user-guide/command-line-interface.md
+++ b/docs/user-guide/command-line-interface.md
@@ -1,6 +1,6 @@
 # Command Line Interface
 
-To run ESLint on Node.js, you must have npm installed. If npm is not installed, follow the instructions here: https://www.npmjs.com/
+To run ESLint on Node.js, you must have npm installed. If npm is not installed, follow the instructions here: <https://www.npmjs.com/>
 
 Once npm is installed, run the following
 
@@ -30,62 +30,62 @@ The command line utility has several options. You can view the options by runnin
 eslint [options] file.js [file.js] [dir]
 
 Basic configuration:
-  --no-eslintrc                  Disable use of configuration from .eslintrc.*
-  -c, --config path::String      Use this configuration, overriding .eslintrc.* config options if present
-  --env [String]                 Specify environments
-  --ext [String]                 Specify JavaScript file extensions - default: .js
-  --global [String]              Define global variables
-  --parser String                Specify the parser to be used
-  --parser-options Object        Specify parser options
+  --no-eslintrc                   Disable use of configuration from .eslintrc.*
+  -c, --config path::String       Use this configuration, overriding .eslintrc.* config options if present
+  --env [String]                  Specify environments
+  --ext [String]                  Specify JavaScript file extensions
+  --global [String]               Define global variables
+  --parser String                 Specify the parser to be used
+  --parser-options Object         Specify parser options
   --resolve-plugins-relative-to path::String  A folder where plugins should be resolved from, CWD by default
 
 Specifying rules and plugins:
-  --rulesdir [path::String]      Use additional rules from this directory
-  --plugin [String]              Specify plugins
-  --rule Object                  Specify rules
+  --plugin [String]               Specify plugins
+  --rule Object                   Specify rules
+  --rulesdir [path::String]       Load additional rules from this directory. Deprecated: Use rules from plugins
 
 Fixing problems:
-  --fix                          Automatically fix problems
-  --fix-dry-run                  Automatically fix problems without saving the changes to the file system
-  --fix-type Array               Specify the types of fixes to apply (directive, problem, suggestion, layout)
+  --fix                           Automatically fix problems
+  --fix-dry-run                   Automatically fix problems without saving the changes to the file system
+  --fix-type Array                Specify the types of fixes to apply (directive, problem, suggestion, layout)
 
 Ignoring files:
-  --ignore-path path::String     Specify path of ignore file
-  --no-ignore                    Disable use of ignore files and patterns
-  --ignore-pattern [String]      Pattern of files to ignore (in addition to those in .eslintignore)
+  --ignore-path path::String      Specify path of ignore file
+  --no-ignore                     Disable use of ignore files and patterns
+  --ignore-pattern [String]       Pattern of files to ignore (in addition to those in .eslintignore)
 
 Using stdin:
-  --stdin                        Lint code provided on <STDIN> - default: false
-  --stdin-filename String        Specify filename to process STDIN as
+  --stdin                         Lint code provided on <STDIN> - default: false
+  --stdin-filename String         Specify filename to process STDIN as
 
 Handling warnings:
-  --quiet                        Report errors only - default: false
-  --max-warnings Int             Number of warnings to trigger nonzero exit code - default: -1
+  --quiet                         Report errors only - default: false
+  --max-warnings Int              Number of warnings to trigger nonzero exit code - default: -1
 
 Output:
   -o, --output-file path::String  Specify file to write report to
-  -f, --format String            Use a specific output format - default: stylish
-  --color, --no-color            Force enabling/disabling of color
+  -f, --format String             Use a specific output format - default: stylish
+  --color, --no-color             Force enabling/disabling of color
 
 Inline configuration comments:
-  --no-inline-config             Prevent comments from changing config or rules
+  --no-inline-config              Prevent comments from changing config or rules
   --report-unused-disable-directives  Adds reported errors for unused eslint-disable directives
 
 Caching:
-  --cache                        Only check changed files - default: false
-  --cache-file path::String      Path to the cache file. Deprecated: use --cache-location - default: .eslintcache
-  --cache-location path::String  Path to the cache file or directory
-  --cache-strategy String        Strategy to use for detecting changed files - either: metadata or content - default: metadata
+  --cache                         Only check changed files - default: false
+  --cache-file path::String       Path to the cache file. Deprecated: use --cache-location - default: .eslintcache
+  --cache-location path::String   Path to the cache file or directory
+  --cache-strategy String         Strategy to use for detecting changed files in the cache - either: metadata or content - default: metadata
 
 Miscellaneous:
-  --init                         Run config initialization wizard - default: false
-  --env-info                     Output execution environment information - default: false
-  --no-error-on-unmatched-pattern  Prevent errors when pattern is unmatched - default: false
-  --exit-on-fatal-error          Exit with exit code 2 in case of fatal error - default: false
-  --debug                        Output debugging information
-  -h, --help                     Show help
-  -v, --version                  Output the version number
-  --print-config path::String    Print the configuration for the given file
+  --init                          Run config initialization wizard - default: false
+  --env-info                      Output execution environment information - default: false
+  --no-error-on-unmatched-pattern  Prevent errors when pattern is unmatched
+  --exit-on-fatal-error           Exit with exit code 2 in case of fatal error - default: false
+  --debug                         Output debugging information
+  -h, --help                      Show help
+  -v, --version                   Output the version number
+  --print-config path::String     Print the configuration for the given file
 ```
 
 Options that accept array values can be specified by repeating the option or with a comma-delimited list (other than `--ignore-pattern` which does not allow the second style).
@@ -178,20 +178,6 @@ Changes the folder where plugins are resolved from. By default, plugins are reso
 
 ### Specifying rules and plugins
 
-#### `--rulesdir`
-
-This option allows you to specify another directory from which to load rules files. This allows you to dynamically load new rules at run time. This is useful when you have custom rules that aren't suitable for being bundled with ESLint.
-
-Example:
-
-    eslint --rulesdir my-rules/ file.js
-
-The rules in your custom rules directory must follow the same format as bundled rules to work properly. You can also specify multiple locations for custom rules by including multiple `--rulesdir` options:
-
-    eslint --rulesdir my-rules/ --rulesdir my-other-rules/ file.js
-
-Note that, as with core rules and plugin rules, you still need to enable the rules in configuration or via the `--rule` CLI option in order to actually run those rules during linting. Specifying a rules directory with `--rulesdir` does not automatically enable the rules within that directory.
-
 #### `--plugin`
 
 This option specifies a plugin to load. You can omit the prefix `eslint-plugin-` from the plugin name.
@@ -215,6 +201,22 @@ Examples:
     eslint --rule 'guard-for-in: error' --rule 'brace-style: [error, 1tbs]'
     eslint --rule 'jquery/dollar-sign: error'
 
+#### `--rulesdir`
+
+**Deprecated**: Use rules from plugins instead.
+
+This option allows you to specify another directory from which to load rules files. This allows you to dynamically load new rules at run time. This is useful when you have custom rules that aren't suitable for being bundled with ESLint.
+
+Example:
+
+    eslint --rulesdir my-rules/ file.js
+
+The rules in your custom rules directory must follow the same format as bundled rules to work properly. You can also specify multiple locations for custom rules by including multiple `--rulesdir` options:
+
+    eslint --rulesdir my-rules/ --rulesdir my-other-rules/ file.js
+
+Note that, as with core rules and plugin rules, you still need to enable the rules in configuration or via the `--rule` CLI option in order to actually run those rules during linting. Specifying a rules directory with `--rulesdir` does not automatically enable the rules within that directory.
+
 ### Fixing problems
 
 #### `--fix`
@@ -232,7 +234,7 @@ This option has the same effect as `--fix` with one difference: the fixes are no
 
 Because the default formatter does not output the fixed code, you'll have to use another one (e.g. `json`) to get the fixes. Here's an example of this pattern:
 
-```
+```sh
 getSomeText | eslint --stdin --fix-dry-run --format=json
 ```
 
@@ -249,7 +251,7 @@ This option allows you to specify the type of fixes to apply when using either `
 
 You can specify one or more fix type on the command line. Here are some examples:
 
-```
+```sh
 eslint --fix --fix-type suggestion .
 eslint --fix --fix-type suggestion --fix-type problem .
 eslint --fix --fix-type suggestion,layout .
@@ -473,7 +475,7 @@ This option causes ESLint to exit with exit code 2 if one or more fatal parsing
 
 #### `--debug`
 
-This option outputs debugging information to the console. This information is useful when you're seeing a problem and having a hard time pinpointing it. The ESLint team may ask for this debugging information to help solve bugs.  
+This option outputs debugging information to the console. This information is useful when you're seeing a problem and having a hard time pinpointing it. The ESLint team may ask for this debugging information to help solve bugs.
 Add this flag to an ESLint command line invocation in order to get extra debug information as the command is run (e.g. `eslint --debug test.js` and `eslint test.js --debug` are equivalent)
 
 #### `-h`, `--help`
diff --git a/docs/user-guide/configuring/configuration-files.md b/docs/user-guide/configuring/configuration-files.md
index 091d043b9..b1fded2a3 100644
--- a/docs/user-guide/configuring/configuration-files.md
+++ b/docs/user-guide/configuring/configuration-files.md
@@ -392,7 +392,7 @@ Here is how overrides work in a configuration file:
 
 ### Relative glob patterns
 
-```
+```pt
 project-root
 ├── app
 │   ├── lib
diff --git a/docs/user-guide/configuring/ignoring-code.md b/docs/user-guide/configuring/ignoring-code.md
index d7b3cfd27..35c2d25dd 100644
--- a/docs/user-guide/configuring/ignoring-code.md
+++ b/docs/user-guide/configuring/ignoring-code.md
@@ -1,6 +1,5 @@
 # Ignoring Code
 
-
 * [`ignorePatterns` in Config Files](#ignorepatterns-in-config-files)
 * [The `.eslintignore` File](#the-eslintignore-file)
 * [Using an Alternate File](#using-an-alternate-file)
diff --git a/docs/user-guide/configuring/language-options.md b/docs/user-guide/configuring/language-options.md
index 1ee3f2d19..37fbbe6e3 100644
--- a/docs/user-guide/configuring/language-options.md
+++ b/docs/user-guide/configuring/language-options.md
@@ -1,6 +1,5 @@
 # Language Options
 
-
 * [Specifying Environments](#specifying-environments)
 * [Specifying Globals](#specifying-globals)
 * [Specifying Parser Options](#specifying-parser-options)
@@ -174,7 +173,6 @@ Globals can be disabled with the string `"off"`. For example, in an environment
 
 For historical reasons, the boolean value `false` and the string value `"readable"` are equivalent to `"readonly"`. Similarly, the boolean value `true` and the string value `"writeable"` are equivalent to `"writable"`. However, the use of older values is deprecated.
 
-
 ## Specifying Parser Options
 
 ESLint allows you to specify the JavaScript language options you want to support. By default, ESLint expects ECMAScript 5 syntax. You can override that setting to enable support for other ECMAScript versions as well as JSX by using parser options.
diff --git a/docs/user-guide/configuring/plugins.md b/docs/user-guide/configuring/plugins.md
index 0235586c9..9d2c9294c 100644
--- a/docs/user-guide/configuring/plugins.md
+++ b/docs/user-guide/configuring/plugins.md
@@ -1,6 +1,5 @@
 # Plugins
 
-
 * [Specifying Parser](#specifying-parser)
 * [Specifying Processor](#specifying-processor)
 * [Configuring Plugins](#configuring-plugins)
diff --git a/docs/user-guide/configuring/rules.md b/docs/user-guide/configuring/rules.md
index 0191f6348..4f45b4a87 100644
--- a/docs/user-guide/configuring/rules.md
+++ b/docs/user-guide/configuring/rules.md
@@ -1,6 +1,5 @@
 # Rules
 
-
 * [Configuring Rules](#configuring-rules)
 * [Disabling Rules](#disabling-rules)
 
diff --git a/docs/user-guide/getting-started.md b/docs/user-guide/getting-started.md
index 3c9633bb3..cf808ddc0 100644
--- a/docs/user-guide/getting-started.md
+++ b/docs/user-guide/getting-started.md
@@ -12,7 +12,7 @@ Prerequisites: [Node.js](https://nodejs.org/en/) (`^12.22.0`, `^14.17.0`, or `>=
 
 You can install ESLint using npm or yarn:
 
-```
+```sh
 npm install eslint --save-dev
 
 # or
@@ -22,7 +22,7 @@ yarn add eslint --dev
 
 You should then set up a configuration file, and the easiest way to do that is to use the `--init` flag:
 
-```
+```sh
 $ npx eslint --init
 
 # or
@@ -34,7 +34,7 @@ $ yarn run eslint --init
 
 After that, you can run ESLint on any file or directory like this:
 
-```
+```sh
 $ npx eslint yourfile.js
 
 # or
diff --git a/docs/user-guide/migrating-from-jscs.md b/docs/user-guide/migrating-from-jscs.md
index c5ac5f235..e05ee70d6 100644
--- a/docs/user-guide/migrating-from-jscs.md
+++ b/docs/user-guide/migrating-from-jscs.md
@@ -15,7 +15,7 @@ Before beginning the process of migrating to ESLint, it's helpful to understand
 
 To install Polyjuice:
 
-```
+```sh
 $ npm install -g polyjuice
 ```
 
@@ -23,7 +23,7 @@ Polyjuice works with JSON configuration files, so if you're using a JavaScript o
 
 To convert your configuration file, pass in the location of your `.jscs.json` file using the `--jscs` flag:
 
-```
+```sh
 $ polyjuice --jscs .jscsrc.json > .eslintrc.json
 ```
 
@@ -31,7 +31,7 @@ This creates a `.eslintrc.json` with the equivalent rules from `.jscsrc.json`.
 
 If you have multiple `.jscsrc.json` files, you can pass them all and Polyjuice will combine them into one `.eslintrc.json` file:
 
-```
+```sh
 $ polyjuice --jscs .jscsrc.json ./foo/.jscsrc.json > .eslintrc.json
 ```
 
@@ -41,7 +41,7 @@ $ polyjuice --jscs .jscsrc.json ./foo/.jscsrc.json > .eslintrc.json
 
 If you don't want to convert your JSCS configuration directly into an ESLint configuration, then you can use ESLint's built-in wizard to get you started. Just run:
 
-```
+```sh
 $ eslint --init
 ```
 
@@ -74,7 +74,7 @@ As an example, suppose that you are using the `airbnb` preset, so your `.jscsrc`
 
 In order to get the same functionality in ESLint, you would first need to install the `eslint-config-airbnb` shareable config package:
 
-```
+```sh
 $ npm install eslint-config-airbnb-base --save-dev
 ```
 
@@ -110,13 +110,13 @@ Both JSCS and ESLint have command line arguments corresponding to many of their
 
 JSCS uses the `--fix` option to apply automatic fixes to code:
 
-```
+```sh
 $ jscs --fix file.js
 ```
 
 ESLint has the same option:
 
-```
+```sh
 $ eslint --fix file.js
 ```
 
@@ -124,13 +124,13 @@ $ eslint --fix file.js
 
 The JSCS `--auto-configure` option created a configuration based on what it found in a given file:
 
-```
+```sh
 $ jscs --auto-configure file.js
 ```
 
 In ESLint, there's a similar option when you use `--init`. Just select "Inspect your JavaScript file(s)":
 
-```
+```sh
 $ eslint --init
 ? How would you like to configure ESLint? (Use arrow keys)
 > Answer questions about your style
@@ -142,30 +142,28 @@ $ eslint --init
 
 JSCS allows you to specify a configuration file to use on the command line using either `--config` or `-c`, such as:
 
-```
+```sh
 $ jscs --config myconfig.json file.js
 $ jscs -c myconfig.json file.js
 ```
 
 Both flags are also supported by ESLint:
 
-```
+```sh
 $ eslint --config myconfig.json file.js
 $ eslint -c myconfig.json file.js
 ```
 
-
-
 ## Piping Code Into ESLint
 
 In JSCS, you can pipe code in like this:
 
-```
+```sh
 $ cat file.js | jscs
 ```
 
 In ESLint, you can also pipe in code, but you need to use the `--stdin` flag:
 
-```
+```sh
 $ cat file.js | eslint --stdin
 ```
diff --git a/docs/user-guide/migrating-to-2.0.0.md b/docs/user-guide/migrating-to-2.0.0.md
index 95a3a1774..c5f50b3a1 100644
--- a/docs/user-guide/migrating-to-2.0.0.md
+++ b/docs/user-guide/migrating-to-2.0.0.md
@@ -285,7 +285,7 @@ if (variable) {
 }
 ```
 
-Further Reading: https://estools.github.io/escope/
+Further Reading: <https://estools.github.io/escope/>
 
 ## Default Changes When Using `eslint:recommended`
 
diff --git a/docs/user-guide/migrating-to-4.0.0.md b/docs/user-guide/migrating-to-4.0.0.md
index b62ef053c..8f78291d5 100644
--- a/docs/user-guide/migrating-to-4.0.0.md
+++ b/docs/user-guide/migrating-to-4.0.0.md
@@ -4,7 +4,7 @@ ESLint v4.0.0 is the fourth major version release. We have made several breaking
 
 The lists below are ordered roughly by the number of users each change is expected to affect, where the first items are expected to affect the most users.
 
-### Breaking changes for users
+## Breaking changes for users
 
 1. [New rules have been added to `eslint:recommended`](#eslint-recommended-changes)
 1. [The `indent` rule is more strict](#indent-rewrite)
@@ -15,14 +15,14 @@ The lists below are ordered roughly by the number of users each change is expect
 1. [The `no-multi-spaces` rule is more strict by default](#no-multi-spaces-eol-comments)
 1. [References to scoped plugins in config files are now required to include the scope](#scoped-plugin-resolution)
 
-### Breaking changes for plugin/custom rule developers
+## Breaking changes for plugin/custom rule developers
 
 1. [`RuleTester` now validates properties of test cases](#rule-tester-validation)
 1. [AST nodes no longer have comment properties](#comment-attachment)
 1. [`LineComment` and `BlockComment` events will no longer be emitted during AST traversal](#event-comments)
 1. [Shebangs are now returned from comment APIs](#shebangs)
 
-### Breaking changes for integration developers
+## Breaking changes for integration developers
 
 1. [The `global` property in the `linter.verify()` API is no longer supported](#global-property)
 1. [More report messages now have full location ranges](#report-locations)
@@ -186,7 +186,7 @@ Starting in 4.0, `LineComment` and `BlockComments` events will not be emitted du
 
 **To address:** Instead of relying on `LineComment` and `BlockComment`, rules can now use `sourceCode.getAllComments()` to get all comments in a file. To check all comments of a specific type, rules can use the following pattern:
 
-```
+```js
 sourceCode.getAllComments().filter(comment => comment.type === "Line");
 sourceCode.getAllComments().filter(comment => comment.type === "Block");
 ```
@@ -199,7 +199,7 @@ In 4.0, shebang comments are treated as comment tokens of type `Shebang` and wil
 
 **To address:** If you have a custom rule that performs operations on comments, some additional logic might be required to ensure that shebang comments are correctly handled or filtered out:
 
-```
+```js
 sourceCode.getAllComments().filter(comment => comment.type !== "Shebang");
 ```
 
diff --git a/docs/user-guide/migrating-to-5.0.0.md b/docs/user-guide/migrating-to-5.0.0.md
index da5c435aa..372963163 100644
--- a/docs/user-guide/migrating-to-5.0.0.md
+++ b/docs/user-guide/migrating-to-5.0.0.md
@@ -4,7 +4,7 @@ ESLint v5.0.0 is the fifth major version release. We have made a few breaking ch
 
 The lists below are ordered roughly by the number of users each change is expected to affect, where the first items are expected to affect the most users.
 
-### Breaking changes for users
+## Breaking changes for users
 
 1. [Node.js 4 is no longer supported](#drop-node-4)
 1. [New rules have been added to `eslint:recommended`](#eslint-recommended-changes)
@@ -16,7 +16,7 @@ The lists below are ordered roughly by the number of users each change is expect
 1. [Plugins in scoped packages are now resolvable in configs](#scoped-plugins)
 1. [Multi-line `eslint-disable-line` directives are now reported as problems](#multiline-directives)
 
-### Breaking changes for plugin/custom rule developers
+## Breaking changes for plugin/custom rule developers
 
 1. [The `parent` property of AST nodes is now set before rules start running](#parent-before-rules)
 1. [When using the default parser, spread operators now have type `SpreadElement`](#spread-operators)
@@ -27,7 +27,7 @@ The lists below are ordered roughly by the number of users each change is expect
 1. [`RuleTester` now uses strict equality checks in its assertions](#rule-tester-equality)
 1. [Rules are now required to provide messages along with reports](#required-report-messages)
 
-### Breaking changes for integration developers
+## Breaking changes for integration developers
 
 1. [The `source` property is no longer available on individual linting messages](#source-property)
 1. [Fatal errors now result in an exit code of 2](#exit-code-two)
diff --git a/docs/user-guide/migrating-to-6.0.0.md b/docs/user-guide/migrating-to-6.0.0.md
index 3baec19d9..225cc4c0e 100644
--- a/docs/user-guide/migrating-to-6.0.0.md
+++ b/docs/user-guide/migrating-to-6.0.0.md
@@ -4,7 +4,7 @@ ESLint v6.0.0 is a major release of ESLint. We have made a few breaking changes
 
 The lists below are ordered roughly by the number of users each change is expected to affect, where the first items are expected to affect the most users.
 
-### Breaking changes for users
+## Breaking changes for users
 
 1. [Node.js 6 is no longer supported](#drop-node-6)
 1. [`eslint:recommended` has been updated](#eslint-recommended-changes)
@@ -20,14 +20,14 @@ The lists below are ordered roughly by the number of users each change is expect
 1. [The deprecated `experimentalObjectRestSpread` option has been removed](#experimental-object-rest-spread)
 1. [User-provided regular expressions in rule options are parsed with the unicode flag](#unicode-regexes)
 
-### Breaking changes for plugin/custom rule developers
+## Breaking changes for plugin/custom rule developers
 
 1. [Plugin authors may need to update installation instructions](#plugin-documentation)
 1. [`RuleTester` now validates against invalid `default` keywords in rule schemas](#rule-tester-defaults)
 1. [`RuleTester` now requires an absolute path on `parser` option](#rule-tester-parser)
 1. [The `eslintExplicitGlobalComment` scope analysis property has been removed](#eslintExplicitGlobalComment)
 
-### Breaking changes for integration developers
+## Breaking changes for integration developers
 
 1. [Plugins and shareable configs are no longer affected by ESLint's location](#package-loading-simplification)
 1. [`Linter` no longer tries to load missing parsers from the filesystem](#linter-parsers)
diff --git a/docs/user-guide/migrating-to-8.0.0.md b/docs/user-guide/migrating-to-8.0.0.md
index 351309cc0..444ac124c 100644
--- a/docs/user-guide/migrating-to-8.0.0.md
+++ b/docs/user-guide/migrating-to-8.0.0.md
@@ -51,7 +51,6 @@ ESLint v8.0.0 has removed the `codeframe` and `table` formatters from the core.
 
 **Related issue(s):** [#14277](https://github.com/eslint/eslint/issues/14277), [#14316](https://github.com/eslint/eslint/pull/14316)
 
-
 ## <a name="comma-dangle"></a> `comma-dangle` rule schema is stricter
 
 In ESLint v7.0.0, the `comma-dangle` rule could be configured like this without error:
@@ -105,7 +104,6 @@ Four new rules have been enabled in the `eslint:recommended` preset.
 
 **Related issue(s):** [#14673](https://github.com/eslint/eslint/issues/14673)
 
-
 ## <a name="suggestions"></a> Rules require `meta.hasSuggestions` to provide suggestions
 
 In ESLint v7.0.0, rules that [provided suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions) did not need to let ESLint know. In v8.0.0, rules providing suggestions need to set their `meta.hasSuggestions` to `true`. This informs ESLint that the rule intends to provide suggestions. Without this property, any attempt to provide a suggestion will result in an error.
@@ -219,7 +217,6 @@ In ESLint v8.0.0 (via Acorn v8.0.0), the key and value are now separate objects
 
 **Related issue(s):** [#14591](https://github.com/eslint/eslint/pull/14591#issuecomment-887733070)
 
-
 ## <a name="remove-cliengine"></a> The `CLIEngine` class has been removed
 
 The `CLIEngine` class has been removed and replaced by the [`ESLint` class](https://eslint.org/docs/developer-guide/nodejs-api#eslint-class).
diff --git a/karma.conf.js b/karma.conf.js
index 05f1a1ceb..2c4c1d11d 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -2,7 +2,7 @@
 const os = require("os");
 const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
 
-if (os.arch() === "arm64") {
+if (os.platform === "linux" && os.arch() === "arm64") {
 
     // For arm64 architecture, install chromium-browser using "apt-get install chromium-browser"
     process.env.CHROME_BIN = "/usr/bin/chromium-browser";
diff --git a/lib/eslint/eslint.js b/lib/eslint/eslint.js
index 29d7e5cbc..6274772ad 100644
--- a/lib/eslint/eslint.js
+++ b/lib/eslint/eslint.js
@@ -622,7 +622,7 @@ class ESLint {
             throw new Error("'name' must be a string");
         }
 
-        const { cliEngine } = privateMembersMap.get(this);
+        const { cliEngine, options } = privateMembersMap.get(this);
         const formatter = cliEngine.getFormatter(name);
 
         if (typeof formatter !== "function") {
@@ -642,6 +642,9 @@ class ESLint {
                 results.sort(compareResultsByFilePath);
 
                 return formatter(results, {
+                    get cwd() {
+                        return options.cwd;
+                    },
                     get rulesMeta() {
                         if (!rulesMeta) {
                             rulesMeta = createRulesMeta(cliEngine.getRules());
diff --git a/lib/options.js b/lib/options.js
index 2dd186de3..6d06e3ddc 100644
--- a/lib/options.js
+++ b/lib/options.js
@@ -50,7 +50,7 @@ const optionator = require("optionator");
  * @property {boolean | undefined} reportUnusedDisableDirectives Adds reported errors for unused eslint-disable directives
  * @property {string} [resolvePluginsRelativeTo] A folder where plugins should be resolved from, CWD by default
  * @property {Object} [rule] Specify rules
- * @property {string[]} [rulesdir] Use additional rules from this directory
+ * @property {string[]} [rulesdir] Load additional rules from this directory. Deprecated: Use rules from plugins
  * @property {boolean} stdin Lint code provided on <STDIN>
  * @property {string} [stdinFilename] Specify filename to process STDIN as
  * @property {boolean} quiet Report errors only
@@ -118,11 +118,6 @@ module.exports = optionator({
         {
             heading: "Specifying rules and plugins"
         },
-        {
-            option: "rulesdir",
-            type: "[path::String]",
-            description: "Use additional rules from this directory"
-        },
         {
             option: "plugin",
             type: "[String]",
@@ -133,6 +128,11 @@ module.exports = optionator({
             type: "Object",
             description: "Specify rules"
         },
+        {
+            option: "rulesdir",
+            type: "[path::String]",
+            description: "Load additional rules from this directory. Deprecated: Use rules from plugins"
+        },
         {
             heading: "Fixing problems"
         },
diff --git a/lib/rules/max-lines-per-function.js b/lib/rules/max-lines-per-function.js
index 5985a739e..c1b945ca1 100644
--- a/lib/rules/max-lines-per-function.js
+++ b/lib/rules/max-lines-per-function.js
@@ -80,7 +80,7 @@ module.exports = {
             OPTIONS_OR_INTEGER_SCHEMA
         ],
         messages: {
-            exceed: "{{name}} has too many lines ({{lineCount}}). Maximum allowed is {{maxLines}}."
+            exceed: "{{name}} has exceeded the limit of lines allowed by {{linesExceed}}. Maximum allowed number of lines per function is {{maxLines}}."
         }
     },
 
@@ -170,18 +170,26 @@ module.exports = {
                 return;
             }
             let lineCount = 0;
+            let comments = 0;
+            let blankLines = 0;
 
             for (let i = node.loc.start.line - 1; i < node.loc.end.line; ++i) {
                 const line = lines[i];
 
                 if (skipComments) {
                     if (commentLineNumbers.has(i + 1) && isFullLineComment(line, i + 1, commentLineNumbers.get(i + 1))) {
+                        if (lineCount <= maxLines) {
+                            comments++;
+                        }
                         continue;
                     }
                 }
 
                 if (skipBlankLines) {
                     if (line.match(/^\s*$/u)) {
+                        if (lineCount <= maxLines) {
+                            blankLines++;
+                        }
                         continue;
                     }
                 }
@@ -191,11 +199,21 @@ module.exports = {
 
             if (lineCount > maxLines) {
                 const name = upperCaseFirst(astUtils.getFunctionNameWithKind(funcNode));
+                const linesExceed = lineCount - maxLines;
+
+                const loc = {
+                    start: {
+                        line: node.loc.start.line + maxLines + (comments + blankLines),
+                        column: 0
+                    },
+                    end: node.loc.end
+                };
 
                 context.report({
                     node,
+                    loc,
                     messageId: "exceed",
-                    data: { name, lineCount, maxLines }
+                    data: { name, linesExceed, maxLines }
                 });
             }
         }
diff --git a/lib/rules/no-constant-condition.js b/lib/rules/no-constant-condition.js
index 2c57d9fb3..0bcb31931 100644
--- a/lib/rules/no-constant-condition.js
+++ b/lib/rules/no-constant-condition.js
@@ -139,6 +139,7 @@ module.exports = {
                 case "ArrowFunctionExpression":
                 case "FunctionExpression":
                 case "ObjectExpression":
+                case "ClassExpression":
                     return true;
                 case "TemplateLiteral":
                     return (inBooleanPosition && node.quasis.some(quasi => quasi.value.cooked.length)) ||
@@ -180,7 +181,8 @@ module.exports = {
                         isLeftShortCircuit ||
                         isRightShortCircuit;
                 }
-
+                case "NewExpression":
+                    return inBooleanPosition;
                 case "AssignmentExpression":
                     if (node.operator === "=") {
                         return isConstant(node.right, inBooleanPosition);
diff --git a/package.json b/package.json
index c3dfa1bb3..6fc8d2877 100644
--- a/package.json
+++ b/package.json
@@ -116,8 +116,8 @@
     "karma-webpack": "^5.0.0",
     "lint-staged": "^11.0.0",
     "load-perf": "^0.2.0",
-    "markdownlint": "^0.23.1",
-    "markdownlint-cli": "^0.28.1",
+    "markdownlint": "^0.24.0",
+    "markdownlint-cli": "^0.30.0",
     "memfs": "^3.0.1",
     "mocha": "^8.3.2",
     "mocha-junit-reporter": "^2.0.0",
diff --git a/templates/bug-report.md b/templates/bug-report.md
index bd3035b54..c8c552d30 100644
--- a/templates/bug-report.md
+++ b/templates/bug-report.md
@@ -1,4 +1,4 @@
-**Tell us about your environment**
+**Tell us about your environment:**
 
 * **ESLint Version:**
 * **Node Version:**
@@ -23,4 +23,3 @@
 **What did you expect to happen?**
 
 **What actually happened? Please include the actual, raw output from ESLint.**
-
diff --git a/templates/rule-change-proposal.md b/templates/rule-change-proposal.md
index ee100011b..a4a8e17cb 100644
--- a/templates/rule-change-proposal.md
+++ b/templates/rule-change-proposal.md
@@ -1,12 +1,9 @@
 **What rule do you want to change?**
 
-
 **Does this change cause the rule to produce more or fewer warnings?**
 
-
 **How will the change be implemented? (New option, new default behavior, etc.)?**
 
-
 **Please provide some example code that this change will affect:**
 
 ```js
@@ -15,6 +12,4 @@
 
 **What does the rule currently do for this code?**
 
-
 **What will the rule do after it's changed?**
-
diff --git a/templates/rule-proposal.md b/templates/rule-proposal.md
index 383b1b481..2adf93176 100644
--- a/templates/rule-proposal.md
+++ b/templates/rule-proposal.md
@@ -1,7 +1,6 @@
 **Please describe what the rule should do:**
 
-
-**What category of rule is this? (place an "X" next to just one item)**
+**What category of rule is this (place an "X" next to just one item)?**
 
 [ ] Enforces code style
 [ ] Warns about a potential error
@@ -15,4 +14,3 @@
 ```
 
 **Why should this rule be included in ESLint (instead of a plugin)?**
-
diff --git a/tools/update-readme.js b/tools/update-readme.js
index 55efb6f2c..0704ceff1 100644
--- a/tools/update-readme.js
+++ b/tools/update-readme.js
@@ -123,5 +123,8 @@ let newReadme = readme.replace(/<!--teamstart-->[\w\W]*?<!--teamend-->/u, ejs.re
 
 newReadme = newReadme.replace(/<!--sponsorsstart-->[\w\W]*?<!--sponsorsend-->/u, formatSponsors(allSponsors));
 
+// replace multiple consecutive blank lines with just one blank line
+newReadme = newReadme.replace(/(?<=^|\n)\n{2,}/gu, "\n");
+
 // output to the file
 fs.writeFileSync(README_FILE_PATH, newReadme, "utf8");


Test patch:
diff --git a/tests/fixtures/formatters/cwd.js b/tests/fixtures/formatters/cwd.js
new file mode 100644
index 000000000..b9c4966ef
--- /dev/null
+++ b/tests/fixtures/formatters/cwd.js
@@ -0,0 +1,4 @@
+/*global module*/
+module.exports = function(results, context) {
+    return context.cwd;
+};
diff --git a/tests/lib/cli-engine/cli-engine.js b/tests/lib/cli-engine/cli-engine.js
index 16beb92b8..2ba4839ba 100644
--- a/tests/lib/cli-engine/cli-engine.js
+++ b/tests/lib/cli-engine/cli-engine.js
@@ -1158,28 +1158,44 @@ describe("CLIEngine", () => {
                 configFile: getFixturePath("configurations", "semi-error.json")
             });
 
-            const report = engine.executeOnFiles([getFixturePath("formatters")]);
+            const fixturePath = getFixturePath("formatters");
+            const report = engine.executeOnFiles([fixturePath]);
 
-            assert.strictEqual(report.results.length, 4);
             assert.strictEqual(report.errorCount, 0);
             assert.strictEqual(report.warningCount, 0);
             assert.strictEqual(report.fixableErrorCount, 0);
             assert.strictEqual(report.fixableWarningCount, 0);
-            assert.strictEqual(report.results[0].messages.length, 0);
-            assert.strictEqual(report.results[1].messages.length, 0);
-            assert.strictEqual(report.results[2].messages.length, 0);
+            assert.strictEqual(report.results.length, 5);
+            assert.strictEqual(path.relative(fixturePath, report.results[0].filePath), "async.js");
             assert.strictEqual(report.results[0].errorCount, 0);
             assert.strictEqual(report.results[0].warningCount, 0);
             assert.strictEqual(report.results[0].fixableErrorCount, 0);
             assert.strictEqual(report.results[0].fixableWarningCount, 0);
+            assert.strictEqual(report.results[0].messages.length, 0);
+            assert.strictEqual(path.relative(fixturePath, report.results[1].filePath), "broken.js");
             assert.strictEqual(report.results[1].errorCount, 0);
             assert.strictEqual(report.results[1].warningCount, 0);
             assert.strictEqual(report.results[1].fixableErrorCount, 0);
             assert.strictEqual(report.results[1].fixableWarningCount, 0);
+            assert.strictEqual(report.results[1].messages.length, 0);
+            assert.strictEqual(path.relative(fixturePath, report.results[2].filePath), "cwd.js");
             assert.strictEqual(report.results[2].errorCount, 0);
             assert.strictEqual(report.results[2].warningCount, 0);
             assert.strictEqual(report.results[2].fixableErrorCount, 0);
             assert.strictEqual(report.results[2].fixableWarningCount, 0);
+            assert.strictEqual(report.results[2].messages.length, 0);
+            assert.strictEqual(path.relative(fixturePath, report.results[3].filePath), "simple.js");
+            assert.strictEqual(report.results[3].errorCount, 0);
+            assert.strictEqual(report.results[3].warningCount, 0);
+            assert.strictEqual(report.results[3].fixableErrorCount, 0);
+            assert.strictEqual(report.results[3].fixableWarningCount, 0);
+            assert.strictEqual(report.results[3].messages.length, 0);
+            assert.strictEqual(path.relative(fixturePath, report.results[4].filePath), path.join("test", "simple.js"));
+            assert.strictEqual(report.results[4].errorCount, 0);
+            assert.strictEqual(report.results[4].warningCount, 0);
+            assert.strictEqual(report.results[4].fixableErrorCount, 0);
+            assert.strictEqual(report.results[4].fixableWarningCount, 0);
+            assert.strictEqual(report.results[4].messages.length, 0);
         });
 
 
@@ -1190,28 +1206,39 @@ describe("CLIEngine", () => {
                 configFile: getFixturePath("configurations", "single-quotes-error.json")
             });
 
-            const report = engine.executeOnFiles([getFixturePath("formatters")]);
+            const fixturePath = getFixturePath("formatters");
+            const report = engine.executeOnFiles([fixturePath]);
 
             assert.strictEqual(report.errorCount, 6);
             assert.strictEqual(report.warningCount, 0);
             assert.strictEqual(report.fixableErrorCount, 6);
             assert.strictEqual(report.fixableWarningCount, 0);
+            assert.strictEqual(report.results.length, 5);
+            assert.strictEqual(path.relative(fixturePath, report.results[0].filePath), "async.js");
             assert.strictEqual(report.results[0].errorCount, 0);
             assert.strictEqual(report.results[0].warningCount, 0);
             assert.strictEqual(report.results[0].fixableErrorCount, 0);
             assert.strictEqual(report.results[0].fixableWarningCount, 0);
+            assert.strictEqual(path.relative(fixturePath, report.results[1].filePath), "broken.js");
             assert.strictEqual(report.results[1].errorCount, 0);
             assert.strictEqual(report.results[1].warningCount, 0);
             assert.strictEqual(report.results[1].fixableErrorCount, 0);
             assert.strictEqual(report.results[1].fixableWarningCount, 0);
-            assert.strictEqual(report.results[2].errorCount, 3);
+            assert.strictEqual(path.relative(fixturePath, report.results[2].filePath), "cwd.js");
+            assert.strictEqual(report.results[2].errorCount, 0);
             assert.strictEqual(report.results[2].warningCount, 0);
-            assert.strictEqual(report.results[2].fixableErrorCount, 3);
+            assert.strictEqual(report.results[2].fixableErrorCount, 0);
             assert.strictEqual(report.results[2].fixableWarningCount, 0);
+            assert.strictEqual(path.relative(fixturePath, report.results[3].filePath), "simple.js");
             assert.strictEqual(report.results[3].errorCount, 3);
             assert.strictEqual(report.results[3].warningCount, 0);
             assert.strictEqual(report.results[3].fixableErrorCount, 3);
             assert.strictEqual(report.results[3].fixableWarningCount, 0);
+            assert.strictEqual(path.relative(fixturePath, report.results[4].filePath), path.join("test", "simple.js"));
+            assert.strictEqual(report.results[4].errorCount, 3);
+            assert.strictEqual(report.results[4].warningCount, 0);
+            assert.strictEqual(report.results[4].fixableErrorCount, 3);
+            assert.strictEqual(report.results[4].fixableWarningCount, 0);
         });
 
         it("should process when file is given by not specifying extensions", () => {
diff --git a/tests/lib/cli.js b/tests/lib/cli.js
index 143a3ac1e..59ff0eaf7 100644
--- a/tests/lib/cli.js
+++ b/tests/lib/cli.js
@@ -249,10 +249,13 @@ describe("cli", () => {
 
             // Check metadata.
             const { metadata } = JSON.parse(log.info.args[0][0]);
-            const expectedMetadata = Array.from(BuiltinRules).reduce((obj, [ruleId, rule]) => {
-                obj.rulesMeta[ruleId] = rule.meta;
-                return obj;
-            }, { rulesMeta: {} });
+            const expectedMetadata = {
+                cwd: process.cwd(),
+                rulesMeta: Array.from(BuiltinRules).reduce((obj, [ruleId, rule]) => {
+                    obj[ruleId] = rule.meta;
+                    return obj;
+                }, {})
+            };
 
             assert.deepStrictEqual(metadata, expectedMetadata);
         });
diff --git a/tests/lib/eslint/eslint.js b/tests/lib/eslint/eslint.js
index d984f5a30..4e140f7fe 100644
--- a/tests/lib/eslint/eslint.js
+++ b/tests/lib/eslint/eslint.js
@@ -1210,24 +1210,40 @@ describe("ESLint", () => {
                 cwd: path.join(fixtureDir, ".."),
                 overrideConfigFile: getFixturePath("configurations", "semi-error.json")
             });
-            const results = await eslint.lintFiles([getFixturePath("formatters")]);
+            const fixturePath = getFixturePath("formatters");
+            const results = await eslint.lintFiles([fixturePath]);
 
-            assert.strictEqual(results.length, 4);
-            assert.strictEqual(results[0].messages.length, 0);
-            assert.strictEqual(results[1].messages.length, 0);
-            assert.strictEqual(results[2].messages.length, 0);
+            assert.strictEqual(results.length, 5);
+            assert.strictEqual(path.relative(fixturePath, results[0].filePath), "async.js");
             assert.strictEqual(results[0].errorCount, 0);
             assert.strictEqual(results[0].warningCount, 0);
             assert.strictEqual(results[0].fixableErrorCount, 0);
             assert.strictEqual(results[0].fixableWarningCount, 0);
+            assert.strictEqual(results[0].messages.length, 0);
+            assert.strictEqual(path.relative(fixturePath, results[1].filePath), "broken.js");
             assert.strictEqual(results[1].errorCount, 0);
             assert.strictEqual(results[1].warningCount, 0);
             assert.strictEqual(results[1].fixableErrorCount, 0);
             assert.strictEqual(results[1].fixableWarningCount, 0);
+            assert.strictEqual(results[1].messages.length, 0);
+            assert.strictEqual(path.relative(fixturePath, results[2].filePath), "cwd.js");
             assert.strictEqual(results[2].errorCount, 0);
             assert.strictEqual(results[2].warningCount, 0);
             assert.strictEqual(results[2].fixableErrorCount, 0);
             assert.strictEqual(results[2].fixableWarningCount, 0);
+            assert.strictEqual(results[2].messages.length, 0);
+            assert.strictEqual(path.relative(fixturePath, results[3].filePath), "simple.js");
+            assert.strictEqual(results[3].errorCount, 0);
+            assert.strictEqual(results[3].warningCount, 0);
+            assert.strictEqual(results[3].fixableErrorCount, 0);
+            assert.strictEqual(results[3].fixableWarningCount, 0);
+            assert.strictEqual(results[3].messages.length, 0);
+            assert.strictEqual(path.relative(fixturePath, results[4].filePath), path.join("test", "simple.js"));
+            assert.strictEqual(results[4].errorCount, 0);
+            assert.strictEqual(results[4].warningCount, 0);
+            assert.strictEqual(results[4].fixableErrorCount, 0);
+            assert.strictEqual(results[4].fixableWarningCount, 0);
+            assert.strictEqual(results[4].messages.length, 0);
         });
 
         it("should process when file is given by not specifying extensions", async () => {
@@ -4731,6 +4747,15 @@ describe("ESLint", () => {
                 await engine.loadFormatter(5);
             }, /'name' must be a string/u);
         });
+
+        it("should pass cwd to the `cwd` property of the second argument.", async () => {
+            const cwd = getFixturePath();
+            const engine = new ESLint({ cwd });
+            const formatterPath = getFixturePath("formatters", "cwd.js");
+            const formatter = await engine.loadFormatter(formatterPath);
+
+            assert.strictEqual(formatter.format([]), cwd);
+        });
     });
 
     describe("getErrorResults()", () => {
diff --git a/tests/lib/rules/max-lines-per-function.js b/tests/lib/rules/max-lines-per-function.js
index ba01206f4..74acab2af 100644
--- a/tests/lib/rules/max-lines-per-function.js
+++ b/tests/lib/rules/max-lines-per-function.js
@@ -199,7 +199,14 @@ if ( x === y ) {
             code: "function name() {\n}",
             options: [1],
             errors: [
-                { messageId: "exceed", data: { name: "Function 'name'", lineCount: 2, maxLines: 1 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Function 'name'", linesExceed: 1, maxLines: 1 },
+                    line: 2,
+                    column: 1,
+                    endLine: 2,
+                    endColumn: 2
+                }
             ]
         },
 
@@ -208,7 +215,14 @@ if ( x === y ) {
             code: "var func = function() {\n}",
             options: [1],
             errors: [
-                { messageId: "exceed", data: { name: "Function", lineCount: 2, maxLines: 1 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Function", linesExceed: 1, maxLines: 1 },
+                    line: 2,
+                    column: 1,
+                    endLine: 2,
+                    endColumn: 2
+                }
             ]
         },
 
@@ -217,7 +231,14 @@ if ( x === y ) {
             code: "const bar = () => {\nconst x = 2 + 1;\nreturn x;\n}",
             options: [3],
             errors: [
-                { messageId: "exceed", data: { name: "Arrow function", lineCount: 4, maxLines: 3 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Arrow function", linesExceed: 1, maxLines: 3 },
+                    line: 4,
+                    column: 1,
+                    endLine: 4,
+                    endColumn: 2
+                }
             ]
         },
 
@@ -226,7 +247,14 @@ if ( x === y ) {
             code: "const bar = () =>\n 2",
             options: [1],
             errors: [
-                { messageId: "exceed", data: { name: "Arrow function", lineCount: 2, maxLines: 1 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Arrow function", linesExceed: 1, maxLines: 1 },
+                    line: 2,
+                    column: 1,
+                    endLine: 2,
+                    endColumn: 3
+                }
             ]
         },
 
@@ -235,7 +263,14 @@ if ( x === y ) {
             code: `() => {${"foo\n".repeat(60)}}`,
             options: [{}],
             errors: [
-                { messageId: "exceed", data: { name: "Arrow function", lineCount: 61, maxLines: 50 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Arrow function", linesExceed: 11, maxLines: 50 },
+                    line: 51,
+                    column: 1,
+                    endLine: 61,
+                    endColumn: 2
+                }
             ]
         },
 
@@ -244,7 +279,14 @@ if ( x === y ) {
             code: "function name() {\nvar x = 5;\n\t\n \n\nvar x = 2;\n}",
             options: [{ max: 6, skipComments: false, skipBlankLines: false }],
             errors: [
-                { messageId: "exceed", data: { name: "Function 'name'", lineCount: 7, maxLines: 6 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Function 'name'", linesExceed: 1, maxLines: 6 },
+                    line: 7,
+                    column: 1,
+                    endLine: 7,
+                    endColumn: 2
+                }
             ]
         },
 
@@ -253,7 +295,14 @@ if ( x === y ) {
             code: "function name() {\r\nvar x = 5;\r\n\t\r\n \r\n\r\nvar x = 2;\r\n}",
             options: [{ max: 6, skipComments: true, skipBlankLines: false }],
             errors: [
-                { messageId: "exceed", data: { name: "Function 'name'", lineCount: 7, maxLines: 6 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Function 'name'", linesExceed: 1, maxLines: 6 },
+                    line: 7,
+                    column: 1,
+                    endLine: 7,
+                    endColumn: 2
+                }
             ]
         },
 
@@ -262,7 +311,14 @@ if ( x === y ) {
             code: "function name() {\nvar x = 5;\n\t\n \n\nvar x = 2;\n}",
             options: [{ max: 2, skipComments: true, skipBlankLines: true }],
             errors: [
-                { messageId: "exceed", data: { name: "Function 'name'", lineCount: 4, maxLines: 2 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Function 'name'", linesExceed: 2, maxLines: 2 },
+                    line: 6,
+                    column: 1,
+                    endLine: 7,
+                    endColumn: 2
+                }
             ]
         },
 
@@ -271,7 +327,14 @@ if ( x === y ) {
             code: "function name() {\r\nvar x = 5;\r\n\t\r\n \r\n\r\nvar x = 2;\r\n}",
             options: [{ max: 2, skipComments: true, skipBlankLines: true }],
             errors: [
-                { messageId: "exceed", data: { name: "Function 'name'", lineCount: 4, maxLines: 2 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Function 'name'", linesExceed: 2, maxLines: 2 },
+                    line: 6,
+                    column: 1,
+                    endLine: 7,
+                    endColumn: 2
+                }
             ]
         },
 
@@ -280,7 +343,14 @@ if ( x === y ) {
             code: "function name() { // end of line comment\nvar x = 5; /* mid line comment */\n\t// single line comment taking up whole line\n\t\n \n\nvar x = 2;\n}",
             options: [{ max: 6, skipComments: true, skipBlankLines: false }],
             errors: [
-                { messageId: "exceed", data: { name: "Function 'name'", lineCount: 7, maxLines: 6 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Function 'name'", linesExceed: 1, maxLines: 6 },
+                    line: 8,
+                    column: 1,
+                    endLine: 8,
+                    endColumn: 2
+                }
             ]
         },
 
@@ -289,7 +359,14 @@ if ( x === y ) {
             code: "function name() { // end of line comment\nvar x = 5; /* mid line comment */\n\t// single line comment taking up whole line\n\t\n \n\nvar x = 2;\n}",
             options: [{ max: 1, skipComments: true, skipBlankLines: true }],
             errors: [
-                { messageId: "exceed", data: { name: "Function 'name'", lineCount: 4, maxLines: 1 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Function 'name'", linesExceed: 3, maxLines: 1 },
+                    line: 2,
+                    column: 1,
+                    endLine: 8,
+                    endColumn: 2
+                }
             ]
         },
 
@@ -298,7 +375,14 @@ if ( x === y ) {
             code: "function name() { // end of line comment\nvar x = 5; /* mid line comment */\n\t// single line comment taking up whole line\n\t\n \n\nvar x = 2;\n}",
             options: [{ max: 1, skipComments: false, skipBlankLines: true }],
             errors: [
-                { messageId: "exceed", data: { name: "Function 'name'", lineCount: 5, maxLines: 1 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Function 'name'", linesExceed: 4, maxLines: 1 },
+                    line: 2,
+                    column: 1,
+                    endLine: 8,
+                    endColumn: 2
+                }
             ]
         },
 
@@ -313,7 +397,14 @@ if ( x === y ) {
 }`,
             options: [{ max: 2, skipComments: true, skipBlankLines: false }],
             errors: [
-                { messageId: "exceed", data: { name: "Function 'foo'", lineCount: 7, maxLines: 2 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Function 'foo'", linesExceed: 5, maxLines: 2 },
+                    line: 3,
+                    column: 1,
+                    endLine: 7,
+                    endColumn: 2
+                }
             ]
         },
 
@@ -328,7 +419,14 @@ function
 ()`,
             options: [{ max: 2, skipComments: true, skipBlankLines: false, IIFEs: true }],
             errors: [
-                { messageId: "exceed", data: { name: "Function", lineCount: 4, maxLines: 2 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Function", linesExceed: 2, maxLines: 2 },
+                    line: 4,
+                    column: 1,
+                    endLine: 5,
+                    endColumn: 2
+                }
             ]
         },
 
@@ -346,7 +444,14 @@ if ( x === y ) {
 }`,
             options: [{ max: 9, skipComments: true, skipBlankLines: false }],
             errors: [
-                { messageId: "exceed", data: { name: "Function 'parent'", lineCount: 10, maxLines: 9 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Function 'parent'", linesExceed: 1, maxLines: 9 },
+                    line: 10,
+                    column: 1,
+                    endLine: 10,
+                    endColumn: 2
+                }
             ]
         },
 
@@ -364,8 +469,22 @@ if ( x === y ) {
 }`,
             options: [{ max: 2, skipComments: true, skipBlankLines: false }],
             errors: [
-                { messageId: "exceed", data: { name: "Function 'parent'", lineCount: 10, maxLines: 2 } },
-                { messageId: "exceed", data: { name: "Function 'nested'", lineCount: 4, maxLines: 2 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Function 'parent'", linesExceed: 8, maxLines: 2 },
+                    line: 3,
+                    column: 1,
+                    endLine: 10,
+                    endColumn: 2
+                },
+                {
+                    messageId: "exceed",
+                    data: { name: "Function 'nested'", linesExceed: 2, maxLines: 2 },
+                    line: 5,
+                    column: 1,
+                    endLine: 6,
+                    endColumn: 2
+                }
             ]
         },
 
@@ -380,7 +499,14 @@ if ( x === y ) {
 }`,
             options: [{ max: 2, skipComments: true, skipBlankLines: false }],
             errors: [
-                { messageId: "exceed", data: { name: "Method 'method'", lineCount: 5, maxLines: 2 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Method 'method'", linesExceed: 3, maxLines: 2 },
+                    line: 4,
+                    column: 1,
+                    endLine: 6,
+                    endColumn: 6
+                }
             ]
         },
 
@@ -395,7 +521,14 @@ if ( x === y ) {
 }`,
             options: [{ max: 2, skipComments: true, skipBlankLines: false }],
             errors: [
-                { messageId: "exceed", data: { name: "Static method 'foo'", lineCount: 5, maxLines: 2 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Static method 'foo'", linesExceed: 3, maxLines: 2 },
+                    line: 4,
+                    column: 1,
+                    endLine: 6,
+                    endColumn: 6
+                }
             ]
         },
 
@@ -408,9 +541,16 @@ if ( x === y ) {
         return 1
     }
 }`,
-            options: [{ max: 2, skipComments: true, skipBlankLines: false }],
+            options: [{ max: 4, skipComments: true, skipBlankLines: false }],
             errors: [
-                { messageId: "exceed", data: { name: "Getter 'foo'", lineCount: 5, maxLines: 2 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Getter 'foo'", linesExceed: 1, maxLines: 4 },
+                    line: 6,
+                    column: 1,
+                    endLine: 6,
+                    endColumn: 6
+                }
             ]
         },
 
@@ -425,7 +565,14 @@ if ( x === y ) {
 }`,
             options: [{ max: 2, skipComments: true, skipBlankLines: false }],
             errors: [
-                { messageId: "exceed", data: { name: "Setter 'foo'", lineCount: 5, maxLines: 2 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Setter 'foo'", linesExceed: 3, maxLines: 2 },
+                    line: 4,
+                    column: 1,
+                    endLine: 6,
+                    endColumn: 6
+                }
             ]
         },
 
@@ -443,7 +590,14 @@ if ( x === y ) {
 }`,
             options: [{ max: 2, skipComments: true, skipBlankLines: false }],
             errors: [
-                { messageId: "exceed", data: { name: "Static method", lineCount: 8, maxLines: 2 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Static method", linesExceed: 6, maxLines: 2 },
+                    line: 4,
+                    column: 1,
+                    endLine: 9,
+                    endColumn: 6
+                }
             ]
         },
 
@@ -458,7 +612,14 @@ if ( x === y ) {
 }());`,
             options: [{ max: 2, skipComments: true, skipBlankLines: false, IIFEs: true }],
             errors: [
-                { messageId: "exceed", data: { name: "Function", lineCount: 7, maxLines: 2 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Function", linesExceed: 5, maxLines: 2 },
+                    line: 3,
+                    column: 1,
+                    endLine: 7,
+                    endColumn: 2
+                }
             ]
         },
 
@@ -473,7 +634,28 @@ if ( x === y ) {
 })();`,
             options: [{ max: 2, skipComments: true, skipBlankLines: false, IIFEs: true }],
             errors: [
-                { messageId: "exceed", data: { name: "Arrow function", lineCount: 7, maxLines: 2 } }
+                {
+                    messageId: "exceed",
+                    data: { name: "Arrow function", linesExceed: 5, maxLines: 2 },
+                    line: 3,
+                    column: 1,
+                    endLine: 7,
+                    endColumn: 2
+                }
+            ]
+        },
+        {
+            code: "\nfoo();\nbar();\nbaz();\nfunction name() {\nvar x = 5;\n/* comment 1 */\n/* comment 2 */\n\t\n \n\nvar x = 2;\n}\nquz();",
+            options: [{ max: 2, skipComments: true, skipBlankLines: true }],
+            errors: [
+                {
+                    messageId: "exceed",
+                    data: { name: "Function 'name'", linesExceed: 2, maxLines: 2 },
+                    line: 12,
+                    column: 1,
+                    endLine: 13,
+                    endColumn: 2
+                }
             ]
         }
     ]
diff --git a/tests/lib/rules/no-constant-condition.js b/tests/lib/rules/no-constant-condition.js
index ecb6de534..0b5f3c5a1 100644
--- a/tests/lib/rules/no-constant-condition.js
+++ b/tests/lib/rules/no-constant-condition.js
@@ -174,7 +174,8 @@ ruleTester.run("no-constant-condition", rule, {
         "function* foo() {for (; ; yield) {}}",
         "function* foo() {while (true) {function* foo() {yield;}yield;}}",
         "function* foo() { for (let x = yield; x < 10; x++) {yield;}yield;}",
-        "function* foo() { for (let x = yield; ; x++) { yield; }}"
+        "function* foo() { for (let x = yield; ; x++) { yield; }}",
+        "if (new Number(x) + 1 === 2) {}"
     ],
     invalid: [
         { code: "for(;true;);", errors: [{ messageId: "unexpected", type: "Literal" }] },
@@ -387,6 +388,16 @@ ruleTester.run("no-constant-condition", rule, {
         { code: "if(0b1n);", parserOptions: { ecmaVersion: 11 }, errors: [{ messageId: "unexpected", type: "Literal" }] },
         { code: "if(0o1n);", parserOptions: { ecmaVersion: 11 }, errors: [{ messageId: "unexpected", type: "Literal" }] },
         { code: "if(0x1n);", parserOptions: { ecmaVersion: 11 }, errors: [{ messageId: "unexpected", type: "Literal" }] },
-        { code: "if(0x1n || foo);", parserOptions: { ecmaVersion: 11 }, errors: [{ messageId: "unexpected", type: "LogicalExpression" }] }
+        { code: "if(0x1n || foo);", parserOptions: { ecmaVersion: 11 }, errors: [{ messageId: "unexpected", type: "LogicalExpression" }] },
+
+        // Classes and instances are always truthy
+        { code: "if(class {}) {}", errors: [{ messageId: "unexpected" }] },
+        { code: "if(new Foo()) {}", errors: [{ messageId: "unexpected" }] },
+
+        // Boxed primitives are always truthy
+        { code: "if(new Boolean(foo)) {}", errors: [{ messageId: "unexpected" }] },
+        { code: "if(new String(foo)) {}", errors: [{ messageId: "unexpected" }] },
+        { code: "if(new Number(foo)) {}", errors: [{ messageId: "unexpected" }] }
+
     ]
 });