eslint 7.3.0 → 7.6.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 +63 -0
- package/README.md +5 -3
- package/lib/cli-engine/config-array-factory.js +1 -28
- package/lib/cli-engine/formatters/checkstyle.js +2 -2
- package/lib/linter/code-path-analysis/code-path-analyzer.js +38 -0
- package/lib/linter/code-path-analysis/code-path-segment.js +0 -1
- package/lib/linter/code-path-analysis/code-path-state.js +59 -0
- package/lib/linter/code-path-analysis/debug-helpers.js +26 -19
- package/lib/rule-tester/rule-tester.js +10 -0
- package/lib/rules/accessor-pairs.js +1 -14
- package/lib/rules/array-callback-return.js +26 -17
- package/lib/rules/arrow-body-style.js +43 -8
- package/lib/rules/arrow-parens.js +91 -108
- package/lib/rules/camelcase.js +47 -0
- package/lib/rules/consistent-return.js +1 -12
- package/lib/rules/constructor-super.js +1 -0
- package/lib/rules/dot-location.js +20 -14
- package/lib/rules/dot-notation.js +36 -33
- package/lib/rules/func-call-spacing.js +42 -6
- package/lib/rules/func-name-matching.js +1 -4
- package/lib/rules/global-require.js +2 -1
- package/lib/rules/id-blacklist.js +14 -11
- package/lib/rules/id-denylist.js +230 -0
- package/lib/rules/indent.js +19 -0
- package/lib/rules/index.js +1 -0
- package/lib/rules/keyword-spacing.js +2 -2
- package/lib/rules/max-len.js +13 -2
- package/lib/rules/new-cap.js +10 -14
- package/lib/rules/newline-per-chained-call.js +15 -5
- package/lib/rules/no-alert.js +10 -3
- package/lib/rules/no-duplicate-case.js +23 -4
- package/lib/rules/no-eval.js +8 -38
- package/lib/rules/no-extend-native.js +37 -40
- package/lib/rules/no-extra-bind.js +57 -17
- package/lib/rules/no-extra-boolean-cast.js +7 -0
- package/lib/rules/no-extra-parens.js +48 -10
- package/lib/rules/no-implicit-coercion.js +11 -6
- package/lib/rules/no-implied-eval.js +7 -28
- package/lib/rules/no-import-assign.js +33 -32
- package/lib/rules/no-irregular-whitespace.js +22 -12
- package/lib/rules/no-magic-numbers.js +4 -8
- package/lib/rules/no-obj-calls.js +7 -4
- package/lib/rules/no-prototype-builtins.js +13 -3
- package/lib/rules/no-self-assign.js +3 -53
- package/lib/rules/no-setter-return.js +5 -8
- package/lib/rules/no-unexpected-multiline.js +2 -2
- package/lib/rules/no-unneeded-ternary.js +0 -2
- package/lib/rules/no-unused-expressions.js +55 -23
- package/lib/rules/no-useless-call.js +10 -7
- package/lib/rules/no-whitespace-before-property.js +16 -4
- package/lib/rules/object-curly-newline.js +4 -4
- package/lib/rules/operator-assignment.js +3 -42
- package/lib/rules/padding-line-between-statements.js +2 -2
- package/lib/rules/prefer-arrow-callback.js +90 -25
- package/lib/rules/prefer-exponentiation-operator.js +1 -1
- package/lib/rules/prefer-numeric-literals.js +4 -13
- package/lib/rules/prefer-promise-reject-errors.js +1 -3
- package/lib/rules/prefer-regex-literals.js +68 -13
- package/lib/rules/prefer-spread.js +2 -6
- package/lib/rules/radix.js +5 -2
- package/lib/rules/sort-imports.js +28 -0
- package/lib/rules/use-isnan.js +1 -1
- package/lib/rules/utils/ast-utils.js +317 -153
- package/lib/rules/wrap-iife.js +9 -2
- package/lib/rules/yoda.js +2 -55
- package/messages/extend-config-missing.txt +1 -1
- package/messages/no-config-found.txt +1 -1
- package/messages/plugin-conflict.txt +1 -1
- package/messages/plugin-missing.txt +1 -1
- package/messages/whitespace-found.txt +1 -1
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,65 @@
|
|
1
|
+
v7.6.0 - July 31, 2020
|
2
|
+
|
3
|
+
* [`ecb2b73`](https://github.com/eslint/eslint/commit/ecb2b7343a0d14fb57d297a16be6c1b176fb3dbf) Update: require `meta` for fixable rules in RuleTester (refs #13349) (#13489) (Milos Djermanovic)
|
4
|
+
* [`6fb4edd`](https://github.com/eslint/eslint/commit/6fb4edde3b7a7ae2faf8ac956a7342fbf80865fc) Docs: fix broken links in developer guide (#13518) (Sam Chen)
|
5
|
+
* [`318fe10`](https://github.com/eslint/eslint/commit/318fe103dbf2548eee293ff456ef0b829dbe3db3) Fix: Do not output `undefined` as line and column when it's unavailable (#13519) (haya14busa)
|
6
|
+
* [`493b5b4`](https://github.com/eslint/eslint/commit/493b5b40cae7a076fdeb19740f8c88fb4ae9c1fb) Sponsors: Sync README with website (ESLint Jenkins)
|
7
|
+
* [`f100143`](https://github.com/eslint/eslint/commit/f100143fa5f529aacb2b50e650a00d2697ca4c54) Sponsors: Sync README with website (ESLint Jenkins)
|
8
|
+
* [`16b10fe`](https://github.com/eslint/eslint/commit/16b10fe8ba3c78939d5ada4a25caf2f0c9e6a058) Fix: Update the chatroom link to go directly to help channel (#13536) (Nicholas C. Zakas)
|
9
|
+
* [`f937eb9`](https://github.com/eslint/eslint/commit/f937eb95407f60d3772bcb956e227aaf99e48777) Sponsors: Sync README with website (ESLint Jenkins)
|
10
|
+
* [`e71e298`](https://github.com/eslint/eslint/commit/e71e2980cd2e319afc70d8c859c7ffd59cf4157b) Update: Change no-duplicate-case to comparing tokens (fixes #13485) (#13494) (Yosuke Ota)
|
11
|
+
* [`6c4aea4`](https://github.com/eslint/eslint/commit/6c4aea44fd78e1eecea5fe3c37e1921e3b1e98a6) Docs: add ECMAScript 2020 to README (#13510) (Milos Djermanovic)
|
12
|
+
|
13
|
+
v7.5.0 - July 18, 2020
|
14
|
+
|
15
|
+
* [`6ea3178`](https://github.com/eslint/eslint/commit/6ea3178776eae0e40c3f5498893e8aab0e23686b) Update: optional chaining support (fixes #12642) (#13416) (Toru Nagashima)
|
16
|
+
* [`540b1af`](https://github.com/eslint/eslint/commit/540b1af77278ae649b621aa8d4bf8d6de03c3155) Chore: enable consistent-meta-messages internal rule (#13487) (Milos Djermanovic)
|
17
|
+
* [`885a145`](https://github.com/eslint/eslint/commit/885a1455691265db88dc0befe9b48a69d69e8b9c) Docs: clarify behavior if `meta.fixable` is omitted (refs #13349) (#13493) (Milos Djermanovic)
|
18
|
+
* [`1a01b42`](https://github.com/eslint/eslint/commit/1a01b420eaab0de03dab5cc190a9f2a860c21a84) Docs: Update technology sponsors in README (#13478) (Nicholas C. Zakas)
|
19
|
+
* [`6ed9e8e`](https://github.com/eslint/eslint/commit/6ed9e8e4ff038c0259b0e7fe7ab7f4fd4ec55801) Upgrade: lodash@4.17.19 (#13499) (Yohan Siguret)
|
20
|
+
* [`45cdf00`](https://github.com/eslint/eslint/commit/45cdf00da6aeff3d584d37b0710fc8d6ad9456d6) Sponsors: Sync README with website (ESLint Jenkins)
|
21
|
+
* [`f1cc725`](https://github.com/eslint/eslint/commit/f1cc725ba1b8646dcf06a83716d96ad9bb726172) Docs: fix linebreaks between versions in changelog (#13488) (Milos Djermanovic)
|
22
|
+
* [`f4d7b9e`](https://github.com/eslint/eslint/commit/f4d7b9e1a599346b2f21ff9de003b311b51411e6) Update: deprecate id-blacklist rule (#13465) (Dimitri Mitropoulos)
|
23
|
+
* [`e14a645`](https://github.com/eslint/eslint/commit/e14a645aa495558081490f990ba221e21aa6b27c) Chore: use espree.latestEcmaVersion in fuzzer (#13484) (Milos Djermanovic)
|
24
|
+
* [`61097fe`](https://github.com/eslint/eslint/commit/61097fe5cc275d414a0c8e19b31c6060cb5568b7) Docs: Update int rule level to string (#13483) (Brandon Mills)
|
25
|
+
* [`c8f9c82`](https://github.com/eslint/eslint/commit/c8f9c8210cf4b9da8f07922093d7b219abad9f10) Update: Improve report location no-irregular-whitespace (refs #12334) (#13462) (Milos Djermanovic)
|
26
|
+
* [`f2e68ec`](https://github.com/eslint/eslint/commit/f2e68ec1d6cee6299e8a5cdf76c522c11d3008dd) Build: update webpack resolve.mainFields to match website config (#13457) (Milos Djermanovic)
|
27
|
+
* [`a96bc5e`](https://github.com/eslint/eslint/commit/a96bc5ec06f3a48bfe458bccd68d4d3b2a280ed9) Fix: arrow-body-style fixer for `in` wrap (fixes #11849) (#13228) (Anix)
|
28
|
+
* [`748734f`](https://github.com/eslint/eslint/commit/748734fdd497fbf61f3a616ff4a09169135b9396) Upgrade: Updated puppeteer version to v4.0.0 (#13444) (odidev)
|
29
|
+
* [`e951457`](https://github.com/eslint/eslint/commit/e951457b7aaa1b12b135588d36e3f4db4d7b8463) Docs: fix wording in configuring.md (#13469) (Piper)
|
30
|
+
* [`0af1d28`](https://github.com/eslint/eslint/commit/0af1d2828d27885483737867653ba1659af72005) Update: add allowSeparatedGroups option to sort-imports (fixes #12951) (#13455) (Milos Djermanovic)
|
31
|
+
* [`1050ee7`](https://github.com/eslint/eslint/commit/1050ee78a95da9484ff333dc1c74dac64c05da6f) Update: Improve report location for no-unneeded-ternary (refs #12334) (#13456) (Milos Djermanovic)
|
32
|
+
* [`b77b420`](https://github.com/eslint/eslint/commit/b77b4202bd1d5d1306f6f645e88d7a41a51715db) Update: Improve report location for max-len (refs #12334) (#13458) (Milos Djermanovic)
|
33
|
+
* [`095194c`](https://github.com/eslint/eslint/commit/095194c0fc0eb02aa69fde6b4280696e0e4de214) Fix: add end location to reports in object-curly-newline (refs #12334) (#13460) (Milos Djermanovic)
|
34
|
+
* [`10251bb`](https://github.com/eslint/eslint/commit/10251bbaeba80ac15244f385fc42cf2f2a30e5d2) Fix: add end location to reports in keyword-spacing (refs #12334) (#13461) (Milos Djermanovic)
|
35
|
+
* [`2ea7ee5`](https://github.com/eslint/eslint/commit/2ea7ee51a4e05ee76a6dae5954c3b6263b0970a3) Sponsors: Sync README with website (ESLint Jenkins)
|
36
|
+
* [`b55fd3b`](https://github.com/eslint/eslint/commit/b55fd3b8c05a29a465a794a524b06c1a28cddf0c) Sponsors: Sync README with website (ESLint Jenkins)
|
37
|
+
|
38
|
+
v7.4.0 - July 3, 2020
|
39
|
+
|
40
|
+
* [`f21bad2`](https://github.com/eslint/eslint/commit/f21bad2680406a2671b877f8dba47f4475d0cc64) Docs: fix description for `never` in multiline-ternary (fixes #13368) (#13452) (Milos Djermanovic)
|
41
|
+
* [`ada2c89`](https://github.com/eslint/eslint/commit/ada2c891298382f82dfabf37cacd59a1057b2bb7) Fix: support typescript generics in arrow-parens (fixes #12570) (#13451) (Milos Djermanovic)
|
42
|
+
* [`89ee01e`](https://github.com/eslint/eslint/commit/89ee01e083f1e02293bf8d1447f9b0fdb3cb9384) Fix: Revert config cloning (fixes #13447) (#13449) (薛定谔的猫)
|
43
|
+
* [`0a463db`](https://github.com/eslint/eslint/commit/0a463dbf7cc5a77d442879c9117204d4d38db972) Docs: fix no-multiple-empty-lines examples (fixes #13432) (#13433) (Milos Djermanovic)
|
44
|
+
* [`ff5317e`](https://github.com/eslint/eslint/commit/ff5317e93425f93cfdf808609551ee67b2032543) Update: Improve array-callback-return report message (#13395) (Philip (flip) Kromer)
|
45
|
+
* [`3f51930`](https://github.com/eslint/eslint/commit/3f51930eea7cddc921a9ee3cb0328c7b649c0f83) Fix: false positive new with member in no-extra-parens (fixes #12740) (#13375) (YeonJuan)
|
46
|
+
* [`825a5b9`](https://github.com/eslint/eslint/commit/825a5b98d3d84f6eb72b75f7d8519de763cc8898) Fix: Clarify documentation on implicit ignore behavior (fixes #12348) (#12600) (Scott Hardin)
|
47
|
+
* [`c139156`](https://github.com/eslint/eslint/commit/c1391566a5f765f25716527de7b5cdee16c0ce36) Sponsors: Sync README with website (ESLint Jenkins)
|
48
|
+
* [`0c17e9d`](https://github.com/eslint/eslint/commit/0c17e9d2ac307cc288eea6ed7971bd5a7d33321a) Sponsors: Sync README with website (ESLint Jenkins)
|
49
|
+
* [`c680387`](https://github.com/eslint/eslint/commit/c680387ba61f6dccf0390d24a85d871fa83e9fea) Sponsors: Sync README with website (ESLint Jenkins)
|
50
|
+
* [`bf3939b`](https://github.com/eslint/eslint/commit/bf3939bbd9a33d0eb96cebe6a53bf61c855f9ba6) Sponsors: Sync README with website (ESLint Jenkins)
|
51
|
+
* [`7baf02e`](https://github.com/eslint/eslint/commit/7baf02e983af909800261263f125cca901a5bd0f) Sponsors: Sync README with website (ESLint Jenkins)
|
52
|
+
* [`5c4c3fd`](https://github.com/eslint/eslint/commit/5c4c3fdfbda18a13223ad36f44283adbfee8c496) Sponsors: Sync README with website (ESLint Jenkins)
|
53
|
+
* [`53912aa`](https://github.com/eslint/eslint/commit/53912aab1856327b399cca26cbb2ba81fd01bfa2) Sponsors: Sync README with website (ESLint Jenkins)
|
54
|
+
* [`51e42ec`](https://github.com/eslint/eslint/commit/51e42eca3e87d8259815d736ffe81e604f184057) Update: Add option "ignoreGlobals" to camelcase rule (fixes #11716) (#12782) (David Gasperoni)
|
55
|
+
* [`0655f66`](https://github.com/eslint/eslint/commit/0655f66525d167ca1288167b79a77087cfc8fcf6) Update: improve report location in arrow-body-style (refs #12334) (#13424) (YeonJuan)
|
56
|
+
* [`d53d69a`](https://github.com/eslint/eslint/commit/d53d69af08cfe55f42e0a0ca725b1014dabccc21) Update: prefer-regex-literal detect regex literals (fixes #12840) (#12842) (Mathias Schreck)
|
57
|
+
* [`004adae`](https://github.com/eslint/eslint/commit/004adae3f959414f56e44e5884f6221e9dcda142) Update: rename id-blacklist to id-denylist (fixes #13407) (#13408) (Kai Cataldo)
|
58
|
+
|
59
|
+
v7.3.1 - June 22, 2020
|
60
|
+
|
61
|
+
* [`de77c11`](https://github.com/eslint/eslint/commit/de77c11e7515f2097ff355ddc0d7b6db9c83c892) Fix: Replace Infinity with Number.MAX_SAFE_INTEGER (fixes #13427) (#13435) (Nicholas C. Zakas)
|
62
|
+
|
1
63
|
v7.3.0 - June 19, 2020
|
2
64
|
|
3
65
|
* [`638a6d6`](https://github.com/eslint/eslint/commit/638a6d6be18b4a37cfdc7223e1f5acd3718694be) Update: add missing `additionalProperties: false` to some rules' schema (#13198) (Milos Djermanovic)
|
@@ -22,6 +84,7 @@ v7.3.0 - June 19, 2020
|
|
22
84
|
* [`0f1f5ed`](https://github.com/eslint/eslint/commit/0f1f5ed2a20b8fb575d4360316861cf4c2b9b7bc) Docs: Add security policy link to README (#13403) (Nicholas C. Zakas)
|
23
85
|
* [`9e9ba89`](https://github.com/eslint/eslint/commit/9e9ba897c566601cfe90522099c635ea316b235f) Sponsors: Sync README with website (ESLint Jenkins)
|
24
86
|
* [`ca59fb9`](https://github.com/eslint/eslint/commit/ca59fb95a395c0a02ed23768a70e086480ab1f6d) Sponsors: Sync README with website (ESLint Jenkins)
|
87
|
+
|
25
88
|
v7.2.0 - June 5, 2020
|
26
89
|
|
27
90
|
* [`b735a48`](https://github.com/eslint/eslint/commit/b735a485e77bcc791e4c4c6b8716801d94e98b2c) Update: add enforceForFunctionPrototypeMethods option to no-extra-parens (#12895) (Milos Djermanovic)
|
package/README.md
CHANGED
@@ -122,7 +122,7 @@ Yes, ESLint natively supports parsing JSX syntax (this must be enabled in [confi
|
|
122
122
|
|
123
123
|
### What ECMAScript versions does ESLint support?
|
124
124
|
|
125
|
-
ESLint has full support for ECMAScript 3, 5 (default), 2015, 2016, 2017, 2018, and
|
125
|
+
ESLint has full support for ECMAScript 3, 5 (default), 2015, 2016, 2017, 2018, 2019, and 2020. You can set your desired ECMAScript syntax (and other settings, like global variables or your target environments) through [configuration](https://eslint.org/docs/user-guide/configuring).
|
126
126
|
|
127
127
|
### What about experimental features?
|
128
128
|
|
@@ -254,11 +254,13 @@ The following companies, organizations, and individuals support ESLint's ongoing
|
|
254
254
|
<!-- NOTE: This section is autogenerated. Do not manually edit.-->
|
255
255
|
<!--sponsorsstart-->
|
256
256
|
<h3>Gold Sponsors</h3>
|
257
|
-
<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>
|
257
|
+
<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> <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>
|
258
258
|
<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>
|
259
|
-
<p><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://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://
|
259
|
+
<p><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://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://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="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/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="http://www.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a></p>
|
260
260
|
<!--sponsorsend-->
|
261
261
|
|
262
262
|
## <a name="technology-sponsors"></a>Technology Sponsors
|
263
263
|
|
264
264
|
* Site search ([eslint.org](https://eslint.org)) is sponsored by [Algolia](https://www.algolia.com)
|
265
|
+
* Hosting for ([eslint.org](https://eslint.org)) is sponsored by [Netlify](https://www.netlify.com)
|
266
|
+
* Password management is sponsored by [1Password](https://www.1password.com)
|
@@ -697,33 +697,6 @@ class ConfigArrayFactory {
|
|
697
697
|
ctx.matchBasePath
|
698
698
|
);
|
699
699
|
|
700
|
-
/**
|
701
|
-
* Cloning the rule's config as we are setting `useDefaults` to true`
|
702
|
-
* which mutates the config with its default value if present. And when we
|
703
|
-
* refer to a same variable for config for different rules, that referred variable will
|
704
|
-
* be mutated and it will be used for both.
|
705
|
-
*
|
706
|
-
* Example:
|
707
|
-
*
|
708
|
-
* const commonRuleConfig = ['error', {}];
|
709
|
-
*
|
710
|
-
* Now if we use this variable as a config for rules like this
|
711
|
-
*
|
712
|
-
* {
|
713
|
-
* rules: {
|
714
|
-
* "a" : commonRuleConfig,
|
715
|
-
* "b" : commonRuleConfig,
|
716
|
-
* }
|
717
|
-
* }
|
718
|
-
*
|
719
|
-
* And if these rules have default values in their schema, their
|
720
|
-
* config will be mutated with default values, the mutated `commonRuleConfig` will be used for `b` as well and it probably
|
721
|
-
* throw schema voilation errors.
|
722
|
-
*
|
723
|
-
* Refer https://github.com/eslint/eslint/issues/12592
|
724
|
-
*/
|
725
|
-
const clonedRulesConfig = rules && JSON.parse(JSON.stringify((rules)));
|
726
|
-
|
727
700
|
// Flatten `extends`.
|
728
701
|
for (const extendName of extendList.filter(Boolean)) {
|
729
702
|
yield* this._loadExtends(extendName, ctx);
|
@@ -758,7 +731,7 @@ class ConfigArrayFactory {
|
|
758
731
|
processor,
|
759
732
|
reportUnusedDisableDirectives,
|
760
733
|
root,
|
761
|
-
rules
|
734
|
+
rules,
|
762
735
|
settings
|
763
736
|
};
|
764
737
|
|
@@ -42,8 +42,8 @@ module.exports = function(results) {
|
|
42
42
|
|
43
43
|
messages.forEach(message => {
|
44
44
|
output += [
|
45
|
-
`<error line="${xmlEscape(message.line)}"`,
|
46
|
-
`column="${xmlEscape(message.column)}"`,
|
45
|
+
`<error line="${xmlEscape(message.line || 0)}"`,
|
46
|
+
`column="${xmlEscape(message.column || 0)}"`,
|
47
47
|
`severity="${xmlEscape(getMessageType(message))}"`,
|
48
48
|
`message="${xmlEscape(message.message)}${message.ruleId ? ` (${message.ruleId})` : ""}"`,
|
49
49
|
`source="${message.ruleId ? xmlEscape(`eslint.rules.${message.ruleId}`) : ""}" />`
|
@@ -244,6 +244,19 @@ function preprocess(analyzer, node) {
|
|
244
244
|
const parent = node.parent;
|
245
245
|
|
246
246
|
switch (parent.type) {
|
247
|
+
|
248
|
+
// The `arguments.length == 0` case is in `postprocess` function.
|
249
|
+
case "CallExpression":
|
250
|
+
if (parent.optional === true && parent.arguments.length >= 1 && parent.arguments[0] === node) {
|
251
|
+
state.makeOptionalRight();
|
252
|
+
}
|
253
|
+
break;
|
254
|
+
case "MemberExpression":
|
255
|
+
if (parent.optional === true && parent.property === node) {
|
256
|
+
state.makeOptionalRight();
|
257
|
+
}
|
258
|
+
break;
|
259
|
+
|
247
260
|
case "LogicalExpression":
|
248
261
|
if (
|
249
262
|
parent.right === node &&
|
@@ -377,6 +390,20 @@ function processCodePathToEnter(analyzer, node) {
|
|
377
390
|
analyzer.emitter.emit("onCodePathStart", codePath, node);
|
378
391
|
break;
|
379
392
|
|
393
|
+
case "ChainExpression":
|
394
|
+
state.pushChainContext();
|
395
|
+
break;
|
396
|
+
case "CallExpression":
|
397
|
+
if (node.optional === true) {
|
398
|
+
state.makeOptionalNode();
|
399
|
+
}
|
400
|
+
break;
|
401
|
+
case "MemberExpression":
|
402
|
+
if (node.optional === true) {
|
403
|
+
state.makeOptionalNode();
|
404
|
+
}
|
405
|
+
break;
|
406
|
+
|
380
407
|
case "LogicalExpression":
|
381
408
|
if (isHandledLogicalOperator(node.operator)) {
|
382
409
|
state.pushChoiceContext(
|
@@ -449,6 +476,10 @@ function processCodePathToExit(analyzer, node) {
|
|
449
476
|
let dontForward = false;
|
450
477
|
|
451
478
|
switch (node.type) {
|
479
|
+
case "ChainExpression":
|
480
|
+
state.popChainContext();
|
481
|
+
break;
|
482
|
+
|
452
483
|
case "IfStatement":
|
453
484
|
case "ConditionalExpression":
|
454
485
|
state.popChoiceContext();
|
@@ -583,6 +614,13 @@ function postprocess(analyzer, node) {
|
|
583
614
|
break;
|
584
615
|
}
|
585
616
|
|
617
|
+
// The `arguments.length >= 1` case is in `preprocess` function.
|
618
|
+
case "CallExpression":
|
619
|
+
if (node.optional === true && node.arguments.length === 0) {
|
620
|
+
CodePath.getState(analyzer.codePath).makeOptionalRight();
|
621
|
+
}
|
622
|
+
break;
|
623
|
+
|
586
624
|
default:
|
587
625
|
break;
|
588
626
|
}
|
@@ -234,6 +234,7 @@ class CodePathState {
|
|
234
234
|
this.tryContext = null;
|
235
235
|
this.loopContext = null;
|
236
236
|
this.breakContext = null;
|
237
|
+
this.chainContext = null;
|
237
238
|
|
238
239
|
this.currentSegments = [];
|
239
240
|
this.initialSegment = this.forkContext.head[0];
|
@@ -555,6 +556,64 @@ class CodePathState {
|
|
555
556
|
);
|
556
557
|
}
|
557
558
|
|
559
|
+
//--------------------------------------------------------------------------
|
560
|
+
// ChainExpression
|
561
|
+
//--------------------------------------------------------------------------
|
562
|
+
|
563
|
+
/**
|
564
|
+
* Push a new `ChainExpression` context to the stack.
|
565
|
+
* This method is called on entering to each `ChainExpression` node.
|
566
|
+
* This context is used to count forking in the optional chain then merge them on the exiting from the `ChainExpression` node.
|
567
|
+
* @returns {void}
|
568
|
+
*/
|
569
|
+
pushChainContext() {
|
570
|
+
this.chainContext = {
|
571
|
+
upper: this.chainContext,
|
572
|
+
countChoiceContexts: 0
|
573
|
+
};
|
574
|
+
}
|
575
|
+
|
576
|
+
/**
|
577
|
+
* Pop a `ChainExpression` context from the stack.
|
578
|
+
* This method is called on exiting from each `ChainExpression` node.
|
579
|
+
* This merges all forks of the last optional chaining.
|
580
|
+
* @returns {void}
|
581
|
+
*/
|
582
|
+
popChainContext() {
|
583
|
+
const context = this.chainContext;
|
584
|
+
|
585
|
+
this.chainContext = context.upper;
|
586
|
+
|
587
|
+
// pop all choice contexts of this.
|
588
|
+
for (let i = context.countChoiceContexts; i > 0; --i) {
|
589
|
+
this.popChoiceContext();
|
590
|
+
}
|
591
|
+
}
|
592
|
+
|
593
|
+
/**
|
594
|
+
* Create a choice context for optional access.
|
595
|
+
* This method is called on entering to each `(Call|Member)Expression[optional=true]` node.
|
596
|
+
* This creates a choice context as similar to `LogicalExpression[operator="??"]` node.
|
597
|
+
* @returns {void}
|
598
|
+
*/
|
599
|
+
makeOptionalNode() {
|
600
|
+
if (this.chainContext) {
|
601
|
+
this.chainContext.countChoiceContexts += 1;
|
602
|
+
this.pushChoiceContext("??", false);
|
603
|
+
}
|
604
|
+
}
|
605
|
+
|
606
|
+
/**
|
607
|
+
* Create a fork.
|
608
|
+
* This method is called on entering to the `arguments|property` property of each `(Call|Member)Expression` node.
|
609
|
+
* @returns {void}
|
610
|
+
*/
|
611
|
+
makeOptionalRight() {
|
612
|
+
if (this.chainContext) {
|
613
|
+
this.makeLogicalRight();
|
614
|
+
}
|
615
|
+
}
|
616
|
+
|
558
617
|
//--------------------------------------------------------------------------
|
559
618
|
// SwitchStatement
|
560
619
|
//--------------------------------------------------------------------------
|
@@ -25,6 +25,22 @@ function getId(segment) { // eslint-disable-line jsdoc/require-jsdoc
|
|
25
25
|
return segment.id + (segment.reachable ? "" : "!");
|
26
26
|
}
|
27
27
|
|
28
|
+
/**
|
29
|
+
* Get string for the given node and operation.
|
30
|
+
* @param {ASTNode} node The node to convert.
|
31
|
+
* @param {"enter" | "exit" | undefined} label The operation label.
|
32
|
+
* @returns {string} The string representation.
|
33
|
+
*/
|
34
|
+
function nodeToString(node, label) {
|
35
|
+
const suffix = label ? `:${label}` : "";
|
36
|
+
|
37
|
+
switch (node.type) {
|
38
|
+
case "Identifier": return `${node.type}${suffix} (${node.name})`;
|
39
|
+
case "Literal": return `${node.type}${suffix} (${node.value})`;
|
40
|
+
default: return `${node.type}${suffix}`;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
28
44
|
//------------------------------------------------------------------------------
|
29
45
|
// Public Interface
|
30
46
|
//------------------------------------------------------------------------------
|
@@ -56,9 +72,15 @@ module.exports = {
|
|
56
72
|
const segInternal = state.currentSegments[i].internal;
|
57
73
|
|
58
74
|
if (leaving) {
|
59
|
-
segInternal.
|
75
|
+
const last = segInternal.nodes.length - 1;
|
76
|
+
|
77
|
+
if (last >= 0 && segInternal.nodes[last] === nodeToString(node, "enter")) {
|
78
|
+
segInternal.nodes[last] = nodeToString(node, void 0);
|
79
|
+
} else {
|
80
|
+
segInternal.nodes.push(nodeToString(node, "exit"));
|
81
|
+
}
|
60
82
|
} else {
|
61
|
-
segInternal.nodes.push(node);
|
83
|
+
segInternal.nodes.push(nodeToString(node, "enter"));
|
62
84
|
}
|
63
85
|
}
|
64
86
|
|
@@ -104,23 +126,8 @@ module.exports = {
|
|
104
126
|
text += "style=\"rounded,dashed,filled\",fillcolor=\"#FF9800\",label=\"<<unreachable>>\\n";
|
105
127
|
}
|
106
128
|
|
107
|
-
if (segment.internal.nodes.length > 0
|
108
|
-
text +=
|
109
|
-
segment.internal.nodes.map(node => {
|
110
|
-
switch (node.type) {
|
111
|
-
case "Identifier": return `${node.type} (${node.name})`;
|
112
|
-
case "Literal": return `${node.type} (${node.value})`;
|
113
|
-
default: return node.type;
|
114
|
-
}
|
115
|
-
}),
|
116
|
-
segment.internal.exitNodes.map(node => {
|
117
|
-
switch (node.type) {
|
118
|
-
case "Identifier": return `${node.type}:exit (${node.name})`;
|
119
|
-
case "Literal": return `${node.type}:exit (${node.value})`;
|
120
|
-
default: return `${node.type}:exit`;
|
121
|
-
}
|
122
|
-
})
|
123
|
-
).join("\\n");
|
129
|
+
if (segment.internal.nodes.length > 0) {
|
130
|
+
text += segment.internal.nodes.join("\\n");
|
124
131
|
} else {
|
125
132
|
text += "????";
|
126
133
|
}
|
@@ -861,6 +861,16 @@ class RuleTester {
|
|
861
861
|
);
|
862
862
|
}
|
863
863
|
|
864
|
+
// Rules that produce fixes must have `meta.fixable` property.
|
865
|
+
if (result.output !== item.code) {
|
866
|
+
assert.ok(
|
867
|
+
hasOwnProperty(rule, "meta"),
|
868
|
+
"Fixable rules should export a `meta.fixable` property."
|
869
|
+
);
|
870
|
+
|
871
|
+
// Linter throws if a rule that produced a fix has `meta` but doesn't have `meta.fixable`.
|
872
|
+
}
|
873
|
+
|
864
874
|
assertASTDidntChange(result.beforeAST, result.afterAST);
|
865
875
|
}
|
866
876
|
|
@@ -86,16 +86,6 @@ function isAccessorKind(node) {
|
|
86
86
|
return node.kind === "get" || node.kind === "set";
|
87
87
|
}
|
88
88
|
|
89
|
-
/**
|
90
|
-
* Checks whether or not a given node is an `Identifier` node which was named a given name.
|
91
|
-
* @param {ASTNode} node A node to check.
|
92
|
-
* @param {string} name An expected name of the node.
|
93
|
-
* @returns {boolean} `true` if the node is an `Identifier` node which was named as expected.
|
94
|
-
*/
|
95
|
-
function isIdentifier(node, name) {
|
96
|
-
return node.type === "Identifier" && node.name === name;
|
97
|
-
}
|
98
|
-
|
99
89
|
/**
|
100
90
|
* Checks whether or not a given node is an argument of a specified method call.
|
101
91
|
* @param {ASTNode} node A node to check.
|
@@ -109,10 +99,7 @@ function isArgumentOfMethodCall(node, index, object, property) {
|
|
109
99
|
|
110
100
|
return (
|
111
101
|
parent.type === "CallExpression" &&
|
112
|
-
parent.callee
|
113
|
-
parent.callee.computed === false &&
|
114
|
-
isIdentifier(parent.callee.object, object) &&
|
115
|
-
isIdentifier(parent.callee.property, property) &&
|
102
|
+
astUtils.isSpecificMemberAccess(parent.callee, object, property) &&
|
116
103
|
parent.arguments[index] === node
|
117
104
|
);
|
118
105
|
}
|
@@ -9,8 +9,6 @@
|
|
9
9
|
// Requirements
|
10
10
|
//------------------------------------------------------------------------------
|
11
11
|
|
12
|
-
const lodash = require("lodash");
|
13
|
-
|
14
12
|
const astUtils = require("./utils/ast-utils");
|
15
13
|
|
16
14
|
//------------------------------------------------------------------------------
|
@@ -30,17 +28,27 @@ function isReachable(segment) {
|
|
30
28
|
}
|
31
29
|
|
32
30
|
/**
|
33
|
-
* Checks a given node is a
|
31
|
+
* Checks a given node is a member access which has the specified name's
|
34
32
|
* property.
|
35
33
|
* @param {ASTNode} node A node to check.
|
36
|
-
* @returns {boolean} `true` if the node is a
|
37
|
-
* the specified name's property
|
34
|
+
* @returns {boolean} `true` if the node is a member access which has
|
35
|
+
* the specified name's property. The node may be a `(Chain|Member)Expression` node.
|
38
36
|
*/
|
39
37
|
function isTargetMethod(node) {
|
40
|
-
return (
|
41
|
-
|
42
|
-
|
43
|
-
|
38
|
+
return astUtils.isSpecificMemberAccess(node, null, TARGET_METHODS);
|
39
|
+
}
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Returns a human-legible description of an array method
|
43
|
+
* @param {string} arrayMethodName A method name to fully qualify
|
44
|
+
* @returns {string} the method name prefixed with `Array.` if it is a class method,
|
45
|
+
* or else `Array.prototype.` if it is an instance method.
|
46
|
+
*/
|
47
|
+
function fullMethodName(arrayMethodName) {
|
48
|
+
if (["from", "of", "isArray"].includes(arrayMethodName)) {
|
49
|
+
return "Array.".concat(arrayMethodName);
|
50
|
+
}
|
51
|
+
return "Array.prototype.".concat(arrayMethodName);
|
44
52
|
}
|
45
53
|
|
46
54
|
/**
|
@@ -65,6 +73,7 @@ function getArrayMethodName(node) {
|
|
65
73
|
*/
|
66
74
|
case "LogicalExpression":
|
67
75
|
case "ConditionalExpression":
|
76
|
+
case "ChainExpression":
|
68
77
|
currentNode = parent;
|
69
78
|
break;
|
70
79
|
|
@@ -153,10 +162,10 @@ module.exports = {
|
|
153
162
|
],
|
154
163
|
|
155
164
|
messages: {
|
156
|
-
expectedAtEnd: "
|
157
|
-
expectedInside: "
|
158
|
-
expectedReturnValue: "{{
|
159
|
-
expectedNoReturnValue: "{{
|
165
|
+
expectedAtEnd: "{{arrayMethodName}}() expects a value to be returned at the end of {{name}}.",
|
166
|
+
expectedInside: "{{arrayMethodName}}() expects a return value from {{name}}.",
|
167
|
+
expectedReturnValue: "{{arrayMethodName}}() expects a return value from {{name}}.",
|
168
|
+
expectedNoReturnValue: "{{arrayMethodName}}() expects no useless return value from {{name}}."
|
160
169
|
}
|
161
170
|
},
|
162
171
|
|
@@ -202,14 +211,13 @@ module.exports = {
|
|
202
211
|
}
|
203
212
|
|
204
213
|
if (messageId) {
|
205
|
-
|
214
|
+
const name = astUtils.getFunctionNameWithKind(node);
|
206
215
|
|
207
|
-
name = messageId === "expectedNoReturnValue" ? lodash.upperFirst(name) : name;
|
208
216
|
context.report({
|
209
217
|
node,
|
210
218
|
loc: astUtils.getFunctionHeadLoc(node, sourceCode),
|
211
219
|
messageId,
|
212
|
-
data: { name }
|
220
|
+
data: { name, arrayMethodName: fullMethodName(funcInfo.arrayMethodName) }
|
213
221
|
});
|
214
222
|
}
|
215
223
|
}
|
@@ -273,7 +281,8 @@ module.exports = {
|
|
273
281
|
node,
|
274
282
|
messageId,
|
275
283
|
data: {
|
276
|
-
name:
|
284
|
+
name: astUtils.getFunctionNameWithKind(funcInfo.node),
|
285
|
+
arrayMethodName: fullMethodName(funcInfo.arrayMethodName)
|
277
286
|
}
|
278
287
|
});
|
279
288
|
}
|
@@ -75,6 +75,7 @@ module.exports = {
|
|
75
75
|
const never = options[0] === "never";
|
76
76
|
const requireReturnForObjectLiteral = options[1] && options[1].requireReturnForObjectLiteral;
|
77
77
|
const sourceCode = context.getSourceCode();
|
78
|
+
let funcInfo = null;
|
78
79
|
|
79
80
|
/**
|
80
81
|
* Checks whether the given node has ASI problem or not.
|
@@ -99,6 +100,21 @@ module.exports = {
|
|
99
100
|
return sourceCode.getTokenAfter(node);
|
100
101
|
}
|
101
102
|
|
103
|
+
/**
|
104
|
+
* Check whether the node is inside of a for loop's init
|
105
|
+
* @param {ASTNode} node node is inside for loop
|
106
|
+
* @returns {boolean} `true` if the node is inside of a for loop, else `false`
|
107
|
+
*/
|
108
|
+
function isInsideForLoopInitializer(node) {
|
109
|
+
if (node && node.parent) {
|
110
|
+
if (node.parent.type === "ForStatement" && node.parent.init === node) {
|
111
|
+
return true;
|
112
|
+
}
|
113
|
+
return isInsideForLoopInitializer(node.parent);
|
114
|
+
}
|
115
|
+
return false;
|
116
|
+
}
|
117
|
+
|
102
118
|
/**
|
103
119
|
* Determines whether a arrow function body needs braces
|
104
120
|
* @param {ASTNode} node The arrow function node.
|
@@ -136,7 +152,7 @@ module.exports = {
|
|
136
152
|
|
137
153
|
context.report({
|
138
154
|
node,
|
139
|
-
loc: arrowBody.loc
|
155
|
+
loc: arrowBody.loc,
|
140
156
|
messageId,
|
141
157
|
fix(fixer) {
|
142
158
|
const fixes = [];
|
@@ -178,11 +194,13 @@ module.exports = {
|
|
178
194
|
* If the first token of the reutrn value is `{` or the return value is a sequence expression,
|
179
195
|
* enclose the return value by parentheses to avoid syntax error.
|
180
196
|
*/
|
181
|
-
if (astUtils.isOpeningBraceToken(firstValueToken) || blockBody[0].argument.type === "SequenceExpression") {
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
197
|
+
if (astUtils.isOpeningBraceToken(firstValueToken) || blockBody[0].argument.type === "SequenceExpression" || (funcInfo.hasInOperator && isInsideForLoopInitializer(node))) {
|
198
|
+
if (!astUtils.isParenthesised(sourceCode, blockBody[0].argument)) {
|
199
|
+
fixes.push(
|
200
|
+
fixer.insertTextBefore(firstValueToken, "("),
|
201
|
+
fixer.insertTextAfter(lastValueToken, ")")
|
202
|
+
);
|
203
|
+
}
|
186
204
|
}
|
187
205
|
|
188
206
|
/*
|
@@ -201,7 +219,7 @@ module.exports = {
|
|
201
219
|
if (always || (asNeeded && requireReturnForObjectLiteral && arrowBody.type === "ObjectExpression")) {
|
202
220
|
context.report({
|
203
221
|
node,
|
204
|
-
loc: arrowBody.loc
|
222
|
+
loc: arrowBody.loc,
|
205
223
|
messageId: "expectedBlock",
|
206
224
|
fix(fixer) {
|
207
225
|
const fixes = [];
|
@@ -245,7 +263,24 @@ module.exports = {
|
|
245
263
|
}
|
246
264
|
|
247
265
|
return {
|
248
|
-
"
|
266
|
+
"BinaryExpression[operator='in']"() {
|
267
|
+
let info = funcInfo;
|
268
|
+
|
269
|
+
while (info) {
|
270
|
+
info.hasInOperator = true;
|
271
|
+
info = info.upper;
|
272
|
+
}
|
273
|
+
},
|
274
|
+
ArrowFunctionExpression() {
|
275
|
+
funcInfo = {
|
276
|
+
upper: funcInfo,
|
277
|
+
hasInOperator: false
|
278
|
+
};
|
279
|
+
},
|
280
|
+
"ArrowFunctionExpression:exit"(node) {
|
281
|
+
validate(node);
|
282
|
+
funcInfo = funcInfo.upper;
|
283
|
+
}
|
249
284
|
};
|
250
285
|
}
|
251
286
|
};
|