]> git.proxmox.com Git - pve-eslint.git/commitdiff
import and build new upstream release 7.2.0
authorThomas Lamprecht <t.lamprecht@proxmox.com>
Sat, 6 Jun 2020 13:59:12 +0000 (15:59 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Sat, 6 Jun 2020 14:55:23 +0000 (16:55 +0200)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
78 files changed:
Makefile
eslint/.github/FUNDING.yml [deleted file]
eslint/.github/ISSUE_TEMPLATE/config.yml [new file with mode: 0644]
eslint/CHANGELOG.md
eslint/CODE_OF_CONDUCT.md [deleted file]
eslint/CONTRIBUTING.md
eslint/README.md
eslint/docs/developer-guide/working-with-rules.md
eslint/docs/rules/no-extra-parens.md
eslint/docs/rules/no-mixed-operators.md
eslint/lib/cli-engine/cli-engine.js
eslint/lib/cli-engine/config-array-factory.js
eslint/lib/init/config-initializer.js
eslint/lib/linter/code-path-analysis/code-path-analyzer.js
eslint/lib/linter/code-path-analysis/code-path-state.js
eslint/lib/linter/config-comment-parser.js
eslint/lib/rules/func-call-spacing.js
eslint/lib/rules/keyword-spacing.js
eslint/lib/rules/multiline-ternary.js
eslint/lib/rules/no-control-regex.js
eslint/lib/rules/no-extra-boolean-cast.js
eslint/lib/rules/no-extra-parens.js
eslint/lib/rules/no-invalid-regexp.js
eslint/lib/rules/no-misleading-character-class.js
eslint/lib/rules/no-mixed-operators.js
eslint/lib/rules/no-mixed-spaces-and-tabs.js
eslint/lib/rules/no-regex-spaces.js
eslint/lib/rules/no-restricted-exports.js
eslint/lib/rules/no-unneeded-ternary.js
eslint/lib/rules/no-unused-expressions.js
eslint/lib/rules/no-unused-vars.js
eslint/lib/rules/no-useless-backreference.js
eslint/lib/rules/prefer-named-capture-group.js
eslint/lib/rules/quote-props.js
eslint/lib/rules/template-tag-spacing.js
eslint/lib/rules/utils/ast-utils.js
eslint/package.json
eslint/tests/_utils/in-memory-fs.js
eslint/tests/fixtures/code-path-analysis/logical--do-while-qq-1.js [new file with mode: 0644]
eslint/tests/fixtures/code-path-analysis/logical--do-while-qq-2.js [new file with mode: 0644]
eslint/tests/fixtures/code-path-analysis/logical--if-mix-and-qq-1.js [new file with mode: 0644]
eslint/tests/fixtures/code-path-analysis/logical--if-mix-and-qq-2.js [new file with mode: 0644]
eslint/tests/fixtures/code-path-analysis/logical--if-mix-or-qq-1.js [new file with mode: 0644]
eslint/tests/fixtures/code-path-analysis/logical--if-mix-or-qq-2.js [new file with mode: 0644]
eslint/tests/fixtures/code-path-analysis/logical--if-qq-1.js [new file with mode: 0644]
eslint/tests/fixtures/code-path-analysis/logical--if-qq-2.js [new file with mode: 0644]
eslint/tests/fixtures/code-path-analysis/logical--if-qq-3.js [new file with mode: 0644]
eslint/tests/fixtures/code-path-analysis/logical--if-qq-4.js [new file with mode: 0644]
eslint/tests/fixtures/code-path-analysis/logical--if-qq-5.js [new file with mode: 0644]
eslint/tests/fixtures/code-path-analysis/logical--simple-3.js [new file with mode: 0644]
eslint/tests/fixtures/code-path-analysis/logical--while-qq-1.js [new file with mode: 0644]
eslint/tests/fixtures/code-path-analysis/logical--while-qq-2.js [new file with mode: 0644]
eslint/tests/lib/cli-engine/cli-engine.js
eslint/tests/lib/eslint/eslint.js
eslint/tests/lib/init/config-initializer.js
eslint/tests/lib/init/source-code-utils.js
eslint/tests/lib/linter/code-path-analysis/code-path-analyzer.js
eslint/tests/lib/linter/linter.js
eslint/tests/lib/rules/camelcase.js
eslint/tests/lib/rules/func-call-spacing.js
eslint/tests/lib/rules/id-blacklist.js
eslint/tests/lib/rules/id-match.js
eslint/tests/lib/rules/keyword-spacing.js
eslint/tests/lib/rules/multiline-ternary.js
eslint/tests/lib/rules/no-extra-boolean-cast.js
eslint/tests/lib/rules/no-extra-parens.js
eslint/tests/lib/rules/no-mixed-operators.js
eslint/tests/lib/rules/no-mixed-spaces-and-tabs.js
eslint/tests/lib/rules/no-restricted-exports.js
eslint/tests/lib/rules/no-restricted-imports.js
eslint/tests/lib/rules/no-undef.js
eslint/tests/lib/rules/no-unneeded-ternary.js
eslint/tests/lib/rules/no-unused-expressions.js
eslint/tests/lib/rules/no-unused-vars.js
eslint/tests/lib/rules/operator-linebreak.js
eslint/tests/lib/rules/template-tag-spacing.js
eslint/tools/code-sample-minimizer.js
src/eslint.js

index 2dc6bd25573c095bea657d9855a90031e8f5aeed..44a29a1479d83aa1679480095192e127c7503b2b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@ DSC=${PACKAGE}_${DEB_VERSION_UPSTREAM_REVISION}.dsc
 
 SRCDIR=src
 UPSTREAM=eslint
-UPSTREAMTAG=v7.1.0
+UPSTREAMTAG=v7.2.0
 BUILDSRC=${UPSTREAM}-${UPSTREAMTAG}
 
 all: ${DEB}
diff --git a/eslint/.github/FUNDING.yml b/eslint/.github/FUNDING.yml
deleted file mode 100644 (file)
index fec5535..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-github: eslint
-open_collective: eslint
diff --git a/eslint/.github/ISSUE_TEMPLATE/config.yml b/eslint/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644 (file)
index 0000000..822fe54
--- /dev/null
@@ -0,0 +1,5 @@
+blank_issues_enabled: false
+contact_links:
+  - name: Breaking/Core change
+    url: https://github.com/eslint/rfcs#how-to-submit-an-rfc
+    about: Please submit an RFC here.
index 3321fe6db254c7548d39f2d6642050293acfc2d1..52ff78da098417b696ebba9ef3d571e5fb0320e2 100644 (file)
@@ -1,3 +1,22 @@
+v7.2.0 - June 5, 2020
+
+* [`b735a48`](https://github.com/eslint/eslint/commit/b735a485e77bcc791e4c4c6b8716801d94e98b2c) Update: add enforceForFunctionPrototypeMethods option to no-extra-parens (#12895) (Milos Djermanovic)
+* [`27ef73f`](https://github.com/eslint/eslint/commit/27ef73ffb7428d5eff792d443186a2313e417bda) Update: reporter locr of func-call-spacing (refs #12334) (#13311) (Anix)
+* [`353bfe9`](https://github.com/eslint/eslint/commit/353bfe9760ec640f470859855d4018df084a4e88) Update: handle parentheses in multiline-ternary (fixes #13195) (#13367) (Milos Djermanovic)
+* [`a7fd343`](https://github.com/eslint/eslint/commit/a7fd343991cde99d8a219e3b25616db5792fe9a9) Update: keyword-spacing unexpected space loc improve (refs #12334) (#13377) (Anix)
+* [`e49732e`](https://github.com/eslint/eslint/commit/e49732eb41bff6347ca7718c3c5ca1d13f1cd2d3) Fix: Ignore import expressions in no-unused-expressions rule (#13387) (Veniamin Krol)
+* [`220349f`](https://github.com/eslint/eslint/commit/220349f5404060effe02fb5ec176a92e1383c3b5) Chore: Remove duplicate health files (#13380) (Nicholas C. Zakas)
+* [`dd949ae`](https://github.com/eslint/eslint/commit/dd949aedb81fa772e10568920156daf075d25ea2) Update: support `??` operator, import.meta, and `export * as ns` (#13196) (Toru Nagashima)
+* [`d5fce9f`](https://github.com/eslint/eslint/commit/d5fce9fa07e37ce61010a1fbb65964f1f7aefd82) Update: enable es2020 environment in --init (#13357) (Milos Djermanovic)
+* [`21b1583`](https://github.com/eslint/eslint/commit/21b15832e326f96d349c063cd7e85e72c3abb670) Docs: fixed broken hash link for working-with-rules.md (#13386) (Yosuke Ota)
+* [`b76aef7`](https://github.com/eslint/eslint/commit/b76aef778befb32afe7ad249934b132dc49713d2) Update: Improve report location for template-tag-spacing (refs #12334) (#13203) (Milos Djermanovic)
+* [`578efad`](https://github.com/eslint/eslint/commit/578efad331b797e28c0f5f1547ce4769d2ea23ee) Chore: update no-unused-vars caughtErrors in eslint-config-eslint (#13351) (Milos Djermanovic)
+* [`426088c`](https://github.com/eslint/eslint/commit/426088c966dc79dc338b33100f3adf827b147d69) Fix: no-unused-vars updated location to last reference (fixes #13181) (#13354) (Anix)
+* [`cb50b69`](https://github.com/eslint/eslint/commit/cb50b69c08d4393e32d5c42c537d769c51dd34d8) Update: Improve location for no-mixed-spaces-and-tabs (refs #12334) (#13365) (Milos Djermanovic)
+* [`f858f2a`](https://github.com/eslint/eslint/commit/f858f2a8f83232484491bd90b0bc5001b5056ad0) Chore: Add Tidelift to funding.yml (#13371) (Nicholas C. Zakas)
+* [`ee30e5d`](https://github.com/eslint/eslint/commit/ee30e5d8bb1a4c82a2a3fbe1b9ee9f979b55c5c4) Sponsors: Sync README with website (ESLint Jenkins)
+* [`c29bd9f`](https://github.com/eslint/eslint/commit/c29bd9f75582e5b1a403a8ffd0aafd1ffc8c58e1) Chore: Add breaking/core change link to issue templates (#13344) (Kai Cataldo)
+* [`d55490f`](https://github.com/eslint/eslint/commit/d55490fa73ff69416de375e4c1cd67b6edba531c) Sponsors: Sync README with website (ESLint Jenkins)
 v7.1.0 - May 22, 2020
 
 * [`a93083a`](https://github.com/eslint/eslint/commit/a93083af89c6f9714dcdd4a7f27c8655a0b0dba6) Fix: astUtils.getNextLocation returns invalid location after CRLF (#13275) (Milos Djermanovic)
diff --git a/eslint/CODE_OF_CONDUCT.md b/eslint/CODE_OF_CONDUCT.md
deleted file mode 100644 (file)
index 2fc80dd..0000000
+++ /dev/null
@@ -1 +0,0 @@
-This project adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
index d0db77ccfe633c44a734f0b769cc3b36745b748a..9260dfefa5e0c11451ae5a22d422c065405b84c2 100644 (file)
@@ -4,7 +4,7 @@ Please be sure to read the contribution guidelines before making or requesting a
 
 ## Code of Conduct
 
-This project adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct). We kindly request that you read over our code of conduct before contributing.
+This project adheres to the [Open JS Foundation Code of Conduct](https://eslint.org/conduct). We kindly request that you read over our code of conduct before contributing.
 
 ## Filing Issues
 
index 1838496e238d0f27ac5a530cc59189e4dcc877a3..0cb3963b2c0b22b9349613d79fc26f91847ed445 100644 (file)
@@ -250,8 +250,8 @@ The following companies, organizations, and individuals support ESLint's ongoing
 <!--sponsorsstart-->
 <h3>Gold Sponsors</h3>
 <p><a href="https://www.shopify.com"><img src="https://images.opencollective.com/shopify/e780cd4/logo.png" alt="Shopify" 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></p><h3>Silver Sponsors</h3>
-<p><a href="https://www.ampproject.org/"><img src="https://images.opencollective.com/amp/c8a3b25/logo.png" alt="AMP Project" height="64"></a></p><h3>Bronze Sponsors</h3>
-<p><a href="https://bruce.agency"><img src="https://images.opencollective.com/brucemade/0c70c59/logo.png" alt="Bruce" height="32"></a> <a href="https://edubirdie.com/"><img src="https://images.opencollective.com/edubirdie2/b1d51ab/logo.png" alt="EduBirdie" height="32"></a> <a href="https://www.casinotop.com/"><img src="https://images.opencollective.com/casinotop-com/10fd95b/logo.png" alt="CasinoTop.com" height="32"></a> <a href="https://www.casinotopp.net/"><img src="https://images.opencollective.com/casino-topp/1dd399a/logo.png" alt="Casino Topp" height="32"></a> <a href="https://writersperhour.com/urgent-essay-writing-service"><img src="https://images.opencollective.com/writersperhour/5787d4b/logo.png" alt="Writers Per Hour" 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://cooltechzone.com/netflix-vpn"><img src="https://images.opencollective.com/vpn-netflix/4850160/logo.png" alt="vpn netflix" height="32"></a> <a href="https://www.kasinot.fi"><img src="https://images.opencollective.com/kasinot-fi/e09aa2e/logo.png" alt="Kasinot.fi" height="32"></a> <a href="https://www.pelisivut.com"><img src="https://images.opencollective.com/pelisivut/04f08f2/logo.png" alt="Pelisivut" height="32"></a> <a href="https://www.nettikasinot.org"><img src="https://images.opencollective.com/nettikasinot-org/bbd887f/logo.png" alt="Nettikasinot.org" height="32"></a> <a href="https://www.bonus.com.de/freispiele"><img src="https://images.opencollective.com/bonusfinder-deutschland/646169e/logo.png" alt="BonusFinder Deutschland" height="32"></a> <a href="https://www.bugsnag.com/platforms?utm_source=Open Collective&utm_medium=Website&utm_content=open-source&utm_campaign=2019-community&utm_term="><img src="https://images.opencollective.com/bugsnag-stability-monitoring/c2cef36/logo.png" alt="Bugsnag Stability Monitoring" height="32"></a> <a href="https://mixpanel.com"><img src="https://images.opencollective.com/mixpanel/cd682f7/logo.png" alt="Mixpanel" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/0b37d14/logo.png" alt="Free Icons by Icons8" height="32"></a> <a href="https://discordapp.com"><img src="https://images.opencollective.com/discordapp/7e3d9a9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://tekhattan.com"><img src="https://images.opencollective.com/tekhattan/bc73c28/logo.png" alt="TekHattan" height="32"></a> <a href="https://www.marfeel.com/"><img src="https://images.opencollective.com/marfeel/4b88e30/logo.png" alt="Marfeel" height="32"></a> <a href="http://www.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a></p>
+<p><a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a> <a href="https://www.ampproject.org/"><img src="https://images.opencollective.com/amp/c8a3b25/logo.png" alt="AMP Project" height="64"></a></p><h3>Bronze Sponsors</h3>
+<p><a href="https://bruce.agency"><img src="https://images.opencollective.com/brucemade/0c70c59/logo.png" alt="Bruce" height="32"></a> <a href="https://edubirdie.com/"><img src="https://images.opencollective.com/edubirdie2/b1d51ab/logo.png" alt="EduBirdie" height="32"></a> <a href="https://www.casinotop.com/"><img src="https://images.opencollective.com/casinotop-com/10fd95b/logo.png" alt="CasinoTop.com" height="32"></a> <a href="https://www.casinotopp.net/"><img src="https://images.opencollective.com/casino-topp/1dd399a/logo.png" alt="Casino Topp" height="32"></a> <a href="https://writersperhour.com/write-my-essay"><img src="https://images.opencollective.com/writersperhour/5787d4b/logo.png" alt="Writers Per Hour" 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://cooltechzone.com/netflix-vpn"><img src="https://images.opencollective.com/vpn-netflix/4850160/logo.png" alt="vpn netflix" height="32"></a> <a href="https://www.kasinot.fi"><img src="https://images.opencollective.com/kasinot-fi/e09aa2e/logo.png" alt="Kasinot.fi" height="32"></a> <a href="https://www.pelisivut.com"><img src="https://images.opencollective.com/pelisivut/04f08f2/logo.png" alt="Pelisivut" height="32"></a> <a href="https://www.nettikasinot.org"><img src="https://images.opencollective.com/nettikasinot-org/bbd887f/logo.png" alt="Nettikasinot.org" height="32"></a> <a href="https://www.bonus.com.de/freispiele"><img src="https://images.opencollective.com/bonusfinder-deutschland/646169e/logo.png" alt="BonusFinder Deutschland" height="32"></a> <a href="https://www.bugsnag.com/platforms?utm_source=Open Collective&utm_medium=Website&utm_content=open-source&utm_campaign=2019-community&utm_term="><img src="https://images.opencollective.com/bugsnag-stability-monitoring/c2cef36/logo.png" alt="Bugsnag Stability Monitoring" height="32"></a> <a href="https://mixpanel.com"><img src="https://images.opencollective.com/mixpanel/cd682f7/logo.png" alt="Mixpanel" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/0b37d14/logo.png" alt="Free Icons by Icons8" height="32"></a> <a href="https://discordapp.com"><img src="https://images.opencollective.com/discordapp/7e3d9a9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://tekhattan.com"><img src="https://images.opencollective.com/tekhattan/bc73c28/logo.png" alt="TekHattan" height="32"></a> <a href="https://www.marfeel.com/"><img src="https://images.opencollective.com/marfeel/4b88e30/logo.png" alt="Marfeel" height="32"></a> <a href="http://www.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a></p>
 <!--sponsorsend-->
 
 ## <a name="technology-sponsors"></a>Technology Sponsors
index 608a38be7bc89fff8b3ed6eb21f40ebf37f31687..17058b4058af92d6c96f489ed4799b4c2d85358f 100644 (file)
@@ -140,7 +140,7 @@ Additionally, the `context` object has the following methods:
     * Otherwise, if the node does not declare any variables, an empty array is returned.
 * `getFilename()` - returns the filename associated with the source.
 * `getScope()` - returns the [scope](./scope-manager-interface.md#scope-interface) of the currently-traversed node. This information can be used to track references to variables.
-* `getSourceCode()` - returns a [`SourceCode`](#contextgetsourcecode) object that you can use to work with the source that was passed to ESLint.
+* `getSourceCode()` - returns a [`SourceCode`](#context-getsourcecode) object that you can use to work with the source that was passed to ESLint.
 * `markVariableAsUsed(name)` - marks a variable with the given name in the current scope as used. This affects the [no-unused-vars](../rules/no-unused-vars.md) rule. Returns `true` if a variable with the given name was found and marked as used, otherwise `false`.
 * `report(descriptor)` - reports a problem in the code (see the [dedicated section](#context-report)).
 
index 4cadaa757e487bc8ee02611c221ede59f66f3bc3..68b986eff6c64f8b50cb26ae6e22ef885b0c8a69 100644 (file)
@@ -7,7 +7,7 @@ This rule restricts the use of parentheses to only where they are necessary.
 This rule always ignores extra parentheses around the following:
 
 * RegExp literals such as `(/abc/).test(var)` to avoid conflicts with the [wrap-regex](wrap-regex.md) rule
-* immediately-invoked function expressions (also known as IIFEs) such as `var x = (function () {})();` and `((function foo() {return 1;})())` to avoid conflicts with the [wrap-iife](wrap-iife.md) rule
+* immediately-invoked function expressions (also known as IIFEs) such as `var x = (function () {})();` and `var x = (function () {}());` to avoid conflicts with the [wrap-iife](wrap-iife.md) rule
 * arrow function arguments to avoid conflicts with the [arrow-parens](arrow-parens.md) rule
 
 ## Options
@@ -26,6 +26,7 @@ This rule has an object option for exceptions to the `"all"` option:
 * `"enforceForArrowConditionals": false` allows extra parentheses around ternary expressions which are the body of an arrow function
 * `"enforceForSequenceExpressions": false` allows extra parentheses around sequence expressions
 * `"enforceForNewInMemberExpressions": false` allows extra parentheses around `new` expressions in member expressions
+* `"enforceForFunctionPrototypeMethods": false` allows extra parentheses around immediate `.call` and `.apply` method calls on function expressions and around function expressions in the same context.
 
 ### all
 
@@ -222,6 +223,22 @@ const quux = (new Bar())[baz];
 (new Bar()).doSomething();
 ```
 
+### enforceForFunctionPrototypeMethods
+
+Examples of **correct** code for this rule with the `"all"` and `{ "enforceForFunctionPrototypeMethods": false }` options:
+
+```js
+/* eslint no-extra-parens: ["error", "all", { "enforceForFunctionPrototypeMethods": false }] */
+
+const foo = (function () {}).call();
+
+const bar = (function () {}).apply();
+
+const baz = (function () {}.call());
+
+const quux = (function () {}.apply());
+```
+
 ### functions
 
 Examples of **incorrect** code for this rule with the `"functions"` option:
index 3206d18fb7d50e861204359368670a31b27d635c..674a847f7fb11a06416377ddf5f86fef4f55ec85 100644 (file)
@@ -100,6 +100,7 @@ The following operators can be used in `groups` option:
 * Bitwise Operators: `"&"`, `"|"`, `"^"`, `"~"`, `"<<"`, `">>"`, `">>>"`
 * Comparison Operators: `"=="`, `"!="`, `"==="`, `"!=="`, `">"`, `">="`, `"<"`, `"<="`
 * Logical Operators: `"&&"`, `"||"`
+* Coalesce Operator: `"??"`
 * Relational Operators: `"in"`, `"instanceof"`
 * Ternary Operator: `?:`
 
index b6aa995beef933b3917f43dea51aae39f24703f9..802a405c04ac7222498916030379b27ec52dc022 100644 (file)
@@ -403,7 +403,7 @@ function getCacheFile(cacheFile, cwd) {
 
     try {
         fileStats = fs.lstatSync(resolvedCacheFile);
-    } catch (ex) {
+    } catch {
         fileStats = null;
     }
 
@@ -991,7 +991,7 @@ class CLIEngine {
                     const npmFormat = naming.normalizePackageName(normalizedFormatName, "eslint-formatter");
 
                     formatterPath = ModuleResolver.resolve(npmFormat, path.join(cwd, "__placeholder__.js"));
-                } catch (e) {
+                } catch {
                     formatterPath = path.resolve(__dirname, "formatters", normalizedFormatName);
                 }
             }
index fa3fdb3bedd89b861a696068aaadcf59b15995bf..7c0fba65c67d0a3ebfe04b3ddbabd00edfc02893 100644 (file)
@@ -517,7 +517,7 @@ class ConfigArrayFactory {
                     try {
                         loadPackageJSONConfigFile(filePath);
                         return filePath;
-                    } catch (error) { /* ignore */ }
+                    } catch { /* ignore */ }
                 } else {
                     return filePath;
                 }
index 00f17678fc66c0e3bdd1c2dabc6711c30be153bc..dce39946e6b876d648f5dc8df3e6d15d151aea33 100644 (file)
@@ -265,11 +265,7 @@ function processAnswers(answers) {
     };
 
     config.parserOptions.ecmaVersion = espree.latestEcmaVersion;
-    config.env.es6 = true;
-    config.globals = {
-        Atomics: "readonly",
-        SharedArrayBuffer: "readonly"
-    };
+    config.env.es2020 = true;
 
     // set the module type
     if (answers.moduleType === "esm") {
@@ -350,7 +346,7 @@ function getLocalESLintVersion() {
         const eslint = require(eslintPath);
 
         return eslint.linter.version || null;
-    } catch (_err) {
+    } catch {
         return null;
     }
 }
index 8a623e33ea0681e7167f3e1fc61dde3e433f1d1c..b612cf43566b0ce0618720a64aa1cbeec2b5ebed 100644 (file)
@@ -33,10 +33,10 @@ function isCaseNode(node) {
  * Checks whether the given logical operator is taken into account for the code
  * path analysis.
  * @param {string} operator The operator found in the LogicalExpression node
- * @returns {boolean} `true` if the operator is "&&" or "||"
+ * @returns {boolean} `true` if the operator is "&&" or "||" or "??"
  */
 function isHandledLogicalOperator(operator) {
-    return operator === "&&" || operator === "||";
+    return operator === "&&" || operator === "||" || operator === "??";
 }
 
 /**
index 75de1bc6ce4c4a4a98903e77f979d236e299aca6..9e760601a0f744202ee19c4ff2d3b3f4094a7555 100644 (file)
@@ -201,6 +201,7 @@ function finalizeTestSegmentsOfFor(context, choiceContext, head) {
     if (!choiceContext.processed) {
         choiceContext.trueForkContext.add(head);
         choiceContext.falseForkContext.add(head);
+        choiceContext.qqForkContext.add(head);
     }
 
     if (context.test !== true) {
@@ -351,6 +352,7 @@ class CodePathState {
             isForkingAsResult,
             trueForkContext: ForkContext.newEmpty(this.forkContext),
             falseForkContext: ForkContext.newEmpty(this.forkContext),
+            qqForkContext: ForkContext.newEmpty(this.forkContext),
             processed: false
         };
     }
@@ -370,6 +372,7 @@ class CodePathState {
         switch (context.kind) {
             case "&&":
             case "||":
+            case "??":
 
                 /*
                  * If any result were not transferred from child contexts,
@@ -379,6 +382,7 @@ class CodePathState {
                 if (!context.processed) {
                     context.trueForkContext.add(headSegments);
                     context.falseForkContext.add(headSegments);
+                    context.qqForkContext.add(headSegments);
                 }
 
                 /*
@@ -390,6 +394,7 @@ class CodePathState {
 
                     parentContext.trueForkContext.addAll(context.trueForkContext);
                     parentContext.falseForkContext.addAll(context.falseForkContext);
+                    parentContext.qqForkContext.addAll(context.qqForkContext);
                     parentContext.processed = true;
 
                     return context;
@@ -456,13 +461,24 @@ class CodePathState {
              * This got segments already from the child choice context.
              * Creates the next path from own true/false fork context.
              */
-            const prevForkContext =
-                context.kind === "&&" ? context.trueForkContext
-                /* kind === "||" */ : context.falseForkContext;
+            let prevForkContext;
+
+            switch (context.kind) {
+                case "&&": // if true then go to the right-hand side.
+                    prevForkContext = context.trueForkContext;
+                    break;
+                case "||": // if false then go to the right-hand side.
+                    prevForkContext = context.falseForkContext;
+                    break;
+                case "??": // Both true/false can short-circuit, so needs the third path to go to the right-hand side. That's qqForkContext.
+                    prevForkContext = context.qqForkContext;
+                    break;
+                default:
+                    throw new Error("unreachable");
+            }
 
             forkContext.replaceHead(prevForkContext.makeNext(0, -1));
             prevForkContext.clear();
-
             context.processed = false;
         } else {
 
@@ -471,14 +487,19 @@ class CodePathState {
              * So addresses the head segments.
              * The head segments are the path of the left-hand operand.
              */
-            if (context.kind === "&&") {
-
-                // The path does short-circuit if false.
-                context.falseForkContext.add(forkContext.head);
-            } else {
-
-                // The path does short-circuit if true.
-                context.trueForkContext.add(forkContext.head);
+            switch (context.kind) {
+                case "&&": // the false path can short-circuit.
+                    context.falseForkContext.add(forkContext.head);
+                    break;
+                case "||": // the true path can short-circuit.
+                    context.trueForkContext.add(forkContext.head);
+                    break;
+                case "??": // both can short-circuit.
+                    context.trueForkContext.add(forkContext.head);
+                    context.falseForkContext.add(forkContext.head);
+                    break;
+                default:
+                    throw new Error("unreachable");
             }
 
             forkContext.replaceHead(forkContext.makeNext(-1, -1));
@@ -501,6 +522,7 @@ class CodePathState {
         if (!context.processed) {
             context.trueForkContext.add(forkContext.head);
             context.falseForkContext.add(forkContext.head);
+            context.qqForkContext.add(forkContext.head);
         }
 
         context.processed = false;
index 35862315d515f8a64345301f009a8ba85f4186fe..067d02480302cb62c114f77804529fadd9974e09 100644 (file)
@@ -78,7 +78,7 @@ module.exports = class ConfigCommentParser {
                     config: items
                 };
             }
-        } catch (ex) {
+        } catch {
 
             debug("Levn parsing failed; falling back to manual parsing.");
 
index dccdd0a40c6d7624773d48ac0261ac6e1ba71a17..5ecb63ecfa7b6053380769acae80c55708331257 100644 (file)
@@ -116,7 +116,13 @@ module.exports = {
             if (never && hasWhitespace) {
                 context.report({
                     node,
-                    loc: leftToken.loc.start,
+                    loc: {
+                        start: leftToken.loc.end,
+                        end: {
+                            line: rightToken.loc.start.line,
+                            column: rightToken.loc.start.column - 1
+                        }
+                    },
                     messageId: "unexpectedWhitespace",
                     fix(fixer) {
 
@@ -134,7 +140,13 @@ module.exports = {
             } else if (!never && !hasWhitespace) {
                 context.report({
                     node,
-                    loc: leftToken.loc.start,
+                    loc: {
+                        start: {
+                            line: leftToken.loc.end.line,
+                            column: leftToken.loc.end.column - 1
+                        },
+                        end: rightToken.loc.start
+                    },
                     messageId: "missing",
                     fix(fixer) {
                         return fixer.insertTextBefore(rightToken, " ");
@@ -143,7 +155,10 @@ module.exports = {
             } else if (!never && !allowNewlines && hasNewline) {
                 context.report({
                     node,
-                    loc: leftToken.loc.start,
+                    loc: {
+                        start: leftToken.loc.end,
+                        end: rightToken.loc.start
+                    },
                     messageId: "unexpectedNewline",
                     fix(fixer) {
                         return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], " ");
index 2b3fef33bd7ac4107bf7304e069114640cd52d4c..99979a32a5bbf7a3354f883494ad7bffd780a627 100644 (file)
@@ -152,7 +152,7 @@ module.exports = {
                 sourceCode.isSpaceBetweenTokens(prevToken, token)
             ) {
                 context.report({
-                    loc: token.loc.start,
+                    loc: { start: prevToken.loc.end, end: token.loc.start },
                     messageId: "unexpectedBefore",
                     data: token,
                     fix(fixer) {
@@ -203,8 +203,9 @@ module.exports = {
                 astUtils.isTokenOnSameLine(token, nextToken) &&
                 sourceCode.isSpaceBetweenTokens(token, nextToken)
             ) {
+
                 context.report({
-                    loc: token.loc.start,
+                    loc: { start: token.loc.end, end: nextToken.loc.start },
                     messageId: "unexpectedAfter",
                     data: token,
                     fix(fixer) {
@@ -442,6 +443,12 @@ module.exports = {
                 checkSpacingAround(sourceCode.getTokenAfter(firstToken));
             }
 
+            if (node.type === "ExportAllDeclaration" && node.exported) {
+                const asToken = sourceCode.getTokenBefore(node.exported);
+
+                checkSpacingBefore(asToken, PREV_TOKEN_M);
+            }
+
             if (node.source) {
                 const fromToken = sourceCode.getTokenBefore(node.source);
 
index 1df90b6feb8321f71877bce4ab783d931f6fae58..6668bff4824842071fbc9a3b2e90efb20a34f25f 100644 (file)
@@ -39,25 +39,7 @@ module.exports = {
         const option = context.options[0];
         const multiline = option !== "never";
         const allowSingleLine = option === "always-multiline";
-
-        //--------------------------------------------------------------------------
-        // Helpers
-        //--------------------------------------------------------------------------
-
-        /**
-         * Tests whether node is preceded by supplied tokens
-         * @param {ASTNode} node node to check
-         * @param {ASTNode} parentNode parent of node to report
-         * @param {boolean} expected whether newline was expected or not
-         * @returns {void}
-         * @private
-         */
-        function reportError(node, parentNode, expected) {
-            context.report({
-                node,
-                messageId: `${expected ? "expected" : "unexpected"}${node === parentNode.test ? "TestCons" : "ConsAlt"}`
-            });
-        }
+        const sourceCode = context.getSourceCode();
 
         //--------------------------------------------------------------------------
         // Public
@@ -65,16 +47,39 @@ module.exports = {
 
         return {
             ConditionalExpression(node) {
-                const areTestAndConsequentOnSameLine = astUtils.isTokenOnSameLine(node.test, node.consequent);
-                const areConsequentAndAlternateOnSameLine = astUtils.isTokenOnSameLine(node.consequent, node.alternate);
+                const questionToken = sourceCode.getTokenAfter(node.test, astUtils.isNotClosingParenToken);
+                const colonToken = sourceCode.getTokenAfter(node.consequent, astUtils.isNotClosingParenToken);
+
+                const firstTokenOfTest = sourceCode.getFirstToken(node);
+                const lastTokenOfTest = sourceCode.getTokenBefore(questionToken);
+                const firstTokenOfConsequent = sourceCode.getTokenAfter(questionToken);
+                const lastTokenOfConsequent = sourceCode.getTokenBefore(colonToken);
+                const firstTokenOfAlternate = sourceCode.getTokenAfter(colonToken);
+
+                const areTestAndConsequentOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfTest, firstTokenOfConsequent);
+                const areConsequentAndAlternateOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfConsequent, firstTokenOfAlternate);
 
                 if (!multiline) {
                     if (!areTestAndConsequentOnSameLine) {
-                        reportError(node.test, node, false);
+                        context.report({
+                            node: node.test,
+                            loc: {
+                                start: firstTokenOfTest.loc.start,
+                                end: lastTokenOfTest.loc.end
+                            },
+                            messageId: "unexpectedTestCons"
+                        });
                     }
 
                     if (!areConsequentAndAlternateOnSameLine) {
-                        reportError(node.consequent, node, false);
+                        context.report({
+                            node: node.consequent,
+                            loc: {
+                                start: firstTokenOfConsequent.loc.start,
+                                end: lastTokenOfConsequent.loc.end
+                            },
+                            messageId: "unexpectedConsAlt"
+                        });
                     }
                 } else {
                     if (allowSingleLine && node.loc.start.line === node.loc.end.line) {
@@ -82,11 +87,25 @@ module.exports = {
                     }
 
                     if (areTestAndConsequentOnSameLine) {
-                        reportError(node.test, node, true);
+                        context.report({
+                            node: node.test,
+                            loc: {
+                                start: firstTokenOfTest.loc.start,
+                                end: lastTokenOfTest.loc.end
+                            },
+                            messageId: "expectedTestCons"
+                        });
                     }
 
                     if (areConsequentAndAlternateOnSameLine) {
-                        reportError(node.consequent, node, true);
+                        context.report({
+                            node: node.consequent,
+                            loc: {
+                                start: firstTokenOfConsequent.loc.start,
+                                end: lastTokenOfConsequent.loc.end
+                            },
+                            messageId: "expectedConsAlt"
+                        });
                     }
                 }
             }
index b39f731c3cdf29e8a72457e19baec71955e8a1d3..146c4f22d01257a2df5d9e1bce6f8872443c0e04 100644 (file)
@@ -35,7 +35,7 @@ const collector = new (class {
         try {
             this._source = regexpStr;
             this._validator.validatePattern(regexpStr); // Call onCharacter hook
-        } catch (err) {
+        } catch {
 
             // Ignore syntax errors in RegExp.
         }
index aba8e63e086a4110f1dd7fefde3d2d1c930860c7..b90757b112658c8bcd8ad869230574ae58bf12f5 100644 (file)
@@ -172,6 +172,9 @@ module.exports = {
                 case "UnaryExpression":
                     return precedence(node) < precedence(parent);
                 case "LogicalExpression":
+                    if (astUtils.isMixedLogicalAndCoalesceExpressions(node, parent)) {
+                        return true;
+                    }
                     if (previousNode === parent.left) {
                         return precedence(node) < precedence(parent);
                     }
index 7cbb7522ebedfad469f428f74e9892d528c7f933..bae1a498cf0cf131d35276d9c3f61d284922a63e 100644 (file)
@@ -51,7 +51,8 @@ module.exports = {
                                 ignoreJSX: { enum: ["none", "all", "single-line", "multi-line"] },
                                 enforceForArrowConditionals: { type: "boolean" },
                                 enforceForSequenceExpressions: { type: "boolean" },
-                                enforceForNewInMemberExpressions: { type: "boolean" }
+                                enforceForNewInMemberExpressions: { type: "boolean" },
+                                enforceForFunctionPrototypeMethods: { type: "boolean" }
                             },
                             additionalProperties: false
                         }
@@ -83,12 +84,28 @@ module.exports = {
             context.options[1].enforceForSequenceExpressions === false;
         const IGNORE_NEW_IN_MEMBER_EXPR = ALL_NODES && context.options[1] &&
             context.options[1].enforceForNewInMemberExpressions === false;
+        const IGNORE_FUNCTION_PROTOTYPE_METHODS = ALL_NODES && context.options[1] &&
+            context.options[1].enforceForFunctionPrototypeMethods === false;
 
         const PRECEDENCE_OF_ASSIGNMENT_EXPR = precedence({ type: "AssignmentExpression" });
         const PRECEDENCE_OF_UPDATE_EXPR = precedence({ type: "UpdateExpression" });
 
         let reportsBuffer;
 
+        /**
+         * Determines whether the given node is a `call` or `apply` method call, invoked directly on a `FunctionExpression` node.
+         * Example: function(){}.call()
+         * @param {ASTNode} node The node to be checked.
+         * @returns {boolean} True if the node is an immediate `call` or `apply` method call.
+         * @private
+         */
+        function isImmediateFunctionPrototypeMethodCall(node) {
+            return node.type === "CallExpression" &&
+                node.callee.type === "MemberExpression" &&
+                node.callee.object.type === "FunctionExpression" &&
+                ["call", "apply"].includes(astUtils.getStaticPropertyName(node.callee));
+        }
+
         /**
          * Determines if this rule should be enforced for a node given the current configuration.
          * @param {ASTNode} node The node to be checked.
@@ -125,6 +142,10 @@ module.exports = {
                 return false;
             }
 
+            if (isImmediateFunctionPrototypeMethodCall(node) && IGNORE_FUNCTION_PROTOTYPE_METHODS) {
+                return false;
+            }
+
             return ALL_NODES || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
         }
 
@@ -478,6 +499,7 @@ module.exports = {
             if (!shouldSkipLeft && hasExcessParens(node.left)) {
                 if (
                     !(node.left.type === "UnaryExpression" && isExponentiation) &&
+                    !astUtils.isMixedLogicalAndCoalesceExpressions(node.left, node) &&
                     (leftPrecedence > prec || (leftPrecedence === prec && !isExponentiation)) ||
                     isParenthesisedTwice(node.left)
                 ) {
@@ -487,6 +509,7 @@ module.exports = {
 
             if (!shouldSkipRight && hasExcessParens(node.right)) {
                 if (
+                    !astUtils.isMixedLogicalAndCoalesceExpressions(node.right, node) &&
                     (rightPrecedence > prec || (rightPrecedence === prec && isExponentiation)) ||
                     isParenthesisedTwice(node.right)
                 ) {
@@ -927,7 +950,12 @@ module.exports = {
             LogicalExpression: checkBinaryLogical,
 
             MemberExpression(node) {
-                const nodeObjHasExcessParens = hasExcessParens(node.object);
+                const nodeObjHasExcessParens = hasExcessParens(node.object) &&
+                    !(
+                        isImmediateFunctionPrototypeMethodCall(node.parent) &&
+                        node.parent.callee === node &&
+                        IGNORE_FUNCTION_PROTOTYPE_METHODS
+                    );
 
                 if (
                     nodeObjHasExcessParens &&
index c09e36fd017697d71903d81e8eb167ab109a2b73..48b7188d49f9c5ec7f00846701e5eede631d1a1a 100644 (file)
@@ -93,7 +93,7 @@ module.exports = {
             try {
                 validator.validateFlags(flags);
                 return null;
-            } catch (err) {
+            } catch {
                 return `Invalid flags supplied to RegExp constructor '${flags}'`;
             }
         }
index 9315ba64972f79d36dd5357d25ab051ef7e9282a..3d004615c3f0707b28935d89d00b40e2ee9f0b81 100644 (file)
@@ -147,7 +147,7 @@ module.exports = {
                     pattern.length,
                     flags.includes("u")
                 );
-            } catch (e) {
+            } catch {
 
                 // Ignore regular expressions with syntax errors
                 return;
index 37e8906e827a4c155f6d9d5be9f45b35a8bc2121..f0290e93ece8db84babb31cbed8ccfa1e99eb755 100644 (file)
@@ -21,13 +21,15 @@ const COMPARISON_OPERATORS = ["==", "!=", "===", "!==", ">", ">=", "<", "<="];
 const LOGICAL_OPERATORS = ["&&", "||"];
 const RELATIONAL_OPERATORS = ["in", "instanceof"];
 const TERNARY_OPERATOR = ["?:"];
+const COALESCE_OPERATOR = ["??"];
 const ALL_OPERATORS = [].concat(
     ARITHMETIC_OPERATORS,
     BITWISE_OPERATORS,
     COMPARISON_OPERATORS,
     LOGICAL_OPERATORS,
     RELATIONAL_OPERATORS,
-    TERNARY_OPERATOR
+    TERNARY_OPERATOR,
+    COALESCE_OPERATOR
 );
 const DEFAULT_GROUPS = [
     ARITHMETIC_OPERATORS,
@@ -236,7 +238,6 @@ module.exports = {
         return {
             BinaryExpression: check,
             LogicalExpression: check
-
         };
     }
 };
index 16c2bd4122e8511bdde6e499af2b1688113eab61..287cbda03daf5a6795aedc74c74e883512765ce8 100644 (file)
@@ -67,7 +67,7 @@ module.exports = {
                  * or the reverse before non-tab/-space
                  * characters begin.
                  */
-                let regex = /^(?=[\t ]*(\t | \t))/u;
+                let regex = /^(?=( +|\t+))\1(?:\t| )/u;
 
                 if (smartTabs) {
 
@@ -75,19 +75,27 @@ module.exports = {
                      * At least one space followed by a tab
                      * before non-tab/-space characters begin.
                      */
-                    regex = /^(?=[\t ]* \t)/u;
+                    regex = /^(?=(\t*))\1(?=( +))\2\t/u;
                 }
 
                 lines.forEach((line, i) => {
                     const match = regex.exec(line);
 
                     if (match) {
-                        const lineNumber = i + 1,
-                            column = match.index + 1,
-                            loc = { line: lineNumber, column };
+                        const lineNumber = i + 1;
+                        const loc = {
+                            start: {
+                                line: lineNumber,
+                                column: match[0].length - 2
+                            },
+                            end: {
+                                line: lineNumber,
+                                column: match[0].length
+                            }
+                        };
 
                         if (!ignoredCommentLines.has(lineNumber)) {
-                            const containingNode = sourceCode.getNodeByRangeIndex(sourceCode.getIndexFromLoc(loc));
+                            const containingNode = sourceCode.getNodeByRangeIndex(sourceCode.getIndexFromLoc(loc.start));
 
                             if (!(containingNode && ["Literal", "TemplateElement"].includes(containingNode.type))) {
                                 context.report({
index afb26d70259f1b4966ab13d63393e09331eac346..e6d4c9efba75febf354d4e4dc498f5418b5bf76e 100644 (file)
@@ -76,7 +76,7 @@ module.exports = {
 
             try {
                 regExpAST = regExpParser.parsePattern(pattern, 0, pattern.length, flags.includes("u"));
-            } catch (e) {
+            } catch {
 
                 // Ignore regular expressions with syntax errors
                 return;
index 5b5c7d9bffb99c2d8cb1e242f9c22d69d17d8294..6031e26de2c7e873c1f0c14dd109d6351dc04e3b 100644 (file)
@@ -61,6 +61,12 @@ module.exports = {
         }
 
         return {
+            ExportAllDeclaration(node) {
+                if (node.exported) {
+                    checkExportedName(node.exported);
+                }
+            },
+
             ExportNamedDeclaration(node) {
                 const declaration = node.declaration;
 
index d4438e2fe08fbeaa9d10fa81ad407ec3ed39b357..0fefc42b909820ff1feeee2fe9e95a573591c99f 100644 (file)
@@ -147,10 +147,12 @@ module.exports = {
                         loc: node.consequent.loc.start,
                         messageId: "unnecessaryConditionalAssignment",
                         fix: fixer => {
-                            const shouldParenthesizeAlternate = (
-                                astUtils.getPrecedence(node.alternate) < OR_PRECEDENCE &&
-                                !astUtils.isParenthesised(sourceCode, node.alternate)
-                            );
+                            const shouldParenthesizeAlternate =
+                                (
+                                    astUtils.getPrecedence(node.alternate) < OR_PRECEDENCE ||
+                                    astUtils.isCoalesceExpression(node.alternate)
+                                ) &&
+                                !astUtils.isParenthesised(sourceCode, node.alternate);
                             const alternateText = shouldParenthesizeAlternate
                                 ? `(${sourceCode.getText(node.alternate)})`
                                 : astUtils.getParenthesisedText(sourceCode, node.alternate);
index 26a25b7584bc80405ec8ddb782c4acb58a81a97b..8c049f556ff2d923607472b2a04c825ee3877151 100644 (file)
@@ -124,7 +124,7 @@ module.exports = {
                 return true;
             }
 
-            return /^(?:Assignment|Call|New|Update|Yield|Await)Expression$/u.test(node.type) ||
+            return /^(?:Assignment|Call|New|Update|Yield|Await|Import)Expression$/u.test(node.type) ||
                 (node.type === "UnaryExpression" && ["delete", "void"].indexOf(node.operator) >= 0);
         }
 
index 18c48bf0d7810c507d4ee18f1839c2407c2c097e..50dcab45fe2bb65e5afece01fcf763df7d3e03c3 100644 (file)
@@ -619,7 +619,9 @@ module.exports = {
                     // Report the first declaration.
                     if (unusedVar.defs.length > 0) {
                         context.report({
-                            node: unusedVar.identifiers[0],
+                            node: unusedVar.references.length ? unusedVar.references[
+                                unusedVar.references.length - 1
+                            ].identifier : unusedVar.identifiers[0],
                             messageId: "unusedVar",
                             data: unusedVar.references.some(ref => ref.isWrite())
                                 ? getAssignedMessageData(unusedVar)
index 8a6fbe14daafe621c581eacfdc750925bb54ad4c..958e3d5dd4e4d5eafc8c1af7039d7fa784b95118 100644 (file)
@@ -95,7 +95,7 @@ module.exports = {
 
             try {
                 regExpAST = parser.parsePattern(pattern, 0, pattern.length, flags.includes("u"));
-            } catch (e) {
+            } catch {
 
                 // Ignore regular expressions with syntax errors
                 return;
index c8af043c1b52689eead8bd1caee3fd9c1904eb67..7d0aa3f9dc094d6ad02a39def39f34305cbce404 100644 (file)
@@ -59,7 +59,7 @@ module.exports = {
 
             try {
                 ast = parser.parsePattern(pattern, 0, pattern.length, uFlag);
-            } catch (_) {
+            } catch {
 
                 // ignore regex syntax errors
                 return;
index a2a4e1d47923ffc46de4eec8c03e4259771ec85a..fab7bdc9c1555b38ca454f67fbcab0ed86985da6 100644 (file)
@@ -154,7 +154,7 @@ module.exports = {
 
                 try {
                     tokens = espree.tokenize(key.value);
-                } catch (e) {
+                } catch {
                     return;
                 }
 
@@ -239,7 +239,7 @@ module.exports = {
 
                         try {
                             tokens = espree.tokenize(key.value);
-                        } catch (e) {
+                        } catch {
                             necessaryQuotes = true;
                             return;
                         }
index 9eb6d86077da36baa6bea5ac8369901021cda8b6..16f586255af567b0bab8cc0dedd7a46207108cf4 100644 (file)
@@ -49,7 +49,10 @@ module.exports = {
             if (never && hasWhitespace) {
                 context.report({
                     node,
-                    loc: tagToken.loc.start,
+                    loc: {
+                        start: tagToken.loc.end,
+                        end: literalToken.loc.start
+                    },
                     messageId: "unexpected",
                     fix(fixer) {
                         const comments = sourceCode.getCommentsBefore(node.quasi);
@@ -68,7 +71,10 @@ module.exports = {
             } else if (!never && !hasWhitespace) {
                 context.report({
                     node,
-                    loc: tagToken.loc.start,
+                    loc: {
+                        start: node.loc.start,
+                        end: literalToken.loc.start
+                    },
                     messageId: "missing",
                     fix(fixer) {
                         return fixer.insertTextAfter(tagToken, " ");
index 83ecf69434dafbd4e1a988457366c2217179972a..ecea6948da236040a023745bd16eee77f9153f76 100644 (file)
@@ -416,6 +416,53 @@ function equalTokens(left, right, sourceCode) {
     return true;
 }
 
+/**
+ * Check if the given node is a true logical expression or not.
+ *
+ * The three binary expressions logical-or (`||`), logical-and (`&&`), and
+ * coalesce (`??`) are known as `ShortCircuitExpression`.
+ * But ESTree represents those by `LogicalExpression` node.
+ *
+ * This function rejects coalesce expressions of `LogicalExpression` node.
+ * @param {ASTNode} node The node to check.
+ * @returns {boolean} `true` if the node is `&&` or `||`.
+ * @see https://tc39.es/ecma262/#prod-ShortCircuitExpression
+ */
+function isLogicalExpression(node) {
+    return (
+        node.type === "LogicalExpression" &&
+            (node.operator === "&&" || node.operator === "||")
+    );
+}
+
+/**
+ * Check if the given node is a nullish coalescing expression or not.
+ *
+ * The three binary expressions logical-or (`||`), logical-and (`&&`), and
+ * coalesce (`??`) are known as `ShortCircuitExpression`.
+ * But ESTree represents those by `LogicalExpression` node.
+ *
+ * This function finds only coalesce expressions of `LogicalExpression` node.
+ * @param {ASTNode} node The node to check.
+ * @returns {boolean} `true` if the node is `??`.
+ */
+function isCoalesceExpression(node) {
+    return node.type === "LogicalExpression" && node.operator === "??";
+}
+
+/**
+ * Check if given two nodes are the pair of a logical expression and a coalesce expression.
+ * @param {ASTNode} left A node to check.
+ * @param {ASTNode} right Another node to check.
+ * @returns {boolean} `true` if the two nodes are the pair of a logical expression and a coalesce expression.
+ */
+function isMixedLogicalAndCoalesceExpressions(left, right) {
+    return (
+        (isLogicalExpression(left) && isCoalesceExpression(right)) ||
+            (isCoalesceExpression(left) && isLogicalExpression(right))
+    );
+}
+
 //------------------------------------------------------------------------------
 // Public Interface
 //------------------------------------------------------------------------------
@@ -779,6 +826,7 @@ module.exports = {
             case "LogicalExpression":
                 switch (node.operator) {
                     case "||":
+                    case "??":
                         return 4;
                     case "&&":
                         return 5;
@@ -1415,7 +1463,7 @@ module.exports = {
 
             try {
                 tokens = espree.tokenize(leftValue, espreeOptions);
-            } catch (e) {
+            } catch {
                 return false;
             }
 
@@ -1444,7 +1492,7 @@ module.exports = {
 
             try {
                 tokens = espree.tokenize(rightValue, espreeOptions);
-            } catch (e) {
+            } catch {
                 return false;
             }
 
@@ -1538,5 +1586,9 @@ module.exports = {
      */
     hasOctalEscapeSequence(rawString) {
         return OCTAL_ESCAPE_PATTERN.test(rawString);
-    }
+    },
+
+    isLogicalExpression,
+    isCoalesceExpression,
+    isMixedLogicalAndCoalesceExpressions
 };
index dddf620c0dd30c8c2f175bb8a406efa815d6a557..f9e204ce2a24f85115b7ae37eef52489e0b2d8ef 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "eslint",
-  "version": "7.1.0",
+  "version": "7.2.0",
   "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
   "description": "An AST-based pattern checker for JavaScript.",
   "bin": {
     "cross-spawn": "^7.0.2",
     "debug": "^4.0.1",
     "doctrine": "^3.0.0",
-    "eslint-scope": "^5.0.0",
+    "eslint-scope": "^5.1.0",
     "eslint-utils": "^2.0.0",
-    "eslint-visitor-keys": "^1.1.0",
-    "espree": "^7.0.0",
+    "eslint-visitor-keys": "^1.2.0",
+    "espree": "^7.1.0",
     "esquery": "^1.2.0",
     "esutils": "^2.0.2",
     "file-entry-cache": "^5.0.1",
@@ -86,7 +86,7 @@
   "devDependencies": {
     "@babel/core": "^7.4.3",
     "@babel/preset-env": "^7.4.3",
-    "acorn": "^7.1.1",
+    "acorn": "^7.2.0",
     "babel-loader": "^8.0.5",
     "chai": "^4.0.1",
     "cheerio": "^0.22.0",
index 5ef4f0453f3390bbe10ca2fa64ab42b5b4a4d50c..a45820917f280d77366bc897650062be955beee5 100644 (file)
@@ -111,7 +111,7 @@ const context = vm.createContext();
 function isExistingFile(fs, filePath) {
     try {
         return fs.statSync(filePath).isFile();
-    } catch (error) {
+    } catch {
         return false;
     }
 }
diff --git a/eslint/tests/fixtures/code-path-analysis/logical--do-while-qq-1.js b/eslint/tests/fixtures/code-path-analysis/logical--do-while-qq-1.js
new file mode 100644 (file)
index 0000000..4b68567
--- /dev/null
@@ -0,0 +1,23 @@
+/*expected
+initial->s1_1->s1_2->s1_3->s1_2->s1_2;
+s1_3->s1_4;
+s1_2->s1_4->final;
+*/
+do {
+    foo();
+} while (a ?? b);
+
+/*DOT
+digraph {
+    node[shape=box,style="rounded,filled",fillcolor=white];
+    initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    s1_1[label="Program\nDoWhileStatement"];
+    s1_2[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (foo)\nLogicalExpression\nIdentifier (a)\nIdentifier:exit (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit\nIdentifier:exit (a)"];
+    s1_3[label="Identifier (b)\nIdentifier:exit (b)\nLogicalExpression:exit"];
+    s1_4[label="DoWhileStatement:exit\nProgram:exit"];
+    initial->s1_1->s1_2->s1_3->s1_2->s1_2;
+    s1_3->s1_4;
+    s1_2->s1_4->final;
+}
+*/
diff --git a/eslint/tests/fixtures/code-path-analysis/logical--do-while-qq-2.js b/eslint/tests/fixtures/code-path-analysis/logical--do-while-qq-2.js
new file mode 100644 (file)
index 0000000..c033142
--- /dev/null
@@ -0,0 +1,33 @@
+/*expected
+initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_2->s1_2;
+s1_3->s1_2;
+s1_4->s1_2;
+s1_5->s1_6;
+s1_2->s1_6;
+s1_3->s1_6;
+s1_4->s1_6->final;
+*/
+do {
+    foo();
+} while (a ?? b ?? c ?? d);
+
+/*DOT
+digraph {
+    node[shape=box,style="rounded,filled",fillcolor=white];
+    initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    s1_1[label="Program\nDoWhileStatement"];
+    s1_2[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (foo)\nLogicalExpression\nLogicalExpression\nLogicalExpression\nIdentifier (a)\nIdentifier:exit (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit\nIdentifier:exit (a)"];
+    s1_3[label="Identifier (b)\nIdentifier:exit (b)\nLogicalExpression:exit"];
+    s1_4[label="Identifier (c)\nIdentifier:exit (c)\nLogicalExpression:exit"];
+    s1_5[label="Identifier (d)\nIdentifier:exit (d)\nLogicalExpression:exit"];
+    s1_6[label="DoWhileStatement:exit\nProgram:exit"];
+    initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_2->s1_2;
+    s1_3->s1_2;
+    s1_4->s1_2;
+    s1_5->s1_6;
+    s1_2->s1_6;
+    s1_3->s1_6;
+    s1_4->s1_6->final;
+}
+*/
diff --git a/eslint/tests/fixtures/code-path-analysis/logical--if-mix-and-qq-1.js b/eslint/tests/fixtures/code-path-analysis/logical--if-mix-and-qq-1.js
new file mode 100644 (file)
index 0000000..4863ac8
--- /dev/null
@@ -0,0 +1,33 @@
+/*expected
+initial->s1_1->s1_2->s1_3->s1_4->s1_6;
+s1_1->s1_5->s1_6;
+s1_2->s1_4;
+s1_3->s1_5;
+s1_2->s1_5;
+s1_6->final;
+*/
+if ((a && b) ?? c) {
+    foo();
+} else {
+    bar();
+}
+
+/*DOT
+digraph {
+    node[shape=box,style="rounded,filled",fillcolor=white];
+    initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    s1_1[label="Program\nIfStatement\nLogicalExpression\nLogicalExpression\nIdentifier (a)\nIdentifier:exit (a)"];
+    s1_2[label="Identifier (b)\nIdentifier:exit (b)\nLogicalExpression:exit"];
+    s1_3[label="Identifier (c)\nIdentifier:exit (c)\nLogicalExpression:exit"];
+    s1_4[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (foo)\nIdentifier:exit (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    s1_6[label="IfStatement:exit\nProgram:exit"];
+    s1_5[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (bar)\nIdentifier:exit (bar)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    initial->s1_1->s1_2->s1_3->s1_4->s1_6;
+    s1_1->s1_5->s1_6;
+    s1_2->s1_4;
+    s1_3->s1_5;
+    s1_2->s1_5;
+    s1_6->final;
+}
+*/
diff --git a/eslint/tests/fixtures/code-path-analysis/logical--if-mix-and-qq-2.js b/eslint/tests/fixtures/code-path-analysis/logical--if-mix-and-qq-2.js
new file mode 100644 (file)
index 0000000..0dd1f2a
--- /dev/null
@@ -0,0 +1,33 @@
+/*expected
+initial->s1_1->s1_2->s1_3->s1_4->s1_6;
+s1_1->s1_5->s1_6;
+s1_2->s1_4;
+s1_3->s1_5;
+s1_2->s1_5;
+s1_6->final;
+*/
+if (a && (b ?? c)) {
+    foo();
+} else {
+    bar();
+}
+
+/*DOT
+digraph {
+    node[shape=box,style="rounded,filled",fillcolor=white];
+    initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    s1_1[label="Program\nIfStatement\nLogicalExpression\nIdentifier (a)\nIdentifier:exit (a)"];
+    s1_2[label="LogicalExpression\nIdentifier (b)\nIdentifier:exit (b)"];
+    s1_3[label="Identifier (c)\nIdentifier:exit (c)\nLogicalExpression:exit\nLogicalExpression:exit"];
+    s1_4[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (foo)\nIdentifier:exit (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    s1_6[label="IfStatement:exit\nProgram:exit"];
+    s1_5[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (bar)\nIdentifier:exit (bar)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    initial->s1_1->s1_2->s1_3->s1_4->s1_6;
+    s1_1->s1_5->s1_6;
+    s1_2->s1_4;
+    s1_3->s1_5;
+    s1_2->s1_5;
+    s1_6->final;
+} 
+*/
diff --git a/eslint/tests/fixtures/code-path-analysis/logical--if-mix-or-qq-1.js b/eslint/tests/fixtures/code-path-analysis/logical--if-mix-or-qq-1.js
new file mode 100644 (file)
index 0000000..e598999
--- /dev/null
@@ -0,0 +1,33 @@
+/*expected
+initial->s1_1->s1_2->s1_3->s1_4->s1_6;
+s1_1->s1_4;
+s1_2->s1_4;
+s1_3->s1_5->s1_6;
+s1_2->s1_5;
+s1_6->final;
+*/
+if ((a || b) ?? c) {
+    foo();
+} else {
+    bar();
+}
+
+/*DOT
+digraph {
+    node[shape=box,style="rounded,filled",fillcolor=white];
+    initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    s1_1[label="Program\nIfStatement\nLogicalExpression\nLogicalExpression\nIdentifier (a)\nIdentifier:exit (a)"];
+    s1_2[label="Identifier (b)\nIdentifier:exit (b)\nLogicalExpression:exit"];
+    s1_3[label="Identifier (c)\nIdentifier:exit (c)\nLogicalExpression:exit"];
+    s1_4[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (foo)\nIdentifier:exit (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    s1_6[label="IfStatement:exit\nProgram:exit"];
+    s1_5[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (bar)\nIdentifier:exit (bar)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    initial->s1_1->s1_2->s1_3->s1_4->s1_6;
+    s1_1->s1_4;
+    s1_2->s1_4;
+    s1_3->s1_5->s1_6;
+    s1_2->s1_5;
+    s1_6->final;
+}
+*/
diff --git a/eslint/tests/fixtures/code-path-analysis/logical--if-mix-or-qq-2.js b/eslint/tests/fixtures/code-path-analysis/logical--if-mix-or-qq-2.js
new file mode 100644 (file)
index 0000000..f98962d
--- /dev/null
@@ -0,0 +1,33 @@
+/*expected
+initial->s1_1->s1_2->s1_3->s1_4->s1_6;
+s1_1->s1_4;
+s1_2->s1_4;
+s1_3->s1_5->s1_6;
+s1_2->s1_5;
+s1_6->final;
+*/
+if (a || (b ?? c)) {
+    foo();
+} else {
+    bar();
+}
+
+/*DOT
+digraph {
+    node[shape=box,style="rounded,filled",fillcolor=white];
+    initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    s1_1[label="Program\nIfStatement\nLogicalExpression\nLogicalExpression\nIdentifier (a)\nIdentifier:exit (a)"];
+    s1_2[label="Identifier (b)\nIdentifier:exit (b)\nLogicalExpression:exit"];
+    s1_3[label="Identifier (c)\nIdentifier:exit (c)\nLogicalExpression:exit"];
+    s1_4[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (foo)\nIdentifier:exit (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    s1_6[label="IfStatement:exit\nProgram:exit"];
+    s1_5[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (bar)\nIdentifier:exit (bar)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    initial->s1_1->s1_2->s1_3->s1_4->s1_6;
+    s1_1->s1_4;
+    s1_2->s1_4;
+    s1_3->s1_5->s1_6;
+    s1_2->s1_5;
+    s1_6->final;
+}
+*/
diff --git a/eslint/tests/fixtures/code-path-analysis/logical--if-qq-1.js b/eslint/tests/fixtures/code-path-analysis/logical--if-qq-1.js
new file mode 100644 (file)
index 0000000..80a7728
--- /dev/null
@@ -0,0 +1,25 @@
+/*expected
+initial->s1_1->s1_2->s1_3->s1_4;
+s1_1->s1_3;
+s1_2->s1_4;
+s1_1->s1_4->final;
+*/
+if (a ?? b) {
+    foo();
+}
+
+/*DOT
+digraph {
+    node[shape=box,style="rounded,filled",fillcolor=white];
+    initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    s1_1[label="Program\nIfStatement\nLogicalExpression\nIdentifier (a)\nIdentifier:exit (a)"];
+    s1_2[label="Identifier (b)\nIdentifier:exit (b)\nLogicalExpression:exit"];
+    s1_3[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (foo)\nIdentifier:exit (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    s1_4[label="IfStatement:exit\nProgram:exit"];
+    initial->s1_1->s1_2->s1_3->s1_4;
+    s1_1->s1_3;
+    s1_2->s1_4;
+    s1_1->s1_4->final;
+}
+*/
diff --git a/eslint/tests/fixtures/code-path-analysis/logical--if-qq-2.js b/eslint/tests/fixtures/code-path-analysis/logical--if-qq-2.js
new file mode 100644 (file)
index 0000000..e9604bf
--- /dev/null
@@ -0,0 +1,30 @@
+/*expected
+initial->s1_1->s1_2->s1_3->s1_5;
+s1_1->s1_3;
+s1_2->s1_4->s1_5;
+s1_1->s1_4;
+s1_5->final;
+*/
+if (a ?? b) {
+    foo();
+} else {
+    bar();
+}
+
+/*DOT
+digraph {
+    node[shape=box,style="rounded,filled",fillcolor=white];
+    initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    s1_1[label="Program\nIfStatement\nLogicalExpression\nIdentifier (a)\nIdentifier:exit (a)"];
+    s1_2[label="Identifier (b)\nIdentifier:exit (b)\nLogicalExpression:exit"];
+    s1_3[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (foo)\nIdentifier:exit (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    s1_5[label="IfStatement:exit\nProgram:exit"];
+    s1_4[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (bar)\nIdentifier:exit (bar)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    initial->s1_1->s1_2->s1_3->s1_5;
+    s1_1->s1_3;
+    s1_2->s1_4->s1_5;
+    s1_1->s1_4;
+    s1_5->final;
+}
+*/
diff --git a/eslint/tests/fixtures/code-path-analysis/logical--if-qq-3.js b/eslint/tests/fixtures/code-path-analysis/logical--if-qq-3.js
new file mode 100644 (file)
index 0000000..3586ce3
--- /dev/null
@@ -0,0 +1,40 @@
+/*expected
+initial->s1_1->s1_2->s1_3->s1_9;
+s1_1->s1_3;
+s1_2->s1_4->s1_5->s1_6->s1_8->s1_9;
+s1_1->s1_4->s1_6;
+s1_5->s1_7->s1_8;
+s1_4->s1_7;
+s1_9->final;
+*/
+if (a ?? b) {
+    foo();
+} else if (c ?? d) {
+    bar();
+} else {
+    qiz();
+}
+
+/*DOT
+digraph {
+    node[shape=box,style="rounded,filled",fillcolor=white];
+    initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    s1_1[label="Program\nIfStatement\nLogicalExpression\nIdentifier (a)\nIdentifier:exit (a)"];
+    s1_2[label="Identifier (b)\nIdentifier:exit (b)\nLogicalExpression:exit"];
+    s1_3[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (foo)\nIdentifier:exit (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    s1_9[label="IfStatement:exit\nProgram:exit"];
+    s1_4[label="IfStatement\nLogicalExpression\nIdentifier (c)\nIdentifier:exit (c)"];
+    s1_5[label="Identifier (d)\nIdentifier:exit (d)\nLogicalExpression:exit"];
+    s1_6[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (bar)\nIdentifier:exit (bar)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    s1_8[label="IfStatement:exit"];
+    s1_7[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (qiz)\nIdentifier:exit (qiz)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    initial->s1_1->s1_2->s1_3->s1_9;
+    s1_1->s1_3;
+    s1_2->s1_4->s1_5->s1_6->s1_8->s1_9;
+    s1_1->s1_4->s1_6;
+    s1_5->s1_7->s1_8;
+    s1_4->s1_7;
+    s1_9->final;
+}
+*/
diff --git a/eslint/tests/fixtures/code-path-analysis/logical--if-qq-4.js b/eslint/tests/fixtures/code-path-analysis/logical--if-qq-4.js
new file mode 100644 (file)
index 0000000..ba81360
--- /dev/null
@@ -0,0 +1,40 @@
+/*expected
+initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_7;
+s1_1->s1_5;
+s1_2->s1_5;
+s1_3->s1_5;
+s1_4->s1_6->s1_7;
+s1_1->s1_6;
+s1_2->s1_6;
+s1_3->s1_6;
+s1_7->final;
+*/
+if (a ?? b ?? c ?? d) {
+    foo();
+} else {
+    bar();
+}
+
+/*DOT
+digraph {
+    node[shape=box,style="rounded,filled",fillcolor=white];
+    initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    s1_1[label="Program\nIfStatement\nLogicalExpression\nLogicalExpression\nLogicalExpression\nIdentifier (a)\nIdentifier:exit (a)"];
+    s1_2[label="Identifier (b)\nIdentifier:exit (b)\nLogicalExpression:exit"];
+    s1_3[label="Identifier (c)\nIdentifier:exit (c)\nLogicalExpression:exit"];
+    s1_4[label="Identifier (d)\nIdentifier:exit (d)\nLogicalExpression:exit"];
+    s1_5[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (foo)\nIdentifier:exit (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    s1_7[label="IfStatement:exit\nProgram:exit"];
+    s1_6[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (bar)\nIdentifier:exit (bar)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_7;
+    s1_1->s1_5;
+    s1_2->s1_5;
+    s1_3->s1_5;
+    s1_4->s1_6->s1_7;
+    s1_1->s1_6;
+    s1_2->s1_6;
+    s1_3->s1_6;
+    s1_7->final;
+}
+*/
diff --git a/eslint/tests/fixtures/code-path-analysis/logical--if-qq-5.js b/eslint/tests/fixtures/code-path-analysis/logical--if-qq-5.js
new file mode 100644 (file)
index 0000000..ba2d222
--- /dev/null
@@ -0,0 +1,44 @@
+/*expected
+initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_7->s1_9;
+s1_1->s1_3;
+s1_2->s1_8->s1_9;
+s1_3->s1_5;
+s1_4->s1_6->s1_7;
+s1_1->s1_8;
+s1_3->s1_6;
+s1_9->final;
+*/
+if (a ?? b) {
+    if (c ?? d) {
+        foo();
+    } else {
+        bar();
+    }
+} else {
+    qiz();
+}
+
+/*DOT
+digraph {
+    node[shape=box,style="rounded,filled",fillcolor=white];
+    initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    s1_1[label="Program\nIfStatement\nLogicalExpression\nIdentifier (a)\nIdentifier:exit (a)"];
+    s1_2[label="Identifier (b)\nIdentifier:exit (b)\nLogicalExpression:exit"];
+    s1_3[label="BlockStatement\nIfStatement\nLogicalExpression\nIdentifier (c)\nIdentifier:exit (c)"];
+    s1_4[label="Identifier (d)\nIdentifier:exit (d)\nLogicalExpression:exit"];
+    s1_5[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (foo)\nIdentifier:exit (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    s1_7[label="IfStatement:exit\nBlockStatement:exit"];
+    s1_9[label="IfStatement:exit\nProgram:exit"];
+    s1_8[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (qiz)\nIdentifier:exit (qiz)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    s1_6[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (bar)\nIdentifier:exit (bar)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_7->s1_9;
+    s1_1->s1_3;
+    s1_2->s1_8->s1_9;
+    s1_3->s1_5;
+    s1_4->s1_6->s1_7;
+    s1_1->s1_8;
+    s1_3->s1_6;
+    s1_9->final;
+}
+*/
diff --git a/eslint/tests/fixtures/code-path-analysis/logical--simple-3.js b/eslint/tests/fixtures/code-path-analysis/logical--simple-3.js
new file mode 100644 (file)
index 0000000..0ae12a3
--- /dev/null
@@ -0,0 +1,24 @@
+/*expected
+initial->s1_1->s1_2->s1_3->s1_4->s1_5;
+s1_1->s1_5;
+s1_2->s1_5;
+s1_3->s1_5->final;
+*/
+a ?? b ?? c ?? d;
+
+/*DOT
+digraph {
+    node[shape=box,style="rounded,filled",fillcolor=white];
+    initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    s1_1[label="Program\nExpressionStatement\nLogicalExpression\nLogicalExpression\nLogicalExpression\nIdentifier (a)"];
+    s1_2[label="Identifier (b)"];
+    s1_3[label="Identifier (c)"];
+    s1_4[label="Identifier (d)"];
+    s1_5[label="LogicalExpression:exit\nExpressionStatement:exit\nProgram:exit"];
+    initial->s1_1->s1_2->s1_3->s1_4->s1_5;
+    s1_1->s1_5;
+    s1_2->s1_5;
+    s1_3->s1_5->final;
+}
+*/
diff --git a/eslint/tests/fixtures/code-path-analysis/logical--while-qq-1.js b/eslint/tests/fixtures/code-path-analysis/logical--while-qq-1.js
new file mode 100644 (file)
index 0000000..de729d7
--- /dev/null
@@ -0,0 +1,24 @@
+/*expected
+initial->s1_1->s1_2->s1_3->s1_4->s1_2->s1_4;
+s1_3->s1_5;
+s1_2->s1_5->final;
+*/
+while (a ?? b) {
+    foo();
+}
+
+/*DOT
+digraph {
+    node[shape=box,style="rounded,filled",fillcolor=white];
+    initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    s1_1[label="Program\nWhileStatement"];
+    s1_2[label="LogicalExpression\nIdentifier (a)\nIdentifier:exit (a)"];
+    s1_3[label="Identifier (b)\nIdentifier:exit (b)\nLogicalExpression:exit"];
+    s1_4[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (foo)\nIdentifier:exit (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    s1_5[label="WhileStatement:exit\nProgram:exit"];
+    initial->s1_1->s1_2->s1_3->s1_4->s1_2->s1_4;
+    s1_3->s1_5;
+    s1_2->s1_5->final;
+}
+*/
diff --git a/eslint/tests/fixtures/code-path-analysis/logical--while-qq-2.js b/eslint/tests/fixtures/code-path-analysis/logical--while-qq-2.js
new file mode 100644 (file)
index 0000000..fac385d
--- /dev/null
@@ -0,0 +1,34 @@
+/*expected
+initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_6->s1_2->s1_6;
+s1_3->s1_6;
+s1_4->s1_6;
+s1_5->s1_7;
+s1_2->s1_7;
+s1_3->s1_7;
+s1_4->s1_7->final;
+*/
+while (a ?? b ?? c ?? d) {
+    foo();
+}
+
+/*DOT
+digraph {
+    node[shape=box,style="rounded,filled",fillcolor=white];
+    initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];
+    s1_1[label="Program\nWhileStatement"];
+    s1_2[label="LogicalExpression\nLogicalExpression\nLogicalExpression\nIdentifier (a)\nIdentifier:exit (a)"];
+    s1_3[label="Identifier (b)\nIdentifier:exit (b)\nLogicalExpression:exit"];
+    s1_4[label="Identifier (c)\nIdentifier:exit (c)\nLogicalExpression:exit"];
+    s1_5[label="Identifier (d)\nIdentifier:exit (d)\nLogicalExpression:exit"];
+    s1_6[label="BlockStatement\nExpressionStatement\nCallExpression\nIdentifier (foo)\nIdentifier:exit (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"];
+    s1_7[label="WhileStatement:exit\nProgram:exit"];
+    initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_6->s1_2->s1_6;
+    s1_3->s1_6;
+    s1_4->s1_6;
+    s1_5->s1_7;
+    s1_2->s1_7;
+    s1_3->s1_7;
+    s1_4->s1_7->final;
+}
+*/
index a8394b63634c681e33fa54513962bb25ea4cb7d9..fb3c365bbbf8e7cf3abfc88753b152985f2d9690 100644 (file)
@@ -58,7 +58,7 @@ describe("CLIEngine", () => {
 
         try {
             return fs.realpathSync(filepath);
-        } catch (e) {
+        } catch {
             return filepath;
         }
     }
@@ -2161,7 +2161,7 @@ describe("CLIEngine", () => {
             function doDelete(filePath) {
                 try {
                     fs.unlinkSync(filePath);
-                } catch (ex) {
+                } catch {
 
                     /*
                      * we don't care if the file didn't exist, since our
@@ -2197,7 +2197,7 @@ describe("CLIEngine", () => {
                 function deleteCacheDir() {
                     try {
                         fs.unlinkSync("./tmp/.cacheFileDir/.cache_hashOfCurrentWorkingDirectory");
-                    } catch (ex) {
+                    } catch {
 
                         /*
                          * we don't care if the file didn't exist, since our
index fc86a781d0d6b71b9e3d096e2901335786da18d4..6807a57aa8ad0de05c75da5d3fb3b14bd3b9b3d6 100644 (file)
@@ -55,7 +55,7 @@ describe("ESLint", () => {
 
         try {
             return fs.realpathSync(filepath);
-        } catch (e) {
+        } catch {
             return filepath;
         }
     }
@@ -2102,7 +2102,7 @@ describe("ESLint", () => {
             function doDelete(filePath) {
                 try {
                     fs.unlinkSync(filePath);
-                } catch (ex) {
+                } catch {
 
                     /*
                      * we don't care if the file didn't exist, since our
@@ -2138,7 +2138,7 @@ describe("ESLint", () => {
                 function deleteCacheDir() {
                     try {
                         fs.unlinkSync("./tmp/.cacheFileDir/.cache_hashOfCurrentWorkingDirectory");
-                    } catch (ex) {
+                    } catch {
 
                         /*
                          * we don't care if the file didn't exist, since our
index fe9120f7de108c0a0a121e697bbd085846e9b3bb..945e1854fba1b05de7ba29dbe874a9bae7835c83 100644 (file)
@@ -67,7 +67,7 @@ describe("configInitializer", () => {
 
         try {
             return fs.realpathSync(filepath);
-        } catch (e) {
+        } catch {
             return filepath;
         }
     }
@@ -136,9 +136,7 @@ describe("configInitializer", () => {
                 assert.deepStrictEqual(config.rules.quotes, ["error", "single"]);
                 assert.deepStrictEqual(config.rules["linebreak-style"], ["error", "unix"]);
                 assert.deepStrictEqual(config.rules.semi, ["error", "always"]);
-                assert.strictEqual(config.env.es6, true);
-                assert.strictEqual(config.globals.Atomics, "readonly");
-                assert.strictEqual(config.globals.SharedArrayBuffer, "readonly");
+                assert.strictEqual(config.env.es2020, true);
                 assert.strictEqual(config.parserOptions.ecmaVersion, espree.latestEcmaVersion);
                 assert.strictEqual(config.parserOptions.sourceType, "module");
                 assert.strictEqual(config.env.browser, true);
index 8c821de7832629ca2b0c9d9ee13394ad721ced9e..994d23d31688a8b8dc8e4d4515453b2e9a0c9f81 100644 (file)
@@ -41,7 +41,7 @@ describe("SourceCodeUtil", () => {
         try {
             filepath = fs.realpathSync(filepath);
             return filepath;
-        } catch (e) {
+        } catch {
             return filepath;
         }
     }
index 6460ba1b67682f12c08ff02a9795feb25b8dbfac..ec516c54a0259fd04aeb8d254096f87ca5da1083 100644 (file)
@@ -556,7 +556,10 @@ describe("CodePathAnalyzer", () => {
                         actual.push(debug.makeDotArrows(codePath));
                     }
                 }));
-                const messages = linter.verify(source, { rules: { test: 2 }, env: { es6: true } });
+                const messages = linter.verify(source, {
+                    parserOptions: { ecmaVersion: 2020 },
+                    rules: { test: 2 }
+                });
 
                 assert.strictEqual(messages.length, 0);
                 assert.strictEqual(actual.length, expected.length, "a count of code paths is wrong.");
index f2efc00c946bb644cb662dbabf64b42db9074e46..093ebcfaf70f4016d963fc44fcbf648cc04bfafb 100644 (file)
@@ -3918,9 +3918,9 @@ var a = "test2";
                     messages,
                     [{
                         column: 25,
-                        endLine: 3,
+                        endLine: 4,
                         endColumn: 28,
-                        line: 3,
+                        line: 4,
                         message: "'aaa' is assigned a value but never used.",
                         messageId: "unusedVar",
                         nodeType: "Identifier",
@@ -3966,9 +3966,9 @@ var a = "test2";
                     messages,
                     [{
                         column: 25,
-                        endLine: 2,
+                        endLine: 3,
                         endColumn: 28,
-                        line: 2,
+                        line: 3,
                         message: "'aaa' is assigned a value but never used.",
                         messageId: "unusedVar",
                         nodeType: "Identifier",
@@ -3989,9 +3989,9 @@ var a = "test2";
                     messages,
                     [{
                         column: 25,
-                        endLine: 2,
+                        endLine: 3,
                         endColumn: 28,
-                        line: 2,
+                        line: 3,
                         message: "'aaa' is assigned a value but never used.",
                         messageId: "unusedVar",
                         nodeType: "Identifier",
@@ -4014,9 +4014,9 @@ var a = "test2";
                     messages,
                     [{
                         column: 25,
-                        endLine: 3,
+                        endLine: 5,
                         endColumn: 28,
-                        line: 3,
+                        line: 5,
                         message: "'aaa' is assigned a value but never used.",
                         messageId: "unusedVar",
                         nodeType: "Identifier",
@@ -4039,9 +4039,9 @@ var a = "test2";
                     messages,
                     [{
                         column: 25,
-                        endLine: 3,
+                        endLine: 5,
                         endColumn: 28,
-                        line: 3,
+                        line: 5,
                         message: "'aaa' is assigned a value but never used.",
                         messageId: "unusedVar",
                         nodeType: "Identifier",
index 1e3eecc211094a7f46aade99690870b471b6bc63..7c7a4576c77d13bad4541744857ae6d51df7410e 100644 (file)
@@ -652,6 +652,17 @@ ruleTester.run("camelcase", rule, {
                 }
             ]
         },
+        {
+            code: "export * as snake_cased from 'mod'",
+            parserOptions: { ecmaVersion: 2020, sourceType: "module" },
+            errors: [
+                {
+                    messageId: "notCamelCase",
+                    data: { name: "snake_cased" },
+                    type: "Identifier"
+                }
+            ]
+        },
         {
             code: "function foo({ no_camelcased }) {};",
             parserOptions: { ecmaVersion: 6 },
index 0774ec4d0c89f260ba53cde39bad6b6afce0c6c2..f0199fd0a4e019a39a5319589f9fdfd63648c199 100644 (file)
@@ -236,12 +236,30 @@ ruleTester.run("func-call-spacing", rule, {
         {
             code: "f.b ();",
             output: "f.b();",
-            errors: [{ messageId: "unexpectedWhitespace", type: "CallExpression", column: 3 }]
+            errors: [
+                {
+                    messageId: "unexpectedWhitespace",
+                    type: "CallExpression",
+                    column: 4,
+                    line: 1,
+                    endColumn: 4,
+                    endLine: 1
+                }
+            ]
         },
         {
             code: "f.b().c ();",
             output: "f.b().c();",
-            errors: [{ messageId: "unexpectedWhitespace", type: "CallExpression", column: 7 }]
+            errors: [
+                {
+                    messageId: "unexpectedWhitespace",
+                    type: "CallExpression",
+                    column: 8,
+                    line: 1,
+                    endColumn: 8,
+                    endLine: 1
+                }
+            ]
         },
         {
             code: "f() ()",
@@ -335,16 +353,34 @@ ruleTester.run("func-call-spacing", rule, {
             errors: [{ messageId: "unexpectedWhitespace", type: "CallExpression" }]
         },
         {
-            code: "f.b ();",
+            code: "f.b  ();",
             output: "f.b();",
             options: ["never"],
-            errors: [{ messageId: "unexpectedWhitespace", type: "CallExpression", column: 3 }]
+            errors: [
+                {
+                    messageId: "unexpectedWhitespace",
+                    type: "CallExpression",
+                    column: 4,
+                    line: 1,
+                    endColumn: 5,
+                    endLine: 1
+                }
+            ]
         },
         {
             code: "f.b().c ();",
             output: "f.b().c();",
             options: ["never"],
-            errors: [{ messageId: "unexpectedWhitespace", type: "CallExpression", column: 7 }]
+            errors: [
+                {
+                    messageId: "unexpectedWhitespace",
+                    type: "CallExpression",
+                    column: 8,
+                    line: 1,
+                    endColumn: 8,
+                    endLine: 1
+                }
+            ]
         },
         {
             code: "f() ()",
@@ -407,7 +443,11 @@ ruleTester.run("func-call-spacing", rule, {
             errors: [
                 {
                     messageId: "unexpectedWhitespace",
-                    type: "CallExpression"
+                    type: "CallExpression",
+                    line: 1,
+                    column: 2,
+                    endLine: 2,
+                    endColumn: 0
                 }
             ]
         },
@@ -424,7 +464,9 @@ ruleTester.run("func-call-spacing", rule, {
                     messageId: "unexpectedWhitespace",
                     type: "CallExpression",
                     line: 2,
-                    column: 23
+                    column: 24,
+                    endLine: 3,
+                    endColumn: 0
                 }
             ]
         },
@@ -440,7 +482,9 @@ ruleTester.run("func-call-spacing", rule, {
                     messageId: "unexpectedWhitespace",
                     type: "CallExpression",
                     line: 1,
-                    column: 9
+                    column: 12,
+                    endLine: 2,
+                    endColumn: 0
                 }
             ]
         },
@@ -456,7 +500,9 @@ ruleTester.run("func-call-spacing", rule, {
                     messageId: "unexpectedWhitespace",
                     type: "CallExpression",
                     line: 1,
-                    column: 9
+                    column: 12,
+                    endColumn: 0,
+                    endLine: 2
                 }
             ]
         },
@@ -534,13 +580,31 @@ ruleTester.run("func-call-spacing", rule, {
             code: "f.b();",
             output: "f.b ();",
             options: ["always"],
-            errors: [{ messageId: "missing", type: "CallExpression", column: 3 }]
+            errors: [
+                {
+                    messageId: "missing",
+                    type: "CallExpression",
+                    column: 3,
+                    line: 1,
+                    endLine: 1,
+                    endColumn: 4
+                }
+            ]
         },
         {
             code: "f.b\n();",
             output: "f.b ();",
             options: ["always"],
-            errors: [{ messageId: "unexpectedNewline", type: "CallExpression", column: 3 }]
+            errors: [
+                {
+                    messageId: "unexpectedNewline",
+                    type: "CallExpression",
+                    column: 4,
+                    line: 1,
+                    endColumn: 1,
+                    endLine: 2
+                }
+            ]
         },
         {
             code: "f.b().c ();",
@@ -552,7 +616,16 @@ ruleTester.run("func-call-spacing", rule, {
             code: "f.b\n().c ();",
             output: "f.b ().c ();",
             options: ["always"],
-            errors: [{ messageId: "unexpectedNewline", type: "CallExpression", column: 3 }]
+            errors: [
+                {
+                    messageId: "unexpectedNewline",
+                    type: "CallExpression",
+                    column: 4,
+                    line: 1,
+                    endColumn: 1,
+                    endLine: 2
+                }
+            ]
         },
         {
             code: "f() ()",
@@ -664,7 +737,13 @@ ruleTester.run("func-call-spacing", rule, {
             code: "f.b();",
             output: "f.b ();",
             options: ["always", { allowNewlines: true }],
-            errors: [{ messageId: "missing", type: "CallExpression", column: 3 }]
+            errors: [
+                {
+                    messageId: "missing",
+                    type: "CallExpression",
+                    column: 3
+                }
+            ]
         },
         {
             code: "f.b().c ();",
@@ -716,6 +795,64 @@ ruleTester.run("func-call-spacing", rule, {
                 { messageId: "missing", type: "CallExpression" },
                 { messageId: "missing", type: "CallExpression" }
             ]
+        },
+        {
+            code: "f    ();",
+            output: "f();",
+            errors: [
+                {
+                    messageId: "unexpectedWhitespace",
+                    type: "CallExpression",
+                    line: 1,
+                    column: 2,
+                    endLine: 1,
+                    endColumn: 5
+                }
+            ]
+        },
+        {
+            code: "f\n ();",
+            output: null,
+            errors: [
+                {
+                    messageId: "unexpectedWhitespace",
+                    type: "CallExpression",
+                    line: 1,
+                    column: 2,
+                    endLine: 2,
+                    endColumn: 1
+                }
+            ]
+        },
+        {
+            code: "fn();",
+            output: "fn ();",
+            options: ["always"],
+            errors: [
+                {
+                    messageId: "missing",
+                    type: "CallExpression",
+                    line: 1,
+                    column: 2,
+                    endLine: 1,
+                    endColumn: 3
+                }
+            ]
+        },
+        {
+            code: "fnn\n (a, b);",
+            output: "fnn (a, b);",
+            options: ["always"],
+            errors: [
+                {
+                    messageId: "unexpectedNewline",
+                    type: "CallExpression",
+                    line: 1,
+                    column: 4,
+                    endLine: 2,
+                    endColumn: 2
+                }
+            ]
         }
     ]
 });
index a900924373f70a7ba8d29386de70a33c7332b261..6c3f729e17ab0883aa9818ccc842dc38c236cb9d 100644 (file)
@@ -251,6 +251,14 @@ ruleTester.run("id-blacklist", rule, {
                 error
             ]
         },
+        {
+            code: "export * as foo from 'mod'",
+            options: ["foo"],
+            parserOptions: { ecmaVersion: 2020, sourceType: "module" },
+            errors: [
+                error
+            ]
+        },
         {
             code: "import { foo } from 'mod'",
             options: ["foo"],
index 77aee1824860b5b46f970d4413426e01176316cf..f733dccbdff0d6ab06d3a374470a15269787ef5c 100644 (file)
@@ -401,6 +401,17 @@ ruleTester.run("id-match", rule, {
                 }
             ]
         },
+        {
+            code: "export * as no_camelcased from \"external-module\";",
+            options: ["^[^_]+$"],
+            parserOptions: { ecmaVersion: 2020, sourceType: "module" },
+            errors: [
+                {
+                    message: "Identifier 'no_camelcased' does not match the pattern '^[^_]+$'.",
+                    type: "Identifier"
+                }
+            ]
+        },
         {
             code: "import { no_camelcased } from \"external-module\";",
             options: ["^[^_]+$", {
index f7f5ccab2b7f13e7a23d1fb2f14a0726c09558f6..b67ee52384b893c0b56f343b512860eadfcd267d 100644 (file)
@@ -129,6 +129,10 @@ ruleTester.run("keyword-spacing", rule, {
         { code: "import*as a from\"foo\"", options: [NEITHER], parserOptions: { ecmaVersion: 6, sourceType: "module" } },
         { code: "import* as a from\"foo\"", options: [override("as", BOTH)], parserOptions: { ecmaVersion: 6, sourceType: "module" } },
         { code: "import *as a from \"foo\"", options: [override("as", NEITHER)], parserOptions: { ecmaVersion: 6, sourceType: "module" } },
+        { code: "export * as a from \"foo\"", parserOptions: { ecmaVersion: 2020, sourceType: "module" } },
+        { code: "export*as a from\"foo\"", options: [NEITHER], parserOptions: { ecmaVersion: 2020, sourceType: "module" } },
+        { code: "export* as a from\"foo\"", options: [override("as", BOTH)], parserOptions: { ecmaVersion: 2020, sourceType: "module" } },
+        { code: "export *as a from \"foo\"", options: [override("as", NEITHER)], parserOptions: { ecmaVersion: 2020, sourceType: "module" } },
 
         //----------------------------------------------------------------------
         // async
@@ -1369,6 +1373,35 @@ ruleTester.run("keyword-spacing", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: unexpectedBefore("as")
         },
+        {
+            code: "import* as a from\"foo\"",
+            output: "import*as a from\"foo\"",
+            options: [NEITHER],
+            parserOptions: { ecmaVersion: 6, sourceType: "module" },
+            errors: [{
+                messageId: "unexpectedBefore",
+                line: 1,
+                column: 8,
+                endLine: 1,
+                endColumn: 9
+            }
+            ]
+        },
+        {
+            code: "import *as a from\"foo\"",
+            output: "import*as a from\"foo\"",
+            options: [NEITHER],
+            parserOptions: { ecmaVersion: 6, sourceType: "module" },
+            errors: [
+                {
+                    messageId: "unexpectedAfter",
+                    line: 1,
+                    column: 7,
+                    endLine: 1,
+                    endColumn: 8
+                }
+            ]
+        },
         {
             code: "import*as a from\"foo\"",
             output: "import* as a from\"foo\"",
@@ -1383,6 +1416,33 @@ ruleTester.run("keyword-spacing", rule, {
             parserOptions: { ecmaVersion: 6, sourceType: "module" },
             errors: unexpectedBefore("as")
         },
+        {
+            code: "export *as a from \"foo\"",
+            output: "export * as a from \"foo\"",
+            parserOptions: { ecmaVersion: 2020, sourceType: "module" },
+            errors: expectedBefore("as")
+        },
+        {
+            code: "export* as a from\"foo\"",
+            output: "export*as a from\"foo\"",
+            options: [NEITHER],
+            parserOptions: { ecmaVersion: 2020, sourceType: "module" },
+            errors: unexpectedBefore("as")
+        },
+        {
+            code: "export*as a from\"foo\"",
+            output: "export* as a from\"foo\"",
+            options: [override("as", BOTH)],
+            parserOptions: { ecmaVersion: 2020, sourceType: "module" },
+            errors: expectedBefore("as")
+        },
+        {
+            code: "export * as a from \"foo\"",
+            output: "export *as a from \"foo\"",
+            options: [override("as", NEITHER)],
+            parserOptions: { ecmaVersion: 2020, sourceType: "module" },
+            errors: unexpectedBefore("as")
+        },
 
         //----------------------------------------------------------------------
         // async
@@ -3134,4 +3194,5 @@ ruleTester.run("keyword-spacing", rule, {
             errors: expectedAfter("async")
         }
     ]
+
 });
index a8d2ef6eaa6da25624cc0fca210065a6f0b4566c..ff0f9d1535d7fc7beca9a2984dabda1a632ff4c6 100644 (file)
@@ -32,6 +32,22 @@ ruleTester.run("multiline-ternary", rule, {
         { code: "a ?\nb :\nc", options: ["always"] },
         { code: "a\n? b\n? c\n: d\n: e", options: ["always"] },
         { code: "a\n? (b\n? c\n: d)\n: e", options: ["always"] },
+        { code: "(a\n ? b\n : c)", options: ["always"] },
+        { code: "(a)\n? b\n: c", options: ["always"] },
+        { code: "((a))\n? b\n: c", options: ["always"] },
+        { code: "(a)?\n b\n: c", options: ["always"] },
+        { code: "((a))?\n b\n: c", options: ["always"] },
+        { code: "a\n? (b)\n: c", options: ["always"] },
+        { code: "a\n? ((b))\n: c", options: ["always"] },
+        { code: "a ?\n (b)\n: c", options: ["always"] },
+        { code: "a ?\n ((b))\n: c", options: ["always"] },
+        { code: "a \n? b\n: (c)", options: ["always"] },
+        { code: "a \n? b\n: ((c))", options: ["always"] },
+        { code: "a \n? b:\n (c)", options: ["always"] },
+        { code: "a \n? b:\n ((c))", options: ["always"] },
+        { code: "(a) \n? (b)\n: (c)", options: ["always"] },
+        { code: "((a)) \n? ((b))\n: ((c))", options: ["always"] },
+        { code: "((a)) ?\n ((b)):\n ((c))", options: ["always"] },
 
         // "always-multiline"
         { code: "a\n? b\n: c", options: ["always-multiline"] },
@@ -43,11 +59,56 @@ ruleTester.run("multiline-ternary", rule, {
         { code: "a ? (b ? c : d) : e", options: ["always-multiline"] },
         { code: "a\n? (b ? c : d)\n: e", options: ["always-multiline"] },
         { code: "a ?\n(b ? c : d) :\ne", options: ["always-multiline"] },
+        { code: "(a\n ? b\n : c)", options: ["always-multiline"] },
+        { code: "(\na ? b : c\n)", options: ["always-multiline"] },
+        { code: "(a)\n? b\n: c", options: ["always-multiline"] },
+        { code: "((a))\n? b\n: c", options: ["always-multiline"] },
+        { code: "(a)?\n b\n: c", options: ["always-multiline"] },
+        { code: "((a))?\n b\n: c", options: ["always-multiline"] },
+        { code: "a\n? (b)\n: c", options: ["always-multiline"] },
+        { code: "a\n? ((b))\n: c", options: ["always-multiline"] },
+        { code: "a ?\n (b)\n: c", options: ["always-multiline"] },
+        { code: "a ?\n ((b))\n: c", options: ["always-multiline"] },
+        { code: "a \n? b\n: (c)", options: ["always-multiline"] },
+        { code: "a \n? b\n: ((c))", options: ["always-multiline"] },
+        { code: "a \n? b:\n (c)", options: ["always-multiline"] },
+        { code: "a \n? b:\n ((c))", options: ["always-multiline"] },
+        { code: "(a) \n? (b)\n: (c)", options: ["always-multiline"] },
+        { code: "((a)) \n? ((b))\n: ((c))", options: ["always-multiline"] },
+        { code: "((a)) ?\n ((b)):\n ((c))", options: ["always-multiline"] },
+        { code: "(a) ? b : c", options: ["always-multiline"] },
+        { code: "((a)) ? b : c", options: ["always-multiline"] },
+        { code: "a ? (b) : c", options: ["always-multiline"] },
+        { code: "a ? ((b)) : c", options: ["always-multiline"] },
+        { code: "a ? b : (c)", options: ["always-multiline"] },
+        { code: "a ? b : ((c))", options: ["always-multiline"] },
+        { code: "(a) ? (b) : (c)", options: ["always-multiline"] },
+        { code: "((a)) ? ((b)) : ((c))", options: ["always-multiline"] },
 
         // "never"
         { code: "a ? b : c", options: ["never"] },
         { code: "a ? b ? c : d : e", options: ["never"] },
-        { code: "a ? (b ? c : d) : e", options: ["never"] }
+        { code: "a ? (b ? c : d) : e", options: ["never"] },
+        { code: "a  +\n b ? c +\n d : e + \nf", options: ["never"] },
+        { code: "(\na ? b : c\n)", options: ["never"] },
+        { code: "(a) ? b : c", options: ["never"] },
+        { code: "((a)) ? b : c", options: ["never"] },
+        { code: "a ? (b) : c", options: ["never"] },
+        { code: "a ? ((b)) : c", options: ["never"] },
+        { code: "a ? b : (c)", options: ["never"] },
+        { code: "a ? b : ((c))", options: ["never"] },
+        { code: "(a) ? (b) : (c)", options: ["never"] },
+        { code: "((a)) ? ((b)) : ((c))", options: ["never"] },
+        { code: "(a\n) ? b : c", options: ["never"] },
+        { code: "((a)\n) ? b : c", options: ["never"] },
+        { code: "a ? (\nb) : c", options: ["never"] },
+        { code: "a ? (\n(b)) : c", options: ["never"] },
+        { code: "a ? (b\n) : c", options: ["never"] },
+        { code: "a ? ((b)\n) : c", options: ["never"] },
+        { code: "a ? b : (\nc)", options: ["never"] },
+        { code: "a ? b : (\n(c))", options: ["never"] },
+        { code: "(a\n) ? (\nb\n) : (\nc)", options: ["never"] },
+        { code: "((a)\n) ? (\n(b)\n) : (\n(c))", options: ["never"] }
     ],
 
     invalid: [
@@ -92,7 +153,9 @@ ruleTester.run("multiline-ternary", rule, {
             {
                 messageId: "expectedConsAlt",
                 line: 1,
-                column: 6
+                column: 5,
+                endLine: 1,
+                endColumn: 16
             },
             {
                 messageId: "expectedTestCons",
@@ -128,7 +191,9 @@ ruleTester.run("multiline-ternary", rule, {
             {
                 messageId: "expectedConsAlt",
                 line: 1,
-                column: 6
+                column: 5,
+                endLine: 3,
+                endColumn: 5
             }]
         },
         {
@@ -136,7 +201,9 @@ ruleTester.run("multiline-ternary", rule, {
             errors: [{
                 messageId: "expectedConsAlt",
                 line: 2,
-                column: 2
+                column: 1,
+                endLine: 3,
+                endColumn: 5
             },
             {
                 messageId: "expectedTestCons",
@@ -149,7 +216,9 @@ ruleTester.run("multiline-ternary", rule, {
             errors: [{
                 messageId: "expectedConsAlt",
                 line: 2,
-                column: 2
+                column: 1,
+                endLine: 3,
+                endColumn: 9
             },
             {
                 messageId: "expectedConsAlt",
@@ -162,7 +231,9 @@ ruleTester.run("multiline-ternary", rule, {
             errors: [{
                 messageId: "expectedConsAlt",
                 line: 2,
-                column: 2
+                column: 1,
+                endLine: 4,
+                endColumn: 6
             }]
         },
 
@@ -173,12 +244,34 @@ ruleTester.run("multiline-ternary", rule, {
             errors: [{
                 messageId: "expectedTestCons",
                 line: 1,
-                column: 1
+                column: 1,
+                endLine: 1,
+                endColumn: 2
             },
             {
                 messageId: "expectedConsAlt",
                 line: 1,
-                column: 5
+                column: 5,
+                endLine: 1,
+                endColumn: 6
+            }]
+        },
+        {
+            code: "f() ? a + b : c",
+            options: ["always"],
+            errors: [{
+                messageId: "expectedTestCons",
+                line: 1,
+                column: 1,
+                endLine: 1,
+                endColumn: 4
+            },
+            {
+                messageId: "expectedConsAlt",
+                line: 1,
+                column: 7,
+                endLine: 1,
+                endColumn: 12
             }]
         },
         {
@@ -210,7 +303,9 @@ ruleTester.run("multiline-ternary", rule, {
             {
                 messageId: "expectedConsAlt",
                 line: 1,
-                column: 6
+                column: 5,
+                endLine: 1,
+                endColumn: 16
             },
             {
                 messageId: "expectedTestCons",
@@ -248,7 +343,9 @@ ruleTester.run("multiline-ternary", rule, {
             {
                 messageId: "expectedConsAlt",
                 line: 1,
-                column: 6
+                column: 5,
+                endLine: 3,
+                endColumn: 5
             }]
         },
         {
@@ -257,7 +354,9 @@ ruleTester.run("multiline-ternary", rule, {
             errors: [{
                 messageId: "expectedConsAlt",
                 line: 2,
-                column: 2
+                column: 1,
+                endLine: 3,
+                endColumn: 5
             },
             {
                 messageId: "expectedTestCons",
@@ -271,7 +370,9 @@ ruleTester.run("multiline-ternary", rule, {
             errors: [{
                 messageId: "expectedConsAlt",
                 line: 2,
-                column: 2
+                column: 1,
+                endLine: 3,
+                endColumn: 9
             },
             {
                 messageId: "expectedConsAlt",
@@ -285,7 +386,133 @@ ruleTester.run("multiline-ternary", rule, {
             errors: [{
                 messageId: "expectedConsAlt",
                 line: 2,
-                column: 2
+                column: 1,
+                endLine: 4,
+                endColumn: 6
+            }]
+        },
+        {
+            code: "(a\n) ? b\n: c",
+            options: ["always"],
+            errors: [{
+                messageId: "expectedTestCons",
+                line: 1,
+                column: 1,
+                endLine: 2,
+                endColumn: 2
+            }]
+        },
+        {
+            code: "((a)\n) ? b\n: c",
+            options: ["always"],
+            errors: [{
+                messageId: "expectedTestCons",
+                line: 1,
+                column: 1,
+                endLine: 2,
+                endColumn: 2
+            }]
+        },
+        {
+            code: "a ? (\nb)\n: c",
+            options: ["always"],
+            errors: [{
+                messageId: "expectedTestCons",
+                line: 1,
+                column: 1,
+                endLine: 1,
+                endColumn: 2
+            }]
+        },
+        {
+            code: "a ? (\n(b))\n: c",
+            options: ["always"],
+            errors: [{
+                messageId: "expectedTestCons",
+                line: 1,
+                column: 1,
+                endLine: 1,
+                endColumn: 2
+            }]
+        },
+        {
+            code: "a\n? (b\n): c",
+            options: ["always"],
+            errors: [{
+                messageId: "expectedConsAlt",
+                line: 2,
+                column: 3,
+                endLine: 3,
+                endColumn: 2
+            }]
+        },
+        {
+            code: "a\n? ((b)\n): c",
+            options: ["always"],
+            errors: [{
+                messageId: "expectedConsAlt",
+                line: 2,
+                column: 3,
+                endLine: 3,
+                endColumn: 2
+            }]
+        },
+        {
+            code: "a\n? b : (\nc)",
+            options: ["always"],
+            errors: [{
+                messageId: "expectedConsAlt",
+                line: 2,
+                column: 3,
+                endLine: 2,
+                endColumn: 4
+            }]
+        },
+        {
+            code: "a\n? b : (\n(c))",
+            options: ["always"],
+            errors: [{
+                messageId: "expectedConsAlt",
+                line: 2,
+                column: 3,
+                endLine: 2,
+                endColumn: 4
+            }]
+        },
+        {
+            code: "(a\n) ? (\nb\n) : (\nc)",
+            options: ["always"],
+            errors: [{
+                messageId: "expectedTestCons",
+                line: 1,
+                column: 1,
+                endLine: 2,
+                endColumn: 2
+            },
+            {
+                messageId: "expectedConsAlt",
+                line: 2,
+                column: 5,
+                endLine: 4,
+                endColumn: 2
+            }]
+        },
+        {
+            code: "((a)\n) ? (\n(b)\n) : (\n(c))",
+            options: ["always"],
+            errors: [{
+                messageId: "expectedTestCons",
+                line: 1,
+                column: 1,
+                endLine: 2,
+                endColumn: 2
+            },
+            {
+                messageId: "expectedConsAlt",
+                line: 2,
+                column: 5,
+                endLine: 4,
+                endColumn: 2
             }]
         },
 
@@ -314,7 +541,9 @@ ruleTester.run("multiline-ternary", rule, {
             errors: [{
                 messageId: "expectedTestCons",
                 line: 1,
-                column: 1
+                column: 1,
+                endLine: 2,
+                endColumn: 2
             },
             {
                 messageId: "expectedConsAlt",
@@ -356,7 +585,9 @@ ruleTester.run("multiline-ternary", rule, {
             errors: [{
                 messageId: "expectedConsAlt",
                 line: 2,
-                column: 2
+                column: 1,
+                endLine: 2,
+                endColumn: 12
             }]
         },
         {
@@ -379,7 +610,9 @@ ruleTester.run("multiline-ternary", rule, {
             {
                 messageId: "expectedConsAlt",
                 line: 1,
-                column: 6
+                column: 5,
+                endLine: 3,
+                endColumn: 5
             }]
         },
         {
@@ -388,7 +621,9 @@ ruleTester.run("multiline-ternary", rule, {
             errors: [{
                 messageId: "expectedConsAlt",
                 line: 2,
-                column: 2
+                column: 1,
+                endLine: 3,
+                endColumn: 5
             },
             {
                 messageId: "expectedTestCons",
@@ -402,7 +637,9 @@ ruleTester.run("multiline-ternary", rule, {
             errors: [{
                 messageId: "expectedConsAlt",
                 line: 2,
-                column: 2
+                column: 1,
+                endLine: 3,
+                endColumn: 9
             },
             {
                 messageId: "expectedConsAlt",
@@ -416,7 +653,133 @@ ruleTester.run("multiline-ternary", rule, {
             errors: [{
                 messageId: "expectedConsAlt",
                 line: 2,
-                column: 2
+                column: 1,
+                endLine: 4,
+                endColumn: 6
+            }]
+        },
+        {
+            code: "(a\n) ? b\n: c",
+            options: ["always-multiline"],
+            errors: [{
+                messageId: "expectedTestCons",
+                line: 1,
+                column: 1,
+                endLine: 2,
+                endColumn: 2
+            }]
+        },
+        {
+            code: "((a)\n) ? b\n: c",
+            options: ["always-multiline"],
+            errors: [{
+                messageId: "expectedTestCons",
+                line: 1,
+                column: 1,
+                endLine: 2,
+                endColumn: 2
+            }]
+        },
+        {
+            code: "a ? (\nb)\n: c",
+            options: ["always-multiline"],
+            errors: [{
+                messageId: "expectedTestCons",
+                line: 1,
+                column: 1,
+                endLine: 1,
+                endColumn: 2
+            }]
+        },
+        {
+            code: "a ? (\n(b))\n: c",
+            options: ["always-multiline"],
+            errors: [{
+                messageId: "expectedTestCons",
+                line: 1,
+                column: 1,
+                endLine: 1,
+                endColumn: 2
+            }]
+        },
+        {
+            code: "a\n? (b\n): c",
+            options: ["always-multiline"],
+            errors: [{
+                messageId: "expectedConsAlt",
+                line: 2,
+                column: 3,
+                endLine: 3,
+                endColumn: 2
+            }]
+        },
+        {
+            code: "a\n? ((b)\n): c",
+            options: ["always-multiline"],
+            errors: [{
+                messageId: "expectedConsAlt",
+                line: 2,
+                column: 3,
+                endLine: 3,
+                endColumn: 2
+            }]
+        },
+        {
+            code: "a\n? b : (\nc)",
+            options: ["always-multiline"],
+            errors: [{
+                messageId: "expectedConsAlt",
+                line: 2,
+                column: 3,
+                endLine: 2,
+                endColumn: 4
+            }]
+        },
+        {
+            code: "a\n? b : (\n(c))",
+            options: ["always-multiline"],
+            errors: [{
+                messageId: "expectedConsAlt",
+                line: 2,
+                column: 3,
+                endLine: 2,
+                endColumn: 4
+            }]
+        },
+        {
+            code: "(a\n) ? (\nb\n) : (\nc)",
+            options: ["always-multiline"],
+            errors: [{
+                messageId: "expectedTestCons",
+                line: 1,
+                column: 1,
+                endLine: 2,
+                endColumn: 2
+            },
+            {
+                messageId: "expectedConsAlt",
+                line: 2,
+                column: 5,
+                endLine: 4,
+                endColumn: 2
+            }]
+        },
+        {
+            code: "((a)\n) ? (\n(b)\n) : (\n(c))",
+            options: ["always-multiline"],
+            errors: [{
+                messageId: "expectedTestCons",
+                line: 1,
+                column: 1,
+                endLine: 2,
+                endColumn: 2
+            },
+            {
+                messageId: "expectedConsAlt",
+                line: 2,
+                column: 5,
+                endLine: 4,
+                endColumn: 2
             }]
         },
 
@@ -450,7 +813,9 @@ ruleTester.run("multiline-ternary", rule, {
             {
                 messageId: "unexpectedConsAlt",
                 line: 2,
-                column: 2
+                column: 1,
+                endLine: 2,
+                endColumn: 12
             }]
         },
         {
@@ -520,7 +885,9 @@ ruleTester.run("multiline-ternary", rule, {
             errors: [{
                 messageId: "unexpectedConsAlt",
                 line: 1,
-                column: 6
+                column: 5,
+                endLine: 3,
+                endColumn: 5
             },
             {
                 messageId: "unexpectedTestCons",
@@ -544,7 +911,9 @@ ruleTester.run("multiline-ternary", rule, {
             {
                 messageId: "unexpectedConsAlt",
                 line: 3,
-                column: 2
+                column: 1,
+                endLine: 7,
+                endColumn: 3
             },
             {
                 messageId: "unexpectedTestCons",
@@ -556,6 +925,60 @@ ruleTester.run("multiline-ternary", rule, {
                 line: 5,
                 column: 1
             }]
+        },
+        {
+            code: "(a)\n ? b \n : (c)",
+            options: ["never"],
+            errors: [{
+                messageId: "unexpectedTestCons",
+                line: 1,
+                column: 1,
+                endLine: 1,
+                endColumn: 4
+            },
+            {
+                messageId: "unexpectedConsAlt",
+                line: 2,
+                column: 4,
+                endLine: 2,
+                endColumn: 5
+            }]
+        },
+        {
+            code: "(a)\n ? (b) \n : (c)",
+            options: ["never"],
+            errors: [{
+                messageId: "unexpectedTestCons",
+                line: 1,
+                column: 1,
+                endLine: 1,
+                endColumn: 4
+            },
+            {
+                messageId: "unexpectedConsAlt",
+                line: 2,
+                column: 4,
+                endLine: 2,
+                endColumn: 7
+            }]
+        },
+        {
+            code: "((a))\n ? ((b)) \n : ((c))",
+            options: ["never"],
+            errors: [{
+                messageId: "unexpectedTestCons",
+                line: 1,
+                column: 1,
+                endLine: 1,
+                endColumn: 6
+            },
+            {
+                messageId: "unexpectedConsAlt",
+                line: 2,
+                column: 4,
+                endLine: 2,
+                endColumn: 9
+            }]
         }
     ]
 });
index 715fe91f5bae612ab68a7a80fe0b6b29b932549a..70ec8bd4f61d328c07164dbb633a1161c6a14430 100644 (file)
@@ -105,6 +105,11 @@ ruleTester.run("no-extra-boolean-cast", rule, {
         {
             code: "if ((!!foo || bar) === baz) {}",
             options: [{ enforceForLogicalOperands: true }]
+        },
+        {
+            code: "if (!!foo ?? bar) {}",
+            options: [{ enforceForLogicalOperands: true }],
+            parserOptions: { ecmaVersion: 2020 }
         }
     ],
 
@@ -2395,6 +2400,14 @@ ruleTester.run("no-extra-boolean-cast", rule, {
                 { messageId: "unexpectedNegation", type: "UnaryExpression" },
                 { messageId: "unexpectedCall", type: "CallExpression" }
             ]
+        },
+
+        {
+            code: "if (Boolean(a ?? b) || c) {}",
+            output: "if ((a ?? b) || c) {}",
+            options: [{ enforceForLogicalOperands: true }],
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [{ messageId: "unexpectedCall", type: "CallExpression" }]
         }
     ]
 });
index 5062857e699d1d640494c97236b6b44dec91c25c..91099f8cba04b0ff7041dadf6dd3bf7745c09db7 100644 (file)
@@ -508,6 +508,27 @@ ruleTester.run("no-extra-parens", rule, {
         { code: "(new foo.bar()).baz()", options: ["all", { enforceForNewInMemberExpressions: false }] },
         { code: "((new foo.bar())).baz()", options: ["all", { enforceForNewInMemberExpressions: false }] },
 
+        // ["all", { enforceForFunctionPrototypeMethods: false }]
+        { code: "var foo = (function(){}).call()", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "var foo = (function(){}).apply()", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "var foo = (function(){}.call())", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "var foo = (function(){}.apply())", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "var foo = (function(){}).call(arg)", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "var foo = (function(){}.apply(arg))", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "var foo = (function(){}['call']())", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "var foo = (function(){})[`apply`]()", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "var foo = ((function(){})).call()", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "var foo = ((function(){}).apply())", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "var foo = ((function(){}.call()))", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "var foo = ((((function(){})).apply()))", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "foo((function(){}).call().bar)", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "foo = (function(){}).call()()", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "foo = (function(){}.call())()", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "var foo = { bar: (function(){}.call()) }", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "var foo = { [(function(){}.call())]: bar  }", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "if((function(){}).call()){}", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+        { code: "while((function(){}.apply())){}", options: ["all", { enforceForFunctionPrototypeMethods: false }] },
+
         "let a = [ ...b ]",
         "let a = { ...b }",
         {
@@ -589,7 +610,17 @@ ruleTester.run("no-extra-parens", rule, {
         "for (let a = b; a; a); a; a;",
         "for (a; a; a); a; a;",
         "for (; a; a); a; a;",
-        "for (let a = (b && c) === d; ;);"
+        "for (let a = (b && c) === d; ;);",
+
+        // Nullish coalescing
+        { code: "var v = (a ?? b) || c", parserOptions: { ecmaVersion: 2020 } },
+        { code: "var v = a ?? (b || c)", parserOptions: { ecmaVersion: 2020 } },
+        { code: "var v = (a ?? b) && c", parserOptions: { ecmaVersion: 2020 } },
+        { code: "var v = a ?? (b && c)", parserOptions: { ecmaVersion: 2020 } },
+        { code: "var v = (a || b) ?? c", parserOptions: { ecmaVersion: 2020 } },
+        { code: "var v = a || (b ?? c)", parserOptions: { ecmaVersion: 2020 } },
+        { code: "var v = (a && b) ?? c", parserOptions: { ecmaVersion: 2020 } },
+        { code: "var v = a && (b ?? c)", parserOptions: { ecmaVersion: 2020 } }
     ],
 
     invalid: [
@@ -1293,6 +1324,316 @@ ruleTester.run("no-extra-parens", rule, {
             ]
         },
 
+        // enforceForFunctionPrototypeMethods
+        {
+            code: "var foo = (function(){}).call()",
+            output: "var foo = function(){}.call()",
+            options: ["all"],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "FunctionExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (function(){}.apply())",
+            output: "var foo = function(){}.apply()",
+            options: ["all"],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "CallExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (function(){}).apply()",
+            output: "var foo = function(){}.apply()",
+            options: ["all", {}],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "FunctionExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (function(){}.call())",
+            output: "var foo = function(){}.call()",
+            options: ["all", {}],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "CallExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (function(){}).call()",
+            output: "var foo = function(){}.call()",
+            options: ["all", { enforceForFunctionPrototypeMethods: true }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "FunctionExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (function(){}).apply()",
+            output: "var foo = function(){}.apply()",
+            options: ["all", { enforceForFunctionPrototypeMethods: true }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "FunctionExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (function(){}.call())",
+            output: "var foo = function(){}.call()",
+            options: ["all", { enforceForFunctionPrototypeMethods: true }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "CallExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (function(){}.apply())",
+            output: "var foo = function(){}.apply()",
+            options: ["all", { enforceForFunctionPrototypeMethods: true }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "CallExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (function(){}.call)()", // removing these parens does not cause any conflicts with wrap-iife
+            output: "var foo = function(){}.call()",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "MemberExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (function(){}.apply)()", // removing these parens does not cause any conflicts with wrap-iife
+            output: "var foo = function(){}.apply()",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "MemberExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (function(){}).call",
+            output: "var foo = function(){}.call",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "FunctionExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (function(){}.call)",
+            output: "var foo = function(){}.call",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "MemberExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = new (function(){}).call()",
+            output: "var foo = new function(){}.call()",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "FunctionExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (new function(){}.call())",
+            output: "var foo = new function(){}.call()",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "NewExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (function(){})[call]()",
+            output: "var foo = function(){}[call]()",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "FunctionExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (function(){}[apply]())",
+            output: "var foo = function(){}[apply]()",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "CallExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (function(){}).bar()",
+            output: "var foo = function(){}.bar()",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "FunctionExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (function(){}.bar())",
+            output: "var foo = function(){}.bar()",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "CallExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (function(){}).call.call()",
+            output: "var foo = function(){}.call.call()",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "FunctionExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (function(){}.call.call())",
+            output: "var foo = function(){}.call.call()",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "CallExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (call())",
+            output: "var foo = call()",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "CallExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (apply())",
+            output: "var foo = apply()",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "CallExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = (bar).call()",
+            output: "var foo = bar.call()",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "Identifier"
+                }
+            ]
+        },
+        {
+            code: "var foo = (bar.call())",
+            output: "var foo = bar.call()",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "CallExpression"
+                }
+            ]
+        },
+        {
+            code: "((() => {}).call())",
+            output: "(() => {}).call()",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "CallExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = function(){}.call((a.b))",
+            output: "var foo = function(){}.call(a.b)",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "MemberExpression"
+                }
+            ]
+        },
+        {
+            code: "var foo = function(){}.call((a).b)",
+            output: "var foo = function(){}.call(a.b)",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "Identifier"
+                }
+            ]
+        },
+        {
+            code: "var foo = function(){}[('call')]()",
+            output: "var foo = function(){}['call']()",
+            options: ["all", { enforceForFunctionPrototypeMethods: false }],
+            errors: [
+                {
+                    messageId: "unexpected",
+                    type: "Literal"
+                }
+            ]
+        },
+
         // https://github.com/eslint/eslint/issues/8175
         invalid(
             "let a = [...(b)]",
@@ -2288,6 +2629,75 @@ ruleTester.run("no-extra-parens", rule, {
         invalid("a+(/^b$/)", "a+/^b$/", "Literal"),
         invalid("a/(/**/b)", "a/ /**/b", "Identifier"),
         invalid("a/(//\nb)", "a/ //\nb", "Identifier"),
-        invalid("a/(/^b$/)", "a/ /^b$/", "Literal")
+        invalid("a/(/^b$/)", "a/ /^b$/", "Literal"),
+
+
+        // Nullish coalescing
+        {
+            code: "var v = ((a ?? b)) || c",
+            output: "var v = (a ?? b) || c",
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [{ messageId: "unexpected" }]
+        },
+        {
+            code: "var v = a ?? ((b || c))",
+            output: "var v = a ?? (b || c)",
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [{ messageId: "unexpected" }]
+        },
+        {
+            code: "var v = ((a ?? b)) && c",
+            output: "var v = (a ?? b) && c",
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [{ messageId: "unexpected" }]
+        },
+        {
+            code: "var v = a ?? ((b && c))",
+            output: "var v = a ?? (b && c)",
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [{ messageId: "unexpected" }]
+        },
+        {
+            code: "var v = ((a || b)) ?? c",
+            output: "var v = (a || b) ?? c",
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [{ messageId: "unexpected" }]
+        },
+        {
+            code: "var v = a || ((b ?? c))",
+            output: "var v = a || (b ?? c)",
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [{ messageId: "unexpected" }]
+        },
+        {
+            code: "var v = ((a && b)) ?? c",
+            output: "var v = (a && b) ?? c",
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [{ messageId: "unexpected" }]
+        },
+        {
+            code: "var v = a && ((b ?? c))",
+            output: "var v = a && (b ?? c)",
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [{ messageId: "unexpected" }]
+        },
+        {
+            code: "var v = (a ?? b) ? b : c",
+            output: "var v = a ?? b ? b : c",
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [{ messageId: "unexpected" }]
+        },
+        {
+            code: "var v = (a | b) ?? c | d",
+            output: "var v = a | b ?? c | d",
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [{ messageId: "unexpected" }]
+        },
+        {
+            code: "var v = a | b ?? (c | d)",
+            output: "var v = a | b ?? c | d",
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [{ messageId: "unexpected" }]
+        }
     ]
 });
index 0e79b56058c2d84488e0f9639db7abd6f32d8511..3650cd09fce397c0ad9515afd56e3bdb53eebada 100644 (file)
@@ -363,6 +363,31 @@ ruleTester.run("no-mixed-operators", rule, {
                     }
                 }
             ]
+        },
+        {
+            code: "a + b ?? c",
+            options: [{ groups: [["+", "??"]] }],
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [
+                {
+                    column: 3,
+                    endColumn: 4,
+                    messageId: "unexpectedMixedOperator",
+                    data: {
+                        leftOperator: "+",
+                        rightOperator: "??"
+                    }
+                },
+                {
+                    column: 7,
+                    endColumn: 9,
+                    messageId: "unexpectedMixedOperator",
+                    data: {
+                        leftOperator: "+",
+                        rightOperator: "??"
+                    }
+                }
+            ]
         }
     ]
 });
index 4e4387029462108c41da6132efe75fa381d81dd0..4dd475d4b6075fbd752b9d3d6a83a7e1f3d3a944 100644 (file)
@@ -20,8 +20,15 @@ const ruleTester = new RuleTester();
 ruleTester.run("no-mixed-spaces-and-tabs", rule, {
 
     valid: [
+        "foo",
+        "foo \t",
+        "foo\t ",
         "\tvar x = 5;",
+        "\t\tvar x = 5;",
+        " var x = 5;",
         "    var x = 5;",
+        " foo\t",
+        "\tfoo ",
         "\t/*\n\t * Hello\n\t */",
         "// foo\n\t/**\n\t * Hello\n\t */",
         "/*\n\n \t \n*/",
@@ -80,6 +87,50 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
         {
             code: "\tvar x = 5,\n\t    y = 2;",
             options: ["smart-tabs"]
+        },
+        {
+            code: "\t\t\t   foo",
+            options: ["smart-tabs"]
+        },
+        {
+            code: "foo",
+            options: ["smart-tabs"]
+        },
+        {
+            code: "foo \t",
+            options: ["smart-tabs"]
+        },
+        {
+            code: "foo\t ",
+            options: ["smart-tabs"]
+        },
+        {
+            code: "\tfoo \t",
+            options: ["smart-tabs"]
+        },
+        {
+            code: "\tvar x = 5;",
+            options: ["smart-tabs"]
+        },
+        {
+            code: "\t\tvar x = 5;",
+            options: ["smart-tabs"]
+        },
+        {
+            code: " var x = 5;",
+            options: ["smart-tabs"]
+        },
+        {
+            code: "    var x = 5;",
+            options: ["smart-tabs"]
+        },
+        {
+            code: " foo\t",
+            options: ["smart-tabs"]
+        },
+        {
+            code: "\tfoo ",
+            options: ["smart-tabs"]
         }
     ],
 
@@ -90,7 +141,10 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                 {
                     messageId: "mixedSpacesAndTabs",
                     type: "Program",
-                    line: 2
+                    line: 2,
+                    column: 1,
+                    endLine: 2,
+                    endColumn: 3
                 }
             ]
         },
@@ -100,7 +154,10 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                 {
                     messageId: "mixedSpacesAndTabs",
                     type: "Program",
-                    line: 1
+                    line: 1,
+                    column: 1,
+                    endLine: 1,
+                    endColumn: 3
                 }
             ]
         },
@@ -110,7 +167,10 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                 {
                     messageId: "mixedSpacesAndTabs",
                     type: "Program",
-                    line: 1
+                    line: 1,
+                    column: 1,
+                    endLine: 1,
+                    endColumn: 3
                 }
             ]
         },
@@ -120,7 +180,10 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                 {
                     messageId: "mixedSpacesAndTabs",
                     type: "Program",
-                    line: 1
+                    line: 1,
+                    column: 1,
+                    endLine: 1,
+                    endColumn: 3
                 }
             ]
         },
@@ -130,7 +193,10 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                 {
                     messageId: "mixedSpacesAndTabs",
                     type: "Program",
-                    line: 1
+                    line: 1,
+                    column: 1,
+                    endLine: 1,
+                    endColumn: 3
                 }
             ]
         },
@@ -140,7 +206,10 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                 {
                     messageId: "mixedSpacesAndTabs",
                     type: "Program",
-                    line: 1
+                    line: 1,
+                    column: 1,
+                    endLine: 1,
+                    endColumn: 3
                 }
             ]
         },
@@ -150,7 +219,10 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                 {
                     messageId: "mixedSpacesAndTabs",
                     type: "Program",
-                    line: 2
+                    line: 2,
+                    column: 1,
+                    endLine: 2,
+                    endColumn: 3
                 }
             ]
         },
@@ -160,12 +232,18 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                 {
                     messageId: "mixedSpacesAndTabs",
                     type: "Program",
-                    line: 1
+                    line: 1,
+                    column: 1,
+                    endLine: 1,
+                    endColumn: 3
                 },
                 {
                     messageId: "mixedSpacesAndTabs",
                     type: "Program",
-                    line: 3
+                    line: 3,
+                    column: 1,
+                    endLine: 3,
+                    endColumn: 3
                 }
             ]
         },
@@ -176,7 +254,10 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                 {
                     messageId: "mixedSpacesAndTabs",
                     type: "Program",
-                    line: 2
+                    line: 2,
+                    column: 2,
+                    endLine: 2,
+                    endColumn: 4
                 }
             ]
         },
@@ -187,7 +268,10 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                 {
                     messageId: "mixedSpacesAndTabs",
                     type: "Program",
-                    line: 2
+                    line: 2,
+                    column: 2,
+                    endLine: 2,
+                    endColumn: 4
                 }
             ]
         },
@@ -200,7 +284,9 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                     messageId: "mixedSpacesAndTabs",
                     type: "Program",
                     line: 2,
-                    column: 2
+                    column: 1,
+                    endLine: 2,
+                    endColumn: 3
                 }
             ]
         },
@@ -212,7 +298,9 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                     messageId: "mixedSpacesAndTabs",
                     type: "Program",
                     line: 2,
-                    column: 2
+                    column: 1,
+                    endLine: 2,
+                    endColumn: 3
                 }
             ]
         },
@@ -222,7 +310,10 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                 {
                     messageId: "mixedSpacesAndTabs",
                     type: "Program",
-                    line: 1
+                    line: 1,
+                    column: 2,
+                    endLine: 1,
+                    endColumn: 4
                 }
             ]
         },
@@ -232,7 +323,64 @@ ruleTester.run("no-mixed-spaces-and-tabs", rule, {
                 {
                     messageId: "mixedSpacesAndTabs",
                     type: "Program",
-                    line: 2
+                    line: 2,
+                    column: 1,
+                    endLine: 2,
+                    endColumn: 3
+                }
+            ]
+        },
+        {
+            code: "   \tfoo",
+            errors: [
+                {
+                    messageId: "mixedSpacesAndTabs",
+                    type: "Program",
+                    line: 1,
+                    column: 3,
+                    endLine: 1,
+                    endColumn: 5
+                }
+            ]
+        },
+        {
+            code: "\t\t\t foo",
+            errors: [
+                {
+                    messageId: "mixedSpacesAndTabs",
+                    type: "Program",
+                    line: 1,
+                    column: 3,
+                    endLine: 1,
+                    endColumn: 5
+                }
+            ]
+        },
+        {
+            code: "\t \tfoo",
+            options: ["smart-tabs"],
+            errors: [
+                {
+                    messageId: "mixedSpacesAndTabs",
+                    type: "Program",
+                    line: 1,
+                    column: 2,
+                    endLine: 1,
+                    endColumn: 4
+                }
+            ]
+        },
+        {
+            code: "\t\t\t   \tfoo",
+            options: ["smart-tabs"],
+            errors: [
+                {
+                    messageId: "mixedSpacesAndTabs",
+                    type: "Program",
+                    line: 1,
+                    column: 6,
+                    endLine: 1,
+                    endColumn: 8
                 }
             ]
         }
index 6d0e693b57d47e6953c93b27b226898f18777a2f..31458f15fc1c877fce091cdaab45dc6179f42219 100644 (file)
@@ -16,7 +16,7 @@ const { RuleTester } = require("../../../lib/rule-tester");
 // Tests
 //------------------------------------------------------------------------------
 
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018, sourceType: "module" } });
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2020, sourceType: "module" } });
 
 ruleTester.run("no-restricted-exports", rule, {
     valid: [
@@ -73,6 +73,7 @@ ruleTester.run("no-restricted-exports", rule, {
 
         // does not check source in re-export declarations
         { code: "export { b } from 'a';", options: [{ restrictedNamedExports: ["a"] }] },
+        { code: "export * as b from 'a';", options: [{ restrictedNamedExports: ["a"] }] },
 
         // does not check non-export declarations
         { code: "var a;", options: [{ restrictedNamedExports: ["a"] }] },
@@ -332,6 +333,11 @@ ruleTester.run("no-restricted-exports", rule, {
             options: [{ restrictedNamedExports: ["a"] }],
             errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 15 }]
         },
+        {
+            code: "export * as a from 'a';",
+            options: [{ restrictedNamedExports: ["a"] }],
+            errors: [{ messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier", column: 13 }]
+        },
 
         // Note: duplicate identifiers in the same export declaration are a 'duplicate export' syntax error. Example: export var a, a;
 
index 680bc1352e38ef297db74633635abd33eb1eb079..363229712c99dd649be5af724325f5c3145fa287 100644 (file)
@@ -16,7 +16,7 @@ const rule = require("../../../lib/rules/no-restricted-imports"),
 // Tests
 //------------------------------------------------------------------------------
 
-const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6, sourceType: "module" } });
+const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2020, sourceType: "module" } });
 
 ruleTester.run("no-restricted-imports", rule, {
     valid: [
@@ -261,6 +261,16 @@ ruleTester.run("no-restricted-imports", rule, {
             column: 1,
             endColumn: 20
         }]
+    }, {
+        code: "export * as ns from \"fs\";",
+        options: ["fs"],
+        errors: [{
+            message: "'fs' import is restricted from being used.",
+            type: "ExportAllDeclaration",
+            line: 1,
+            column: 1,
+            endColumn: 26
+        }]
     }, {
         code: "export {a} from \"fs\";",
         options: ["fs"],
@@ -287,6 +297,22 @@ ruleTester.run("no-restricted-imports", rule, {
             column: 9,
             endColumn: 17
         }]
+    }, {
+        code: "export * as ns from \"fs\";",
+        options: [{
+            paths: [{
+                name: "fs",
+                importNames: ["foo"],
+                message: "Don't import 'foo'."
+            }]
+        }],
+        errors: [{
+            message: "* import is invalid because 'foo' from 'fs' is restricted. Don't import 'foo'.",
+            type: "ExportAllDeclaration",
+            line: 1,
+            column: 8,
+            endColumn: 9
+        }]
     }, {
         code: "import withGitignores from \"foo\";",
         options: [{
index 13bca8c3d2261c794873e0716a074346422ff8d5..8c9c053a55a4ed1d66fc5c82c00a8702bd7f15bb 100644 (file)
@@ -71,13 +71,25 @@ ruleTester.run("no-undef", rule, {
         // new.target: https://github.com/eslint/eslint/issues/5420
         { code: "class A { constructor() { new.target; } }", parserOptions: { ecmaVersion: 6 } },
 
-        // Experimental,
+        // Rest property
         {
             code: "var {bacon, ...others} = stuff; foo(others)",
             parserOptions: {
                 ecmaVersion: 2018
             },
             globals: { stuff: false, foo: false }
+        },
+
+        // export * as ns from "source"
+        {
+            code: 'export * as ns from "source"',
+            parserOptions: { ecmaVersion: 2020, sourceType: "module" }
+        },
+
+        // import.meta
+        {
+            code: "import.meta",
+            parserOptions: { ecmaVersion: 2020, sourceType: "module" }
         }
     ],
     invalid: [
index 25aab8a0cd181477c2f0a102dbd351c8a7820305..82479a94cb3a5e1755dd0dfdcee1984d544a4fb9 100644 (file)
@@ -357,6 +357,18 @@ ruleTester.run("no-unneeded-ternary", rule, {
                 line: 1,
                 column: 15
             }]
+        },
+        {
+            code: "var a = foo ? foo : a ?? b;",
+            output: "var a = foo || (a ?? b);",
+            options: [{ defaultAssignment: false }],
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [{
+                messageId: "unnecessaryConditionalAssignment",
+                type: "ConditionalExpression",
+                line: 1,
+                column: 15
+            }]
         }
     ]
 });
index 34051daa7b5fec80a380093be5fe4b483e23a9c5..8ef2028c66207a6a90e8edb0264b8b30288f80a7 100644 (file)
@@ -70,6 +70,10 @@ ruleTester.run("no-unused-expressions", rule, {
             code: "shouldNotBeAffectedByAllowTemplateTagsOption()",
             options: [{ allowTaggedTemplates: true }],
             parserOptions: { ecmaVersion: 6 }
+        },
+        {
+            code: "import(\"foo\")",
+            parserOptions: { ecmaVersion: 11 }
         }
     ],
     invalid: [
index ec23acae19dbf3ce49b0dc2e80103f2434311039..061ac08d51f4b7c51131bc35a17d81bdfe828d99 100644 (file)
@@ -304,6 +304,18 @@ ruleTester.run("no-unused-vars", rule, {
         {
             code: "const a = () => () => { a(); }; a();",
             parserOptions: { ecmaVersion: 2015 }
+        },
+
+        // export * as ns from "source"
+        {
+            code: 'export * as ns from "source"',
+            parserOptions: { ecmaVersion: 2020, sourceType: "module" }
+        },
+
+        // import.meta
+        {
+            code: "import.meta",
+            parserOptions: { ecmaVersion: 2020, sourceType: "module" }
         }
     ],
     invalid: [
@@ -444,7 +456,7 @@ ruleTester.run("no-unused-vars", rule, {
             code: "(function(obj) { var name; for ( name in obj ) { i(); return; } })({});",
             errors: [{
                 line: 1,
-                column: 22,
+                column: 34,
                 messageId: "unusedVar",
                 data: {
                     varName: "name",
@@ -457,7 +469,7 @@ ruleTester.run("no-unused-vars", rule, {
             code: "(function(obj) { var name; for ( name in obj ) { } })({});",
             errors: [{
                 line: 1,
-                column: 22,
+                column: 34,
                 messageId: "unusedVar",
                 data: {
                     varName: "name",
@@ -1021,6 +1033,62 @@ ruleTester.run("no-unused-vars", rule, {
             code: "const a = () => () => { a(); };",
             parserOptions: { ecmaVersion: 2015 },
             errors: [assignedError("a")]
+        },
+        {
+            code: `let myArray = [1,2,3,4].filter((x) => x == 0);
+    myArray = myArray.filter((x) => x == 1);`,
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [{ ...assignedError("myArray"), line: 2, column: 15 }]
+        },
+        {
+            code: "const a = 1; a += 1;",
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [{ ...assignedError("a"), line: 1, column: 14 }]
+        },
+        {
+            code: "var a = function() { a(); };",
+            errors: [{ ...assignedError("a"), line: 1, column: 22 }]
+        },
+        {
+            code: "var a = function(){ return function() { a(); } };",
+            errors: [{ ...assignedError("a"), line: 1, column: 41 }]
+        },
+        {
+            code: "const a = () => { a(); };",
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [{ ...assignedError("a"), line: 1, column: 19 }]
+        },
+        {
+            code: "const a = () => () => { a(); };",
+            parserOptions: { ecmaVersion: 2015 },
+            errors: [{ ...assignedError("a"), line: 1, column: 25 }]
+        },
+        {
+
+            code: `let a = 'a';
+            a = 10;
+            function foo(){
+                a = 11;
+                a = () => {
+                    a = 13
+                }
+            }`,
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [{ ...definedError("foo"), line: 3, column: 22 }, { ...assignedError("a"), line: 6, column: 21 }]
+        },
+        {
+            code: `let c = 'c'
+c = 10
+function foo1() {
+  c = 11
+  c = () => {
+    c = 13
+  }
+}
+
+c = foo1`,
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [{ ...assignedError("c"), line: 10, column: 1 }]
         }
     ]
 });
index 3910ac8a0e7f45b1b6ccf0f2e3de06425a79e3ab..18a37e3fc80aca6211fd111f8912f80427be9eaa 100644 (file)
@@ -628,6 +628,16 @@ ruleTester.run("operator-linebreak", rule, {
                 endLine: 1,
                 endColumn: 14
             }]
+        },
+        {
+            code: "foo ??\n bar",
+            output: "foo\n ?? bar",
+            options: ["after", { overrides: { "??": "before" } }],
+            parserOptions: { ecmaVersion: 2020 },
+            errors: [{
+                messageId: "operatorAtBeginning",
+                data: { operator: "??" }
+            }]
         }
     ]
 });
index 08859369a2984bb7507e525f14047731c4cdba4c..f01dbdce3a09d01ef0d4f125ae3982e29eaf181e 100644 (file)
@@ -17,8 +17,6 @@ const rule = require("../../../lib/rules/template-tag-spacing"),
 //------------------------------------------------------------------------------
 
 const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
-const unexpectedError = { messageId: "unexpected" };
-const missingError = { messageId: "missing" };
 
 ruleTester.run("template-tag-spacing", rule, {
     valid: [
@@ -55,167 +53,413 @@ ruleTester.run("template-tag-spacing", rule, {
         {
             code: "tag `name`",
             output: "tag`name`",
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 4,
+                endLine: 1,
+                endColumn: 5
+            }]
         },
         {
             code: "tag `name`",
             output: "tag`name`",
             options: ["never"],
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 4,
+                endLine: 1,
+                endColumn: 5
+            }]
         },
         {
             code: "tag`name`",
             output: "tag `name`",
             options: ["always"],
-            errors: [missingError]
+            errors: [{
+                messageId: "missing",
+                line: 1,
+                column: 1,
+                endLine: 1,
+                endColumn: 4
+            }]
         },
         {
             code: "tag /*here's a comment*/`Hello world`",
             output: "tag/*here's a comment*/`Hello world`",
             options: ["never"],
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 4,
+                endLine: 1,
+                endColumn: 25
+            }]
         },
         {
             code: "tag/*here's a comment*/ `Hello world`",
             output: "tag/*here's a comment*/`Hello world`",
             options: ["never"],
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 4,
+                endLine: 1,
+                endColumn: 25
+            }]
         },
         {
             code: "tag/*here's a comment*/`Hello world`",
             output: "tag /*here's a comment*/`Hello world`",
             options: ["always"],
-            errors: [missingError]
+            errors: [{
+                messageId: "missing",
+                line: 1,
+                column: 1,
+                endLine: 1,
+                endColumn: 24
+            }]
         },
         {
             code: "tag // here's a comment \n`bar`",
             output: null,
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 4,
+                endLine: 2,
+                endColumn: 1
+            }]
         },
         {
             code: "tag // here's a comment \n`bar`",
             output: null,
             options: ["never"],
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 4,
+                endLine: 2,
+                endColumn: 1
+            }]
         },
         {
             code: "tag `hello ${name}`",
             output: "tag`hello ${name}`",
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 4,
+                endLine: 1,
+                endColumn: 5
+            }]
         },
         {
             code: "tag `hello ${name}`",
             output: "tag`hello ${name}`",
             options: ["never"],
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 4,
+                endLine: 1,
+                endColumn: 5
+            }]
         },
         {
             code: "tag`hello ${name}`",
             output: "tag `hello ${name}`",
             options: ["always"],
-            errors: [missingError]
+            errors: [{
+                messageId: "missing",
+                line: 1,
+                column: 1,
+                endLine: 1,
+                endColumn: 4
+            }]
         },
         {
             code: "new tag `name`",
             output: "new tag`name`",
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 8,
+                endLine: 1,
+                endColumn: 9
+            }]
         },
         {
             code: "new tag `name`",
             output: "new tag`name`",
             options: ["never"],
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 8,
+                endLine: 1,
+                endColumn: 9
+            }]
         },
         {
             code: "new tag`name`",
             output: "new tag `name`",
             options: ["always"],
-            errors: [missingError]
+            errors: [{
+                messageId: "missing",
+                line: 1,
+                column: 5,
+                endLine: 1,
+                endColumn: 8
+            }]
         },
         {
             code: "new tag `hello ${name}`",
             output: "new tag`hello ${name}`",
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 8,
+                endLine: 1,
+                endColumn: 9
+            }]
         },
         {
             code: "new tag `hello ${name}`",
             output: "new tag`hello ${name}`",
             options: ["never"],
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 8,
+                endLine: 1,
+                endColumn: 9
+            }]
         },
         {
             code: "new tag`hello ${name}`",
             output: "new tag `hello ${name}`",
             options: ["always"],
-            errors: [missingError]
+            errors: [{
+                messageId: "missing",
+                line: 1,
+                column: 5,
+                endLine: 1,
+                endColumn: 8
+            }]
         },
         {
             code: "(tag) `name`",
             output: "(tag)`name`",
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 6,
+                endLine: 1,
+                endColumn: 7
+            }]
         },
         {
             code: "(tag) `name`",
             output: "(tag)`name`",
             options: ["never"],
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 6,
+                endLine: 1,
+                endColumn: 7
+            }]
         },
         {
             code: "(tag)`name`",
             output: "(tag) `name`",
             options: ["always"],
-            errors: [missingError]
+            errors: [{
+                messageId: "missing",
+                line: 1,
+                column: 1,
+                endLine: 1,
+                endColumn: 6
+            }]
         },
         {
             code: "(tag) `hello ${name}`",
             output: "(tag)`hello ${name}`",
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 6,
+                endLine: 1,
+                endColumn: 7
+            }]
         },
         {
             code: "(tag) `hello ${name}`",
             output: "(tag)`hello ${name}`",
             options: ["never"],
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 6,
+                endLine: 1,
+                endColumn: 7
+            }]
         },
         {
             code: "(tag)`hello ${name}`",
             output: "(tag) `hello ${name}`",
             options: ["always"],
-            errors: [missingError]
+            errors: [{
+                messageId: "missing",
+                line: 1,
+                column: 1,
+                endLine: 1,
+                endColumn: 6
+            }]
         },
         {
             code: "new (tag) `name`",
             output: "new (tag)`name`",
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 10,
+                endLine: 1,
+                endColumn: 11
+            }]
         },
         {
             code: "new (tag) `name`",
             output: "new (tag)`name`",
             options: ["never"],
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 10,
+                endLine: 1,
+                endColumn: 11
+            }]
         },
         {
             code: "new (tag)`name`",
             output: "new (tag) `name`",
             options: ["always"],
-            errors: [missingError]
+            errors: [{
+                messageId: "missing",
+                line: 1,
+                column: 5,
+                endLine: 1,
+                endColumn: 10
+            }]
         },
         {
             code: "new (tag) `hello ${name}`",
             output: "new (tag)`hello ${name}`",
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 10,
+                endLine: 1,
+                endColumn: 11
+            }]
         },
         {
             code: "new (tag) `hello ${name}`",
             output: "new (tag)`hello ${name}`",
             options: ["never"],
-            errors: [unexpectedError]
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 10,
+                endLine: 1,
+                endColumn: 11
+            }]
         },
         {
             code: "new (tag)`hello ${name}`",
             output: "new (tag) `hello ${name}`",
             options: ["always"],
-            errors: [missingError]
+            errors: [{
+                messageId: "missing",
+                line: 1,
+                column: 5,
+                endLine: 1,
+                endColumn: 10
+            }]
+        },
+        {
+            code: "tag   `name`",
+            output: "tag`name`",
+            options: ["never"],
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 4,
+                endLine: 1,
+                endColumn: 7
+            }]
+        },
+        {
+            code: "tag\n`name`",
+            output: "tag`name`",
+            options: ["never"],
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 4,
+                endLine: 2,
+                endColumn: 1
+            }]
+        },
+        {
+            code: "tag \n  `name`",
+            output: "tag`name`",
+            options: ["never"],
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 4,
+                endLine: 2,
+                endColumn: 3
+            }]
+        },
+        {
+            code: "tag\n\n`name`",
+            output: "tag`name`",
+            options: ["never"],
+            errors: [{
+                messageId: "unexpected",
+                line: 1,
+                column: 4,
+                endLine: 3,
+                endColumn: 1
+            }]
+        },
+        {
+            code: "foo\n  .bar`Hello world`",
+            output: "foo\n  .bar `Hello world`",
+            options: ["always"],
+            errors: [{
+                messageId: "missing",
+                line: 1,
+                column: 1,
+                endLine: 2,
+                endColumn: 7
+            }]
+        },
+        {
+            code: "foo(\n  bar\n)`Hello world`",
+            output: "foo(\n  bar\n) `Hello world`",
+            options: ["always"],
+            errors: [{
+                messageId: "missing",
+                line: 1,
+                column: 1,
+                endLine: 3,
+                endColumn: 2
+            }]
         }
     ]
 });
index 2954bf08f10092f8348206c77a1aef50d4c37e24..512b692fe74ca56444cc4841192fb3046e46ed18 100644 (file)
@@ -76,7 +76,7 @@ function reduceBadExampleSize({
     function reproducesBadCase(updatedSourceText) {
         try {
             parser.parse(updatedSourceText);
-        } catch (err) {
+        } catch {
             return false;
         }
 
index 0fa18d84edec24770b96e0fbcadbf8de9f13cbfc..836b0647f02db7d07fa749d11ee636dc06fe5dfc 100755 (executable)
@@ -18968,7 +18968,7 @@ module.exports = {
 /* 383 */
 /***/ (function(module) {
 
-module.exports = JSON.parse("{\"_from\":\"estraverse@^4.1.1\",\"_id\":\"estraverse@4.3.0\",\"_inBundle\":false,\"_integrity\":\"sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==\",\"_location\":\"/estraverse\",\"_phantomChildren\":{},\"_requested\":{\"type\":\"range\",\"registry\":true,\"raw\":\"estraverse@^4.1.1\",\"name\":\"estraverse\",\"escapedName\":\"estraverse\",\"rawSpec\":\"^4.1.1\",\"saveSpec\":null,\"fetchSpec\":\"^4.1.1\"},\"_requiredBy\":[\"/babel-eslint/eslint-scope\",\"/eslint-scope\",\"/esrecurse\",\"/webpack/eslint-scope\"],\"_resolved\":\"https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz\",\"_shasum\":\"398ad3f3c5a24948be7725e83d11a7de28cdbd1d\",\"_spec\":\"estraverse@^4.1.1\",\"_where\":\"/root/sources/pve/pve-eslint/eslint-v7.1.0/node_modules/eslint-scope\",\"bugs\":{\"url\":\"https://github.com/estools/estraverse/issues\"},\"bundleDependencies\":false,\"deprecated\":false,\"description\":\"ECMAScript JS AST traversal functions\",\"devDependencies\":{\"babel-preset-env\":\"^1.6.1\",\"babel-register\":\"^6.3.13\",\"chai\":\"^2.1.1\",\"espree\":\"^1.11.0\",\"gulp\":\"^3.8.10\",\"gulp-bump\":\"^0.2.2\",\"gulp-filter\":\"^2.0.0\",\"gulp-git\":\"^1.0.1\",\"gulp-tag-version\":\"^1.3.0\",\"jshint\":\"^2.5.6\",\"mocha\":\"^2.1.0\"},\"engines\":{\"node\":\">=4.0\"},\"homepage\":\"https://github.com/estools/estraverse\",\"license\":\"BSD-2-Clause\",\"main\":\"estraverse.js\",\"maintainers\":[{\"name\":\"Yusuke Suzuki\",\"email\":\"utatane.tea@gmail.com\",\"url\":\"http://github.com/Constellation\"}],\"name\":\"estraverse\",\"repository\":{\"type\":\"git\",\"url\":\"git+ssh://git@github.com/estools/estraverse.git\"},\"scripts\":{\"lint\":\"jshint estraverse.js\",\"test\":\"npm run-script lint && npm run-script unit-test\",\"unit-test\":\"mocha --compilers js:babel-register\"},\"version\":\"4.3.0\"}");
+module.exports = JSON.parse("{\"_from\":\"estraverse@^4.1.1\",\"_id\":\"estraverse@4.3.0\",\"_inBundle\":false,\"_integrity\":\"sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==\",\"_location\":\"/estraverse\",\"_phantomChildren\":{},\"_requested\":{\"type\":\"range\",\"registry\":true,\"raw\":\"estraverse@^4.1.1\",\"name\":\"estraverse\",\"escapedName\":\"estraverse\",\"rawSpec\":\"^4.1.1\",\"saveSpec\":null,\"fetchSpec\":\"^4.1.1\"},\"_requiredBy\":[\"/babel-eslint/eslint-scope\",\"/eslint-scope\",\"/esrecurse\",\"/webpack/eslint-scope\"],\"_resolved\":\"https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz\",\"_shasum\":\"398ad3f3c5a24948be7725e83d11a7de28cdbd1d\",\"_spec\":\"estraverse@^4.1.1\",\"_where\":\"/root/sources/pve/pve-eslint/eslint-v7.2.0/node_modules/eslint-scope\",\"bugs\":{\"url\":\"https://github.com/estools/estraverse/issues\"},\"bundleDependencies\":false,\"deprecated\":false,\"description\":\"ECMAScript JS AST traversal functions\",\"devDependencies\":{\"babel-preset-env\":\"^1.6.1\",\"babel-register\":\"^6.3.13\",\"chai\":\"^2.1.1\",\"espree\":\"^1.11.0\",\"gulp\":\"^3.8.10\",\"gulp-bump\":\"^0.2.2\",\"gulp-filter\":\"^2.0.0\",\"gulp-git\":\"^1.0.1\",\"gulp-tag-version\":\"^1.3.0\",\"jshint\":\"^2.5.6\",\"mocha\":\"^2.1.0\"},\"engines\":{\"node\":\">=4.0\"},\"homepage\":\"https://github.com/estools/estraverse\",\"license\":\"BSD-2-Clause\",\"main\":\"estraverse.js\",\"maintainers\":[{\"name\":\"Yusuke Suzuki\",\"email\":\"utatane.tea@gmail.com\",\"url\":\"http://github.com/Constellation\"}],\"name\":\"estraverse\",\"repository\":{\"type\":\"git\",\"url\":\"git+ssh://git@github.com/estools/estraverse.git\"},\"scripts\":{\"lint\":\"jshint estraverse.js\",\"test\":\"npm run-script lint && npm run-script unit-test\",\"unit-test\":\"mocha --compilers js:babel-register\"},\"version\":\"4.3.0\"}");
 
 /***/ }),
 /* 384 */
@@ -19871,17 +19871,27 @@ class Referencer extends esrecurse.Visitor {
     }
 
     this.visitChildren(node);
-  }
+  } // TODO: ExportDeclaration doesn't exist. for bc?
+
 
   ExportDeclaration(node) {
     this.visitExportDeclaration(node);
   }
 
+  ExportAllDeclaration(node) {
+    this.visitExportDeclaration(node);
+  }
+
+  ExportDefaultDeclaration(node) {
+    this.visitExportDeclaration(node);
+  }
+
   ExportNamedDeclaration(node) {
     this.visitExportDeclaration(node);
   }
 
   ExportSpecifier(node) {
+    // TODO: `node.id` doesn't exist. for bc?
     const local = node.id || node.local;
     this.visit(local);
   }
@@ -20027,7 +20037,7 @@ module.exports = Referencer;
 /* 389 */
 /***/ (function(module) {
 
-module.exports = JSON.parse("{\"_from\":\"esrecurse@^4.1.0\",\"_id\":\"esrecurse@4.2.1\",\"_inBundle\":false,\"_integrity\":\"sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==\",\"_location\":\"/esrecurse\",\"_phantomChildren\":{},\"_requested\":{\"type\":\"range\",\"registry\":true,\"raw\":\"esrecurse@^4.1.0\",\"name\":\"esrecurse\",\"escapedName\":\"esrecurse\",\"rawSpec\":\"^4.1.0\",\"saveSpec\":null,\"fetchSpec\":\"^4.1.0\"},\"_requiredBy\":[\"/babel-eslint/eslint-scope\",\"/eslint-scope\",\"/webpack/eslint-scope\"],\"_resolved\":\"https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz\",\"_shasum\":\"007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf\",\"_spec\":\"esrecurse@^4.1.0\",\"_where\":\"/root/sources/pve/pve-eslint/eslint-v7.1.0/node_modules/eslint-scope\",\"babel\":{\"presets\":[\"es2015\"]},\"bugs\":{\"url\":\"https://github.com/estools/esrecurse/issues\"},\"bundleDependencies\":false,\"dependencies\":{\"estraverse\":\"^4.1.0\"},\"deprecated\":false,\"description\":\"ECMAScript AST recursive visitor\",\"devDependencies\":{\"babel-cli\":\"^6.24.1\",\"babel-eslint\":\"^7.2.3\",\"babel-preset-es2015\":\"^6.24.1\",\"babel-register\":\"^6.24.1\",\"chai\":\"^4.0.2\",\"esprima\":\"^4.0.0\",\"gulp\":\"^3.9.0\",\"gulp-bump\":\"^2.7.0\",\"gulp-eslint\":\"^4.0.0\",\"gulp-filter\":\"^5.0.0\",\"gulp-git\":\"^2.4.1\",\"gulp-mocha\":\"^4.3.1\",\"gulp-tag-version\":\"^1.2.1\",\"jsdoc\":\"^3.3.0-alpha10\",\"minimist\":\"^1.1.0\"},\"engines\":{\"node\":\">=4.0\"},\"homepage\":\"https://github.com/estools/esrecurse\",\"license\":\"BSD-2-Clause\",\"main\":\"esrecurse.js\",\"maintainers\":[{\"name\":\"Yusuke Suzuki\",\"email\":\"utatane.tea@gmail.com\",\"url\":\"https://github.com/Constellation\"}],\"name\":\"esrecurse\",\"repository\":{\"type\":\"git\",\"url\":\"git+https://github.com/estools/esrecurse.git\"},\"scripts\":{\"lint\":\"gulp lint\",\"test\":\"gulp travis\",\"unit-test\":\"gulp test\"},\"version\":\"4.2.1\"}");
+module.exports = JSON.parse("{\"_from\":\"esrecurse@^4.1.0\",\"_id\":\"esrecurse@4.2.1\",\"_inBundle\":false,\"_integrity\":\"sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==\",\"_location\":\"/esrecurse\",\"_phantomChildren\":{},\"_requested\":{\"type\":\"range\",\"registry\":true,\"raw\":\"esrecurse@^4.1.0\",\"name\":\"esrecurse\",\"escapedName\":\"esrecurse\",\"rawSpec\":\"^4.1.0\",\"saveSpec\":null,\"fetchSpec\":\"^4.1.0\"},\"_requiredBy\":[\"/babel-eslint/eslint-scope\",\"/eslint-scope\",\"/webpack/eslint-scope\"],\"_resolved\":\"https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz\",\"_shasum\":\"007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf\",\"_spec\":\"esrecurse@^4.1.0\",\"_where\":\"/root/sources/pve/pve-eslint/eslint-v7.2.0/node_modules/eslint-scope\",\"babel\":{\"presets\":[\"es2015\"]},\"bugs\":{\"url\":\"https://github.com/estools/esrecurse/issues\"},\"bundleDependencies\":false,\"dependencies\":{\"estraverse\":\"^4.1.0\"},\"deprecated\":false,\"description\":\"ECMAScript AST recursive visitor\",\"devDependencies\":{\"babel-cli\":\"^6.24.1\",\"babel-eslint\":\"^7.2.3\",\"babel-preset-es2015\":\"^6.24.1\",\"babel-register\":\"^6.24.1\",\"chai\":\"^4.0.2\",\"esprima\":\"^4.0.0\",\"gulp\":\"^3.9.0\",\"gulp-bump\":\"^2.7.0\",\"gulp-eslint\":\"^4.0.0\",\"gulp-filter\":\"^5.0.0\",\"gulp-git\":\"^2.4.1\",\"gulp-mocha\":\"^4.3.1\",\"gulp-tag-version\":\"^1.2.1\",\"jsdoc\":\"^3.3.0-alpha10\",\"minimist\":\"^1.1.0\"},\"engines\":{\"node\":\">=4.0\"},\"homepage\":\"https://github.com/estools/esrecurse\",\"license\":\"BSD-2-Clause\",\"main\":\"esrecurse.js\",\"maintainers\":[{\"name\":\"Yusuke Suzuki\",\"email\":\"utatane.tea@gmail.com\",\"url\":\"https://github.com/Constellation\"}],\"name\":\"esrecurse\",\"repository\":{\"type\":\"git\",\"url\":\"git+https://github.com/estools/esrecurse.git\"},\"scripts\":{\"lint\":\"gulp lint\",\"test\":\"gulp travis\",\"unit-test\":\"gulp test\"},\"version\":\"4.2.1\"}");
 
 /***/ }),
 /* 390 */
@@ -20178,7 +20188,7 @@ module.exports = PatternVisitor;
 /* 391 */
 /***/ (function(module) {
 
-module.exports = JSON.parse("{\"_from\":\"eslint-scope@^5.0.0\",\"_id\":\"eslint-scope@5.0.0\",\"_inBundle\":false,\"_integrity\":\"sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==\",\"_location\":\"/eslint-scope\",\"_phantomChildren\":{},\"_requested\":{\"type\":\"range\",\"registry\":true,\"raw\":\"eslint-scope@^5.0.0\",\"name\":\"eslint-scope\",\"escapedName\":\"eslint-scope\",\"rawSpec\":\"^5.0.0\",\"saveSpec\":null,\"fetchSpec\":\"^5.0.0\"},\"_requiredBy\":[\"/\",\"/eslint\"],\"_resolved\":\"https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz\",\"_shasum\":\"e87c8887c73e8d1ec84f1ca591645c358bfc8fb9\",\"_spec\":\"eslint-scope@^5.0.0\",\"_where\":\"/root/sources/pve/pve-eslint/eslint-v7.1.0\",\"bugs\":{\"url\":\"https://github.com/eslint/eslint-scope/issues\"},\"bundleDependencies\":false,\"dependencies\":{\"esrecurse\":\"^4.1.0\",\"estraverse\":\"^4.1.1\"},\"deprecated\":false,\"description\":\"ECMAScript scope analyzer for ESLint\",\"devDependencies\":{\"@typescript-eslint/parser\":\"^1.11.0\",\"chai\":\"^4.2.0\",\"eslint\":\"^6.0.1\",\"eslint-config-eslint\":\"^5.0.1\",\"eslint-plugin-node\":\"^9.1.0\",\"eslint-release\":\"^1.0.0\",\"espree\":\"^6.0.0\",\"istanbul\":\"^0.4.5\",\"mocha\":\"^6.1.4\",\"npm-license\":\"^0.3.3\",\"shelljs\":\"^0.8.3\",\"typescript\":\"^3.5.2\"},\"engines\":{\"node\":\">=8.0.0\"},\"files\":[\"LICENSE\",\"README.md\",\"lib\"],\"homepage\":\"http://github.com/eslint/eslint-scope\",\"license\":\"BSD-2-Clause\",\"main\":\"lib/index.js\",\"name\":\"eslint-scope\",\"repository\":{\"type\":\"git\",\"url\":\"git+https://github.com/eslint/eslint-scope.git\"},\"scripts\":{\"generate-alpharelease\":\"eslint-generate-prerelease alpha\",\"generate-betarelease\":\"eslint-generate-prerelease beta\",\"generate-rcrelease\":\"eslint-generate-prerelease rc\",\"generate-release\":\"eslint-generate-release\",\"lint\":\"node Makefile.js lint\",\"publish-release\":\"eslint-publish-release\",\"test\":\"node Makefile.js test\"},\"version\":\"5.0.0\"}");
+module.exports = JSON.parse("{\"_from\":\"eslint-scope@^5.1.0\",\"_id\":\"eslint-scope@5.1.0\",\"_inBundle\":false,\"_integrity\":\"sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==\",\"_location\":\"/eslint-scope\",\"_phantomChildren\":{},\"_requested\":{\"type\":\"range\",\"registry\":true,\"raw\":\"eslint-scope@^5.1.0\",\"name\":\"eslint-scope\",\"escapedName\":\"eslint-scope\",\"rawSpec\":\"^5.1.0\",\"saveSpec\":null,\"fetchSpec\":\"^5.1.0\"},\"_requiredBy\":[\"/\",\"/eslint\"],\"_resolved\":\"https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz\",\"_shasum\":\"d0f971dfe59c69e0cada684b23d49dbf82600ce5\",\"_spec\":\"eslint-scope@^5.1.0\",\"_where\":\"/root/sources/pve/pve-eslint/eslint-v7.2.0\",\"bugs\":{\"url\":\"https://github.com/eslint/eslint-scope/issues\"},\"bundleDependencies\":false,\"dependencies\":{\"esrecurse\":\"^4.1.0\",\"estraverse\":\"^4.1.1\"},\"deprecated\":false,\"description\":\"ECMAScript scope analyzer for ESLint\",\"devDependencies\":{\"@typescript-eslint/parser\":\"^1.11.0\",\"chai\":\"^4.2.0\",\"eslint\":\"^6.0.1\",\"eslint-config-eslint\":\"^5.0.1\",\"eslint-plugin-node\":\"^9.1.0\",\"eslint-release\":\"^1.0.0\",\"eslint-visitor-keys\":\"^1.2.0\",\"espree\":\"^7.1.0\",\"istanbul\":\"^0.4.5\",\"mocha\":\"^6.1.4\",\"npm-license\":\"^0.3.3\",\"shelljs\":\"^0.8.3\",\"typescript\":\"^3.5.2\"},\"engines\":{\"node\":\">=8.0.0\"},\"files\":[\"LICENSE\",\"README.md\",\"lib\"],\"homepage\":\"http://github.com/eslint/eslint-scope\",\"license\":\"BSD-2-Clause\",\"main\":\"lib/index.js\",\"name\":\"eslint-scope\",\"repository\":{\"type\":\"git\",\"url\":\"git+https://github.com/eslint/eslint-scope.git\"},\"scripts\":{\"generate-alpharelease\":\"eslint-generate-prerelease alpha\",\"generate-betarelease\":\"eslint-generate-prerelease beta\",\"generate-rcrelease\":\"eslint-generate-prerelease rc\",\"generate-release\":\"eslint-generate-release\",\"lint\":\"node Makefile.js lint\",\"publish-release\":\"eslint-publish-release\",\"test\":\"node Makefile.js test\"},\"version\":\"5.1.0\"}");
 
 /***/ }),
 /* 392 */
@@ -20266,7 +20276,7 @@ module.exports = Object.freeze({
 /* 393 */
 /***/ (function(module) {
 
-module.exports = JSON.parse("{\"AssignmentExpression\":[\"left\",\"right\"],\"AssignmentPattern\":[\"left\",\"right\"],\"ArrayExpression\":[\"elements\"],\"ArrayPattern\":[\"elements\"],\"ArrowFunctionExpression\":[\"params\",\"body\"],\"AwaitExpression\":[\"argument\"],\"BlockStatement\":[\"body\"],\"BinaryExpression\":[\"left\",\"right\"],\"BreakStatement\":[\"label\"],\"CallExpression\":[\"callee\",\"arguments\"],\"CatchClause\":[\"param\",\"body\"],\"ClassBody\":[\"body\"],\"ClassDeclaration\":[\"id\",\"superClass\",\"body\"],\"ClassExpression\":[\"id\",\"superClass\",\"body\"],\"ConditionalExpression\":[\"test\",\"consequent\",\"alternate\"],\"ContinueStatement\":[\"label\"],\"DebuggerStatement\":[],\"DoWhileStatement\":[\"body\",\"test\"],\"EmptyStatement\":[],\"ExportAllDeclaration\":[\"source\"],\"ExportDefaultDeclaration\":[\"declaration\"],\"ExportNamedDeclaration\":[\"declaration\",\"specifiers\",\"source\"],\"ExportSpecifier\":[\"exported\",\"local\"],\"ExpressionStatement\":[\"expression\"],\"ExperimentalRestProperty\":[\"argument\"],\"ExperimentalSpreadProperty\":[\"argument\"],\"ForStatement\":[\"init\",\"test\",\"update\",\"body\"],\"ForInStatement\":[\"left\",\"right\",\"body\"],\"ForOfStatement\":[\"left\",\"right\",\"body\"],\"FunctionDeclaration\":[\"id\",\"params\",\"body\"],\"FunctionExpression\":[\"id\",\"params\",\"body\"],\"Identifier\":[],\"IfStatement\":[\"test\",\"consequent\",\"alternate\"],\"ImportDeclaration\":[\"specifiers\",\"source\"],\"ImportDefaultSpecifier\":[\"local\"],\"ImportExpression\":[\"source\"],\"ImportNamespaceSpecifier\":[\"local\"],\"ImportSpecifier\":[\"imported\",\"local\"],\"JSXAttribute\":[\"name\",\"value\"],\"JSXClosingElement\":[\"name\"],\"JSXElement\":[\"openingElement\",\"children\",\"closingElement\"],\"JSXEmptyExpression\":[],\"JSXExpressionContainer\":[\"expression\"],\"JSXIdentifier\":[],\"JSXMemberExpression\":[\"object\",\"property\"],\"JSXNamespacedName\":[\"namespace\",\"name\"],\"JSXOpeningElement\":[\"name\",\"attributes\"],\"JSXSpreadAttribute\":[\"argument\"],\"JSXText\":[],\"JSXFragment\":[\"openingFragment\",\"children\",\"closingFragment\"],\"Literal\":[],\"LabeledStatement\":[\"label\",\"body\"],\"LogicalExpression\":[\"left\",\"right\"],\"MemberExpression\":[\"object\",\"property\"],\"MetaProperty\":[\"meta\",\"property\"],\"MethodDefinition\":[\"key\",\"value\"],\"NewExpression\":[\"callee\",\"arguments\"],\"ObjectExpression\":[\"properties\"],\"ObjectPattern\":[\"properties\"],\"Program\":[\"body\"],\"Property\":[\"key\",\"value\"],\"RestElement\":[\"argument\"],\"ReturnStatement\":[\"argument\"],\"SequenceExpression\":[\"expressions\"],\"SpreadElement\":[\"argument\"],\"Super\":[],\"SwitchStatement\":[\"discriminant\",\"cases\"],\"SwitchCase\":[\"test\",\"consequent\"],\"TaggedTemplateExpression\":[\"tag\",\"quasi\"],\"TemplateElement\":[],\"TemplateLiteral\":[\"quasis\",\"expressions\"],\"ThisExpression\":[],\"ThrowStatement\":[\"argument\"],\"TryStatement\":[\"block\",\"handler\",\"finalizer\"],\"UnaryExpression\":[\"argument\"],\"UpdateExpression\":[\"argument\"],\"VariableDeclaration\":[\"declarations\"],\"VariableDeclarator\":[\"id\",\"init\"],\"WhileStatement\":[\"test\",\"body\"],\"WithStatement\":[\"object\",\"body\"],\"YieldExpression\":[\"argument\"]}");
+module.exports = JSON.parse("{\"AssignmentExpression\":[\"left\",\"right\"],\"AssignmentPattern\":[\"left\",\"right\"],\"ArrayExpression\":[\"elements\"],\"ArrayPattern\":[\"elements\"],\"ArrowFunctionExpression\":[\"params\",\"body\"],\"AwaitExpression\":[\"argument\"],\"BlockStatement\":[\"body\"],\"BinaryExpression\":[\"left\",\"right\"],\"BreakStatement\":[\"label\"],\"CallExpression\":[\"callee\",\"arguments\"],\"CatchClause\":[\"param\",\"body\"],\"ClassBody\":[\"body\"],\"ClassDeclaration\":[\"id\",\"superClass\",\"body\"],\"ClassExpression\":[\"id\",\"superClass\",\"body\"],\"ConditionalExpression\":[\"test\",\"consequent\",\"alternate\"],\"ContinueStatement\":[\"label\"],\"DebuggerStatement\":[],\"DoWhileStatement\":[\"body\",\"test\"],\"EmptyStatement\":[],\"ExportAllDeclaration\":[\"exported\",\"source\"],\"ExportDefaultDeclaration\":[\"declaration\"],\"ExportNamedDeclaration\":[\"declaration\",\"specifiers\",\"source\"],\"ExportSpecifier\":[\"exported\",\"local\"],\"ExpressionStatement\":[\"expression\"],\"ExperimentalRestProperty\":[\"argument\"],\"ExperimentalSpreadProperty\":[\"argument\"],\"ForStatement\":[\"init\",\"test\",\"update\",\"body\"],\"ForInStatement\":[\"left\",\"right\",\"body\"],\"ForOfStatement\":[\"left\",\"right\",\"body\"],\"FunctionDeclaration\":[\"id\",\"params\",\"body\"],\"FunctionExpression\":[\"id\",\"params\",\"body\"],\"Identifier\":[],\"IfStatement\":[\"test\",\"consequent\",\"alternate\"],\"ImportDeclaration\":[\"specifiers\",\"source\"],\"ImportDefaultSpecifier\":[\"local\"],\"ImportExpression\":[\"source\"],\"ImportNamespaceSpecifier\":[\"local\"],\"ImportSpecifier\":[\"imported\",\"local\"],\"JSXAttribute\":[\"name\",\"value\"],\"JSXClosingElement\":[\"name\"],\"JSXElement\":[\"openingElement\",\"children\",\"closingElement\"],\"JSXEmptyExpression\":[],\"JSXExpressionContainer\":[\"expression\"],\"JSXIdentifier\":[],\"JSXMemberExpression\":[\"object\",\"property\"],\"JSXNamespacedName\":[\"namespace\",\"name\"],\"JSXOpeningElement\":[\"name\",\"attributes\"],\"JSXSpreadAttribute\":[\"argument\"],\"JSXText\":[],\"JSXFragment\":[\"openingFragment\",\"children\",\"closingFragment\"],\"Literal\":[],\"LabeledStatement\":[\"label\",\"body\"],\"LogicalExpression\":[\"left\",\"right\"],\"MemberExpression\":[\"object\",\"property\"],\"MetaProperty\":[\"meta\",\"property\"],\"MethodDefinition\":[\"key\",\"value\"],\"NewExpression\":[\"callee\",\"arguments\"],\"ObjectExpression\":[\"properties\"],\"ObjectPattern\":[\"properties\"],\"Program\":[\"body\"],\"Property\":[\"key\",\"value\"],\"RestElement\":[\"argument\"],\"ReturnStatement\":[\"argument\"],\"SequenceExpression\":[\"expressions\"],\"SpreadElement\":[\"argument\"],\"Super\":[],\"SwitchStatement\":[\"discriminant\",\"cases\"],\"SwitchCase\":[\"test\",\"consequent\"],\"TaggedTemplateExpression\":[\"tag\",\"quasi\"],\"TemplateElement\":[],\"TemplateLiteral\":[\"quasis\",\"expressions\"],\"ThisExpression\":[],\"ThrowStatement\":[\"argument\"],\"TryStatement\":[\"block\",\"handler\",\"finalizer\"],\"UnaryExpression\":[\"argument\"],\"UpdateExpression\":[\"argument\"],\"VariableDeclaration\":[\"declarations\"],\"VariableDeclarator\":[\"id\",\"init\"],\"WhileStatement\":[\"test\",\"body\"],\"WithStatement\":[\"object\",\"body\"],\"YieldExpression\":[\"argument\"]}");
 
 /***/ }),
 /* 394 */
@@ -28593,7 +28603,7 @@ module.exports = {
 /* 402 */
 /***/ (function(module) {
 
-module.exports = JSON.parse("{\"_from\":\"espree@^7.0.0\",\"_id\":\"espree@7.0.0\",\"_inBundle\":false,\"_integrity\":\"sha512-/r2XEx5Mw4pgKdyb7GNLQNsu++asx/dltf/CI8RFi9oGHxmQFgvLbc5Op4U6i8Oaj+kdslhJtVlEZeAqH5qOTw==\",\"_location\":\"/espree\",\"_phantomChildren\":{},\"_requested\":{\"type\":\"range\",\"registry\":true,\"raw\":\"espree@^7.0.0\",\"name\":\"espree\",\"escapedName\":\"espree\",\"rawSpec\":\"^7.0.0\",\"saveSpec\":null,\"fetchSpec\":\"^7.0.0\"},\"_requiredBy\":[\"/\",\"/eslint\"],\"_resolved\":\"https://registry.npmjs.org/espree/-/espree-7.0.0.tgz\",\"_shasum\":\"8a7a60f218e69f120a842dc24c5a88aa7748a74e\",\"_spec\":\"espree@^7.0.0\",\"_where\":\"/root/sources/pve/pve-eslint/eslint-v7.1.0\",\"author\":{\"name\":\"Nicholas C. Zakas\",\"email\":\"nicholas+npm@nczconsulting.com\"},\"bugs\":{\"url\":\"http://github.com/eslint/espree.git\"},\"bundleDependencies\":false,\"dependencies\":{\"acorn\":\"^7.1.1\",\"acorn-jsx\":\"^5.2.0\",\"eslint-visitor-keys\":\"^1.1.0\"},\"deprecated\":false,\"description\":\"An Esprima-compatible JavaScript parser built on Acorn\",\"devDependencies\":{\"browserify\":\"^16.5.0\",\"chai\":\"^4.2.0\",\"eslint\":\"^6.0.1\",\"eslint-config-eslint\":\"^5.0.1\",\"eslint-plugin-node\":\"^9.1.0\",\"eslint-release\":\"^1.0.0\",\"esprima\":\"latest\",\"esprima-fb\":\"^8001.2001.0-dev-harmony-fb\",\"json-diff\":\"^0.5.4\",\"leche\":\"^2.3.0\",\"mocha\":\"^6.2.0\",\"nyc\":\"^14.1.1\",\"regenerate\":\"^1.4.0\",\"shelljs\":\"^0.3.0\",\"shelljs-nodecli\":\"^0.1.1\",\"unicode-6.3.0\":\"^0.7.5\"},\"engines\":{\"node\":\"^10.12.0 || >=12.0.0\"},\"files\":[\"lib\",\"espree.js\"],\"homepage\":\"https://github.com/eslint/espree\",\"keywords\":[\"ast\",\"ecmascript\",\"javascript\",\"parser\",\"syntax\",\"acorn\"],\"license\":\"BSD-2-Clause\",\"main\":\"espree.js\",\"name\":\"espree\",\"repository\":{\"type\":\"git\",\"url\":\"git+https://github.com/eslint/espree.git\"},\"scripts\":{\"browserify\":\"node Makefile.js browserify\",\"generate-alpharelease\":\"eslint-generate-prerelease alpha\",\"generate-betarelease\":\"eslint-generate-prerelease beta\",\"generate-rcrelease\":\"eslint-generate-prerelease rc\",\"generate-regex\":\"node tools/generate-identifier-regex.js\",\"generate-release\":\"eslint-generate-release\",\"lint\":\"node Makefile.js lint\",\"publish-release\":\"eslint-publish-release\",\"sync-docs\":\"node Makefile.js docs\",\"test\":\"npm run-script lint && node Makefile.js test\"},\"version\":\"7.0.0\"}");
+module.exports = JSON.parse("{\"_from\":\"espree@^7.1.0\",\"_id\":\"espree@7.1.0\",\"_inBundle\":false,\"_integrity\":\"sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==\",\"_location\":\"/espree\",\"_phantomChildren\":{},\"_requested\":{\"type\":\"range\",\"registry\":true,\"raw\":\"espree@^7.1.0\",\"name\":\"espree\",\"escapedName\":\"espree\",\"rawSpec\":\"^7.1.0\",\"saveSpec\":null,\"fetchSpec\":\"^7.1.0\"},\"_requiredBy\":[\"/\",\"/eslint\"],\"_resolved\":\"https://registry.npmjs.org/espree/-/espree-7.1.0.tgz\",\"_shasum\":\"a9c7f18a752056735bf1ba14cb1b70adc3a5ce1c\",\"_spec\":\"espree@^7.1.0\",\"_where\":\"/root/sources/pve/pve-eslint/eslint-v7.2.0\",\"author\":{\"name\":\"Nicholas C. Zakas\",\"email\":\"nicholas+npm@nczconsulting.com\"},\"bugs\":{\"url\":\"http://github.com/eslint/espree.git\"},\"bundleDependencies\":false,\"dependencies\":{\"acorn\":\"^7.2.0\",\"acorn-jsx\":\"^5.2.0\",\"eslint-visitor-keys\":\"^1.2.0\"},\"deprecated\":false,\"description\":\"An Esprima-compatible JavaScript parser built on Acorn\",\"devDependencies\":{\"browserify\":\"^16.5.0\",\"chai\":\"^4.2.0\",\"eslint\":\"^6.0.1\",\"eslint-config-eslint\":\"^5.0.1\",\"eslint-plugin-node\":\"^9.1.0\",\"eslint-release\":\"^1.0.0\",\"esprima\":\"latest\",\"esprima-fb\":\"^8001.2001.0-dev-harmony-fb\",\"json-diff\":\"^0.5.4\",\"leche\":\"^2.3.0\",\"mocha\":\"^6.2.0\",\"nyc\":\"^14.1.1\",\"regenerate\":\"^1.4.0\",\"shelljs\":\"^0.3.0\",\"shelljs-nodecli\":\"^0.1.1\",\"unicode-6.3.0\":\"^0.7.5\"},\"engines\":{\"node\":\"^10.12.0 || >=12.0.0\"},\"files\":[\"lib\",\"espree.js\"],\"homepage\":\"https://github.com/eslint/espree\",\"keywords\":[\"ast\",\"ecmascript\",\"javascript\",\"parser\",\"syntax\",\"acorn\"],\"license\":\"BSD-2-Clause\",\"main\":\"espree.js\",\"name\":\"espree\",\"repository\":{\"type\":\"git\",\"url\":\"git+https://github.com/eslint/espree.git\"},\"scripts\":{\"browserify\":\"node Makefile.js browserify\",\"fixlint\":\"node Makefile.js lint --fix\",\"generate-alpharelease\":\"eslint-generate-prerelease alpha\",\"generate-betarelease\":\"eslint-generate-prerelease beta\",\"generate-rcrelease\":\"eslint-generate-prerelease rc\",\"generate-regex\":\"node tools/generate-identifier-regex.js\",\"generate-release\":\"eslint-generate-release\",\"lint\":\"node Makefile.js lint\",\"publish-release\":\"eslint-publish-release\",\"sync-docs\":\"node Makefile.js docs\",\"test\":\"npm run-script lint && node Makefile.js test\"},\"version\":\"7.1.0\"}");
 
 /***/ }),
 /* 403 */
@@ -45929,7 +45939,7 @@ module.exports = JSON.parse("{\"builtin\":{\"Array\":false,\"ArrayBuffer\":false
 /* 408 */
 /***/ (function(module) {
 
-module.exports = JSON.parse("{\"name\":\"eslint\",\"version\":\"7.1.0\",\"author\":\"Nicholas C. Zakas <nicholas+npm@nczconsulting.com>\",\"description\":\"An AST-based pattern checker for JavaScript.\",\"bin\":{\"eslint\":\"./bin/eslint.js\"},\"main\":\"./lib/api.js\",\"scripts\":{\"test\":\"node Makefile.js test\",\"test:cli\":\"mocha\",\"lint\":\"node Makefile.js lint\",\"fix\":\"node Makefile.js lint -- fix\",\"fuzz\":\"node Makefile.js fuzz\",\"generate-release\":\"node Makefile.js generateRelease\",\"generate-alpharelease\":\"node Makefile.js generatePrerelease -- alpha\",\"generate-betarelease\":\"node Makefile.js generatePrerelease -- beta\",\"generate-rcrelease\":\"node Makefile.js generatePrerelease -- rc\",\"publish-release\":\"node Makefile.js publishRelease\",\"docs\":\"node Makefile.js docs\",\"gensite\":\"node Makefile.js gensite\",\"webpack\":\"node Makefile.js webpack\",\"perf\":\"node Makefile.js perf\"},\"gitHooks\":{\"pre-commit\":\"lint-staged\"},\"lint-staged\":{\"*.js\":[\"eslint --fix\",\"git add\"],\"*.md\":\"markdownlint\"},\"files\":[\"LICENSE\",\"README.md\",\"bin\",\"conf\",\"lib\",\"messages\"],\"repository\":\"eslint/eslint\",\"funding\":\"https://opencollective.com/eslint\",\"homepage\":\"https://eslint.org\",\"bugs\":\"https://github.com/eslint/eslint/issues/\",\"dependencies\":{\"@babel/code-frame\":\"^7.0.0\",\"ajv\":\"^6.10.0\",\"chalk\":\"^4.0.0\",\"cross-spawn\":\"^7.0.2\",\"debug\":\"^4.0.1\",\"doctrine\":\"^3.0.0\",\"eslint-scope\":\"^5.0.0\",\"eslint-utils\":\"^2.0.0\",\"eslint-visitor-keys\":\"^1.1.0\",\"espree\":\"^7.0.0\",\"esquery\":\"^1.2.0\",\"esutils\":\"^2.0.2\",\"file-entry-cache\":\"^5.0.1\",\"functional-red-black-tree\":\"^1.0.1\",\"glob-parent\":\"^5.0.0\",\"globals\":\"^12.1.0\",\"ignore\":\"^4.0.6\",\"import-fresh\":\"^3.0.0\",\"imurmurhash\":\"^0.1.4\",\"inquirer\":\"^7.0.0\",\"is-glob\":\"^4.0.0\",\"js-yaml\":\"^3.13.1\",\"json-stable-stringify-without-jsonify\":\"^1.0.1\",\"levn\":\"^0.4.1\",\"lodash\":\"^4.17.14\",\"minimatch\":\"^3.0.4\",\"natural-compare\":\"^1.4.0\",\"optionator\":\"^0.9.1\",\"progress\":\"^2.0.0\",\"regexpp\":\"^3.1.0\",\"semver\":\"^7.2.1\",\"strip-ansi\":\"^6.0.0\",\"strip-json-comments\":\"^3.1.0\",\"table\":\"^5.2.3\",\"text-table\":\"^0.2.0\",\"v8-compile-cache\":\"^2.0.3\"},\"devDependencies\":{\"@babel/core\":\"^7.4.3\",\"@babel/preset-env\":\"^7.4.3\",\"acorn\":\"^7.1.1\",\"babel-loader\":\"^8.0.5\",\"chai\":\"^4.0.1\",\"cheerio\":\"^0.22.0\",\"common-tags\":\"^1.8.0\",\"core-js\":\"^3.1.3\",\"dateformat\":\"^3.0.3\",\"ejs\":\"^3.0.2\",\"escape-string-regexp\":\"^3.0.0\",\"eslint\":\"file:.\",\"eslint-config-eslint\":\"file:packages/eslint-config-eslint\",\"eslint-plugin-eslint-plugin\":\"^2.2.1\",\"eslint-plugin-internal-rules\":\"file:tools/internal-rules\",\"eslint-plugin-jsdoc\":\"^22.1.0\",\"eslint-plugin-node\":\"^11.1.0\",\"eslint-release\":\"^2.0.0\",\"eslump\":\"^2.0.0\",\"esprima\":\"^4.0.1\",\"glob\":\"^7.1.6\",\"jsdoc\":\"^3.5.5\",\"karma\":\"^4.0.1\",\"karma-chrome-launcher\":\"^3.1.0\",\"karma-mocha\":\"^1.3.0\",\"karma-mocha-reporter\":\"^2.2.3\",\"karma-webpack\":\"^4.0.0-rc.6\",\"leche\":\"^2.2.3\",\"lint-staged\":\"^10.1.2\",\"load-perf\":\"^0.2.0\",\"markdownlint\":\"^0.19.0\",\"markdownlint-cli\":\"^0.22.0\",\"memfs\":\"^3.0.1\",\"mocha\":\"^7.1.1\",\"mocha-junit-reporter\":\"^1.23.0\",\"npm-license\":\"^0.3.3\",\"nyc\":\"^15.0.1\",\"proxyquire\":\"^2.0.1\",\"puppeteer\":\"^2.1.1\",\"recast\":\"^0.19.0\",\"regenerator-runtime\":\"^0.13.2\",\"shelljs\":\"^0.8.2\",\"sinon\":\"^9.0.1\",\"temp\":\"^0.9.0\",\"webpack\":\"^4.35.0\",\"webpack-cli\":\"^3.3.5\",\"yorkie\":\"^2.0.0\"},\"keywords\":[\"ast\",\"lint\",\"javascript\",\"ecmascript\",\"espree\"],\"license\":\"MIT\",\"engines\":{\"node\":\"^10.12.0 || >=12.0.0\"}}");
+module.exports = JSON.parse("{\"name\":\"eslint\",\"version\":\"7.2.0\",\"author\":\"Nicholas C. Zakas <nicholas+npm@nczconsulting.com>\",\"description\":\"An AST-based pattern checker for JavaScript.\",\"bin\":{\"eslint\":\"./bin/eslint.js\"},\"main\":\"./lib/api.js\",\"scripts\":{\"test\":\"node Makefile.js test\",\"test:cli\":\"mocha\",\"lint\":\"node Makefile.js lint\",\"fix\":\"node Makefile.js lint -- fix\",\"fuzz\":\"node Makefile.js fuzz\",\"generate-release\":\"node Makefile.js generateRelease\",\"generate-alpharelease\":\"node Makefile.js generatePrerelease -- alpha\",\"generate-betarelease\":\"node Makefile.js generatePrerelease -- beta\",\"generate-rcrelease\":\"node Makefile.js generatePrerelease -- rc\",\"publish-release\":\"node Makefile.js publishRelease\",\"docs\":\"node Makefile.js docs\",\"gensite\":\"node Makefile.js gensite\",\"webpack\":\"node Makefile.js webpack\",\"perf\":\"node Makefile.js perf\"},\"gitHooks\":{\"pre-commit\":\"lint-staged\"},\"lint-staged\":{\"*.js\":[\"eslint --fix\",\"git add\"],\"*.md\":\"markdownlint\"},\"files\":[\"LICENSE\",\"README.md\",\"bin\",\"conf\",\"lib\",\"messages\"],\"repository\":\"eslint/eslint\",\"funding\":\"https://opencollective.com/eslint\",\"homepage\":\"https://eslint.org\",\"bugs\":\"https://github.com/eslint/eslint/issues/\",\"dependencies\":{\"@babel/code-frame\":\"^7.0.0\",\"ajv\":\"^6.10.0\",\"chalk\":\"^4.0.0\",\"cross-spawn\":\"^7.0.2\",\"debug\":\"^4.0.1\",\"doctrine\":\"^3.0.0\",\"eslint-scope\":\"^5.1.0\",\"eslint-utils\":\"^2.0.0\",\"eslint-visitor-keys\":\"^1.2.0\",\"espree\":\"^7.1.0\",\"esquery\":\"^1.2.0\",\"esutils\":\"^2.0.2\",\"file-entry-cache\":\"^5.0.1\",\"functional-red-black-tree\":\"^1.0.1\",\"glob-parent\":\"^5.0.0\",\"globals\":\"^12.1.0\",\"ignore\":\"^4.0.6\",\"import-fresh\":\"^3.0.0\",\"imurmurhash\":\"^0.1.4\",\"inquirer\":\"^7.0.0\",\"is-glob\":\"^4.0.0\",\"js-yaml\":\"^3.13.1\",\"json-stable-stringify-without-jsonify\":\"^1.0.1\",\"levn\":\"^0.4.1\",\"lodash\":\"^4.17.14\",\"minimatch\":\"^3.0.4\",\"natural-compare\":\"^1.4.0\",\"optionator\":\"^0.9.1\",\"progress\":\"^2.0.0\",\"regexpp\":\"^3.1.0\",\"semver\":\"^7.2.1\",\"strip-ansi\":\"^6.0.0\",\"strip-json-comments\":\"^3.1.0\",\"table\":\"^5.2.3\",\"text-table\":\"^0.2.0\",\"v8-compile-cache\":\"^2.0.3\"},\"devDependencies\":{\"@babel/core\":\"^7.4.3\",\"@babel/preset-env\":\"^7.4.3\",\"acorn\":\"^7.2.0\",\"babel-loader\":\"^8.0.5\",\"chai\":\"^4.0.1\",\"cheerio\":\"^0.22.0\",\"common-tags\":\"^1.8.0\",\"core-js\":\"^3.1.3\",\"dateformat\":\"^3.0.3\",\"ejs\":\"^3.0.2\",\"escape-string-regexp\":\"^3.0.0\",\"eslint\":\"file:.\",\"eslint-config-eslint\":\"file:packages/eslint-config-eslint\",\"eslint-plugin-eslint-plugin\":\"^2.2.1\",\"eslint-plugin-internal-rules\":\"file:tools/internal-rules\",\"eslint-plugin-jsdoc\":\"^22.1.0\",\"eslint-plugin-node\":\"^11.1.0\",\"eslint-release\":\"^2.0.0\",\"eslump\":\"^2.0.0\",\"esprima\":\"^4.0.1\",\"glob\":\"^7.1.6\",\"jsdoc\":\"^3.5.5\",\"karma\":\"^4.0.1\",\"karma-chrome-launcher\":\"^3.1.0\",\"karma-mocha\":\"^1.3.0\",\"karma-mocha-reporter\":\"^2.2.3\",\"karma-webpack\":\"^4.0.0-rc.6\",\"leche\":\"^2.2.3\",\"lint-staged\":\"^10.1.2\",\"load-perf\":\"^0.2.0\",\"markdownlint\":\"^0.19.0\",\"markdownlint-cli\":\"^0.22.0\",\"memfs\":\"^3.0.1\",\"mocha\":\"^7.1.1\",\"mocha-junit-reporter\":\"^1.23.0\",\"npm-license\":\"^0.3.3\",\"nyc\":\"^15.0.1\",\"proxyquire\":\"^2.0.1\",\"puppeteer\":\"^2.1.1\",\"recast\":\"^0.19.0\",\"regenerator-runtime\":\"^0.13.2\",\"shelljs\":\"^0.8.2\",\"sinon\":\"^9.0.1\",\"temp\":\"^0.9.0\",\"webpack\":\"^4.35.0\",\"webpack-cli\":\"^3.3.5\",\"yorkie\":\"^2.0.0\"},\"keywords\":[\"ast\",\"lint\",\"javascript\",\"ecmascript\",\"espree\"],\"license\":\"MIT\",\"engines\":{\"node\":\"^10.12.0 || >=12.0.0\"}}");
 
 /***/ }),
 /* 409 */
@@ -48734,6 +48744,50 @@ function equalTokens(left, right, sourceCode) {
   }
 
   return true;
+}
+/**
+ * Check if the given node is a true logical expression or not.
+ *
+ * The three binary expressions logical-or (`||`), logical-and (`&&`), and
+ * coalesce (`??`) are known as `ShortCircuitExpression`.
+ * But ESTree represents those by `LogicalExpression` node.
+ *
+ * This function rejects coalesce expressions of `LogicalExpression` node.
+ * @param {ASTNode} node The node to check.
+ * @returns {boolean} `true` if the node is `&&` or `||`.
+ * @see https://tc39.es/ecma262/#prod-ShortCircuitExpression
+ */
+
+
+function isLogicalExpression(node) {
+  return node.type === "LogicalExpression" && (node.operator === "&&" || node.operator === "||");
+}
+/**
+ * Check if the given node is a nullish coalescing expression or not.
+ *
+ * The three binary expressions logical-or (`||`), logical-and (`&&`), and
+ * coalesce (`??`) are known as `ShortCircuitExpression`.
+ * But ESTree represents those by `LogicalExpression` node.
+ *
+ * This function finds only coalesce expressions of `LogicalExpression` node.
+ * @param {ASTNode} node The node to check.
+ * @returns {boolean} `true` if the node is `??`.
+ */
+
+
+function isCoalesceExpression(node) {
+  return node.type === "LogicalExpression" && node.operator === "??";
+}
+/**
+ * Check if given two nodes are the pair of a logical expression and a coalesce expression.
+ * @param {ASTNode} left A node to check.
+ * @param {ASTNode} right Another node to check.
+ * @returns {boolean} `true` if the two nodes are the pair of a logical expression and a coalesce expression.
+ */
+
+
+function isMixedLogicalAndCoalesceExpressions(left, right) {
+  return isLogicalExpression(left) && isCoalesceExpression(right) || isCoalesceExpression(left) && isLogicalExpression(right);
 } //------------------------------------------------------------------------------
 // Public Interface
 //------------------------------------------------------------------------------
@@ -49071,6 +49125,7 @@ module.exports = {
       case "LogicalExpression":
         switch (node.operator) {
           case "||":
+          case "??":
             return 4;
 
           case "&&":
@@ -49697,7 +49752,7 @@ module.exports = {
 
       try {
         tokens = espree.tokenize(leftValue, espreeOptions);
-      } catch (e) {
+      } catch (_unused) {
         return false;
       }
 
@@ -49726,7 +49781,7 @@ module.exports = {
 
       try {
         tokens = espree.tokenize(rightValue, espreeOptions);
-      } catch (e) {
+      } catch (_unused2) {
         return false;
       }
 
@@ -49810,8 +49865,11 @@ module.exports = {
    */
   hasOctalEscapeSequence(rawString) {
     return OCTAL_ESCAPE_PATTERN.test(rawString);
-  }
+  },
 
+  isLogicalExpression,
+  isCoalesceExpression,
+  isMixedLogicalAndCoalesceExpressions
 };
 
 /***/ }),
@@ -56731,7 +56789,13 @@ module.exports = {
       if (never && hasWhitespace) {
         context.report({
           node,
-          loc: leftToken.loc.start,
+          loc: {
+            start: leftToken.loc.end,
+            end: {
+              line: rightToken.loc.start.line,
+              column: rightToken.loc.start.column - 1
+            }
+          },
           messageId: "unexpectedWhitespace",
 
           fix(fixer) {
@@ -56750,7 +56814,13 @@ module.exports = {
       } else if (!never && !hasWhitespace) {
         context.report({
           node,
-          loc: leftToken.loc.start,
+          loc: {
+            start: {
+              line: leftToken.loc.end.line,
+              column: leftToken.loc.end.column - 1
+            },
+            end: rightToken.loc.start
+          },
           messageId: "missing",
 
           fix(fixer) {
@@ -56761,7 +56831,10 @@ module.exports = {
       } else if (!never && !allowNewlines && hasNewline) {
         context.report({
           node,
-          loc: leftToken.loc.start,
+          loc: {
+            start: leftToken.loc.end,
+            end: rightToken.loc.start
+          },
           messageId: "unexpectedNewline",
 
           fix(fixer) {
@@ -63931,7 +64004,10 @@ module.exports = {
 
       if (prevToken && (CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) && !isOpenParenOfTemplate(prevToken) && astUtils.isTokenOnSameLine(prevToken, token) && sourceCode.isSpaceBetweenTokens(prevToken, token)) {
         context.report({
-          loc: token.loc.start,
+          loc: {
+            start: prevToken.loc.end,
+            end: token.loc.start
+          },
           messageId: "unexpectedBefore",
           data: token,
 
@@ -63979,7 +64055,10 @@ module.exports = {
 
       if (nextToken && (CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) && !isCloseParenOfTemplate(nextToken) && astUtils.isTokenOnSameLine(token, nextToken) && sourceCode.isSpaceBetweenTokens(token, nextToken)) {
         context.report({
-          loc: token.loc.start,
+          loc: {
+            start: token.loc.end,
+            end: nextToken.loc.start
+          },
           messageId: "unexpectedAfter",
           data: token,
 
@@ -64228,6 +64307,11 @@ module.exports = {
         checkSpacingAround(sourceCode.getTokenAfter(firstToken));
       }
 
+      if (node.type === "ExportAllDeclaration" && node.exported) {
+        const asToken = sourceCode.getTokenBefore(node.exported);
+        checkSpacingBefore(asToken, PREV_TOKEN_M);
+      }
+
       if (node.source) {
         const fromToken = sourceCode.getTokenBefore(node.source);
         checkSpacingBefore(fromToken, PREV_TOKEN_M);
@@ -67354,41 +67438,44 @@ module.exports = {
   create(context) {
     const option = context.options[0];
     const multiline = option !== "never";
-    const allowSingleLine = option === "always-multiline"; //--------------------------------------------------------------------------
-    // Helpers
-    //--------------------------------------------------------------------------
-
-    /**
-     * Tests whether node is preceded by supplied tokens
-     * @param {ASTNode} node node to check
-     * @param {ASTNode} parentNode parent of node to report
-     * @param {boolean} expected whether newline was expected or not
-     * @returns {void}
-     * @private
-     */
-
-    function reportError(node, parentNode, expected) {
-      context.report({
-        node,
-        messageId: "".concat(expected ? "expected" : "unexpected").concat(node === parentNode.test ? "TestCons" : "ConsAlt")
-      });
-    } //--------------------------------------------------------------------------
+    const allowSingleLine = option === "always-multiline";
+    const sourceCode = context.getSourceCode(); //--------------------------------------------------------------------------
     // Public
     //--------------------------------------------------------------------------
 
-
     return {
       ConditionalExpression(node) {
-        const areTestAndConsequentOnSameLine = astUtils.isTokenOnSameLine(node.test, node.consequent);
-        const areConsequentAndAlternateOnSameLine = astUtils.isTokenOnSameLine(node.consequent, node.alternate);
+        const questionToken = sourceCode.getTokenAfter(node.test, astUtils.isNotClosingParenToken);
+        const colonToken = sourceCode.getTokenAfter(node.consequent, astUtils.isNotClosingParenToken);
+        const firstTokenOfTest = sourceCode.getFirstToken(node);
+        const lastTokenOfTest = sourceCode.getTokenBefore(questionToken);
+        const firstTokenOfConsequent = sourceCode.getTokenAfter(questionToken);
+        const lastTokenOfConsequent = sourceCode.getTokenBefore(colonToken);
+        const firstTokenOfAlternate = sourceCode.getTokenAfter(colonToken);
+        const areTestAndConsequentOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfTest, firstTokenOfConsequent);
+        const areConsequentAndAlternateOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfConsequent, firstTokenOfAlternate);
 
         if (!multiline) {
           if (!areTestAndConsequentOnSameLine) {
-            reportError(node.test, node, false);
+            context.report({
+              node: node.test,
+              loc: {
+                start: firstTokenOfTest.loc.start,
+                end: lastTokenOfTest.loc.end
+              },
+              messageId: "unexpectedTestCons"
+            });
           }
 
           if (!areConsequentAndAlternateOnSameLine) {
-            reportError(node.consequent, node, false);
+            context.report({
+              node: node.consequent,
+              loc: {
+                start: firstTokenOfConsequent.loc.start,
+                end: lastTokenOfConsequent.loc.end
+              },
+              messageId: "unexpectedConsAlt"
+            });
           }
         } else {
           if (allowSingleLine && node.loc.start.line === node.loc.end.line) {
@@ -67396,11 +67483,25 @@ module.exports = {
           }
 
           if (areTestAndConsequentOnSameLine) {
-            reportError(node.test, node, true);
+            context.report({
+              node: node.test,
+              loc: {
+                start: firstTokenOfTest.loc.start,
+                end: lastTokenOfTest.loc.end
+              },
+              messageId: "expectedTestCons"
+            });
           }
 
           if (areConsequentAndAlternateOnSameLine) {
-            reportError(node.consequent, node, true);
+            context.report({
+              node: node.consequent,
+              loc: {
+                start: firstTokenOfConsequent.loc.start,
+                end: lastTokenOfConsequent.loc.end
+              },
+              messageId: "expectedConsAlt"
+            });
           }
         }
       }
@@ -69978,7 +70079,7 @@ const collector = new class {
 
       this._validator.validatePattern(regexpStr); // Call onCharacter hook
 
-    } catch (err) {// Ignore syntax errors in RegExp.
+    } catch (_unused) {// Ignore syntax errors in RegExp.
     }
 
     return this._controlChars;
@@ -75048,6 +75149,10 @@ module.exports = {
           return precedence(node) < precedence(parent);
 
         case "LogicalExpression":
+          if (astUtils.isMixedLogicalAndCoalesceExpressions(node, parent)) {
+            return true;
+          }
+
           if (previousNode === parent.left) {
             return precedence(node) < precedence(parent);
           }
@@ -77251,6 +77356,9 @@ module.exports = {
             },
             enforceForNewInMemberExpressions: {
               type: "boolean"
+            },
+            enforceForFunctionPrototypeMethods: {
+              type: "boolean"
             }
           },
           additionalProperties: false
@@ -77276,6 +77384,7 @@ module.exports = {
     const IGNORE_ARROW_CONDITIONALS = ALL_NODES && context.options[1] && context.options[1].enforceForArrowConditionals === false;
     const IGNORE_SEQUENCE_EXPRESSIONS = ALL_NODES && context.options[1] && context.options[1].enforceForSequenceExpressions === false;
     const IGNORE_NEW_IN_MEMBER_EXPR = ALL_NODES && context.options[1] && context.options[1].enforceForNewInMemberExpressions === false;
+    const IGNORE_FUNCTION_PROTOTYPE_METHODS = ALL_NODES && context.options[1] && context.options[1].enforceForFunctionPrototypeMethods === false;
     const PRECEDENCE_OF_ASSIGNMENT_EXPR = precedence({
       type: "AssignmentExpression"
     });
@@ -77283,6 +77392,17 @@ module.exports = {
       type: "UpdateExpression"
     });
     let reportsBuffer;
+    /**
+     * Determines whether the given node is a `call` or `apply` method call, invoked directly on a `FunctionExpression` node.
+     * Example: function(){}.call()
+     * @param {ASTNode} node The node to be checked.
+     * @returns {boolean} True if the node is an immediate `call` or `apply` method call.
+     * @private
+     */
+
+    function isImmediateFunctionPrototypeMethodCall(node) {
+      return node.type === "CallExpression" && node.callee.type === "MemberExpression" && node.callee.object.type === "FunctionExpression" && ["call", "apply"].includes(astUtils.getStaticPropertyName(node.callee));
+    }
     /**
      * Determines if this rule should be enforced for a node given the current configuration.
      * @param {ASTNode} node The node to be checked.
@@ -77290,6 +77410,7 @@ module.exports = {
      * @private
      */
 
+
     function ruleApplies(node) {
       if (node.type === "JSXElement" || node.type === "JSXFragment") {
         const isSingleLine = node.loc.start.line === node.loc.end.line;
@@ -77318,6 +77439,10 @@ module.exports = {
         return false;
       }
 
+      if (isImmediateFunctionPrototypeMethodCall(node) && IGNORE_FUNCTION_PROTOTYPE_METHODS) {
+        return false;
+      }
+
       return ALL_NODES || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
     }
     /**
@@ -77670,13 +77795,13 @@ module.exports = {
       const shouldSkipRight = NESTED_BINARY && (node.right.type === "BinaryExpression" || node.right.type === "LogicalExpression");
 
       if (!shouldSkipLeft && hasExcessParens(node.left)) {
-        if (!(node.left.type === "UnaryExpression" && isExponentiation) && (leftPrecedence > prec || leftPrecedence === prec && !isExponentiation) || isParenthesisedTwice(node.left)) {
+        if (!(node.left.type === "UnaryExpression" && isExponentiation) && !astUtils.isMixedLogicalAndCoalesceExpressions(node.left, node) && (leftPrecedence > prec || leftPrecedence === prec && !isExponentiation) || isParenthesisedTwice(node.left)) {
           report(node.left);
         }
       }
 
       if (!shouldSkipRight && hasExcessParens(node.right)) {
-        if (rightPrecedence > prec || rightPrecedence === prec && isExponentiation || isParenthesisedTwice(node.right)) {
+        if (!astUtils.isMixedLogicalAndCoalesceExpressions(node.right, node) && (rightPrecedence > prec || rightPrecedence === prec && isExponentiation) || isParenthesisedTwice(node.right)) {
           report(node.right);
         }
       }
@@ -78093,7 +78218,7 @@ module.exports = {
       LogicalExpression: checkBinaryLogical,
 
       MemberExpression(node) {
-        const nodeObjHasExcessParens = hasExcessParens(node.object);
+        const nodeObjHasExcessParens = hasExcessParens(node.object) && !(isImmediateFunctionPrototypeMethodCall(node.parent) && node.parent.callee === node && IGNORE_FUNCTION_PROTOTYPE_METHODS);
 
         if (nodeObjHasExcessParens && precedence(node.object) >= precedence(node) && (node.computed || !(astUtils.isDecimalInteger(node.object) || // RegExp literal is allowed to have parens (#1589)
         node.object.type === "Literal" && node.object.regex))) {
@@ -79756,7 +79881,7 @@ module.exports = {
       try {
         validator.validateFlags(flags);
         return null;
-      } catch (err) {
+      } catch (_unused) {
         return "Invalid flags supplied to RegExp constructor '".concat(flags, "'");
       }
     }
@@ -81397,7 +81522,7 @@ module.exports = {
 
       try {
         patternNode = parser.parsePattern(pattern, 0, pattern.length, flags.includes("u"));
-      } catch (e) {
+      } catch (_unused) {
         // Ignore regular expressions with syntax errors
         return;
       }
@@ -81578,7 +81703,8 @@ const COMPARISON_OPERATORS = ["==", "!=", "===", "!==", ">", ">=", "<", "<="];
 const LOGICAL_OPERATORS = ["&&", "||"];
 const RELATIONAL_OPERATORS = ["in", "instanceof"];
 const TERNARY_OPERATOR = ["?:"];
-const ALL_OPERATORS = [].concat(ARITHMETIC_OPERATORS, BITWISE_OPERATORS, COMPARISON_OPERATORS, LOGICAL_OPERATORS, RELATIONAL_OPERATORS, TERNARY_OPERATOR);
+const COALESCE_OPERATOR = ["??"];
+const ALL_OPERATORS = [].concat(ARITHMETIC_OPERATORS, BITWISE_OPERATORS, COMPARISON_OPERATORS, LOGICAL_OPERATORS, RELATIONAL_OPERATORS, TERNARY_OPERATOR, COALESCE_OPERATOR);
 const DEFAULT_GROUPS = [ARITHMETIC_OPERATORS, BITWISE_OPERATORS, COMPARISON_OPERATORS, LOGICAL_OPERATORS, RELATIONAL_OPERATORS];
 const TARGET_NODE_TYPE = /^(?:Binary|Logical|Conditional)Expression$/u;
 /**
@@ -82038,29 +82164,34 @@ module.exports = {
          * characters begin.
          */
 
-        let regex = /^(?=[\t ]*(\t | \t))/u;
+        let regex = /^(?=( +|\t+))\1(?:\t| )/u;
 
         if (smartTabs) {
           /*
            * At least one space followed by a tab
            * before non-tab/-space characters begin.
            */
-          regex = /^(?=[\t ]* \t)/u;
+          regex = /^(?=(\t*))\1(?=( +))\2\t/u;
         }
 
         lines.forEach((line, i) => {
           const match = regex.exec(line);
 
           if (match) {
-            const lineNumber = i + 1,
-                  column = match.index + 1,
-                  loc = {
-              line: lineNumber,
-              column
+            const lineNumber = i + 1;
+            const loc = {
+              start: {
+                line: lineNumber,
+                column: match[0].length - 2
+              },
+              end: {
+                line: lineNumber,
+                column: match[0].length
+              }
             };
 
             if (!ignoredCommentLines.has(lineNumber)) {
-              const containingNode = sourceCode.getNodeByRangeIndex(sourceCode.getIndexFromLoc(loc));
+              const containingNode = sourceCode.getNodeByRangeIndex(sourceCode.getIndexFromLoc(loc.start));
 
               if (!(containingNode && ["Literal", "TemplateElement"].includes(containingNode.type))) {
                 context.report({
@@ -84084,7 +84215,7 @@ module.exports = {
 
       try {
         regExpAST = regExpParser.parsePattern(pattern, 0, pattern.length, flags.includes("u"));
-      } catch (e) {
+      } catch (_unused) {
         // Ignore regular expressions with syntax errors
         return;
       }
@@ -84244,6 +84375,12 @@ module.exports = {
     }
 
     return {
+      ExportAllDeclaration(node) {
+        if (node.exported) {
+          checkExportedName(node.exported);
+        }
+      },
+
       ExportNamedDeclaration(node) {
         const declaration = node.declaration;
 
@@ -88646,7 +88783,7 @@ module.exports = {
             loc: node.consequent.loc.start,
             messageId: "unnecessaryConditionalAssignment",
             fix: fixer => {
-              const shouldParenthesizeAlternate = astUtils.getPrecedence(node.alternate) < OR_PRECEDENCE && !astUtils.isParenthesised(sourceCode, node.alternate);
+              const shouldParenthesizeAlternate = (astUtils.getPrecedence(node.alternate) < OR_PRECEDENCE || astUtils.isCoalesceExpression(node.alternate)) && !astUtils.isParenthesised(sourceCode, node.alternate);
               const alternateText = shouldParenthesizeAlternate ? "(".concat(sourceCode.getText(node.alternate), ")") : astUtils.getParenthesisedText(sourceCode, node.alternate);
               const testText = astUtils.getParenthesisedText(sourceCode, node.test);
               return fixer.replaceText(node, "".concat(testText, " || ").concat(alternateText));
@@ -89245,7 +89382,7 @@ module.exports = {
         return true;
       }
 
-      return /^(?:Assignment|Call|New|Update|Yield|Await)Expression$/u.test(node.type) || node.type === "UnaryExpression" && ["delete", "void"].indexOf(node.operator) >= 0;
+      return /^(?:Assignment|Call|New|Update|Yield|Await|Import)Expression$/u.test(node.type) || node.type === "UnaryExpression" && ["delete", "void"].indexOf(node.operator) >= 0;
     }
 
     return {
@@ -89953,7 +90090,7 @@ module.exports = {
 
           if (unusedVar.defs.length > 0) {
             context.report({
-              node: unusedVar.identifiers[0],
+              node: unusedVar.references.length ? unusedVar.references[unusedVar.references.length - 1].identifier : unusedVar.identifiers[0],
               messageId: "unusedVar",
               data: unusedVar.references.some(ref => ref.isWrite()) ? getAssignedMessageData(unusedVar) : getDefinedMessageData(unusedVar)
             }); // If there are no regular declaration, report the first `/*globals*/` comment directive.
@@ -90314,7 +90451,7 @@ module.exports = {
 
       try {
         regExpAST = parser.parsePattern(pattern, 0, pattern.length, flags.includes("u"));
-      } catch (e) {
+      } catch (_unused) {
         // Ignore regular expressions with syntax errors
         return;
       }
@@ -96987,7 +97124,7 @@ module.exports = {
 
       try {
         ast = parser.parsePattern(pattern, 0, pattern.length, uFlag);
-      } catch (_) {
+      } catch (_unused) {
         // ignore regex syntax errors
         return;
       }
@@ -98456,7 +98593,7 @@ module.exports = {
 
         try {
           tokens = espree.tokenize(key.value);
-        } catch (e) {
+        } catch (_unused) {
           return;
         }
 
@@ -98549,7 +98686,7 @@ module.exports = {
 
             try {
               tokens = espree.tokenize(key.value);
-            } catch (e) {
+            } catch (_unused2) {
               necessaryQuotes = true;
               return;
             }
@@ -103439,7 +103576,10 @@ module.exports = {
       if (never && hasWhitespace) {
         context.report({
           node,
-          loc: tagToken.loc.start,
+          loc: {
+            start: tagToken.loc.end,
+            end: literalToken.loc.start
+          },
           messageId: "unexpected",
 
           fix(fixer) {
@@ -103456,7 +103596,10 @@ module.exports = {
       } else if (!never && !hasWhitespace) {
         context.report({
           node,
-          loc: tagToken.loc.start,
+          loc: {
+            start: node.loc.start,
+            end: literalToken.loc.start
+          },
           messageId: "missing",
 
           fix(fixer) {
@@ -106720,7 +106863,7 @@ module.exports = {
 /* 720 */
 /***/ (function(module) {
 
-module.exports = JSON.parse("{\"_from\":\"doctrine@^3.0.0\",\"_id\":\"doctrine@3.0.0\",\"_inBundle\":false,\"_integrity\":\"sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==\",\"_location\":\"/doctrine\",\"_phantomChildren\":{},\"_requested\":{\"type\":\"range\",\"registry\":true,\"raw\":\"doctrine@^3.0.0\",\"name\":\"doctrine\",\"escapedName\":\"doctrine\",\"rawSpec\":\"^3.0.0\",\"saveSpec\":null,\"fetchSpec\":\"^3.0.0\"},\"_requiredBy\":[\"/\",\"/eslint\"],\"_resolved\":\"https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz\",\"_shasum\":\"addebead72a6574db783639dc87a121773973961\",\"_spec\":\"doctrine@^3.0.0\",\"_where\":\"/root/sources/pve/pve-eslint/eslint-v7.1.0\",\"bugs\":{\"url\":\"https://github.com/eslint/doctrine/issues\"},\"bundleDependencies\":false,\"dependencies\":{\"esutils\":\"^2.0.2\"},\"deprecated\":false,\"description\":\"JSDoc parser\",\"devDependencies\":{\"coveralls\":\"^3.0.1\",\"dateformat\":\"^1.0.11\",\"eslint\":\"^1.10.3\",\"eslint-release\":\"^1.0.0\",\"linefix\":\"^0.1.1\",\"mocha\":\"^3.4.2\",\"npm-license\":\"^0.3.1\",\"nyc\":\"^10.3.2\",\"semver\":\"^5.0.3\",\"shelljs\":\"^0.5.3\",\"shelljs-nodecli\":\"^0.1.1\",\"should\":\"^5.0.1\"},\"directories\":{\"lib\":\"./lib\"},\"engines\":{\"node\":\">=6.0.0\"},\"files\":[\"lib\"],\"homepage\":\"https://github.com/eslint/doctrine\",\"license\":\"Apache-2.0\",\"main\":\"lib/doctrine.js\",\"maintainers\":[{\"name\":\"Nicholas C. Zakas\",\"email\":\"nicholas+npm@nczconsulting.com\",\"url\":\"https://www.nczonline.net\"},{\"name\":\"Yusuke Suzuki\",\"email\":\"utatane.tea@gmail.com\",\"url\":\"https://github.com/Constellation\"}],\"name\":\"doctrine\",\"repository\":{\"type\":\"git\",\"url\":\"git+https://github.com/eslint/doctrine.git\"},\"scripts\":{\"coveralls\":\"nyc report --reporter=text-lcov | coveralls\",\"generate-alpharelease\":\"eslint-generate-prerelease alpha\",\"generate-betarelease\":\"eslint-generate-prerelease beta\",\"generate-rcrelease\":\"eslint-generate-prerelease rc\",\"generate-release\":\"eslint-generate-release\",\"lint\":\"eslint lib/\",\"pretest\":\"npm run lint\",\"publish-release\":\"eslint-publish-release\",\"test\":\"nyc mocha\"},\"version\":\"3.0.0\"}");
+module.exports = JSON.parse("{\"_from\":\"doctrine@^3.0.0\",\"_id\":\"doctrine@3.0.0\",\"_inBundle\":false,\"_integrity\":\"sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==\",\"_location\":\"/doctrine\",\"_phantomChildren\":{},\"_requested\":{\"type\":\"range\",\"registry\":true,\"raw\":\"doctrine@^3.0.0\",\"name\":\"doctrine\",\"escapedName\":\"doctrine\",\"rawSpec\":\"^3.0.0\",\"saveSpec\":null,\"fetchSpec\":\"^3.0.0\"},\"_requiredBy\":[\"/\",\"/eslint\"],\"_resolved\":\"https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz\",\"_shasum\":\"addebead72a6574db783639dc87a121773973961\",\"_spec\":\"doctrine@^3.0.0\",\"_where\":\"/root/sources/pve/pve-eslint/eslint-v7.2.0\",\"bugs\":{\"url\":\"https://github.com/eslint/doctrine/issues\"},\"bundleDependencies\":false,\"dependencies\":{\"esutils\":\"^2.0.2\"},\"deprecated\":false,\"description\":\"JSDoc parser\",\"devDependencies\":{\"coveralls\":\"^3.0.1\",\"dateformat\":\"^1.0.11\",\"eslint\":\"^1.10.3\",\"eslint-release\":\"^1.0.0\",\"linefix\":\"^0.1.1\",\"mocha\":\"^3.4.2\",\"npm-license\":\"^0.3.1\",\"nyc\":\"^10.3.2\",\"semver\":\"^5.0.3\",\"shelljs\":\"^0.5.3\",\"shelljs-nodecli\":\"^0.1.1\",\"should\":\"^5.0.1\"},\"directories\":{\"lib\":\"./lib\"},\"engines\":{\"node\":\">=6.0.0\"},\"files\":[\"lib\"],\"homepage\":\"https://github.com/eslint/doctrine\",\"license\":\"Apache-2.0\",\"main\":\"lib/doctrine.js\",\"maintainers\":[{\"name\":\"Nicholas C. Zakas\",\"email\":\"nicholas+npm@nczconsulting.com\",\"url\":\"https://www.nczonline.net\"},{\"name\":\"Yusuke Suzuki\",\"email\":\"utatane.tea@gmail.com\",\"url\":\"https://github.com/Constellation\"}],\"name\":\"doctrine\",\"repository\":{\"type\":\"git\",\"url\":\"git+https://github.com/eslint/doctrine.git\"},\"scripts\":{\"coveralls\":\"nyc report --reporter=text-lcov | coveralls\",\"generate-alpharelease\":\"eslint-generate-prerelease alpha\",\"generate-betarelease\":\"eslint-generate-prerelease beta\",\"generate-rcrelease\":\"eslint-generate-prerelease rc\",\"generate-release\":\"eslint-generate-release\",\"lint\":\"eslint lib/\",\"pretest\":\"npm run lint\",\"publish-release\":\"eslint-publish-release\",\"test\":\"nyc mocha\"},\"version\":\"3.0.0\"}");
 
 /***/ }),
 /* 721 */
@@ -117829,12 +117972,12 @@ function isCaseNode(node) {
  * Checks whether the given logical operator is taken into account for the code
  * path analysis.
  * @param {string} operator The operator found in the LogicalExpression node
- * @returns {boolean} `true` if the operator is "&&" or "||"
+ * @returns {boolean} `true` if the operator is "&&" or "||" or "??"
  */
 
 
 function isHandledLogicalOperator(operator) {
-  return operator === "&&" || operator === "||";
+  return operator === "&&" || operator === "||" || operator === "??";
 }
 /**
  * Gets the label if the parent node of a given node is a LabeledStatement.
@@ -118925,6 +119068,7 @@ function finalizeTestSegmentsOfFor(context, choiceContext, head) {
   if (!choiceContext.processed) {
     choiceContext.trueForkContext.add(head);
     choiceContext.falseForkContext.add(head);
+    choiceContext.qqForkContext.add(head);
   }
 
   if (context.test !== true) {
@@ -119072,6 +119216,7 @@ class CodePathState {
       isForkingAsResult,
       trueForkContext: ForkContext.newEmpty(this.forkContext),
       falseForkContext: ForkContext.newEmpty(this.forkContext),
+      qqForkContext: ForkContext.newEmpty(this.forkContext),
       processed: false
     };
   }
@@ -119090,6 +119235,7 @@ class CodePathState {
     switch (context.kind) {
       case "&&":
       case "||":
+      case "??":
         /*
          * If any result were not transferred from child contexts,
          * this sets the head segments to both cases.
@@ -119098,6 +119244,7 @@ class CodePathState {
         if (!context.processed) {
           context.trueForkContext.add(headSegments);
           context.falseForkContext.add(headSegments);
+          context.qqForkContext.add(headSegments);
         }
         /*
          * Transfers results to upper context if this context is in
@@ -119109,6 +119256,7 @@ class CodePathState {
           const parentContext = this.choiceContext;
           parentContext.trueForkContext.addAll(context.trueForkContext);
           parentContext.falseForkContext.addAll(context.falseForkContext);
+          parentContext.qqForkContext.addAll(context.qqForkContext);
           parentContext.processed = true;
           return context;
         }
@@ -119170,9 +119318,28 @@ class CodePathState {
        * This got segments already from the child choice context.
        * Creates the next path from own true/false fork context.
        */
-      const prevForkContext = context.kind === "&&" ? context.trueForkContext
-      /* kind === "||" */
-      : context.falseForkContext;
+      let prevForkContext;
+
+      switch (context.kind) {
+        case "&&":
+          // if true then go to the right-hand side.
+          prevForkContext = context.trueForkContext;
+          break;
+
+        case "||":
+          // if false then go to the right-hand side.
+          prevForkContext = context.falseForkContext;
+          break;
+
+        case "??":
+          // Both true/false can short-circuit, so needs the third path to go to the right-hand side. That's qqForkContext.
+          prevForkContext = context.qqForkContext;
+          break;
+
+        default:
+          throw new Error("unreachable");
+      }
+
       forkContext.replaceHead(prevForkContext.makeNext(0, -1));
       prevForkContext.clear();
       context.processed = false;
@@ -119182,12 +119349,25 @@ class CodePathState {
        * So addresses the head segments.
        * The head segments are the path of the left-hand operand.
        */
-      if (context.kind === "&&") {
-        // The path does short-circuit if false.
-        context.falseForkContext.add(forkContext.head);
-      } else {
-        // The path does short-circuit if true.
-        context.trueForkContext.add(forkContext.head);
+      switch (context.kind) {
+        case "&&":
+          // the false path can short-circuit.
+          context.falseForkContext.add(forkContext.head);
+          break;
+
+        case "||":
+          // the true path can short-circuit.
+          context.trueForkContext.add(forkContext.head);
+          break;
+
+        case "??":
+          // both can short-circuit.
+          context.trueForkContext.add(forkContext.head);
+          context.falseForkContext.add(forkContext.head);
+          break;
+
+        default:
+          throw new Error("unreachable");
       }
 
       forkContext.replaceHead(forkContext.makeNext(-1, -1));
@@ -119211,6 +119391,7 @@ class CodePathState {
     if (!context.processed) {
       context.trueForkContext.add(forkContext.head);
       context.falseForkContext.add(forkContext.head);
+      context.qqForkContext.add(forkContext.head);
     }
 
     context.processed = false; // Creates new path from the `true` case.
@@ -121074,7 +121255,7 @@ module.exports = class ConfigCommentParser {
           config: items
         };
       }
-    } catch (ex) {
+    } catch (_unused) {
       debug("Levn parsing failed; falling back to manual parsing."); // ignore to parse the string by a fallback.
     }
     /*
@@ -127214,7 +127395,7 @@ function getCacheFile(cacheFile, cwd) {
 
   try {
     fileStats = fs.lstatSync(resolvedCacheFile);
-  } catch (ex) {
+  } catch (_unused) {
     fileStats = null;
   }
   /*
@@ -127769,7 +127950,7 @@ class CLIEngine {
         try {
           const npmFormat = naming.normalizePackageName(normalizedFormatName, "eslint-formatter");
           formatterPath = ModuleResolver.resolve(npmFormat, path.join(cwd, "__placeholder__.js"));
-        } catch (e) {
+        } catch (_unused2) {
           formatterPath = path.resolve(__dirname, "formatters", normalizedFormatName);
         }
       }
@@ -129039,7 +129220,7 @@ class ConfigArrayFactory {
           try {
             loadPackageJSONConfigFile(filePath);
             return filePath;
-          } catch (error) {
+          } catch (_unused) {
             /* ignore */
           }
         } else {