eslint 7.11.0 → 7.14.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 +54 -0
- package/README.md +6 -5
- package/bin/eslint.js +1 -1
- package/lib/cli-engine/cli-engine.js +26 -7
- package/lib/cli-engine/file-enumerator.js +12 -3
- package/lib/linter/report-translator.js +13 -9
- package/lib/linter/timing.js +23 -2
- package/lib/rules/constructor-super.js +11 -0
- package/lib/rules/index.js +1 -0
- package/lib/rules/no-constant-condition.js +42 -20
- package/lib/rules/no-irregular-whitespace.js +7 -9
- package/lib/rules/no-nonoctal-decimal-escape.js +147 -0
- package/lib/rules/no-prototype-builtins.js +4 -4
- package/lib/rules/no-script-url.js +21 -7
- package/lib/rules/no-useless-constructor.js +8 -0
- package/lib/rules/prefer-destructuring.js +19 -1
- package/lib/rules/prefer-template.js +14 -22
- package/lib/rules/quotes.js +5 -2
- package/lib/rules/space-before-blocks.js +34 -9
- package/lib/rules/utils/ast-utils.js +22 -7
- package/lib/rules/yoda.js +33 -23
- package/package.json +2 -2
- package/lib/cli-engine/cascading-config-array-factory.js +0 -502
- package/lib/cli-engine/config-array/config-array.js +0 -536
- package/lib/cli-engine/config-array/config-dependency.js +0 -128
- package/lib/cli-engine/config-array/extracted-config.js +0 -158
- package/lib/cli-engine/config-array/ignore-pattern.js +0 -249
- package/lib/cli-engine/config-array/index.js +0 -32
- package/lib/cli-engine/config-array/override-tester.js +0 -235
- package/lib/cli-engine/config-array-factory.js +0 -1092
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,57 @@
|
|
1
|
+
v7.14.0 - November 20, 2020
|
2
|
+
|
3
|
+
* [`5f09073`](https://github.com/eslint/eslint/commit/5f0907399a9666dec78c74384c8969c01483c30e) Update: fix 'skip' options in no-irregular-whitespace (fixes #13852) (#13853) (Milos Djermanovic)
|
4
|
+
* [`1861b40`](https://github.com/eslint/eslint/commit/1861b4086f1018f43ab19744d866d5da986c500d) Docs: correct the function-call-argument-newline 'default' descriptions (#13866) (Trevin Hofmann)
|
5
|
+
* [`98c00c4`](https://github.com/eslint/eslint/commit/98c00c41d2aecb3a990393d430694f4ce6b47de5) New: Add no-nonoctal-decimal-escape rule (fixes #13765) (#13845) (Milos Djermanovic)
|
6
|
+
* [`95d2fe6`](https://github.com/eslint/eslint/commit/95d2fe6057498fc1cc2193d28c8c2d1593224b33) Chore: remove eslint comment from no-octal-escape tests (#13846) (Milos Djermanovic)
|
7
|
+
* [`2004b7e`](https://github.com/eslint/eslint/commit/2004b7ecd3db0d4e7376cc3344246f7b9ada5801) Fix: enable debug logs for @eslint/eslintrc (fixes #13850) (#13861) (Milos Djermanovic)
|
8
|
+
* [`d2239a1`](https://github.com/eslint/eslint/commit/d2239a1fdec452e24ede04e990d16d42516fa538) Fix: no-useless-constructor crash on bodyless constructor (fixes #13830) (#13842) (Ari Perkkiö)
|
9
|
+
* [`eda0aa1`](https://github.com/eslint/eslint/commit/eda0aa18498dd85eb618873e8e0f4ac97032cfca) Docs: no-restricted-imports is only for static imports (#13863) (Robat Williams)
|
10
|
+
* [`042ae44`](https://github.com/eslint/eslint/commit/042ae44682a8a6c5037d920689124e2304056dd8) Docs: Fix JS syntax and doc URL in working-with-custom-formatters.md (#13828) (Raphael LANG)
|
11
|
+
* [`038dc73`](https://github.com/eslint/eslint/commit/038dc73c99ae68eae2035ef303f3a947053c8f05) Chore: Test on Node.js 15 (#13844) (Brandon Mills)
|
12
|
+
* [`37a06d6`](https://github.com/eslint/eslint/commit/37a06d633d3669f0f43236141dc43465b8bc7ec5) Sponsors: Sync README with website (ESLint Jenkins)
|
13
|
+
|
14
|
+
v7.13.0 - November 6, 2020
|
15
|
+
|
16
|
+
* [`254e00f`](https://github.com/eslint/eslint/commit/254e00fea8745ff5a8bcc8cb874fcfd02996d81b) New: Configurable List Size For Per-Rule Performance Metrics (#13812) (Bryan Mishkin)
|
17
|
+
* [`6c3c710`](https://github.com/eslint/eslint/commit/6c3c710ade7cd8654990f1adb55b58f038eab92d) Docs: fix broken url in docs (#13815) (SaintMalik)
|
18
|
+
* [`4a09149`](https://github.com/eslint/eslint/commit/4a091495a236d231a5065ece972719a0c4dd1b77) Sponsors: Sync README with website (ESLint Jenkins)
|
19
|
+
* [`fb6fcbf`](https://github.com/eslint/eslint/commit/fb6fcbfe0a8c41b92f0a33ab90f159037bd195e2) Docs: Fix reference to Code of Conduct (#13797) (Tobias Nießen)
|
20
|
+
* [`1b89ebe`](https://github.com/eslint/eslint/commit/1b89ebe1bdbef7de6001100945b8f71429df302c) Sponsors: Sync README with website (ESLint Jenkins)
|
21
|
+
|
22
|
+
v7.12.1 - October 26, 2020
|
23
|
+
|
24
|
+
* [`08f33e8`](https://github.com/eslint/eslint/commit/08f33e8b9a353c3183be6f937785db7a30fb90eb) Upgrade: @eslint/eslintrc to fix rule schema validation (fixes #13793) (#13794) (Brandon Mills)
|
25
|
+
* [`aeef485`](https://github.com/eslint/eslint/commit/aeef485dc790571b1a82ac09904329e0226b66a9) Fix: Pass internal config paths in FileEnumerator default (fixes #13789) (#13792) (Brandon Mills)
|
26
|
+
* [`631ae8b`](https://github.com/eslint/eslint/commit/631ae8b50e5f7975f10860e9e763b70b4f25182e) Sponsors: Sync README with website (ESLint Jenkins)
|
27
|
+
|
28
|
+
v7.12.0 - October 23, 2020
|
29
|
+
|
30
|
+
* [`cbf3585`](https://github.com/eslint/eslint/commit/cbf3585f1d6c60414c07380367a8b4505ee3538d) Update: skip keyword check for fns in space-before-blocks (fixes #13553) (#13712) (Milos Djermanovic)
|
31
|
+
* [`256f656`](https://github.com/eslint/eslint/commit/256f656455b47bcf9ed3fc30fbf72532678f97da) Fix: autofix shouldn't produce template literals with `\8` or `\9` (#13737) (Milos Djermanovic)
|
32
|
+
* [`b165aa5`](https://github.com/eslint/eslint/commit/b165aa5f4d4d19328f13ab80e5f058cbce94c3a6) Fix: yoda rule autofix produces syntax errors with adjacent tokens (#13760) (Milos Djermanovic)
|
33
|
+
* [`3175316`](https://github.com/eslint/eslint/commit/3175316db26aebef4b19e269aca90c8ce3955363) Fix: prefer-destructuring invalid autofix with comma operator (#13761) (Milos Djermanovic)
|
34
|
+
* [`1a9f171`](https://github.com/eslint/eslint/commit/1a9f17151a4e93eb17c8a2bf4f0a5320cce616de) Chore: Remove more ESLintRC-related files (refs #13481) (#13762) (Nicholas C. Zakas)
|
35
|
+
* [`bfddced`](https://github.com/eslint/eslint/commit/bfddcedace5587d662c840c2edf33062b54a178e) Update: remove suggestion if it didn't provide a fix (fixes #13723) (#13772) (Milos Djermanovic)
|
36
|
+
* [`5183b14`](https://github.com/eslint/eslint/commit/5183b14a2420b42b4089fb134a61ae57142f31fd) Update: check template literal in no-script-url (#13775) (YeonJuan)
|
37
|
+
* [`bfe97d2`](https://github.com/eslint/eslint/commit/bfe97d2332e711ca76b1fd2e7f8548b0cc84cb1c) Sponsors: Sync README with website (ESLint Jenkins)
|
38
|
+
* [`6c51ade`](https://github.com/eslint/eslint/commit/6c51adeb86f1de292cd02d2ee19f7b56182e358b) Sponsors: Sync README with website (ESLint Jenkins)
|
39
|
+
* [`603de04`](https://github.com/eslint/eslint/commit/603de04cab5e700df12999af2918decd4da9d11b) Update: treat all literals like boolean literal in no-constant-condition (#13245) (Zen)
|
40
|
+
* [`289aa6f`](https://github.com/eslint/eslint/commit/289aa6fcef3874ba5f86455f9302dc4209ea83e5) Sponsors: Sync README with website (ESLint Jenkins)
|
41
|
+
* [`9a1f669`](https://github.com/eslint/eslint/commit/9a1f6694e59eb3e584d4c5a98b98675c895a9783) Sponsors: Sync README with website (ESLint Jenkins)
|
42
|
+
* [`637f818`](https://github.com/eslint/eslint/commit/637f8187404ded600fb3d4013b3cd495d5ae675b) Docs: add more examples for no-func-assign (fixes #13705) (#13777) (Nitin Kumar)
|
43
|
+
* [`17cc0dd`](https://github.com/eslint/eslint/commit/17cc0dd9b5d2d500359c36881cd3e5637443c133) Chore: add test case for no-func-assign (refs #13705) (#13783) (Nitin Kumar)
|
44
|
+
* [`dee0f77`](https://github.com/eslint/eslint/commit/dee0f7764a1d5a323c89b22c4db94acee2b3c718) Docs: add TOC to user-guide/configuring.md (#13727) (metasean)
|
45
|
+
* [`0510621`](https://github.com/eslint/eslint/commit/05106212985cb1ffa1e6fa996a57f6fd2fc3c970) Update: Fix && vs || short-circuiting false negatives (fixes #13634) (#13769) (Brandon Mills)
|
46
|
+
* [`8b6ed69`](https://github.com/eslint/eslint/commit/8b6ed691c48189b7d096339441a78cb5874d4137) Sponsors: Sync README with website (ESLint Jenkins)
|
47
|
+
* [`1457509`](https://github.com/eslint/eslint/commit/145750991b04fd4cfb3fff3c5d4211a4428e011c) Docs: fix broken links in Node.js API docs (#13771) (Laura Barluzzi)
|
48
|
+
* [`7c813d4`](https://github.com/eslint/eslint/commit/7c813d458f9aedf7a94351d137728a4647542879) Docs: Fix typo in v7 migration page (#13778) (Yusuke Sasaki)
|
49
|
+
* [`b025795`](https://github.com/eslint/eslint/commit/b0257953be704d0bb387fc15afd7859fd6f19ba5) Docs: Fix the format option name in the document (#13770) (Hideki Igarashi)
|
50
|
+
* [`84fd591`](https://github.com/eslint/eslint/commit/84fd591c234accc41bb5af555f178825012fd35d) Chore: Increase Mocha timeout for copying fixtures (#13768) (Brandon Mills)
|
51
|
+
* [`1faeb84`](https://github.com/eslint/eslint/commit/1faeb84e663d88c5d85a3cb3f15cd224cc552c2d) Docs: clarify that space-unary-ops doesn't apply when space is required (#13767) (Taylor Morgan)
|
52
|
+
* [`67c0605`](https://github.com/eslint/eslint/commit/67c06059dd1ddcee6f369c650ce71220da1510c3) Update: check computed keys in no-prototype-builtins (fixes #13088) (#13755) (Milos Djermanovic)
|
53
|
+
* [`b5e011c`](https://github.com/eslint/eslint/commit/b5e011c865e95d700d29cb9a4ba71c671d99e423) Sponsors: Sync README with website (ESLint Jenkins)
|
54
|
+
|
1
55
|
v7.11.0 - October 9, 2020
|
2
56
|
|
3
57
|
* [`23e966f`](https://github.com/eslint/eslint/commit/23e966f6cf2a6c6b699dff5d6950ece3cc396498) Chore: Refactor CLIEngine tests (refs #13481) (#13709) (Nicholas C. Zakas)
|
package/README.md
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
[Rules](https://eslint.org/docs/rules/) |
|
15
15
|
[Contributing](https://eslint.org/docs/developer-guide/contributing) |
|
16
16
|
[Reporting Bugs](https://eslint.org/docs/developer-guide/contributing/reporting-bugs) |
|
17
|
-
[Code of Conduct](https://
|
17
|
+
[Code of Conduct](https://eslint.org/conduct) |
|
18
18
|
[Twitter](https://twitter.com/geteslint) |
|
19
19
|
[Mailing List](https://groups.google.com/group/eslint) |
|
20
20
|
[Chat Room](https://eslint.org/chat)
|
@@ -85,7 +85,7 @@ The three error levels allow you fine-grained control over how ESLint applies ru
|
|
85
85
|
|
86
86
|
## <a name="code-of-conduct"></a>Code of Conduct
|
87
87
|
|
88
|
-
ESLint adheres to the [JS Foundation Code of Conduct](https://
|
88
|
+
ESLint adheres to the [JS Foundation Code of Conduct](https://eslint.org/conduct).
|
89
89
|
|
90
90
|
## <a name="filing-issues"></a>Filing Issues
|
91
91
|
|
@@ -263,10 +263,11 @@ The following companies, organizations, and individuals support ESLint's ongoing
|
|
263
263
|
|
264
264
|
<!-- NOTE: This section is autogenerated. Do not manually edit.-->
|
265
265
|
<!--sponsorsstart-->
|
266
|
-
<h3>
|
267
|
-
<p><a href="https://
|
266
|
+
<h3>Platinum Sponsors</h3>
|
267
|
+
<p><a href="https://automattic.com"><img src="https://images.opencollective.com/photomatt/ff91f0b/logo.png" alt="Automattic" height="undefined"></a></p><h3>Gold Sponsors</h3>
|
268
|
+
<p><a href="https://google.com/chrome"><img src="https://images.opencollective.com/chrome/dc55bd4/logo.png" alt="Chrome's Web Framework & Tools Performance Fund" height="96"></a> <a href="https://www.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> <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
269
|
<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://writersperhour.com
|
270
|
+
<p><a href="https://writersperhour.com"><img src="https://images.opencollective.com/writersperhour/5787d4b/logo.png" alt="Writers Per Hour" height="32"></a> <a href="https://www.betacalendars.com/printable-calendar"><img src="https://images.opencollective.com/betacalendars/9334b33/logo.png" alt="2021 calendar" height="32"></a> <a href="https://buy.fineproxy.org/eng/"><img src="https://images.opencollective.com/buy-fineproxy-org/b282e39/logo.png" alt="Buy.Fineproxy.Org" 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.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" 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/7fa1641/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.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a></p>
|
270
271
|
<!--sponsorsend-->
|
271
272
|
|
272
273
|
## <a name="technology-sponsors"></a>Technology Sponsors
|
package/bin/eslint.js
CHANGED
@@ -14,7 +14,7 @@ require("v8-compile-cache");
|
|
14
14
|
|
15
15
|
// must do this initialization *before* other requires in order to work
|
16
16
|
if (process.argv.includes("--debug")) {
|
17
|
-
require("debug").enable("eslint:*,-eslint:code-path");
|
17
|
+
require("debug").enable("eslint:*,-eslint:code-path,eslintrc:*");
|
18
18
|
}
|
19
19
|
|
20
20
|
//------------------------------------------------------------------------------
|
@@ -19,14 +19,29 @@ 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
|
-
|
23
|
-
|
24
|
-
const
|
22
|
+
|
23
|
+
|
24
|
+
const {
|
25
|
+
Legacy: {
|
26
|
+
ConfigOps,
|
27
|
+
naming,
|
28
|
+
CascadingConfigArrayFactory,
|
29
|
+
IgnorePattern,
|
30
|
+
getUsedExtractedConfigs
|
31
|
+
}
|
32
|
+
} = require("@eslint/eslintrc");
|
33
|
+
|
34
|
+
/*
|
35
|
+
* For some reason, ModuleResolver must be included via filepath instead of by
|
36
|
+
* API exports in order to work properly. That's why this is separated out onto
|
37
|
+
* its own require() statement.
|
38
|
+
*/
|
39
|
+
const ModuleResolver = require("@eslint/eslintrc/lib/shared/relative-module-resolver");
|
40
|
+
const { FileEnumerator } = require("./file-enumerator");
|
41
|
+
|
25
42
|
const { Linter } = require("../linter");
|
26
43
|
const builtInRules = require("../rules");
|
27
|
-
const
|
28
|
-
const { IgnorePattern, getUsedExtractedConfigs } = require("./config-array");
|
29
|
-
const { FileEnumerator } = require("./file-enumerator");
|
44
|
+
const loadRules = require("./load-rules");
|
30
45
|
const hash = require("./hash");
|
31
46
|
const LintResultCache = require("./lint-result-cache");
|
32
47
|
|
@@ -559,7 +574,11 @@ class CLIEngine {
|
|
559
574
|
resolvePluginsRelativeTo: options.resolvePluginsRelativeTo,
|
560
575
|
rulePaths: options.rulePaths,
|
561
576
|
specificConfigPath: options.configFile,
|
562
|
-
useEslintrc: options.useEslintrc
|
577
|
+
useEslintrc: options.useEslintrc,
|
578
|
+
builtInRules,
|
579
|
+
loadRules,
|
580
|
+
eslintRecommendedPath: path.resolve(__dirname, "../../conf/eslint-recommended.js"),
|
581
|
+
eslintAllPath: path.resolve(__dirname, "../../conf/eslint-all.js")
|
563
582
|
});
|
564
583
|
const fileEnumerator = new FileEnumerator({
|
565
584
|
configArrayFactory,
|
@@ -40,8 +40,13 @@ const getGlobParent = require("glob-parent");
|
|
40
40
|
const isGlob = require("is-glob");
|
41
41
|
const { escapeRegExp } = require("lodash");
|
42
42
|
const { Minimatch } = require("minimatch");
|
43
|
-
|
44
|
-
const {
|
43
|
+
|
44
|
+
const {
|
45
|
+
Legacy: {
|
46
|
+
IgnorePattern,
|
47
|
+
CascadingConfigArrayFactory
|
48
|
+
}
|
49
|
+
} = require("@eslint/eslintrc");
|
45
50
|
const debug = require("debug")("eslint:file-enumerator");
|
46
51
|
|
47
52
|
//------------------------------------------------------------------------------
|
@@ -208,7 +213,11 @@ class FileEnumerator {
|
|
208
213
|
*/
|
209
214
|
constructor({
|
210
215
|
cwd = process.cwd(),
|
211
|
-
configArrayFactory = new CascadingConfigArrayFactory({
|
216
|
+
configArrayFactory = new CascadingConfigArrayFactory({
|
217
|
+
cwd,
|
218
|
+
eslintRecommendedPath: path.resolve(__dirname, "../../conf/eslint-recommended.js"),
|
219
|
+
eslintAllPath: path.resolve(__dirname, "../../conf/eslint-all.js")
|
220
|
+
}),
|
212
221
|
extensions = null,
|
213
222
|
globInputPaths = true,
|
214
223
|
errorOnUnmatchedPattern = true,
|
@@ -196,15 +196,19 @@ function mapSuggestions(descriptor, sourceCode, messages) {
|
|
196
196
|
return [];
|
197
197
|
}
|
198
198
|
|
199
|
-
return descriptor.suggest
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
199
|
+
return descriptor.suggest
|
200
|
+
.map(suggestInfo => {
|
201
|
+
const computedDesc = suggestInfo.desc || messages[suggestInfo.messageId];
|
202
|
+
|
203
|
+
return {
|
204
|
+
...suggestInfo,
|
205
|
+
desc: interpolate(computedDesc, suggestInfo.data),
|
206
|
+
fix: normalizeFixes(suggestInfo, sourceCode)
|
207
|
+
};
|
208
|
+
})
|
209
|
+
|
210
|
+
// Remove suggestions that didn't provide a fix
|
211
|
+
.filter(({ fix }) => fix);
|
208
212
|
}
|
209
213
|
|
210
214
|
/**
|
package/lib/linter/timing.js
CHANGED
@@ -44,6 +44,26 @@ const enabled = !!process.env.TIMING;
|
|
44
44
|
const HEADERS = ["Rule", "Time (ms)", "Relative"];
|
45
45
|
const ALIGN = [alignLeft, alignRight, alignRight];
|
46
46
|
|
47
|
+
/**
|
48
|
+
* Decide how many rules to show in the output list.
|
49
|
+
* @returns {number} the number of rules to show
|
50
|
+
*/
|
51
|
+
function getListSize() {
|
52
|
+
const MINIMUM_SIZE = 10;
|
53
|
+
|
54
|
+
if (typeof process.env.TIMING !== "string") {
|
55
|
+
return MINIMUM_SIZE;
|
56
|
+
}
|
57
|
+
|
58
|
+
if (process.env.TIMING.toLowerCase() === "all") {
|
59
|
+
return Number.POSITIVE_INFINITY;
|
60
|
+
}
|
61
|
+
|
62
|
+
const TIMING_ENV_VAR_AS_INTEGER = Number.parseInt(process.env.TIMING, 10);
|
63
|
+
|
64
|
+
return TIMING_ENV_VAR_AS_INTEGER > 10 ? TIMING_ENV_VAR_AS_INTEGER : MINIMUM_SIZE;
|
65
|
+
}
|
66
|
+
|
47
67
|
/* istanbul ignore next */
|
48
68
|
/**
|
49
69
|
* display the data
|
@@ -61,7 +81,7 @@ function display(data) {
|
|
61
81
|
return [key, time];
|
62
82
|
})
|
63
83
|
.sort((a, b) => b[1] - a[1])
|
64
|
-
.slice(0,
|
84
|
+
.slice(0, getListSize());
|
65
85
|
|
66
86
|
rows.forEach(row => {
|
67
87
|
row.push(`${(row[1] * 100 / total).toFixed(1)}%`);
|
@@ -133,7 +153,8 @@ module.exports = (function() {
|
|
133
153
|
|
134
154
|
return {
|
135
155
|
time,
|
136
|
-
enabled
|
156
|
+
enabled,
|
157
|
+
getListSize
|
137
158
|
};
|
138
159
|
|
139
160
|
}());
|
@@ -79,6 +79,17 @@ function isPossibleConstructor(node) {
|
|
79
79
|
return false;
|
80
80
|
|
81
81
|
case "LogicalExpression":
|
82
|
+
|
83
|
+
/*
|
84
|
+
* If the && operator short-circuits, the left side was falsy and therefore not a constructor, and if
|
85
|
+
* it doesn't short-circuit, it takes the value from the right side, so the right side must always be a
|
86
|
+
* possible constructor. A future improvement could verify that the left side could be truthy by
|
87
|
+
* excluding falsy literals.
|
88
|
+
*/
|
89
|
+
if (node.operator === "&&") {
|
90
|
+
return isPossibleConstructor(node.right);
|
91
|
+
}
|
92
|
+
|
82
93
|
return (
|
83
94
|
isPossibleConstructor(node.left) ||
|
84
95
|
isPossibleConstructor(node.right)
|
package/lib/rules/index.js
CHANGED
@@ -169,6 +169,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
|
|
169
169
|
"no-new-require": () => require("./no-new-require"),
|
170
170
|
"no-new-symbol": () => require("./no-new-symbol"),
|
171
171
|
"no-new-wrappers": () => require("./no-new-wrappers"),
|
172
|
+
"no-nonoctal-decimal-escape": () => require("./no-nonoctal-decimal-escape"),
|
172
173
|
"no-obj-calls": () => require("./no-obj-calls"),
|
173
174
|
"no-octal": () => require("./no-octal"),
|
174
175
|
"no-octal-escape": () => require("./no-octal-escape"),
|
@@ -9,9 +9,6 @@
|
|
9
9
|
// Helpers
|
10
10
|
//------------------------------------------------------------------------------
|
11
11
|
|
12
|
-
const EQUALITY_OPERATORS = ["===", "!==", "==", "!="];
|
13
|
-
const RELATIONAL_OPERATORS = [">", "<", ">=", "<=", "in", "instanceof"];
|
14
|
-
|
15
12
|
//------------------------------------------------------------------------------
|
16
13
|
// Rule Definition
|
17
14
|
//------------------------------------------------------------------------------
|
@@ -56,6 +53,35 @@ module.exports = {
|
|
56
53
|
// Helpers
|
57
54
|
//--------------------------------------------------------------------------
|
58
55
|
|
56
|
+
/**
|
57
|
+
* Returns literal's value converted to the Boolean type
|
58
|
+
* @param {ASTNode} node any `Literal` node
|
59
|
+
* @returns {boolean | null} `true` when node is truthy, `false` when node is falsy,
|
60
|
+
* `null` when it cannot be determined.
|
61
|
+
*/
|
62
|
+
function getBooleanValue(node) {
|
63
|
+
if (node.value === null) {
|
64
|
+
|
65
|
+
/*
|
66
|
+
* it might be a null literal or bigint/regex literal in unsupported environments .
|
67
|
+
* https://github.com/estree/estree/blob/14df8a024956ea289bd55b9c2226a1d5b8a473ee/es5.md#regexpliteral
|
68
|
+
* https://github.com/estree/estree/blob/14df8a024956ea289bd55b9c2226a1d5b8a473ee/es2020.md#bigintliteral
|
69
|
+
*/
|
70
|
+
|
71
|
+
if (node.raw === "null") {
|
72
|
+
return false;
|
73
|
+
}
|
74
|
+
|
75
|
+
// regex is always truthy
|
76
|
+
if (typeof node.regex === "object") {
|
77
|
+
return true;
|
78
|
+
}
|
79
|
+
|
80
|
+
return null;
|
81
|
+
}
|
82
|
+
|
83
|
+
return !!node.value;
|
84
|
+
}
|
59
85
|
|
60
86
|
/**
|
61
87
|
* Checks if a branch node of LogicalExpression short circuits the whole condition
|
@@ -66,15 +92,23 @@ module.exports = {
|
|
66
92
|
function isLogicalIdentity(node, operator) {
|
67
93
|
switch (node.type) {
|
68
94
|
case "Literal":
|
69
|
-
return (operator === "||" && node
|
70
|
-
(operator === "&&" && node
|
95
|
+
return (operator === "||" && getBooleanValue(node) === true) ||
|
96
|
+
(operator === "&&" && getBooleanValue(node) === false);
|
71
97
|
|
72
98
|
case "UnaryExpression":
|
73
99
|
return (operator === "&&" && node.operator === "void");
|
74
100
|
|
75
101
|
case "LogicalExpression":
|
76
|
-
|
77
|
-
|
102
|
+
|
103
|
+
/*
|
104
|
+
* handles `a && false || b`
|
105
|
+
* `false` is an identity element of `&&` but not `||`
|
106
|
+
*/
|
107
|
+
return operator === node.operator &&
|
108
|
+
(
|
109
|
+
isLogicalIdentity(node.left, node.operator) ||
|
110
|
+
isLogicalIdentity(node.right, node.operator)
|
111
|
+
);
|
78
112
|
|
79
113
|
// no default
|
80
114
|
}
|
@@ -129,21 +163,9 @@ module.exports = {
|
|
129
163
|
const isLeftConstant = isConstant(node.left, inBooleanPosition);
|
130
164
|
const isRightConstant = isConstant(node.right, inBooleanPosition);
|
131
165
|
const isLeftShortCircuit = (isLeftConstant && isLogicalIdentity(node.left, node.operator));
|
132
|
-
const isRightShortCircuit = (isRightConstant && isLogicalIdentity(node.right, node.operator));
|
166
|
+
const isRightShortCircuit = (inBooleanPosition && isRightConstant && isLogicalIdentity(node.right, node.operator));
|
133
167
|
|
134
168
|
return (isLeftConstant && isRightConstant) ||
|
135
|
-
(
|
136
|
-
|
137
|
-
// in the case of an "OR", we need to know if the right constant value is truthy
|
138
|
-
node.operator === "||" &&
|
139
|
-
isRightConstant &&
|
140
|
-
node.right.value &&
|
141
|
-
(
|
142
|
-
!node.parent ||
|
143
|
-
node.parent.type !== "BinaryExpression" ||
|
144
|
-
!(EQUALITY_OPERATORS.includes(node.parent.operator) || RELATIONAL_OPERATORS.includes(node.parent.operator))
|
145
|
-
)
|
146
|
-
) ||
|
147
169
|
isLeftShortCircuit ||
|
148
170
|
isRightShortCircuit;
|
149
171
|
}
|
@@ -82,7 +82,7 @@ module.exports = {
|
|
82
82
|
const commentNodes = sourceCode.getAllComments();
|
83
83
|
|
84
84
|
/**
|
85
|
-
* Removes errors that occur inside
|
85
|
+
* Removes errors that occur inside the given node
|
86
86
|
* @param {ASTNode} node to check for matching errors.
|
87
87
|
* @returns {void}
|
88
88
|
* @private
|
@@ -91,14 +91,12 @@ module.exports = {
|
|
91
91
|
const locStart = node.loc.start;
|
92
92
|
const locEnd = node.loc.end;
|
93
93
|
|
94
|
-
errors = errors.filter(({ loc: { start:
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
return true;
|
101
|
-
});
|
94
|
+
errors = errors.filter(({ loc: { start: errorLocStart } }) => (
|
95
|
+
errorLocStart.line < locStart.line ||
|
96
|
+
errorLocStart.line === locStart.line && errorLocStart.column < locStart.column ||
|
97
|
+
errorLocStart.line === locEnd.line && errorLocStart.column >= locEnd.column ||
|
98
|
+
errorLocStart.line > locEnd.line
|
99
|
+
));
|
102
100
|
}
|
103
101
|
|
104
102
|
/**
|
@@ -0,0 +1,147 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Rule to disallow `\8` and `\9` escape sequences in string literals.
|
3
|
+
* @author Milos Djermanovic
|
4
|
+
*/
|
5
|
+
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
// Helpers
|
10
|
+
//------------------------------------------------------------------------------
|
11
|
+
|
12
|
+
const QUICK_TEST_REGEX = /\\[89]/u;
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Returns unicode escape sequence that represents the given character.
|
16
|
+
* @param {string} character A single code unit.
|
17
|
+
* @returns {string} "\uXXXX" sequence.
|
18
|
+
*/
|
19
|
+
function getUnicodeEscape(character) {
|
20
|
+
return `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`;
|
21
|
+
}
|
22
|
+
|
23
|
+
//------------------------------------------------------------------------------
|
24
|
+
// Rule Definition
|
25
|
+
//------------------------------------------------------------------------------
|
26
|
+
|
27
|
+
module.exports = {
|
28
|
+
meta: {
|
29
|
+
type: "suggestion",
|
30
|
+
|
31
|
+
docs: {
|
32
|
+
description: "disallow `\\8` and `\\9` escape sequences in string literals",
|
33
|
+
category: "Best Practices",
|
34
|
+
recommended: false,
|
35
|
+
url: "https://eslint.org/docs/rules/no-nonoctal-decimal-escape",
|
36
|
+
suggestion: true
|
37
|
+
},
|
38
|
+
|
39
|
+
schema: [],
|
40
|
+
|
41
|
+
messages: {
|
42
|
+
decimalEscape: "Don't use '{{decimalEscape}}' escape sequence.",
|
43
|
+
|
44
|
+
// suggestions
|
45
|
+
refactor: "Replace '{{original}}' with '{{replacement}}'. This maintains the current functionality.",
|
46
|
+
escapeBackslash: "Replace '{{original}}' with '{{replacement}}' to include the actual backslash character."
|
47
|
+
}
|
48
|
+
},
|
49
|
+
|
50
|
+
create(context) {
|
51
|
+
const sourceCode = context.getSourceCode();
|
52
|
+
|
53
|
+
/**
|
54
|
+
* Creates a new Suggestion object.
|
55
|
+
* @param {string} messageId "refactor" or "escapeBackslash".
|
56
|
+
* @param {int[]} range The range to replace.
|
57
|
+
* @param {string} replacement New text for the range.
|
58
|
+
* @returns {Object} Suggestion
|
59
|
+
*/
|
60
|
+
function createSuggestion(messageId, range, replacement) {
|
61
|
+
return {
|
62
|
+
messageId,
|
63
|
+
data: {
|
64
|
+
original: sourceCode.getText().slice(...range),
|
65
|
+
replacement
|
66
|
+
},
|
67
|
+
fix(fixer) {
|
68
|
+
return fixer.replaceTextRange(range, replacement);
|
69
|
+
}
|
70
|
+
};
|
71
|
+
}
|
72
|
+
|
73
|
+
return {
|
74
|
+
Literal(node) {
|
75
|
+
if (typeof node.value !== "string") {
|
76
|
+
return;
|
77
|
+
}
|
78
|
+
|
79
|
+
if (!QUICK_TEST_REGEX.test(node.raw)) {
|
80
|
+
return;
|
81
|
+
}
|
82
|
+
|
83
|
+
const regex = /(?:[^\\]|(?<previousEscape>\\.))*?(?<decimalEscape>\\[89])/suy;
|
84
|
+
let match;
|
85
|
+
|
86
|
+
while ((match = regex.exec(node.raw))) {
|
87
|
+
const { previousEscape, decimalEscape } = match.groups;
|
88
|
+
const decimalEscapeRangeEnd = node.range[0] + match.index + match[0].length;
|
89
|
+
const decimalEscapeRangeStart = decimalEscapeRangeEnd - decimalEscape.length;
|
90
|
+
const decimalEscapeRange = [decimalEscapeRangeStart, decimalEscapeRangeEnd];
|
91
|
+
const suggest = [];
|
92
|
+
|
93
|
+
// When `regex` is matched, `previousEscape` can only capture characters adjacent to `decimalEscape`
|
94
|
+
if (previousEscape === "\\0") {
|
95
|
+
|
96
|
+
/*
|
97
|
+
* Now we have a NULL escape "\0" immediately followed by a decimal escape, e.g.: "\0\8".
|
98
|
+
* Fixing this to "\08" would turn "\0" into a legacy octal escape. To avoid producing
|
99
|
+
* an octal escape while fixing a decimal escape, we provide different suggestions.
|
100
|
+
*/
|
101
|
+
suggest.push(
|
102
|
+
createSuggestion( // "\0\8" -> "\u00008"
|
103
|
+
"refactor",
|
104
|
+
[decimalEscapeRangeStart - previousEscape.length, decimalEscapeRangeEnd],
|
105
|
+
`${getUnicodeEscape("\0")}${decimalEscape[1]}`
|
106
|
+
),
|
107
|
+
createSuggestion( // "\8" -> "\u0038"
|
108
|
+
"refactor",
|
109
|
+
decimalEscapeRange,
|
110
|
+
getUnicodeEscape(decimalEscape[1])
|
111
|
+
)
|
112
|
+
);
|
113
|
+
} else {
|
114
|
+
suggest.push(
|
115
|
+
createSuggestion( // "\8" -> "8"
|
116
|
+
"refactor",
|
117
|
+
decimalEscapeRange,
|
118
|
+
decimalEscape[1]
|
119
|
+
)
|
120
|
+
);
|
121
|
+
}
|
122
|
+
|
123
|
+
suggest.push(
|
124
|
+
createSuggestion( // "\8" -> "\\8"
|
125
|
+
"escapeBackslash",
|
126
|
+
decimalEscapeRange,
|
127
|
+
`\\${decimalEscape}`
|
128
|
+
)
|
129
|
+
);
|
130
|
+
|
131
|
+
context.report({
|
132
|
+
node,
|
133
|
+
loc: {
|
134
|
+
start: sourceCode.getLocFromIndex(decimalEscapeRangeStart),
|
135
|
+
end: sourceCode.getLocFromIndex(decimalEscapeRangeEnd)
|
136
|
+
},
|
137
|
+
messageId: "decimalEscape",
|
138
|
+
data: {
|
139
|
+
decimalEscape
|
140
|
+
},
|
141
|
+
suggest
|
142
|
+
});
|
143
|
+
}
|
144
|
+
}
|
145
|
+
};
|
146
|
+
}
|
147
|
+
};
|
@@ -46,15 +46,15 @@ module.exports = {
|
|
46
46
|
*/
|
47
47
|
function disallowBuiltIns(node) {
|
48
48
|
|
49
|
-
// TODO: just use `astUtils.getStaticPropertyName(node.callee)`
|
50
49
|
const callee = astUtils.skipChainExpression(node.callee);
|
51
50
|
|
52
|
-
if (callee.type !== "MemberExpression"
|
51
|
+
if (callee.type !== "MemberExpression") {
|
53
52
|
return;
|
54
53
|
}
|
55
|
-
const propName = callee.property.name;
|
56
54
|
|
57
|
-
|
55
|
+
const propName = astUtils.getStaticPropertyName(callee);
|
56
|
+
|
57
|
+
if (propName !== null && DISALLOWED_PROPS.indexOf(propName) > -1) {
|
58
58
|
context.report({
|
59
59
|
messageId: "prototypeBuildIn",
|
60
60
|
loc: callee.property.loc,
|