eslint 7.7.0 → 7.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/README.md +2 -2
- package/conf/config-schema.js +12 -0
- package/lib/cli-engine/cascading-config-array-factory.js +12 -0
- package/lib/cli-engine/cli-engine.js +2 -2
- package/lib/cli-engine/config-array/config-array.js +12 -0
- package/lib/cli-engine/config-array/config-dependency.js +12 -0
- package/lib/cli-engine/config-array/extracted-config.js +12 -0
- package/lib/cli-engine/config-array/ignore-pattern.js +12 -0
- package/lib/cli-engine/config-array/index.js +12 -0
- package/lib/cli-engine/config-array/override-tester.js +12 -0
- package/lib/cli-engine/config-array-factory.js +13 -1
- package/lib/eslint/eslint.js +7 -1
- package/lib/init/autoconfig.js +1 -1
- package/lib/init/config-initializer.js +3 -3
- package/lib/linter/code-path-analysis/code-path-analyzer.js +38 -0
- package/lib/linter/code-path-analysis/code-path-state.js +2 -2
- package/lib/linter/config-comment-parser.js +1 -1
- package/lib/linter/linter.js +6 -3
- package/lib/rules/constructor-super.js +17 -1
- package/lib/rules/id-length.js +19 -1
- package/lib/rules/no-loss-of-precision.js +10 -2
- package/lib/rules/no-magic-numbers.js +20 -3
- package/lib/rules/no-warning-comments.js +40 -7
- package/lib/rules/operator-assignment.js +1 -1
- package/lib/rules/prefer-numeric-literals.js +10 -0
- package/lib/rules/utils/ast-utils.js +47 -13
- package/lib/shared/config-validator.js +14 -2
- package/lib/shared/relative-module-resolver.js +12 -0
- package/lib/shared/types.js +1 -1
- package/package.json +3 -2
- package/conf/environments.js +0 -168
- package/lib/shared/config-ops.js +0 -130
- package/lib/shared/naming.js +0 -97
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
v7.8.0 - August 31, 2020
|
2
|
+
|
3
|
+
* [`58abd93`](https://github.com/eslint/eslint/commit/58abd9311900a8af5a3c0963daaf64675bdd8383) Update: support logical assignments in code path analysis (refs #13569) (#13612) (Milos Djermanovic)
|
4
|
+
* [`db7488e`](https://github.com/eslint/eslint/commit/db7488e6326fd1b7ea04c5062beb1c5f75fc15ed) Update: support logical assignments in core rules (refs #13569) (#13618) (Milos Djermanovic)
|
5
|
+
* [`3729219`](https://github.com/eslint/eslint/commit/372921924778f2e525535985e17c97b988546210) Docs: Update Step 1 of Development Environment documentation (klkhan)
|
6
|
+
* [`a320324`](https://github.com/eslint/eslint/commit/a32032430a0779a4e3b2d137d4d0682844084b82) Chore: Test formatted integers in no-dupe-keys (refs #13568) (#13626) (Brandon Mills)
|
7
|
+
* [`88a9ade`](https://github.com/eslint/eslint/commit/88a9ade7643bb166efbab45cee15f3269496f4be) Update: add es2021 environment (refs #13602) (#13603) (Milos Djermanovic)
|
8
|
+
* [`0003dc0`](https://github.com/eslint/eslint/commit/0003dc0f966f2b47555595586f84eb3163cb0179) Update: support numeric separators (refs #13568) (#13581) (Milos Djermanovic)
|
9
|
+
* [`96b11a0`](https://github.com/eslint/eslint/commit/96b11a0717bf32b94ec768611574372320fb774b) Update: Add exceptionPatterns to id-length rule (fixes #13094) (#13576) (sodam)
|
10
|
+
* [`3439fea`](https://github.com/eslint/eslint/commit/3439fea5c0ed330d01d874b0c9df51dd51ae792c) Update: support numeric-separator in no-loss-of-precision (refs #13568) (#13574) (Anix)
|
11
|
+
* [`ed64767`](https://github.com/eslint/eslint/commit/ed64767859d776145d68145419a61f5379b4dd63) Update: add comment to message in no-warning-comments (fixes #12327) (#13522) (Anix)
|
12
|
+
* [`e60ec07`](https://github.com/eslint/eslint/commit/e60ec07fad0c1d4c966f28d214c5379da753ff4e) Sponsors: Sync README with website (ESLint Jenkins)
|
13
|
+
* [`483bf7f`](https://github.com/eslint/eslint/commit/483bf7f3cc40e0d866798d6ca9ee1c19aa77ddd2) Docs: fix examples in object-curly-newline (#13605) (Soobin Bak)
|
14
|
+
* [`1c35d57`](https://github.com/eslint/eslint/commit/1c35d57b0a5f374cc55f1727a7561bcab1962e83) Docs: Remove stale Keybase 2FA instructions (#13622) (Brandon Mills)
|
15
|
+
* [`82669fa`](https://github.com/eslint/eslint/commit/82669fa66670a00988db5b1d10fe8f3bf30be84e) Chore: Extract some functionality to eslintrc (refs #13481) (#13613) (Nicholas C. Zakas)
|
16
|
+
* [`4111d21`](https://github.com/eslint/eslint/commit/4111d21a046b73892e2c84f92815a21ef4db63e1) Docs: Fix typo and missing article before noun in docs (#13611) (Patrice Sandhu)
|
17
|
+
* [`091e52a`](https://github.com/eslint/eslint/commit/091e52ae1ca408f3e668f394c14d214c9ce806e6) Upgrade: espree@7.3.0 (refs #13568) (#13609) (Kai Cataldo)
|
18
|
+
* [`05074fb`](https://github.com/eslint/eslint/commit/05074fb2c243e904e8c09d714ad9d084acdd80d2) Sponsors: Sync README with website (ESLint Jenkins)
|
19
|
+
* [`bdb65ec`](https://github.com/eslint/eslint/commit/bdb65ec2e672c9815bee356b61d1cd60a1072152) Chore: add 3rd party parsers in BUG_REPORT template (#13606) (YeonJuan)
|
20
|
+
* [`f954476`](https://github.com/eslint/eslint/commit/f954476fb6b0664679c73babd5e8a0647572b81f) Chore: add common 3rd party parsers to issue template (#13596) (Kai Cataldo)
|
21
|
+
* [`2bee6d2`](https://github.com/eslint/eslint/commit/2bee6d256ae0516c9a9003bb3fdca24ff93253b5) Chore: Mark config-related files (refs #13481) (#13597) (Nicholas C. Zakas)
|
22
|
+
* [`66442a9`](https://github.com/eslint/eslint/commit/66442a9faf9872db4a40f56dde28c48f4d02fc7b) Update: Add no-magic-numbers 'ignoreDefaultValues' option (#12611) (Dieter Luypaert)
|
23
|
+
* [`b487164`](https://github.com/eslint/eslint/commit/b487164d01dd0bf66fdf2df0e374ce1c3bdb0339) Docs: add exponentiation operators to operator-assignment documentation (#13577) (Milos Djermanovic)
|
24
|
+
* [`2f27836`](https://github.com/eslint/eslint/commit/2f27836e989f3dfe236e34054b490febc359bc48) Sponsors: Sync README with website (ESLint Jenkins)
|
25
|
+
* [`60eafc1`](https://github.com/eslint/eslint/commit/60eafc15075f38955cb6816bf1f0bcf6e6e6d3a6) Sponsors: Sync README with website (ESLint Jenkins)
|
26
|
+
|
1
27
|
v7.7.0 - August 14, 2020
|
2
28
|
|
3
29
|
* [`b46f3ee`](https://github.com/eslint/eslint/commit/b46f3ee0dae4add9df99cae940b641ad8de58b9e) Update: allowFunctionParams option in no-underscore-dangle (fixes 12579) (#13545) (Sunghyun Cho)
|
package/README.md
CHANGED
@@ -265,8 +265,8 @@ The following companies, organizations, and individuals support ESLint's ongoing
|
|
265
265
|
<!--sponsorsstart-->
|
266
266
|
<h3>Gold Sponsors</h3>
|
267
267
|
<p><a href="https://www.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a> <a href="https://aka.ms/microsoftfossfund"><img src="https://avatars1.githubusercontent.com/u/67931232?u=7fddc652a464d7151b97e8f108392af7d54fa3e8&v=4" alt="Microsoft FOSS Fund Sponsorships" height="96"></a></p><h3>Silver Sponsors</h3>
|
268
|
-
<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>
|
269
|
-
<p><a href="https://vpn-review.com/netflix-vpn"><img src="https://images.opencollective.com/vpn-for-netflix/4887627/logo.png" alt="vpn for netflix" height="32"></a> <a href="https://
|
268
|
+
<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> <a href="https://eslint.org/"><img src="https://images.opencollective.com/eslint/96b09dc/logo.png" alt="ESLint" height="64"></a> <a href="https://eslint.org/"><img src="https://images.opencollective.com/eslint/96b09dc/logo.png" alt="ESLint" height="64"></a></p><h3>Bronze Sponsors</h3>
|
269
|
+
<p><a href="https://vpn-review.com/netflix-vpn"><img src="https://images.opencollective.com/vpn-for-netflix/4887627/logo.png" alt="vpn for netflix" height="32"></a> <a href="https://www.veikkaajat.com"><img src="https://images.opencollective.com/veikkaajat/b92b427/logo.png" alt="Veikkaajat.com" height="32"></a> <a href="https://www.nettikasinot.media/"><img src="https://images.opencollective.com/nettikasinot-media/2dba7da/logo.png" alt="Nettikasinot.media" height="32"></a> <a href="https://mytruemedia.com/"><img src="https://images.opencollective.com/my-true-media/03e2168/logo.png" alt="My True Media" height="32"></a> <a href="https://www.norgekasino.com"><img src="https://images.opencollective.com/norgekasino/ecfd57a/logo.png" alt="Norgekasino" height="32"></a> <a href="https://www.japanesecasino.com/"><img src="https://images.opencollective.com/japanesecasino/b0ffe3c/logo.png" alt="Japanesecasino" height="32"></a> <a href="https://bruce.agency"><img src="https://images.opencollective.com/brucemade/0c70c59/logo.png" alt="Bruce" 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://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/53a4b44/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="null"><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/6e889f6/logo.png" alt="Icons8: free icons, photos, illustrations, and music" 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://www.marfeel.com/"><img src="https://images.opencollective.com/marfeel/4b88e30/logo.png" alt="Marfeel" height="32"></a> <a href="https://www.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a></p>
|
270
270
|
<!--sponsorsend-->
|
271
271
|
|
272
272
|
## <a name="technology-sponsors"></a>Technology Sponsors
|
package/conf/config-schema.js
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* STOP!!! DO NOT MODIFY.
|
3
|
+
*
|
4
|
+
* This file is part of the ongoing work to move the eslintrc-style config
|
5
|
+
* system into the @eslint/eslintrc package. This file needs to remain
|
6
|
+
* unchanged in order for this work to proceed.
|
7
|
+
*
|
8
|
+
* If you think you need to change this file, please contact @nzakas first.
|
9
|
+
*
|
10
|
+
* Thanks in advance for your cooperation.
|
11
|
+
*/
|
12
|
+
|
1
13
|
/**
|
2
14
|
* @fileoverview Defines a schema for configs.
|
3
15
|
* @author Sylvan Mably
|
@@ -1,3 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* STOP!!! DO NOT MODIFY.
|
3
|
+
*
|
4
|
+
* This file is part of the ongoing work to move the eslintrc-style config
|
5
|
+
* system into the @eslint/eslintrc package. This file needs to remain
|
6
|
+
* unchanged in order for this work to proceed.
|
7
|
+
*
|
8
|
+
* If you think you need to change this file, please contact @nzakas first.
|
9
|
+
*
|
10
|
+
* Thanks in advance for your cooperation.
|
11
|
+
*/
|
12
|
+
|
1
13
|
/**
|
2
14
|
* @fileoverview `CascadingConfigArrayFactory` class.
|
3
15
|
*
|
@@ -19,8 +19,8 @@ const fs = require("fs");
|
|
19
19
|
const path = require("path");
|
20
20
|
const defaultOptions = require("../../conf/default-cli-options");
|
21
21
|
const pkg = require("../../package.json");
|
22
|
-
const ConfigOps = require("
|
23
|
-
const naming = require("
|
22
|
+
const ConfigOps = require("@eslint/eslintrc/lib/shared/config-ops");
|
23
|
+
const naming = require("@eslint/eslintrc/lib/shared/naming");
|
24
24
|
const ModuleResolver = require("../shared/relative-module-resolver");
|
25
25
|
const { Linter } = require("../linter");
|
26
26
|
const builtInRules = require("../rules");
|
@@ -1,3 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* STOP!!! DO NOT MODIFY.
|
3
|
+
*
|
4
|
+
* This file is part of the ongoing work to move the eslintrc-style config
|
5
|
+
* system into the @eslint/eslintrc package. This file needs to remain
|
6
|
+
* unchanged in order for this work to proceed.
|
7
|
+
*
|
8
|
+
* If you think you need to change this file, please contact @nzakas first.
|
9
|
+
*
|
10
|
+
* Thanks in advance for your cooperation.
|
11
|
+
*/
|
12
|
+
|
1
13
|
/**
|
2
14
|
* @fileoverview `ConfigArray` class.
|
3
15
|
*
|
@@ -1,3 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* STOP!!! DO NOT MODIFY.
|
3
|
+
*
|
4
|
+
* This file is part of the ongoing work to move the eslintrc-style config
|
5
|
+
* system into the @eslint/eslintrc package. This file needs to remain
|
6
|
+
* unchanged in order for this work to proceed.
|
7
|
+
*
|
8
|
+
* If you think you need to change this file, please contact @nzakas first.
|
9
|
+
*
|
10
|
+
* Thanks in advance for your cooperation.
|
11
|
+
*/
|
12
|
+
|
1
13
|
/**
|
2
14
|
* @fileoverview `ConfigDependency` class.
|
3
15
|
*
|
@@ -1,3 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* STOP!!! DO NOT MODIFY.
|
3
|
+
*
|
4
|
+
* This file is part of the ongoing work to move the eslintrc-style config
|
5
|
+
* system into the @eslint/eslintrc package. This file needs to remain
|
6
|
+
* unchanged in order for this work to proceed.
|
7
|
+
*
|
8
|
+
* If you think you need to change this file, please contact @nzakas first.
|
9
|
+
*
|
10
|
+
* Thanks in advance for your cooperation.
|
11
|
+
*/
|
12
|
+
|
1
13
|
/**
|
2
14
|
* @fileoverview `ExtractedConfig` class.
|
3
15
|
*
|
@@ -1,3 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* STOP!!! DO NOT MODIFY.
|
3
|
+
*
|
4
|
+
* This file is part of the ongoing work to move the eslintrc-style config
|
5
|
+
* system into the @eslint/eslintrc package. This file needs to remain
|
6
|
+
* unchanged in order for this work to proceed.
|
7
|
+
*
|
8
|
+
* If you think you need to change this file, please contact @nzakas first.
|
9
|
+
*
|
10
|
+
* Thanks in advance for your cooperation.
|
11
|
+
*/
|
12
|
+
|
1
13
|
/**
|
2
14
|
* @fileoverview `IgnorePattern` class.
|
3
15
|
*
|
@@ -1,3 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* STOP!!! DO NOT MODIFY.
|
3
|
+
*
|
4
|
+
* This file is part of the ongoing work to move the eslintrc-style config
|
5
|
+
* system into the @eslint/eslintrc package. This file needs to remain
|
6
|
+
* unchanged in order for this work to proceed.
|
7
|
+
*
|
8
|
+
* If you think you need to change this file, please contact @nzakas first.
|
9
|
+
*
|
10
|
+
* Thanks in advance for your cooperation.
|
11
|
+
*/
|
12
|
+
|
1
13
|
/**
|
2
14
|
* @fileoverview `ConfigArray` class.
|
3
15
|
* @author Toru Nagashima <https://github.com/mysticatea>
|
@@ -1,3 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* STOP!!! DO NOT MODIFY.
|
3
|
+
*
|
4
|
+
* This file is part of the ongoing work to move the eslintrc-style config
|
5
|
+
* system into the @eslint/eslintrc package. This file needs to remain
|
6
|
+
* unchanged in order for this work to proceed.
|
7
|
+
*
|
8
|
+
* If you think you need to change this file, please contact @nzakas first.
|
9
|
+
*
|
10
|
+
* Thanks in advance for your cooperation.
|
11
|
+
*/
|
12
|
+
|
1
13
|
/**
|
2
14
|
* @fileoverview `OverrideTester` class.
|
3
15
|
*
|
@@ -1,3 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* STOP!!! DO NOT MODIFY.
|
3
|
+
*
|
4
|
+
* This file is part of the ongoing work to move the eslintrc-style config
|
5
|
+
* system into the @eslint/eslintrc package. This file needs to remain
|
6
|
+
* unchanged in order for this work to proceed.
|
7
|
+
*
|
8
|
+
* If you think you need to change this file, please contact @nzakas first.
|
9
|
+
*
|
10
|
+
* Thanks in advance for your cooperation.
|
11
|
+
*/
|
12
|
+
|
1
13
|
/**
|
2
14
|
* @fileoverview The factory of `ConfigArray` objects.
|
3
15
|
*
|
@@ -44,7 +56,7 @@ const path = require("path");
|
|
44
56
|
const importFresh = require("import-fresh");
|
45
57
|
const stripComments = require("strip-json-comments");
|
46
58
|
const { validateConfigSchema } = require("../shared/config-validator");
|
47
|
-
const naming = require("
|
59
|
+
const naming = require("@eslint/eslintrc/lib/shared/naming");
|
48
60
|
const ModuleResolver = require("../shared/relative-module-resolver");
|
49
61
|
const {
|
50
62
|
ConfigArray,
|
package/lib/eslint/eslint.js
CHANGED
@@ -15,7 +15,13 @@ const fs = require("fs");
|
|
15
15
|
const { promisify } = require("util");
|
16
16
|
const { CLIEngine, getCLIEngineInternalSlots } = require("../cli-engine/cli-engine");
|
17
17
|
const BuiltinRules = require("../rules");
|
18
|
-
const {
|
18
|
+
const {
|
19
|
+
Legacy: {
|
20
|
+
ConfigOps: {
|
21
|
+
getRuleSeverity
|
22
|
+
}
|
23
|
+
}
|
24
|
+
} = require("@eslint/eslintrc");
|
19
25
|
const { version } = require("../../package.json");
|
20
26
|
|
21
27
|
//------------------------------------------------------------------------------
|
package/lib/init/autoconfig.js
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
|
12
12
|
const lodash = require("lodash"),
|
13
13
|
recConfig = require("../../conf/eslint-recommended"),
|
14
|
-
ConfigOps = require("
|
14
|
+
ConfigOps = require("@eslint/eslintrc/lib/shared/config-ops"),
|
15
15
|
{ Linter } = require("../linter"),
|
16
16
|
configRule = require("./config-rule");
|
17
17
|
|
@@ -17,9 +17,9 @@ const util = require("util"),
|
|
17
17
|
semver = require("semver"),
|
18
18
|
espree = require("espree"),
|
19
19
|
recConfig = require("../../conf/eslint-recommended"),
|
20
|
-
ConfigOps = require("
|
20
|
+
ConfigOps = require("@eslint/eslintrc/lib/shared/config-ops"),
|
21
21
|
log = require("../shared/logging"),
|
22
|
-
naming = require("
|
22
|
+
naming = require("@eslint/eslintrc/lib/shared/naming"),
|
23
23
|
ModuleResolver = require("../shared/relative-module-resolver"),
|
24
24
|
autoconfig = require("./autoconfig.js"),
|
25
25
|
ConfigFile = require("./config-file"),
|
@@ -265,7 +265,7 @@ function processAnswers(answers) {
|
|
265
265
|
};
|
266
266
|
|
267
267
|
config.parserOptions.ecmaVersion = espree.latestEcmaVersion;
|
268
|
-
config.env.
|
268
|
+
config.env.es2021 = true;
|
269
269
|
|
270
270
|
// set the module type
|
271
271
|
if (answers.moduleType === "esm") {
|
@@ -39,6 +39,17 @@ function isHandledLogicalOperator(operator) {
|
|
39
39
|
return operator === "&&" || operator === "||" || operator === "??";
|
40
40
|
}
|
41
41
|
|
42
|
+
/**
|
43
|
+
* Checks whether the given assignment operator is a logical assignment operator.
|
44
|
+
* Logical assignments are taken into account for the code path analysis
|
45
|
+
* because of their short-circuiting semantics.
|
46
|
+
* @param {string} operator The operator found in the AssignmentExpression node
|
47
|
+
* @returns {boolean} `true` if the operator is "&&=" or "||=" or "??="
|
48
|
+
*/
|
49
|
+
function isLogicalAssignmentOperator(operator) {
|
50
|
+
return operator === "&&=" || operator === "||=" || operator === "??=";
|
51
|
+
}
|
52
|
+
|
42
53
|
/**
|
43
54
|
* Gets the label if the parent node of a given node is a LabeledStatement.
|
44
55
|
* @param {ASTNode} node A node to get.
|
@@ -71,6 +82,9 @@ function isForkingByTrueOrFalse(node) {
|
|
71
82
|
case "LogicalExpression":
|
72
83
|
return isHandledLogicalOperator(parent.operator);
|
73
84
|
|
85
|
+
case "AssignmentExpression":
|
86
|
+
return isLogicalAssignmentOperator(parent.operator);
|
87
|
+
|
74
88
|
default:
|
75
89
|
return false;
|
76
90
|
}
|
@@ -266,6 +280,15 @@ function preprocess(analyzer, node) {
|
|
266
280
|
}
|
267
281
|
break;
|
268
282
|
|
283
|
+
case "AssignmentExpression":
|
284
|
+
if (
|
285
|
+
parent.right === node &&
|
286
|
+
isLogicalAssignmentOperator(parent.operator)
|
287
|
+
) {
|
288
|
+
state.makeLogicalRight();
|
289
|
+
}
|
290
|
+
break;
|
291
|
+
|
269
292
|
case "ConditionalExpression":
|
270
293
|
case "IfStatement":
|
271
294
|
|
@@ -413,6 +436,15 @@ function processCodePathToEnter(analyzer, node) {
|
|
413
436
|
}
|
414
437
|
break;
|
415
438
|
|
439
|
+
case "AssignmentExpression":
|
440
|
+
if (isLogicalAssignmentOperator(node.operator)) {
|
441
|
+
state.pushChoiceContext(
|
442
|
+
node.operator.slice(0, -1), // removes `=` from the end
|
443
|
+
isForkingByTrueOrFalse(node)
|
444
|
+
);
|
445
|
+
}
|
446
|
+
break;
|
447
|
+
|
416
448
|
case "ConditionalExpression":
|
417
449
|
case "IfStatement":
|
418
450
|
state.pushChoiceContext("test", false);
|
@@ -491,6 +523,12 @@ function processCodePathToExit(analyzer, node) {
|
|
491
523
|
}
|
492
524
|
break;
|
493
525
|
|
526
|
+
case "AssignmentExpression":
|
527
|
+
if (isLogicalAssignmentOperator(node.operator)) {
|
528
|
+
state.popChoiceContext();
|
529
|
+
}
|
530
|
+
break;
|
531
|
+
|
494
532
|
case "SwitchStatement":
|
495
533
|
state.popSwitchContext();
|
496
534
|
break;
|
@@ -317,7 +317,7 @@ class CodePathState {
|
|
317
317
|
//--------------------------------------------------------------------------
|
318
318
|
|
319
319
|
/**
|
320
|
-
* Creates a context for ConditionalExpression, LogicalExpression,
|
320
|
+
* Creates a context for ConditionalExpression, LogicalExpression, AssignmentExpression (logical assignments only),
|
321
321
|
* IfStatement, WhileStatement, DoWhileStatement, or ForStatement.
|
322
322
|
*
|
323
323
|
* LogicalExpressions have cases that it goes different paths between the
|
@@ -339,7 +339,7 @@ class CodePathState {
|
|
339
339
|
* a -> b -> foo();
|
340
340
|
* a -> b -> bar();
|
341
341
|
* @param {string} kind A kind string.
|
342
|
-
* If the new context is LogicalExpression's, this is `"&&"` or `"||"`.
|
342
|
+
* If the new context is LogicalExpression's or AssignmentExpression's, this is `"&&"` or `"||"` or `"??"`.
|
343
343
|
* If it's IfStatement's or ConditionalExpression's, this is `"test"`.
|
344
344
|
* Otherwise, this is `"loop"`.
|
345
345
|
* @param {boolean} isForkingAsResult A flag that shows that goes different
|
@@ -11,7 +11,7 @@
|
|
11
11
|
//------------------------------------------------------------------------------
|
12
12
|
|
13
13
|
const levn = require("levn"),
|
14
|
-
ConfigOps = require("
|
14
|
+
ConfigOps = require("@eslint/eslintrc/lib/shared/config-ops");
|
15
15
|
|
16
16
|
const debug = require("debug")("eslint:config-comment-parser");
|
17
17
|
|
package/lib/linter/linter.js
CHANGED
@@ -16,11 +16,11 @@ const
|
|
16
16
|
evk = require("eslint-visitor-keys"),
|
17
17
|
espree = require("espree"),
|
18
18
|
lodash = require("lodash"),
|
19
|
-
BuiltInEnvironments = require("
|
19
|
+
BuiltInEnvironments = require("@eslint/eslintrc/conf/environments"),
|
20
20
|
pkg = require("../../package.json"),
|
21
21
|
astUtils = require("../shared/ast-utils"),
|
22
|
-
ConfigOps = require("
|
23
|
-
|
22
|
+
ConfigOps = require("@eslint/eslintrc/lib/shared/config-ops"),
|
23
|
+
ConfigValidator = require("@eslint/eslintrc/lib/shared/config-validator"),
|
24
24
|
Traverser = require("../shared/traverser"),
|
25
25
|
{ SourceCode } = require("../source-code"),
|
26
26
|
CodePathAnalyzer = require("./code-path-analysis/code-path-analyzer"),
|
@@ -293,6 +293,9 @@ function getDirectiveComments(filename, ast, ruleMapper, warnInlineConfig) {
|
|
293
293
|
const exportedVariables = {};
|
294
294
|
const problems = [];
|
295
295
|
const disableDirectives = [];
|
296
|
+
const validator = new ConfigValidator({
|
297
|
+
builtInRules: Rules
|
298
|
+
});
|
296
299
|
|
297
300
|
ast.comments.filter(token => token.type !== "Shebang").forEach(comment => {
|
298
301
|
const trimmedCommentText = stripDirectiveComment(comment.value);
|
@@ -60,7 +60,23 @@ function isPossibleConstructor(node) {
|
|
60
60
|
return node.name !== "undefined";
|
61
61
|
|
62
62
|
case "AssignmentExpression":
|
63
|
-
|
63
|
+
if (["=", "&&="].includes(node.operator)) {
|
64
|
+
return isPossibleConstructor(node.right);
|
65
|
+
}
|
66
|
+
|
67
|
+
if (["||=", "??="].includes(node.operator)) {
|
68
|
+
return (
|
69
|
+
isPossibleConstructor(node.left) ||
|
70
|
+
isPossibleConstructor(node.right)
|
71
|
+
);
|
72
|
+
}
|
73
|
+
|
74
|
+
/**
|
75
|
+
* All other assignment operators are mathematical assignment operators (arithmetic or bitwise).
|
76
|
+
* An assignment expression with a mathematical operator can either evaluate to a primitive value,
|
77
|
+
* or throw, depending on the operands. Thus, it cannot evaluate to a constructor function.
|
78
|
+
*/
|
79
|
+
return false;
|
64
80
|
|
65
81
|
case "LogicalExpression":
|
66
82
|
return (
|
package/lib/rules/id-length.js
CHANGED
@@ -39,6 +39,13 @@ module.exports = {
|
|
39
39
|
type: "string"
|
40
40
|
}
|
41
41
|
},
|
42
|
+
exceptionPatterns: {
|
43
|
+
type: "array",
|
44
|
+
uniqueItems: true,
|
45
|
+
items: {
|
46
|
+
type: "string"
|
47
|
+
}
|
48
|
+
},
|
42
49
|
properties: {
|
43
50
|
enum: ["always", "never"]
|
44
51
|
}
|
@@ -63,8 +70,19 @@ module.exports = {
|
|
63
70
|
|
64
71
|
return obj;
|
65
72
|
}, {});
|
73
|
+
const exceptionPatterns = (options.exceptionPatterns || []).map(pattern => new RegExp(pattern, "u"));
|
66
74
|
const reportedNode = new Set();
|
67
75
|
|
76
|
+
/**
|
77
|
+
* Checks if a string matches the provided exception patterns
|
78
|
+
* @param {string} name The string to check.
|
79
|
+
* @returns {boolean} if the string is a match
|
80
|
+
* @private
|
81
|
+
*/
|
82
|
+
function matchesExceptionPattern(name) {
|
83
|
+
return exceptionPatterns.some(pattern => pattern.test(name));
|
84
|
+
}
|
85
|
+
|
68
86
|
const SUPPORTED_EXPRESSIONS = {
|
69
87
|
MemberExpression: properties && function(parent) {
|
70
88
|
return !parent.computed && (
|
@@ -112,7 +130,7 @@ module.exports = {
|
|
112
130
|
const isShort = name.length < minLength;
|
113
131
|
const isLong = name.length > maxLength;
|
114
132
|
|
115
|
-
if (!(isShort || isLong) || exceptions[name]) {
|
133
|
+
if (!(isShort || isLong) || exceptions[name] || matchesExceptionPattern(name)) {
|
116
134
|
return; // Nothing to report
|
117
135
|
}
|
118
136
|
|
@@ -36,6 +36,14 @@ module.exports = {
|
|
36
36
|
return typeof node.value === "number";
|
37
37
|
}
|
38
38
|
|
39
|
+
/**
|
40
|
+
* Gets the source code of the given number literal. Removes `_` numeric separators from the result.
|
41
|
+
* @param {Node} node the number `Literal` node
|
42
|
+
* @returns {string} raw source code of the literal, without numeric separators
|
43
|
+
*/
|
44
|
+
function getRaw(node) {
|
45
|
+
return node.raw.replace(/_/gu, "");
|
46
|
+
}
|
39
47
|
|
40
48
|
/**
|
41
49
|
* Checks whether the number is base ten
|
@@ -55,7 +63,7 @@ module.exports = {
|
|
55
63
|
* @returns {boolean} true if they do not match
|
56
64
|
*/
|
57
65
|
function notBaseTenLosesPrecision(node) {
|
58
|
-
const rawString = node.
|
66
|
+
const rawString = getRaw(node).toUpperCase();
|
59
67
|
let base = 0;
|
60
68
|
|
61
69
|
if (rawString.startsWith("0B")) {
|
@@ -161,7 +169,7 @@ module.exports = {
|
|
161
169
|
* @returns {boolean} true if they do not match
|
162
170
|
*/
|
163
171
|
function baseTenLosesPrecision(node) {
|
164
|
-
const normalizedRawNumber = convertNumberToScientificNotation(node
|
172
|
+
const normalizedRawNumber = convertNumberToScientificNotation(getRaw(node));
|
165
173
|
const requestedPrecision = normalizedRawNumber.split("e")[0].replace(".", "").length;
|
166
174
|
|
167
175
|
if (requestedPrecision > 100) {
|
@@ -61,6 +61,10 @@ module.exports = {
|
|
61
61
|
ignoreArrayIndexes: {
|
62
62
|
type: "boolean",
|
63
63
|
default: false
|
64
|
+
},
|
65
|
+
ignoreDefaultValues: {
|
66
|
+
type: "boolean",
|
67
|
+
default: false
|
64
68
|
}
|
65
69
|
},
|
66
70
|
additionalProperties: false
|
@@ -77,7 +81,8 @@ module.exports = {
|
|
77
81
|
detectObjects = !!config.detectObjects,
|
78
82
|
enforceConst = !!config.enforceConst,
|
79
83
|
ignore = (config.ignore || []).map(normalizeIgnoreValue),
|
80
|
-
ignoreArrayIndexes = !!config.ignoreArrayIndexes
|
84
|
+
ignoreArrayIndexes = !!config.ignoreArrayIndexes,
|
85
|
+
ignoreDefaultValues = !!config.ignoreDefaultValues;
|
81
86
|
|
82
87
|
const okTypes = detectObjects ? [] : ["ObjectExpression", "Property", "AssignmentExpression"];
|
83
88
|
|
@@ -90,6 +95,17 @@ module.exports = {
|
|
90
95
|
return ignore.indexOf(value) !== -1;
|
91
96
|
}
|
92
97
|
|
98
|
+
/**
|
99
|
+
* Returns whether the number is a default value assignment.
|
100
|
+
* @param {ASTNode} fullNumberNode `Literal` or `UnaryExpression` full number node
|
101
|
+
* @returns {boolean} true if the number is a default value
|
102
|
+
*/
|
103
|
+
function isDefaultValue(fullNumberNode) {
|
104
|
+
const parent = fullNumberNode.parent;
|
105
|
+
|
106
|
+
return parent.type === "AssignmentPattern" && parent.right === fullNumberNode;
|
107
|
+
}
|
108
|
+
|
93
109
|
/**
|
94
110
|
* Returns whether the given node is used as a radix within parseInt() or Number.parseInt()
|
95
111
|
* @param {ASTNode} fullNumberNode `Literal` or `UnaryExpression` full number node
|
@@ -172,9 +188,12 @@ module.exports = {
|
|
172
188
|
raw = node.raw;
|
173
189
|
}
|
174
190
|
|
191
|
+
const parent = fullNumberNode.parent;
|
192
|
+
|
175
193
|
// Always allow radix arguments and JSX props
|
176
194
|
if (
|
177
195
|
isIgnoredValue(value) ||
|
196
|
+
(ignoreDefaultValues && isDefaultValue(fullNumberNode)) ||
|
178
197
|
isParseIntRadix(fullNumberNode) ||
|
179
198
|
isJSXNumber(fullNumberNode) ||
|
180
199
|
(ignoreArrayIndexes && isArrayIndex(fullNumberNode, value))
|
@@ -182,8 +201,6 @@ module.exports = {
|
|
182
201
|
return;
|
183
202
|
}
|
184
203
|
|
185
|
-
const parent = fullNumberNode.parent;
|
186
|
-
|
187
204
|
if (parent.type === "VariableDeclarator") {
|
188
205
|
if (enforceConst && parent.parent.kind !== "const") {
|
189
206
|
context.report({
|
@@ -8,6 +8,8 @@
|
|
8
8
|
const { escapeRegExp } = require("lodash");
|
9
9
|
const astUtils = require("./utils/ast-utils");
|
10
10
|
|
11
|
+
const CHAR_LIMIT = 40;
|
12
|
+
|
11
13
|
//------------------------------------------------------------------------------
|
12
14
|
// Rule Definition
|
13
15
|
//------------------------------------------------------------------------------
|
@@ -42,12 +44,11 @@ module.exports = {
|
|
42
44
|
],
|
43
45
|
|
44
46
|
messages: {
|
45
|
-
unexpectedComment: "Unexpected '{{matchedTerm}}' comment."
|
47
|
+
unexpectedComment: "Unexpected '{{matchedTerm}}' comment: '{{comment}}'."
|
46
48
|
}
|
47
49
|
},
|
48
50
|
|
49
51
|
create(context) {
|
50
|
-
|
51
52
|
const sourceCode = context.getSourceCode(),
|
52
53
|
configuration = context.options[0] || {},
|
53
54
|
warningTerms = configuration.terms || ["todo", "fixme", "xxx"],
|
@@ -107,7 +108,15 @@ module.exports = {
|
|
107
108
|
* \bTERM\b|\bTERM\b, this checks the entire comment
|
108
109
|
* for the term.
|
109
110
|
*/
|
110
|
-
return new RegExp(
|
111
|
+
return new RegExp(
|
112
|
+
prefix +
|
113
|
+
escaped +
|
114
|
+
suffix +
|
115
|
+
eitherOrWordBoundary +
|
116
|
+
term +
|
117
|
+
wordBoundary,
|
118
|
+
"iu"
|
119
|
+
);
|
111
120
|
}
|
112
121
|
|
113
122
|
const warningRegExps = warningTerms.map(convertToRegExp);
|
@@ -135,18 +144,40 @@ module.exports = {
|
|
135
144
|
* @returns {void} undefined.
|
136
145
|
*/
|
137
146
|
function checkComment(node) {
|
138
|
-
|
147
|
+
const comment = node.value;
|
148
|
+
|
149
|
+
if (
|
150
|
+
astUtils.isDirectiveComment(node) &&
|
151
|
+
selfConfigRegEx.test(comment)
|
152
|
+
) {
|
139
153
|
return;
|
140
154
|
}
|
141
155
|
|
142
|
-
const matches = commentContainsWarningTerm(
|
156
|
+
const matches = commentContainsWarningTerm(comment);
|
143
157
|
|
144
158
|
matches.forEach(matchedTerm => {
|
159
|
+
let commentToDisplay = "";
|
160
|
+
let truncated = false;
|
161
|
+
|
162
|
+
for (const c of comment.trim().split(/\s+/u)) {
|
163
|
+
const tmp = commentToDisplay ? `${commentToDisplay} ${c}` : c;
|
164
|
+
|
165
|
+
if (tmp.length <= CHAR_LIMIT) {
|
166
|
+
commentToDisplay = tmp;
|
167
|
+
} else {
|
168
|
+
truncated = true;
|
169
|
+
break;
|
170
|
+
}
|
171
|
+
}
|
172
|
+
|
145
173
|
context.report({
|
146
174
|
node,
|
147
175
|
messageId: "unexpectedComment",
|
148
176
|
data: {
|
149
|
-
matchedTerm
|
177
|
+
matchedTerm,
|
178
|
+
comment: `${commentToDisplay}${
|
179
|
+
truncated ? "..." : ""
|
180
|
+
}`
|
150
181
|
}
|
151
182
|
});
|
152
183
|
});
|
@@ -156,7 +187,9 @@ module.exports = {
|
|
156
187
|
Program() {
|
157
188
|
const comments = sourceCode.getAllComments();
|
158
189
|
|
159
|
-
comments
|
190
|
+
comments
|
191
|
+
.filter(token => token.type !== "Shebang")
|
192
|
+
.forEach(checkComment);
|
160
193
|
}
|
161
194
|
};
|
162
195
|
}
|
@@ -151,7 +151,7 @@ module.exports = {
|
|
151
151
|
* @returns {void}
|
152
152
|
*/
|
153
153
|
function prohibit(node) {
|
154
|
-
if (node.operator !== "=") {
|
154
|
+
if (node.operator !== "=" && !astUtils.isLogicalAssignmentOperator(node.operator)) {
|
155
155
|
context.report({
|
156
156
|
node,
|
157
157
|
messageId: "unexpected",
|
@@ -103,6 +103,16 @@ module.exports = {
|
|
103
103
|
/*
|
104
104
|
* If the newly-produced literal would be invalid, (e.g. 0b1234),
|
105
105
|
* or it would yield an incorrect parseInt result for some other reason, don't make a fix.
|
106
|
+
*
|
107
|
+
* If `str` had numeric separators, `+replacement` will evaluate to `NaN` because unary `+`
|
108
|
+
* per the specification doesn't support numeric separators. Thus, the above condition will be `true`
|
109
|
+
* (`NaN !== anything` is always `true`) regardless of the `parseInt(str, radix)` value.
|
110
|
+
* Consequently, no autofixes will be made. This is correct behavior because `parseInt` also
|
111
|
+
* doesn't support numeric separators, but it does parse part of the string before the first `_`,
|
112
|
+
* so the autofix would be invalid:
|
113
|
+
*
|
114
|
+
* parseInt("1_1", 2) // === 1
|
115
|
+
* 0b1_1 // === 3
|
106
116
|
*/
|
107
117
|
return null;
|
108
118
|
}
|
@@ -37,9 +37,11 @@ const LINEBREAKS = new Set(["\r\n", "\r", "\n", "\u2028", "\u2029"]);
|
|
37
37
|
// A set of node types that can contain a list of statements
|
38
38
|
const STATEMENT_LIST_PARENTS = new Set(["Program", "BlockStatement", "SwitchCase"]);
|
39
39
|
|
40
|
-
const DECIMAL_INTEGER_PATTERN = /^(0|[1-9]
|
40
|
+
const DECIMAL_INTEGER_PATTERN = /^(0|[1-9](?:_?\d)*)$/u;
|
41
41
|
const OCTAL_ESCAPE_PATTERN = /^(?:[^\\]|\\[^0-7]|\\0(?![0-9]))*\\(?:[1-7]|0[0-9])/u;
|
42
42
|
|
43
|
+
const LOGICAL_ASSIGNMENT_OPERATORS = new Set(["&&=", "||=", "??="]);
|
44
|
+
|
43
45
|
/**
|
44
46
|
* Checks reference if is non initializer and writable.
|
45
47
|
* @param {Reference} reference A reference to check.
|
@@ -722,6 +724,15 @@ function isMixedLogicalAndCoalesceExpressions(left, right) {
|
|
722
724
|
);
|
723
725
|
}
|
724
726
|
|
727
|
+
/**
|
728
|
+
* Checks if the given operator is a logical assignment operator.
|
729
|
+
* @param {string} operator The operator to check.
|
730
|
+
* @returns {boolean} `true` if the operator is a logical assignment operator.
|
731
|
+
*/
|
732
|
+
function isLogicalAssignmentOperator(operator) {
|
733
|
+
return LOGICAL_ASSIGNMENT_OPERATORS.has(operator);
|
734
|
+
}
|
735
|
+
|
725
736
|
//------------------------------------------------------------------------------
|
726
737
|
// Public Interface
|
727
738
|
//------------------------------------------------------------------------------
|
@@ -1228,16 +1239,25 @@ module.exports = {
|
|
1228
1239
|
* @returns {boolean} `true` if this node is a decimal integer.
|
1229
1240
|
* @example
|
1230
1241
|
*
|
1231
|
-
*
|
1232
|
-
* 5
|
1233
|
-
*
|
1234
|
-
*
|
1235
|
-
*
|
1236
|
-
*
|
1237
|
-
*
|
1238
|
-
*
|
1239
|
-
*
|
1240
|
-
*
|
1242
|
+
* 0 // true
|
1243
|
+
* 5 // true
|
1244
|
+
* 50 // true
|
1245
|
+
* 5_000 // true
|
1246
|
+
* 1_234_56 // true
|
1247
|
+
* 5. // false
|
1248
|
+
* .5 // false
|
1249
|
+
* 5.0 // false
|
1250
|
+
* 5.00_00 // false
|
1251
|
+
* 05 // false
|
1252
|
+
* 0x5 // false
|
1253
|
+
* 0b101 // false
|
1254
|
+
* 0b11_01 // false
|
1255
|
+
* 0o5 // false
|
1256
|
+
* 5e0 // false
|
1257
|
+
* 5e1_000 // false
|
1258
|
+
* 5n // false
|
1259
|
+
* 1_000n // false
|
1260
|
+
* '5' // false
|
1241
1261
|
*/
|
1242
1262
|
isDecimalInteger(node) {
|
1243
1263
|
return node.type === "Literal" && typeof node.value === "number" &&
|
@@ -1567,7 +1587,20 @@ module.exports = {
|
|
1567
1587
|
return true; // possibly an error object.
|
1568
1588
|
|
1569
1589
|
case "AssignmentExpression":
|
1570
|
-
|
1590
|
+
if (["=", "&&="].includes(node.operator)) {
|
1591
|
+
return module.exports.couldBeError(node.right);
|
1592
|
+
}
|
1593
|
+
|
1594
|
+
if (["||=", "??="].includes(node.operator)) {
|
1595
|
+
return module.exports.couldBeError(node.left) || module.exports.couldBeError(node.right);
|
1596
|
+
}
|
1597
|
+
|
1598
|
+
/**
|
1599
|
+
* All other assignment operators are mathematical assignment operators (arithmetic or bitwise).
|
1600
|
+
* An assignment expression with a mathematical operator can either evaluate to a primitive value,
|
1601
|
+
* or throw, depending on the operands. Thus, it cannot evaluate to an `Error` object.
|
1602
|
+
*/
|
1603
|
+
return false;
|
1571
1604
|
|
1572
1605
|
case "SequenceExpression": {
|
1573
1606
|
const exprs = node.expressions;
|
@@ -1754,5 +1787,6 @@ module.exports = {
|
|
1754
1787
|
isSpecificId,
|
1755
1788
|
isSpecificMemberAccess,
|
1756
1789
|
equalLiteralValue,
|
1757
|
-
isSameReference
|
1790
|
+
isSameReference,
|
1791
|
+
isLogicalAssignmentOperator
|
1758
1792
|
};
|
@@ -1,3 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* STOP!!! DO NOT MODIFY.
|
3
|
+
*
|
4
|
+
* This file is part of the ongoing work to move the eslintrc-style config
|
5
|
+
* system into the @eslint/eslintrc package. This file needs to remain
|
6
|
+
* unchanged in order for this work to proceed.
|
7
|
+
*
|
8
|
+
* If you think you need to change this file, please contact @nzakas first.
|
9
|
+
*
|
10
|
+
* Thanks in advance for your cooperation.
|
11
|
+
*/
|
12
|
+
|
1
13
|
/**
|
2
14
|
* @fileoverview Validates configs.
|
3
15
|
* @author Brandon Mills
|
@@ -12,9 +24,9 @@
|
|
12
24
|
const
|
13
25
|
util = require("util"),
|
14
26
|
configSchema = require("../../conf/config-schema"),
|
15
|
-
BuiltInEnvironments = require("
|
27
|
+
BuiltInEnvironments = require("@eslint/eslintrc/conf/environments"),
|
16
28
|
BuiltInRules = require("../rules"),
|
17
|
-
ConfigOps = require("
|
29
|
+
ConfigOps = require("@eslint/eslintrc/lib/shared/config-ops"),
|
18
30
|
{ emitDeprecationWarning } = require("./deprecation-warnings");
|
19
31
|
|
20
32
|
const ajv = require("./ajv")();
|
@@ -1,3 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* STOP!!! DO NOT MODIFY.
|
3
|
+
*
|
4
|
+
* This file is part of the ongoing work to move the eslintrc-style config
|
5
|
+
* system into the @eslint/eslintrc package. This file needs to remain
|
6
|
+
* unchanged in order for this work to proceed.
|
7
|
+
*
|
8
|
+
* If you think you need to change this file, please contact @nzakas first.
|
9
|
+
*
|
10
|
+
* Thanks in advance for your cooperation.
|
11
|
+
*/
|
12
|
+
|
1
13
|
/**
|
2
14
|
* Utility for resolving a module relative to another module
|
3
15
|
* @author Teddy Katz
|
package/lib/shared/types.js
CHANGED
@@ -21,7 +21,7 @@ module.exports = {};
|
|
21
21
|
/**
|
22
22
|
* @typedef {Object} ParserOptions
|
23
23
|
* @property {EcmaFeatures} [ecmaFeatures] The optional features.
|
24
|
-
* @property {3|5|6|7|8|9|10|11|2015|2016|2017|2018|2019|2020} [ecmaVersion] The ECMAScript version (or revision number).
|
24
|
+
* @property {3|5|6|7|8|9|10|11|12|2015|2016|2017|2018|2019|2020|2021} [ecmaVersion] The ECMAScript version (or revision number).
|
25
25
|
* @property {"script"|"module"} [sourceType] The source code type.
|
26
26
|
*/
|
27
27
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "7.
|
3
|
+
"version": "7.8.0",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"bin": {
|
@@ -47,6 +47,7 @@
|
|
47
47
|
"bugs": "https://github.com/eslint/eslint/issues/",
|
48
48
|
"dependencies": {
|
49
49
|
"@babel/code-frame": "^7.0.0",
|
50
|
+
"@eslint/eslintrc": "^0.1.0",
|
50
51
|
"ajv": "^6.10.0",
|
51
52
|
"chalk": "^4.0.0",
|
52
53
|
"cross-spawn": "^7.0.2",
|
@@ -56,7 +57,7 @@
|
|
56
57
|
"eslint-scope": "^5.1.0",
|
57
58
|
"eslint-utils": "^2.1.0",
|
58
59
|
"eslint-visitor-keys": "^1.3.0",
|
59
|
-
"espree": "^7.
|
60
|
+
"espree": "^7.3.0",
|
60
61
|
"esquery": "^1.2.0",
|
61
62
|
"esutils": "^2.0.2",
|
62
63
|
"file-entry-cache": "^5.0.1",
|
package/conf/environments.js
DELETED
@@ -1,168 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @fileoverview Defines environment settings and globals.
|
3
|
-
* @author Elan Shanker
|
4
|
-
*/
|
5
|
-
"use strict";
|
6
|
-
|
7
|
-
//------------------------------------------------------------------------------
|
8
|
-
// Requirements
|
9
|
-
//------------------------------------------------------------------------------
|
10
|
-
|
11
|
-
const globals = require("globals");
|
12
|
-
|
13
|
-
//------------------------------------------------------------------------------
|
14
|
-
// Helpers
|
15
|
-
//------------------------------------------------------------------------------
|
16
|
-
|
17
|
-
/**
|
18
|
-
* Get the object that has difference.
|
19
|
-
* @param {Record<string,boolean>} current The newer object.
|
20
|
-
* @param {Record<string,boolean>} prev The older object.
|
21
|
-
* @returns {Record<string,boolean>} The difference object.
|
22
|
-
*/
|
23
|
-
function getDiff(current, prev) {
|
24
|
-
const retv = {};
|
25
|
-
|
26
|
-
for (const [key, value] of Object.entries(current)) {
|
27
|
-
if (!Object.hasOwnProperty.call(prev, key)) {
|
28
|
-
retv[key] = value;
|
29
|
-
}
|
30
|
-
}
|
31
|
-
|
32
|
-
return retv;
|
33
|
-
}
|
34
|
-
|
35
|
-
const newGlobals2015 = getDiff(globals.es2015, globals.es5); // 19 variables such as Promise, Map, ...
|
36
|
-
const newGlobals2017 = {
|
37
|
-
Atomics: false,
|
38
|
-
SharedArrayBuffer: false
|
39
|
-
};
|
40
|
-
const newGlobals2020 = {
|
41
|
-
BigInt: false,
|
42
|
-
BigInt64Array: false,
|
43
|
-
BigUint64Array: false,
|
44
|
-
globalThis: false
|
45
|
-
};
|
46
|
-
|
47
|
-
//------------------------------------------------------------------------------
|
48
|
-
// Public Interface
|
49
|
-
//------------------------------------------------------------------------------
|
50
|
-
|
51
|
-
/** @type {Map<string, import("../lib/shared/types").Environment>} */
|
52
|
-
module.exports = new Map(Object.entries({
|
53
|
-
|
54
|
-
// Language
|
55
|
-
builtin: {
|
56
|
-
globals: globals.es5
|
57
|
-
},
|
58
|
-
es6: {
|
59
|
-
globals: newGlobals2015,
|
60
|
-
parserOptions: {
|
61
|
-
ecmaVersion: 6
|
62
|
-
}
|
63
|
-
},
|
64
|
-
es2015: {
|
65
|
-
globals: newGlobals2015,
|
66
|
-
parserOptions: {
|
67
|
-
ecmaVersion: 6
|
68
|
-
}
|
69
|
-
},
|
70
|
-
es2017: {
|
71
|
-
globals: { ...newGlobals2015, ...newGlobals2017 },
|
72
|
-
parserOptions: {
|
73
|
-
ecmaVersion: 8
|
74
|
-
}
|
75
|
-
},
|
76
|
-
es2020: {
|
77
|
-
globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020 },
|
78
|
-
parserOptions: {
|
79
|
-
ecmaVersion: 11
|
80
|
-
}
|
81
|
-
},
|
82
|
-
|
83
|
-
// Platforms
|
84
|
-
browser: {
|
85
|
-
globals: globals.browser
|
86
|
-
},
|
87
|
-
node: {
|
88
|
-
globals: globals.node,
|
89
|
-
parserOptions: {
|
90
|
-
ecmaFeatures: {
|
91
|
-
globalReturn: true
|
92
|
-
}
|
93
|
-
}
|
94
|
-
},
|
95
|
-
"shared-node-browser": {
|
96
|
-
globals: globals["shared-node-browser"]
|
97
|
-
},
|
98
|
-
worker: {
|
99
|
-
globals: globals.worker
|
100
|
-
},
|
101
|
-
serviceworker: {
|
102
|
-
globals: globals.serviceworker
|
103
|
-
},
|
104
|
-
|
105
|
-
// Frameworks
|
106
|
-
commonjs: {
|
107
|
-
globals: globals.commonjs,
|
108
|
-
parserOptions: {
|
109
|
-
ecmaFeatures: {
|
110
|
-
globalReturn: true
|
111
|
-
}
|
112
|
-
}
|
113
|
-
},
|
114
|
-
amd: {
|
115
|
-
globals: globals.amd
|
116
|
-
},
|
117
|
-
mocha: {
|
118
|
-
globals: globals.mocha
|
119
|
-
},
|
120
|
-
jasmine: {
|
121
|
-
globals: globals.jasmine
|
122
|
-
},
|
123
|
-
jest: {
|
124
|
-
globals: globals.jest
|
125
|
-
},
|
126
|
-
phantomjs: {
|
127
|
-
globals: globals.phantomjs
|
128
|
-
},
|
129
|
-
jquery: {
|
130
|
-
globals: globals.jquery
|
131
|
-
},
|
132
|
-
qunit: {
|
133
|
-
globals: globals.qunit
|
134
|
-
},
|
135
|
-
prototypejs: {
|
136
|
-
globals: globals.prototypejs
|
137
|
-
},
|
138
|
-
shelljs: {
|
139
|
-
globals: globals.shelljs
|
140
|
-
},
|
141
|
-
meteor: {
|
142
|
-
globals: globals.meteor
|
143
|
-
},
|
144
|
-
mongo: {
|
145
|
-
globals: globals.mongo
|
146
|
-
},
|
147
|
-
protractor: {
|
148
|
-
globals: globals.protractor
|
149
|
-
},
|
150
|
-
applescript: {
|
151
|
-
globals: globals.applescript
|
152
|
-
},
|
153
|
-
nashorn: {
|
154
|
-
globals: globals.nashorn
|
155
|
-
},
|
156
|
-
atomtest: {
|
157
|
-
globals: globals.atomtest
|
158
|
-
},
|
159
|
-
embertest: {
|
160
|
-
globals: globals.embertest
|
161
|
-
},
|
162
|
-
webextensions: {
|
163
|
-
globals: globals.webextensions
|
164
|
-
},
|
165
|
-
greasemonkey: {
|
166
|
-
globals: globals.greasemonkey
|
167
|
-
}
|
168
|
-
}));
|
package/lib/shared/config-ops.js
DELETED
@@ -1,130 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @fileoverview Config file operations. This file must be usable in the browser,
|
3
|
-
* so no Node-specific code can be here.
|
4
|
-
* @author Nicholas C. Zakas
|
5
|
-
*/
|
6
|
-
"use strict";
|
7
|
-
|
8
|
-
//------------------------------------------------------------------------------
|
9
|
-
// Private
|
10
|
-
//------------------------------------------------------------------------------
|
11
|
-
|
12
|
-
const RULE_SEVERITY_STRINGS = ["off", "warn", "error"],
|
13
|
-
RULE_SEVERITY = RULE_SEVERITY_STRINGS.reduce((map, value, index) => {
|
14
|
-
map[value] = index;
|
15
|
-
return map;
|
16
|
-
}, {}),
|
17
|
-
VALID_SEVERITIES = [0, 1, 2, "off", "warn", "error"];
|
18
|
-
|
19
|
-
//------------------------------------------------------------------------------
|
20
|
-
// Public Interface
|
21
|
-
//------------------------------------------------------------------------------
|
22
|
-
|
23
|
-
module.exports = {
|
24
|
-
|
25
|
-
/**
|
26
|
-
* Normalizes the severity value of a rule's configuration to a number
|
27
|
-
* @param {(number|string|[number, ...*]|[string, ...*])} ruleConfig A rule's configuration value, generally
|
28
|
-
* received from the user. A valid config value is either 0, 1, 2, the string "off" (treated the same as 0),
|
29
|
-
* the string "warn" (treated the same as 1), the string "error" (treated the same as 2), or an array
|
30
|
-
* whose first element is one of the above values. Strings are matched case-insensitively.
|
31
|
-
* @returns {(0|1|2)} The numeric severity value if the config value was valid, otherwise 0.
|
32
|
-
*/
|
33
|
-
getRuleSeverity(ruleConfig) {
|
34
|
-
const severityValue = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig;
|
35
|
-
|
36
|
-
if (severityValue === 0 || severityValue === 1 || severityValue === 2) {
|
37
|
-
return severityValue;
|
38
|
-
}
|
39
|
-
|
40
|
-
if (typeof severityValue === "string") {
|
41
|
-
return RULE_SEVERITY[severityValue.toLowerCase()] || 0;
|
42
|
-
}
|
43
|
-
|
44
|
-
return 0;
|
45
|
-
},
|
46
|
-
|
47
|
-
/**
|
48
|
-
* Converts old-style severity settings (0, 1, 2) into new-style
|
49
|
-
* severity settings (off, warn, error) for all rules. Assumption is that severity
|
50
|
-
* values have already been validated as correct.
|
51
|
-
* @param {Object} config The config object to normalize.
|
52
|
-
* @returns {void}
|
53
|
-
*/
|
54
|
-
normalizeToStrings(config) {
|
55
|
-
|
56
|
-
if (config.rules) {
|
57
|
-
Object.keys(config.rules).forEach(ruleId => {
|
58
|
-
const ruleConfig = config.rules[ruleId];
|
59
|
-
|
60
|
-
if (typeof ruleConfig === "number") {
|
61
|
-
config.rules[ruleId] = RULE_SEVERITY_STRINGS[ruleConfig] || RULE_SEVERITY_STRINGS[0];
|
62
|
-
} else if (Array.isArray(ruleConfig) && typeof ruleConfig[0] === "number") {
|
63
|
-
ruleConfig[0] = RULE_SEVERITY_STRINGS[ruleConfig[0]] || RULE_SEVERITY_STRINGS[0];
|
64
|
-
}
|
65
|
-
});
|
66
|
-
}
|
67
|
-
},
|
68
|
-
|
69
|
-
/**
|
70
|
-
* Determines if the severity for the given rule configuration represents an error.
|
71
|
-
* @param {int|string|Array} ruleConfig The configuration for an individual rule.
|
72
|
-
* @returns {boolean} True if the rule represents an error, false if not.
|
73
|
-
*/
|
74
|
-
isErrorSeverity(ruleConfig) {
|
75
|
-
return module.exports.getRuleSeverity(ruleConfig) === 2;
|
76
|
-
},
|
77
|
-
|
78
|
-
/**
|
79
|
-
* Checks whether a given config has valid severity or not.
|
80
|
-
* @param {number|string|Array} ruleConfig The configuration for an individual rule.
|
81
|
-
* @returns {boolean} `true` if the configuration has valid severity.
|
82
|
-
*/
|
83
|
-
isValidSeverity(ruleConfig) {
|
84
|
-
let severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig;
|
85
|
-
|
86
|
-
if (typeof severity === "string") {
|
87
|
-
severity = severity.toLowerCase();
|
88
|
-
}
|
89
|
-
return VALID_SEVERITIES.indexOf(severity) !== -1;
|
90
|
-
},
|
91
|
-
|
92
|
-
/**
|
93
|
-
* Checks whether every rule of a given config has valid severity or not.
|
94
|
-
* @param {Object} config The configuration for rules.
|
95
|
-
* @returns {boolean} `true` if the configuration has valid severity.
|
96
|
-
*/
|
97
|
-
isEverySeverityValid(config) {
|
98
|
-
return Object.keys(config).every(ruleId => this.isValidSeverity(config[ruleId]));
|
99
|
-
},
|
100
|
-
|
101
|
-
/**
|
102
|
-
* Normalizes a value for a global in a config
|
103
|
-
* @param {(boolean|string|null)} configuredValue The value given for a global in configuration or in
|
104
|
-
* a global directive comment
|
105
|
-
* @returns {("readable"|"writeable"|"off")} The value normalized as a string
|
106
|
-
* @throws Error if global value is invalid
|
107
|
-
*/
|
108
|
-
normalizeConfigGlobal(configuredValue) {
|
109
|
-
switch (configuredValue) {
|
110
|
-
case "off":
|
111
|
-
return "off";
|
112
|
-
|
113
|
-
case true:
|
114
|
-
case "true":
|
115
|
-
case "writeable":
|
116
|
-
case "writable":
|
117
|
-
return "writable";
|
118
|
-
|
119
|
-
case null:
|
120
|
-
case false:
|
121
|
-
case "false":
|
122
|
-
case "readable":
|
123
|
-
case "readonly":
|
124
|
-
return "readonly";
|
125
|
-
|
126
|
-
default:
|
127
|
-
throw new Error(`'${configuredValue}' is not a valid configuration for a global (use 'readonly', 'writable', or 'off')`);
|
128
|
-
}
|
129
|
-
}
|
130
|
-
};
|
package/lib/shared/naming.js
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @fileoverview Common helpers for naming of plugins, formatters and configs
|
3
|
-
*/
|
4
|
-
"use strict";
|
5
|
-
|
6
|
-
const NAMESPACE_REGEX = /^@.*\//iu;
|
7
|
-
|
8
|
-
/**
|
9
|
-
* Brings package name to correct format based on prefix
|
10
|
-
* @param {string} name The name of the package.
|
11
|
-
* @param {string} prefix Can be either "eslint-plugin", "eslint-config" or "eslint-formatter"
|
12
|
-
* @returns {string} Normalized name of the package
|
13
|
-
* @private
|
14
|
-
*/
|
15
|
-
function normalizePackageName(name, prefix) {
|
16
|
-
let normalizedName = name;
|
17
|
-
|
18
|
-
/**
|
19
|
-
* On Windows, name can come in with Windows slashes instead of Unix slashes.
|
20
|
-
* Normalize to Unix first to avoid errors later on.
|
21
|
-
* https://github.com/eslint/eslint/issues/5644
|
22
|
-
*/
|
23
|
-
if (normalizedName.includes("\\")) {
|
24
|
-
normalizedName = normalizedName.replace(/\\/gu, "/");
|
25
|
-
}
|
26
|
-
|
27
|
-
if (normalizedName.charAt(0) === "@") {
|
28
|
-
|
29
|
-
/**
|
30
|
-
* it's a scoped package
|
31
|
-
* package name is the prefix, or just a username
|
32
|
-
*/
|
33
|
-
const scopedPackageShortcutRegex = new RegExp(`^(@[^/]+)(?:/(?:${prefix})?)?$`, "u"),
|
34
|
-
scopedPackageNameRegex = new RegExp(`^${prefix}(-|$)`, "u");
|
35
|
-
|
36
|
-
if (scopedPackageShortcutRegex.test(normalizedName)) {
|
37
|
-
normalizedName = normalizedName.replace(scopedPackageShortcutRegex, `$1/${prefix}`);
|
38
|
-
} else if (!scopedPackageNameRegex.test(normalizedName.split("/")[1])) {
|
39
|
-
|
40
|
-
/**
|
41
|
-
* for scoped packages, insert the prefix after the first / unless
|
42
|
-
* the path is already @scope/eslint or @scope/eslint-xxx-yyy
|
43
|
-
*/
|
44
|
-
normalizedName = normalizedName.replace(/^@([^/]+)\/(.*)$/u, `@$1/${prefix}-$2`);
|
45
|
-
}
|
46
|
-
} else if (!normalizedName.startsWith(`${prefix}-`)) {
|
47
|
-
normalizedName = `${prefix}-${normalizedName}`;
|
48
|
-
}
|
49
|
-
|
50
|
-
return normalizedName;
|
51
|
-
}
|
52
|
-
|
53
|
-
/**
|
54
|
-
* Removes the prefix from a fullname.
|
55
|
-
* @param {string} fullname The term which may have the prefix.
|
56
|
-
* @param {string} prefix The prefix to remove.
|
57
|
-
* @returns {string} The term without prefix.
|
58
|
-
*/
|
59
|
-
function getShorthandName(fullname, prefix) {
|
60
|
-
if (fullname[0] === "@") {
|
61
|
-
let matchResult = new RegExp(`^(@[^/]+)/${prefix}$`, "u").exec(fullname);
|
62
|
-
|
63
|
-
if (matchResult) {
|
64
|
-
return matchResult[1];
|
65
|
-
}
|
66
|
-
|
67
|
-
matchResult = new RegExp(`^(@[^/]+)/${prefix}-(.+)$`, "u").exec(fullname);
|
68
|
-
if (matchResult) {
|
69
|
-
return `${matchResult[1]}/${matchResult[2]}`;
|
70
|
-
}
|
71
|
-
} else if (fullname.startsWith(`${prefix}-`)) {
|
72
|
-
return fullname.slice(prefix.length + 1);
|
73
|
-
}
|
74
|
-
|
75
|
-
return fullname;
|
76
|
-
}
|
77
|
-
|
78
|
-
/**
|
79
|
-
* Gets the scope (namespace) of a term.
|
80
|
-
* @param {string} term The term which may have the namespace.
|
81
|
-
* @returns {string} The namespace of the term if it has one.
|
82
|
-
*/
|
83
|
-
function getNamespaceFromTerm(term) {
|
84
|
-
const match = term.match(NAMESPACE_REGEX);
|
85
|
-
|
86
|
-
return match ? match[0] : "";
|
87
|
-
}
|
88
|
-
|
89
|
-
//------------------------------------------------------------------------------
|
90
|
-
// Public Interface
|
91
|
-
//------------------------------------------------------------------------------
|
92
|
-
|
93
|
-
module.exports = {
|
94
|
-
normalizePackageName,
|
95
|
-
getShorthandName,
|
96
|
-
getNamespaceFromTerm
|
97
|
-
};
|