eslint 7.15.0 → 7.19.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 CHANGED
@@ -1,3 +1,75 @@
1
+ v7.19.0 - January 30, 2021
2
+
3
+ * [`ce7f061`](https://github.com/eslint/eslint/commit/ce7f06121d9eb9cc2b3da24b4456b4d382e1413b) Update: add shadowed variable loc to message in no-shadow (fixes #13646) (#13841) (t-mangoe)
4
+ * [`c60e23f`](https://github.com/eslint/eslint/commit/c60e23ff306a14ca6eabcadb275ed27995fcc6e4) Update: fix `let` logic in for-in and for-of loops in no-extra-parens (#14011) (Milos Djermanovic)
5
+ * [`d76e8f6`](https://github.com/eslint/eslint/commit/d76e8f69bd791357c67ada7b5c55608acf29b622) Fix: no-useless-rename invalid autofix with parenthesized identifiers (#14032) (Milos Djermanovic)
6
+ * [`5800d92`](https://github.com/eslint/eslint/commit/5800d921144ec330b6ee7cd03364434007331354) Docs: Clarify stylistic rule update policy (#14052) (Brandon Mills)
7
+ * [`0ccf6d2`](https://github.com/eslint/eslint/commit/0ccf6d200147437b338cadb34546451972befd75) Docs: remove configuring.md (#14036) (Milos Djermanovic)
8
+ * [`65bb0ab`](https://github.com/eslint/eslint/commit/65bb0abde56f72586036fff151aa2d13f1b7be6c) Chore: Clean up new issue workflow (#14040) (Nicholas C. Zakas)
9
+ * [`e1da90f`](https://github.com/eslint/eslint/commit/e1da90fc414a3c9c16f52db4a5bd81bd4f9532a4) Fix: nested indenting for offsetTernaryExpressions: true (fixes #13971) (#13972) (Chris Brody)
10
+ * [`1a078b9`](https://github.com/eslint/eslint/commit/1a078b9166f29cb3760435ddbc1a0da4a0974d4a) Update: check ternary `:` even if `?` was reported in space-infix-ops (#13963) (Milos Djermanovic)
11
+ * [`fb27422`](https://github.com/eslint/eslint/commit/fb274226242eaebc1480fc9c901202986afc3c8a) Fix: extend prefer-const fixer range to whole declaration (fixes #13899) (#14033) (Nitin Kumar)
12
+ * [`e0b05c7`](https://github.com/eslint/eslint/commit/e0b05c704f3ce6f549d14718236d22fe49fcb611) Docs: add a correct example to no-unsafe-optional-chaining (refs #14029) (#14050) (armin yahya)
13
+ * [`46e836d`](https://github.com/eslint/eslint/commit/46e836d46442d2ec756038a2e12ba19b74394dbd) Sponsors: Sync README with website (ESLint Jenkins)
14
+ * [`3fc4fa4`](https://github.com/eslint/eslint/commit/3fc4fa485ca9ccd5e16dbc7e53ba31452d22dc4a) Docs: update configuring links (#14038) (Milos Djermanovic)
15
+ * [`8561c21`](https://github.com/eslint/eslint/commit/8561c2116ef89e53ebffb750066f1b00a4acdb76) Docs: fix broken links in configuring/README.md (#14046) (Milos Djermanovic)
16
+ * [`1c309eb`](https://github.com/eslint/eslint/commit/1c309ebca4a81a0faf397103dbc621019dea8c9c) Update: fix no-invalid-regexp false negatives with no flags specified (#14018) (Milos Djermanovic)
17
+ * [`f6602d5`](https://github.com/eslint/eslint/commit/f6602d569427e9e2a4f3b5ca3fc3a8bffb28d15e) Docs: Reorganize Configuration Documentation (#13837) (klkhan)
18
+ * [`c753b44`](https://github.com/eslint/eslint/commit/c753b442ef67867a178ffc2ad29b4e0534f72469) Sponsors: Sync README with website (ESLint Jenkins)
19
+ * [`a4fdb70`](https://github.com/eslint/eslint/commit/a4fdb7001aa41b9ad8bb92cc8a47b9135c94afc7) Docs: Fixed Typo (#14007) (Yash Singh)
20
+ * [`f7ca481`](https://github.com/eslint/eslint/commit/f7ca48165d025e01c38698352cff24d1de87cc8b) Docs: Explain why we disable lock files (refs eslint/tsc-meetings#234) (#14006) (Brandon Mills)
21
+
22
+ v7.18.0 - January 15, 2021
23
+
24
+ * [`e3264b2`](https://github.com/eslint/eslint/commit/e3264b26a625d926a1ea96df1c4b643af5c3797c) Upgrade: @eslint/eslintrc to improve error message for invalid extends (#14009) (Milos Djermanovic)
25
+ * [`f17c3c3`](https://github.com/eslint/eslint/commit/f17c3c371789ffa84f0cda57101e8193899adbe6) Update: check logical assignment operators in the complexity rule (#13979) (Milos Djermanovic)
26
+ * [`672deb0`](https://github.com/eslint/eslint/commit/672deb057a14a7acad8c669189870009f1edb8a6) Docs: fix no-invalid-regexp docs regarding ecmaVersion (#13991) (Milos Djermanovic)
27
+ * [`179a910`](https://github.com/eslint/eslint/commit/179a910b32e853bc12a9dd71f7c10e762cbeac44) Fix: --init crash on question to upgrade/downgrade ESLint (fixes #13978) (#13995) (Milos Djermanovic)
28
+ * [`292b1c0`](https://github.com/eslint/eslint/commit/292b1c0017bc442d399f67e01d699c59e6b71453) Fix: no-extra-parens false positive with `let` identifier in for-loop (#13981) (Milos Djermanovic)
29
+ * [`de61f94`](https://github.com/eslint/eslint/commit/de61f9444cf58a4d70e126ab3d10bf20851de7c9) Sponsors: Sync README with website (ESLint Jenkins)
30
+ * [`9250d16`](https://github.com/eslint/eslint/commit/9250d167ceb5684669eabe93dae326e33f0684f2) Upgrade: Bump lodash to fix security issue (#13993) (Frederik Prijck)
31
+ * [`75fea9b`](https://github.com/eslint/eslint/commit/75fea9bcdd3dde5a07e0089d9011a4df518cdbe3) Sponsors: Sync README with website (ESLint Jenkins)
32
+ * [`f2687e7`](https://github.com/eslint/eslint/commit/f2687e71f9e2a2773f821c4dc1a02abe95b97df4) Docs: update space-in-parens related rules (#13985) (Chris Brody)
33
+ * [`4a38bbe`](https://github.com/eslint/eslint/commit/4a38bbe81b4b29ca1a4e62d0a0cc8d525455b063) Docs: space-in-parens examples with no arguments etc. (#13987) (Chris Brody)
34
+ * [`3e49169`](https://github.com/eslint/eslint/commit/3e491698687aa08b3b798cee0931f0872ca1bc55) Sponsors: Sync README with website (ESLint Jenkins)
35
+ * [`c5bf1f2`](https://github.com/eslint/eslint/commit/c5bf1f2150a9fbbb9e74c04808dc3bfeda1ed321) Sponsors: Sync README with website (ESLint Jenkins)
36
+ * [`98a729c`](https://github.com/eslint/eslint/commit/98a729c9def54cee9e5478e75e8bd6f28167d5e8) Sponsors: Sync README with website (ESLint Jenkins)
37
+ * [`e83a696`](https://github.com/eslint/eslint/commit/e83a6962b51b05c2ddfe42b0748b405d515eeb9d) Sponsors: Sync README with website (ESLint Jenkins)
38
+ * [`78cb483`](https://github.com/eslint/eslint/commit/78cb48345c725e9f90fd0e631c476802244df4a4) Chore: test `foo( )` with space-in-parens option "always" (#13986) (Chris Brody)
39
+ * [`f6948f6`](https://github.com/eslint/eslint/commit/f6948f6bdc763dca0787bb2786bc9f6f9ed88f43) Docs: Update semantic versioning policy (#13970) (Nicholas C. Zakas)
40
+ * [`0688212`](https://github.com/eslint/eslint/commit/068821248e2d2eff11152f270102d537d8fa8126) Sponsors: Sync README with website (ESLint Jenkins)
41
+ * [`aeba5e5`](https://github.com/eslint/eslint/commit/aeba5e5e6062095a06d9b867d7e7ee75422f25b9) Chore: fix typo (#13975) (Nitin Kumar)
42
+ * [`4ee1134`](https://github.com/eslint/eslint/commit/4ee113414bdcbea240a5d9db27da6a10df472005) Sponsors: Sync README with website (ESLint Jenkins)
43
+
44
+ v7.17.0 - January 1, 2021
45
+
46
+ * [`e128e77`](https://github.com/eslint/eslint/commit/e128e775e9fa116a0ad68a071f1f0997589f8cd4) Update: check logical assignment in no-constant-condition (#13946) (Milos Djermanovic)
47
+ * [`cc48713`](https://github.com/eslint/eslint/commit/cc4871369645c3409dc56ded7a555af8a9f63d51) Chore: refactor calculating range and loc in no-useless-escape (#13964) (Milos Djermanovic)
48
+ * [`535fe47`](https://github.com/eslint/eslint/commit/535fe47fee6544b4957378f9408117c8318d4762) Update: use regexpp's default ecmaVersion in no-control-regex (#13969) (Milos Djermanovic)
49
+ * [`83e98cd`](https://github.com/eslint/eslint/commit/83e98cd48ce3d1acf729f4fb9be40cff332abd6e) Fix: use regexpp's default ecmaVersion in no-invalid-regexp (#13968) (Milos Djermanovic)
50
+ * [`7297363`](https://github.com/eslint/eslint/commit/7297363ea355d0e3b2a74aaec586126deb91fd93) Docs: fix examples for no-multi-str (#13966) (Milos Djermanovic)
51
+ * [`0649871`](https://github.com/eslint/eslint/commit/06498716bfba65ed8c7217917a29a07ad267193a) Update: add autofix to rule multiline-ternary (#13958) (薛定谔的猫)
52
+ * [`f6e7e32`](https://github.com/eslint/eslint/commit/f6e7e3231bc43c989f8c953de8e0d328bac5eea0) Fix: no-useless-escape wrong loc and fix with CRLF in template elements (#13953) (Milos Djermanovic)
53
+ * [`19c69c0`](https://github.com/eslint/eslint/commit/19c69c0293a98634ff0d4884a0cdabc1213ebcb4) Fix: one-var shouldn't split declaration if it isn't in a statement list (#13959) (Milos Djermanovic)
54
+ * [`e451b96`](https://github.com/eslint/eslint/commit/e451b9664aface32ad9321eaf5619c875dc76553) Docs: update build tool for webpack (#13962) (Sam Chen)
55
+ * [`c3e9acc`](https://github.com/eslint/eslint/commit/c3e9accce2f61b04ab699fd37c90703305281aa3) Chore: fix typos (#13960) (YeonJuan)
56
+ * [`7289ecf`](https://github.com/eslint/eslint/commit/7289ecf58ed0d2e7f0ad7f1e5004c8927a7bf805) Sponsors: Sync README with website (ESLint Jenkins)
57
+
58
+ v7.16.0 - December 18, 2020
59
+
60
+ * [`a62ad6f`](https://github.com/eslint/eslint/commit/a62ad6f03151358b93b5fede022a30d67310705c) Update: fix false negative of no-extra-parens with NewExpression (#13930) (Milos Djermanovic)
61
+ * [`f85b4c7`](https://github.com/eslint/eslint/commit/f85b4c72668c95c79fdb342b74dbd53d21baa93f) Fix: require-atomic-updates false positive across await (fixes #11954) (#13915) (buhi)
62
+ * [`301d0c0`](https://github.com/eslint/eslint/commit/301d0c05229dbd6cfb1045d716524e8ec46fa2c1) Fix: no-constant-condition false positives with unary expressions (#13927) (Milos Djermanovic)
63
+ * [`555c128`](https://github.com/eslint/eslint/commit/555c128b49ae6d9c100a9f8429416417edb40d13) Fix: false positive with await and ** in no-extra-parens (fixes #12739) (#13923) (Milos Djermanovic)
64
+ * [`d93c935`](https://github.com/eslint/eslint/commit/d93c9350361d2aa1a1976c553e47ab399e51e8c9) Docs: update JSON Schema links (#13936) (Milos Djermanovic)
65
+ * [`8d0c93a`](https://github.com/eslint/eslint/commit/8d0c93a7ef9449c7b7d082bbb4b7d8465b0d6bac) Upgrade: table@6.0.4 (#13920) (Rouven Weßling)
66
+ * [`9247683`](https://github.com/eslint/eslint/commit/924768377a4935a95a6ff3866f9545a5a6178b53) Docs: Remove for deleted npm run profile script (#13931) (Brandon Mills)
67
+ * [`ab240d4`](https://github.com/eslint/eslint/commit/ab240d49833b4e6e594667c1abe5b0caa8a9cf70) Fix: prefer-exponentiation-operator invalid autofix with await (#13924) (Milos Djermanovic)
68
+ * [`dc76911`](https://github.com/eslint/eslint/commit/dc7691103554a99bdb2142561cb507f50f547e3b) Chore: Add .pre-commit-hooks.yaml file (#13628) (Álvaro Mondéjar)
69
+ * [`2124e1b`](https://github.com/eslint/eslint/commit/2124e1b5dad30a905dc26bde9da472bf622d3f50) Docs: Fix wrong rule name (#13913) (noisyboy25)
70
+ * [`06b5809`](https://github.com/eslint/eslint/commit/06b58096975935ec016d96dd5f333f059c270f26) Sponsors: Sync README with website (ESLint Jenkins)
71
+ * [`26fc12f`](https://github.com/eslint/eslint/commit/26fc12f88109af9d4081bf0e16364c411bce3009) Docs: Update README team and sponsors (ESLint Jenkins)
72
+
1
73
  v7.15.0 - December 5, 2020
2
74
 
3
75
  * [`5c11aab`](https://github.com/eslint/eslint/commit/5c11aabbe8249aeb8cad29bc6a33fc20c8c683ef) Upgrade: @eslint/esintrc and espree for bug fixes (refs #13878) (#13908) (Brandon Mills)
package/README.md CHANGED
@@ -35,10 +35,11 @@ ESLint is a tool for identifying and reporting on patterns found in ECMAScript/J
35
35
  6. [Releases](#releases)
36
36
  7. [Security Policy](#security-policy)
37
37
  8. [Semantic Versioning Policy](#semantic-versioning-policy)
38
- 9. [License](#license)
39
- 10. [Team](#team)
40
- 11. [Sponsors](#sponsors)
41
- 12. [Technology Sponsors](#technology-sponsors)
38
+ 9. [Stylistic Rule Updates](#stylistic-rule-updates)
39
+ 10. [License](#license)
40
+ 11. [Team](#team)
41
+ 12. [Sponsors](#sponsors)
42
+ 13. [Technology Sponsors](#technology-sponsors)
42
43
 
43
44
  ## <a name="installation-and-usage"></a>Installation and Usage
44
45
 
@@ -136,6 +137,16 @@ Once a language feature has been adopted into the ECMAScript standard (stage 4 a
136
137
 
137
138
  Join our [Mailing List](https://groups.google.com/group/eslint) or [Chatroom](https://eslint.org/chat).
138
139
 
140
+ ### Why doesn't ESLint lock dependency versions?
141
+
142
+ Lock files like `package-lock.json` are helpful for deployed applications. They ensure that dependencies are consistent between environments and across deployments.
143
+
144
+ Packages like `eslint` that get published to the npm registry do not include lock files. `npm install eslint` as a user will respect version constraints in ESLint's `package.json`. ESLint and its dependencies will be included in the user's lock file if one exists, but ESLint's own lock file would not be used.
145
+
146
+ We intentionally don't lock dependency versions so that we have the latest compatible dependency versions in development and CI that our users get when installing ESLint in a project.
147
+
148
+ The Twilio blog has a [deeper dive](https://www.twilio.com/blog/lockfiles-nodejs) to learn more.
149
+
139
150
  ## <a name="releases"></a>Releases
140
151
 
141
152
  We have scheduled releases every two weeks on Friday or Saturday. You can follow a [release issue](https://github.com/eslint/eslint/issues?q=is%3Aopen+is%3Aissue+label%3Arelease) for updates about the scheduling of any particular release.
@@ -158,6 +169,7 @@ ESLint follows [semantic versioning](https://semver.org). However, due to the na
158
169
  * A bug fix in a rule that results in ESLint reporting more linting errors.
159
170
  * A new rule is created.
160
171
  * A new option to an existing rule that does not result in ESLint reporting more linting errors by default.
172
+ * A new addition to an existing rule to support a newly-added language feature (within the last 12 months) that will result in ESLint reporting more linting errors by default.
161
173
  * An existing rule is deprecated.
162
174
  * A new CLI capability is created.
163
175
  * New capabilities to the public API are added (new classes, new methods, new arguments to existing methods, etc.).
@@ -176,6 +188,15 @@ ESLint follows [semantic versioning](https://semver.org). However, due to the na
176
188
 
177
189
  According to our policy, any minor update may report more linting errors than the previous release (ex: from a bug fix). As such, we recommend using the tilde (`~`) in `package.json` e.g. `"eslint": "~3.1.0"` to guarantee the results of your builds.
178
190
 
191
+ ## <a name="stylistic-rule-updates"></a>Stylistic Rule Updates
192
+
193
+ Stylistic rules are frozen according to [our policy](https://eslint.org/blog/2020/05/changes-to-rules-policies) on how we evaluate new rules and rule changes.
194
+ This means:
195
+
196
+ * **Bug fixes**: We will still fix bugs in stylistic rules.
197
+ * **New ECMAScript features**: We will also make sure stylistic rules are compatible with new ECMAScript features.
198
+ * **New options**: We will **not** add any new options to stylistic rules unless an option is the only way to fix a bug or support a newly-added ECMAScript feature.
199
+
179
200
  ## <a name="license"></a>License
180
201
 
181
202
  [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Feslint%2Feslint.svg?type=large)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Feslint%2Feslint?ref=badge_large)
@@ -207,11 +228,6 @@ Brandon Mills
207
228
  Toru Nagashima
208
229
  </a>
209
230
  </td><td align="center" valign="top" width="11%">
210
- <a href="https://github.com/kaicataldo">
211
- <img src="https://github.com/kaicataldo.png?s=75" width="75" height="75"><br />
212
- Kai Cataldo
213
- </a>
214
- </td><td align="center" valign="top" width="11%">
215
231
  <a href="https://github.com/mdjermanovic">
216
232
  <img src="https://github.com/mdjermanovic.png?s=75" width="75" height="75"><br />
217
233
  Milos Djermanovic
@@ -265,9 +281,9 @@ The following companies, organizations, and individuals support ESLint's ongoing
265
281
  <!--sponsorsstart-->
266
282
  <h3>Platinum Sponsors</h3>
267
283
  <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>
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>
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>
284
+ <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://avatars.githubusercontent.com/u/67931232?u=7fddc652a464d7151b97e8f108392af7d54fa3e8&v=4" alt="Microsoft FOSS Fund Sponsorships" height="96"></a></p><h3>Silver Sponsors</h3>
285
+ <p><a href="https://retool.com/"><img src="https://images.opencollective.com/retool/98ea68e/logo.png" alt="Retool" height="64"></a> <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>
286
+ <p><a href="https://streamat.se"><img src="https://images.opencollective.com/streamat/46890db/logo.png" alt="Streamat" height="32"></a> <a href="https://thestandarddaily.com/"><img src="https://images.opencollective.com/eric-watson/db4e598/avatar.png" alt="The Standard Daily" height="32"></a> <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/february-calendar.html"><img src="https://images.opencollective.com/betacalendars/9334b33/logo.png" alt="February 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.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>
271
287
  <!--sponsorsend-->
272
288
 
273
289
  ## <a name="technology-sponsors"></a>Technology Sponsors
@@ -272,7 +272,7 @@ function processOptions({
272
272
  errors.push("'rulePaths' must be an array of non-empty strings.");
273
273
  }
274
274
  if (typeof useEslintrc !== "boolean") {
275
- errors.push("'useElintrc' must be a boolean.");
275
+ errors.push("'useEslintrc' must be a boolean.");
276
276
  }
277
277
 
278
278
  if (errors.length > 0) {
@@ -563,7 +563,7 @@ class ESLint {
563
563
 
564
564
  /**
565
565
  * Returns the formatter representing the given formatter name.
566
- * @param {string} [name] The name of the formattter to load.
566
+ * @param {string} [name] The name of the formatter to load.
567
567
  * The following values are allowed:
568
568
  * - `undefined` ... Load `stylish` builtin formatter.
569
569
  * - A builtin formatter name ... Load the builtin formatter.
@@ -565,7 +565,8 @@ function promptUser() {
565
565
  {
566
566
  type: "toggle",
567
567
  name: "installESLint",
568
- message(answers) {
568
+ message() {
569
+ const { answers } = this.state;
569
570
  const verb = semver.ltr(answers.localESLintVersion, answers.requiredESLintVersionRange)
570
571
  ? "upgrade"
571
572
  : "downgrade";
@@ -191,7 +191,7 @@ module.exports = {
191
191
  }
192
192
 
193
193
  /*
194
- * If the first token of the reutrn value is `{` or the return value is a sequence expression,
194
+ * If the first token of the return value is `{` or the return value is a sequence expression,
195
195
  * enclose the return value by parentheses to avoid syntax error.
196
196
  */
197
197
  if (astUtils.isOpeningBraceToken(firstValueToken) || blockBody[0].argument.type === "SequenceExpression" || (funcInfo.hasInOperator && isInsideForLoopInitializer(node))) {
@@ -59,9 +59,9 @@ module.exports = {
59
59
  }
60
60
 
61
61
  /**
62
- * Check to see if a node contains only identifers
62
+ * Check to see if a node contains only identifiers
63
63
  * @param {ASTNode} node The node to check
64
- * @returns {boolean} Whether or not the node contains only identifers
64
+ * @returns {boolean} Whether or not the node contains only identifiers
65
65
  */
66
66
  function containsOnlyIdentifiers(node) {
67
67
  if (node.type === "Identifier") {
@@ -153,7 +153,13 @@ module.exports = {
153
153
  IfStatement: increaseComplexity,
154
154
  SwitchCase: increaseSwitchComplexity,
155
155
  WhileStatement: increaseComplexity,
156
- DoWhileStatement: increaseComplexity
156
+ DoWhileStatement: increaseComplexity,
157
+
158
+ AssignmentExpression(node) {
159
+ if (astUtils.isLogicalAssignmentOperator(node.operator)) {
160
+ increaseComplexity();
161
+ }
162
+ }
157
163
  };
158
164
 
159
165
  }
@@ -46,7 +46,7 @@ module.exports = {
46
46
  const sourceCode = context.getSourceCode();
47
47
 
48
48
  /**
49
- * Reports if the dot between object and property is on the correct loccation.
49
+ * Reports if the dot between object and property is on the correct location.
50
50
  * @param {ASTNode} node The `MemberExpression` node.
51
51
  * @returns {void}
52
52
  */
@@ -131,7 +131,7 @@ module.exports = {
131
131
  return null;
132
132
  }
133
133
 
134
- // If `?.` exsits, it doesn't hide no-undexpected-multiline errors
134
+ // If `?.` exists, it doesn't hide no-unexpected-multiline errors
135
135
  if (node.optional) {
136
136
  return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], "?.");
137
137
  }
@@ -177,7 +177,7 @@ module.exports = {
177
177
  /*
178
178
  * Only autofix if there is no newline
179
179
  * https://github.com/eslint/eslint/issues/7787
180
- * But if `?.` exsits, it doesn't hide no-undexpected-multiline errors
180
+ * But if `?.` exists, it doesn't hide no-unexpected-multiline errors
181
181
  */
182
182
  if (!node.optional) {
183
183
  return null;
@@ -1178,6 +1178,7 @@ module.exports = {
1178
1178
  offsets.setDesiredOffset(colonToken, firstToken, 1);
1179
1179
 
1180
1180
  offsets.setDesiredOffset(firstConsequentToken, firstToken,
1181
+ firstConsequentToken.type === "Punctuator" &&
1181
1182
  options.offsetTernaryExpressions ? 2 : 1);
1182
1183
 
1183
1184
  /*
@@ -27,19 +27,22 @@ module.exports = {
27
27
  enum: ["always", "always-multiline", "never"]
28
28
  }
29
29
  ],
30
+
30
31
  messages: {
31
32
  expectedTestCons: "Expected newline between test and consequent of ternary expression.",
32
33
  expectedConsAlt: "Expected newline between consequent and alternate of ternary expression.",
33
34
  unexpectedTestCons: "Unexpected newline between test and consequent of ternary expression.",
34
35
  unexpectedConsAlt: "Unexpected newline between consequent and alternate of ternary expression."
35
- }
36
+ },
37
+
38
+ fixable: "whitespace"
36
39
  },
37
40
 
38
41
  create(context) {
42
+ const sourceCode = context.getSourceCode();
39
43
  const option = context.options[0];
40
44
  const multiline = option !== "never";
41
45
  const allowSingleLine = option === "always-multiline";
42
- const sourceCode = context.getSourceCode();
43
46
 
44
47
  //--------------------------------------------------------------------------
45
48
  // Public
@@ -59,6 +62,8 @@ module.exports = {
59
62
  const areTestAndConsequentOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfTest, firstTokenOfConsequent);
60
63
  const areConsequentAndAlternateOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfConsequent, firstTokenOfAlternate);
61
64
 
65
+ const hasComments = !!sourceCode.getCommentsInside(node).length;
66
+
62
67
  if (!multiline) {
63
68
  if (!areTestAndConsequentOnSameLine) {
64
69
  context.report({
@@ -67,7 +72,24 @@ module.exports = {
67
72
  start: firstTokenOfTest.loc.start,
68
73
  end: lastTokenOfTest.loc.end
69
74
  },
70
- messageId: "unexpectedTestCons"
75
+ messageId: "unexpectedTestCons",
76
+ fix: fixer => {
77
+ if (hasComments) {
78
+ return null;
79
+ }
80
+ const fixers = [];
81
+ const areTestAndQuestionOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfTest, questionToken);
82
+ const areQuestionAndConsOnSameLine = astUtils.isTokenOnSameLine(questionToken, firstTokenOfConsequent);
83
+
84
+ if (!areTestAndQuestionOnSameLine) {
85
+ fixers.push(fixer.removeRange([lastTokenOfTest.range[1], questionToken.range[0]]));
86
+ }
87
+ if (!areQuestionAndConsOnSameLine) {
88
+ fixers.push(fixer.removeRange([questionToken.range[1], firstTokenOfConsequent.range[0]]));
89
+ }
90
+
91
+ return fixers;
92
+ }
71
93
  });
72
94
  }
73
95
 
@@ -78,7 +100,24 @@ module.exports = {
78
100
  start: firstTokenOfConsequent.loc.start,
79
101
  end: lastTokenOfConsequent.loc.end
80
102
  },
81
- messageId: "unexpectedConsAlt"
103
+ messageId: "unexpectedConsAlt",
104
+ fix: fixer => {
105
+ if (hasComments) {
106
+ return null;
107
+ }
108
+ const fixers = [];
109
+ const areConsAndColonOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfConsequent, colonToken);
110
+ const areColonAndAltOnSameLine = astUtils.isTokenOnSameLine(colonToken, firstTokenOfAlternate);
111
+
112
+ if (!areConsAndColonOnSameLine) {
113
+ fixers.push(fixer.removeRange([lastTokenOfConsequent.range[1], colonToken.range[0]]));
114
+ }
115
+ if (!areColonAndAltOnSameLine) {
116
+ fixers.push(fixer.removeRange([colonToken.range[1], firstTokenOfAlternate.range[0]]));
117
+ }
118
+
119
+ return fixers;
120
+ }
82
121
  });
83
122
  }
84
123
  } else {
@@ -93,7 +132,16 @@ module.exports = {
93
132
  start: firstTokenOfTest.loc.start,
94
133
  end: lastTokenOfTest.loc.end
95
134
  },
96
- messageId: "expectedTestCons"
135
+ messageId: "expectedTestCons",
136
+ fix: fixer => (hasComments ? null : (
137
+ fixer.replaceTextRange(
138
+ [
139
+ lastTokenOfTest.range[1],
140
+ questionToken.range[0]
141
+ ],
142
+ "\n"
143
+ )
144
+ ))
97
145
  });
98
146
  }
99
147
 
@@ -104,7 +152,16 @@ module.exports = {
104
152
  start: firstTokenOfConsequent.loc.start,
105
153
  end: lastTokenOfConsequent.loc.end
106
154
  },
107
- messageId: "expectedConsAlt"
155
+ messageId: "expectedConsAlt",
156
+ fix: (fixer => (hasComments ? null : (
157
+ fixer.replaceTextRange(
158
+ [
159
+ lastTokenOfConsequent.range[1],
160
+ colonToken.range[0]
161
+ ],
162
+ "\n"
163
+ )
164
+ )))
108
165
  });
109
166
  }
110
167
  }
@@ -106,10 +106,15 @@ module.exports = {
106
106
  */
107
107
  return operator === node.operator &&
108
108
  (
109
- isLogicalIdentity(node.left, node.operator) ||
110
- isLogicalIdentity(node.right, node.operator)
109
+ isLogicalIdentity(node.left, operator) ||
110
+ isLogicalIdentity(node.right, operator)
111
111
  );
112
112
 
113
+ case "AssignmentExpression":
114
+ return ["||=", "&&="].includes(node.operator) &&
115
+ operator === node.operator.slice(0, -1) &&
116
+ isLogicalIdentity(node.right, operator);
117
+
113
118
  // no default
114
119
  }
115
120
  return false;
@@ -147,12 +152,18 @@ module.exports = {
147
152
  }
148
153
 
149
154
  case "UnaryExpression":
150
- if (node.operator === "void") {
155
+ if (
156
+ node.operator === "void" ||
157
+ node.operator === "typeof" && inBooleanPosition
158
+ ) {
151
159
  return true;
152
160
  }
153
161
 
154
- return (node.operator === "typeof" && inBooleanPosition) ||
155
- isConstant(node.argument, true);
162
+ if (node.operator === "!") {
163
+ return isConstant(node.argument, true);
164
+ }
165
+
166
+ return isConstant(node.argument, false);
156
167
 
157
168
  case "BinaryExpression":
158
169
  return isConstant(node.left, false) &&
@@ -171,7 +182,15 @@ module.exports = {
171
182
  }
172
183
 
173
184
  case "AssignmentExpression":
174
- return (node.operator === "=") && isConstant(node.right, inBooleanPosition);
185
+ if (node.operator === "=") {
186
+ return isConstant(node.right, inBooleanPosition);
187
+ }
188
+
189
+ if (["||=", "&&="].includes(node.operator) && inBooleanPosition) {
190
+ return isLogicalIdentity(node.right, node.operator.slice(0, -1));
191
+ }
192
+
193
+ return false;
175
194
 
176
195
  case "SequenceExpression":
177
196
  return isConstant(node.expressions[node.expressions.length - 1], inBooleanPosition);
@@ -8,7 +8,6 @@
8
8
  const RegExpValidator = require("regexpp").RegExpValidator;
9
9
  const collector = new (class {
10
10
  constructor() {
11
- this.ecmaVersion = 2018;
12
11
  this._source = "";
13
12
  this._controlChars = [];
14
13
  this._validator = new RegExpValidator(this);
@@ -138,7 +138,7 @@ module.exports = {
138
138
  }
139
139
 
140
140
  /*
141
- * `identifierNode.parent` is a MamberExpression `*.prototype`.
141
+ * `identifierNode.parent` is a MemberExpression `*.prototype`.
142
142
  * If it's an optional member access, it may be wrapped by a `ChainExpression` node.
143
143
  */
144
144
  const prototypeNode =
@@ -472,20 +472,34 @@ module.exports = {
472
472
  const callee = node.callee;
473
473
 
474
474
  if (hasExcessParensWithPrecedence(callee, precedence(node))) {
475
- const hasNewParensException = callee.type === "NewExpression" && !isNewExpressionWithParens(callee);
476
-
477
475
  if (
478
476
  hasDoubleExcessParens(callee) ||
479
- !isIIFE(node) &&
480
- !hasNewParensException &&
481
477
  !(
482
-
483
- // Allow extra parens around a new expression if they are intervening parentheses.
484
- node.type === "NewExpression" &&
485
- callee.type === "MemberExpression" &&
486
- doesMemberExpressionContainCallExpression(callee)
487
- ) &&
488
- !(!node.optional && callee.type === "ChainExpression")
478
+ isIIFE(node) ||
479
+
480
+ // (new A)(); new (new A)();
481
+ (
482
+ callee.type === "NewExpression" &&
483
+ !isNewExpressionWithParens(callee) &&
484
+ !(
485
+ node.type === "NewExpression" &&
486
+ !isNewExpressionWithParens(node)
487
+ )
488
+ ) ||
489
+
490
+ // new (a().b)(); new (a.b().c);
491
+ (
492
+ node.type === "NewExpression" &&
493
+ callee.type === "MemberExpression" &&
494
+ doesMemberExpressionContainCallExpression(callee)
495
+ ) ||
496
+
497
+ // (a?.b)(); (a?.())();
498
+ (
499
+ !node.optional &&
500
+ callee.type === "ChainExpression"
501
+ )
502
+ )
489
503
  ) {
490
504
  report(node.callee);
491
505
  }
@@ -511,7 +525,7 @@ module.exports = {
511
525
 
512
526
  if (!shouldSkipLeft && hasExcessParens(node.left)) {
513
527
  if (
514
- !(node.left.type === "UnaryExpression" && isExponentiation) &&
528
+ !(["AwaitExpression", "UnaryExpression"].includes(node.left.type) && isExponentiation) &&
515
529
  !astUtils.isMixedLogicalAndCoalesceExpressions(node.left, node) &&
516
530
  (leftPrecedence > prec || (leftPrecedence === prec && !isExponentiation)) ||
517
531
  isParenthesisedTwice(node.left)
@@ -830,45 +844,49 @@ module.exports = {
830
844
  ExportDefaultDeclaration: node => checkExpressionOrExportStatement(node.declaration),
831
845
  ExpressionStatement: node => checkExpressionOrExportStatement(node.expression),
832
846
 
833
- "ForInStatement, ForOfStatement"(node) {
834
- if (node.left.type !== "VariableDeclarator") {
847
+ ForInStatement(node) {
848
+ if (node.left.type !== "VariableDeclaration") {
835
849
  const firstLeftToken = sourceCode.getFirstToken(node.left, astUtils.isNotOpeningParenToken);
836
850
 
837
851
  if (
838
- firstLeftToken.value === "let" && (
839
-
840
- /*
841
- * If `let` is the only thing on the left side of the loop, it's the loop variable: `for ((let) of foo);`
842
- * Removing it will cause a syntax error, because it will be parsed as the start of a VariableDeclarator.
843
- */
844
- (firstLeftToken.range[1] === node.left.range[1] || /*
845
- * If `let` is followed by a `[` token, it's a property access on the `let` value: `for ((let[foo]) of bar);`
846
- * Removing it will cause the property access to be parsed as a destructuring declaration of `foo` instead.
847
- */
848
- astUtils.isOpeningBracketToken(
849
- sourceCode.getTokenAfter(firstLeftToken, astUtils.isNotClosingParenToken)
850
- ))
852
+ firstLeftToken.value === "let" &&
853
+ astUtils.isOpeningBracketToken(
854
+ sourceCode.getTokenAfter(firstLeftToken, astUtils.isNotClosingParenToken)
851
855
  )
852
856
  ) {
857
+
858
+ // ForInStatement#left expression cannot start with `let[`.
853
859
  tokensToIgnore.add(firstLeftToken);
854
860
  }
855
861
  }
856
862
 
857
- if (node.type === "ForOfStatement") {
858
- const hasExtraParens = node.right.type === "SequenceExpression"
859
- ? hasDoubleExcessParens(node.right)
860
- : hasExcessParens(node.right);
863
+ if (hasExcessParens(node.left)) {
864
+ report(node.left);
865
+ }
861
866
 
862
- if (hasExtraParens) {
863
- report(node.right);
864
- }
865
- } else if (hasExcessParens(node.right)) {
867
+ if (hasExcessParens(node.right)) {
866
868
  report(node.right);
867
869
  }
870
+ },
871
+
872
+ ForOfStatement(node) {
873
+ if (node.left.type !== "VariableDeclaration") {
874
+ const firstLeftToken = sourceCode.getFirstToken(node.left, astUtils.isNotOpeningParenToken);
875
+
876
+ if (firstLeftToken.value === "let") {
877
+
878
+ // ForOfStatement#left expression cannot start with `let`.
879
+ tokensToIgnore.add(firstLeftToken);
880
+ }
881
+ }
868
882
 
869
883
  if (hasExcessParens(node.left)) {
870
884
  report(node.left);
871
885
  }
886
+
887
+ if (hasExcessParensWithPrecedence(node.right, PRECEDENCE_OF_ASSIGNMENT_EXPR)) {
888
+ report(node.right);
889
+ }
872
890
  },
873
891
 
874
892
  ForStatement(node) {
@@ -881,6 +899,22 @@ module.exports = {
881
899
  }
882
900
 
883
901
  if (node.init) {
902
+
903
+ if (node.init.type !== "VariableDeclaration") {
904
+ const firstToken = sourceCode.getFirstToken(node.init, astUtils.isNotOpeningParenToken);
905
+
906
+ if (
907
+ firstToken.value === "let" &&
908
+ astUtils.isOpeningBracketToken(
909
+ sourceCode.getTokenAfter(firstToken, astUtils.isNotClosingParenToken)
910
+ )
911
+ ) {
912
+
913
+ // ForStatement#init expression cannot start with `let[`.
914
+ tokensToIgnore.add(firstToken);
915
+ }
916
+ }
917
+
884
918
  startNewReportsBuffering();
885
919
 
886
920
  if (hasExcessParens(node.init)) {
@@ -97,10 +97,10 @@ function isIterationVariable(node) {
97
97
  * - `Object.defineProperties`
98
98
  * - `Object.freeze`
99
99
  * - `Object.setPrototypeOf`
100
- * - `Refrect.defineProperty`
101
- * - `Refrect.deleteProperty`
102
- * - `Refrect.set`
103
- * - `Refrect.setPrototypeOf`
100
+ * - `Reflect.defineProperty`
101
+ * - `Reflect.deleteProperty`
102
+ * - `Reflect.set`
103
+ * - `Reflect.setPrototypeOf`
104
104
  * @param {ASTNode} node The node to check.
105
105
  * @param {Scope} scope A `escope.Scope` object to find variable (whichever).
106
106
  * @returns {boolean} `true` if the node is at the first argument of a well-known mutation function.
@@ -9,7 +9,7 @@
9
9
  //------------------------------------------------------------------------------
10
10
 
11
11
  const RegExpValidator = require("regexpp").RegExpValidator;
12
- const validator = new RegExpValidator({ ecmaVersion: 2018 });
12
+ const validator = new RegExpValidator();
13
13
  const validFlags = /[gimuys]/gu;
14
14
  const undefined1 = void 0;
15
15
 
@@ -69,6 +69,28 @@ module.exports = {
69
69
  return node && node.type === "Literal" && typeof node.value === "string";
70
70
  }
71
71
 
72
+ /**
73
+ * Gets flags of a regular expression created by the given `RegExp()` or `new RegExp()` call
74
+ * Examples:
75
+ * new RegExp(".") // => ""
76
+ * new RegExp(".", "gu") // => "gu"
77
+ * new RegExp(".", flags) // => null
78
+ * @param {ASTNode} node `CallExpression` or `NewExpression` node
79
+ * @returns {string|null} flags if they can be determined, `null` otherwise
80
+ * @private
81
+ */
82
+ function getFlags(node) {
83
+ if (node.arguments.length < 2) {
84
+ return "";
85
+ }
86
+
87
+ if (isString(node.arguments[1])) {
88
+ return node.arguments[1].value;
89
+ }
90
+
91
+ return null;
92
+ }
93
+
72
94
  /**
73
95
  * Check syntax error in a given pattern.
74
96
  * @param {string} pattern The RegExp pattern to validate.
@@ -104,18 +126,23 @@ module.exports = {
104
126
  return;
105
127
  }
106
128
  const pattern = node.arguments[0].value;
107
- let flags = isString(node.arguments[1]) ? node.arguments[1].value : "";
129
+ let flags = getFlags(node);
108
130
 
109
- if (allowedFlags) {
131
+ if (flags && allowedFlags) {
110
132
  flags = flags.replace(allowedFlags, "");
111
133
  }
112
134
 
113
- // If flags are unknown, check both are errored or not.
114
- const message = validateRegExpFlags(flags) || (
115
- flags
116
- ? validateRegExpPattern(pattern, flags.indexOf("u") !== -1)
117
- : validateRegExpPattern(pattern, true) && validateRegExpPattern(pattern, false)
118
- );
135
+ const message =
136
+ (
137
+ flags && validateRegExpFlags(flags)
138
+ ) ||
139
+ (
140
+
141
+ // If flags are unknown, report the regex only if its pattern is invalid both with and without the "u" flag
142
+ flags === null
143
+ ? validateRegExpPattern(pattern, true) && validateRegExpPattern(pattern, false)
144
+ : validateRegExpPattern(pattern, flags.includes("u"))
145
+ );
119
146
 
120
147
  if (message) {
121
148
  context.report({
@@ -45,7 +45,7 @@ module.exports = {
45
45
 
46
46
  /**
47
47
  * Checks and reports given exported identifier.
48
- * @param {ASTNode} node exported `Identifer` node to check.
48
+ * @param {ASTNode} node exported `Identifier` node to check.
49
49
  * @returns {void}
50
50
  */
51
51
  function checkExportedName(node) {
@@ -44,7 +44,8 @@ module.exports = {
44
44
  ],
45
45
 
46
46
  messages: {
47
- noShadow: "'{{name}}' is already declared in the upper scope."
47
+ noShadow: "'{{name}}' is already declared in the upper scope on line {{shadowedLine}} column {{shadowedColumn}}.",
48
+ noShadowGlobal: "'{{name}}' is already a global variable."
48
49
  }
49
50
  },
50
51
 
@@ -117,6 +118,29 @@ module.exports = {
117
118
  return def && def.name.range;
118
119
  }
119
120
 
121
+ /**
122
+ * Get declared line and column of a variable.
123
+ * @param {eslint-scope.Variable} variable The variable to get.
124
+ * @returns {Object} The declared line and column of the variable.
125
+ */
126
+ function getDeclaredLocation(variable) {
127
+ const identifier = variable.identifiers[0];
128
+ let obj;
129
+
130
+ if (identifier) {
131
+ obj = {
132
+ global: false,
133
+ line: identifier.loc.start.line,
134
+ column: identifier.loc.start.column + 1
135
+ };
136
+ } else {
137
+ obj = {
138
+ global: true
139
+ };
140
+ }
141
+ return obj;
142
+ }
143
+
120
144
  /**
121
145
  * Checks if a variable is in TDZ of scopeVar.
122
146
  * @param {Object} variable The variable to check.
@@ -165,10 +189,18 @@ module.exports = {
165
189
  !isOnInitializer(variable, shadowed) &&
166
190
  !(options.hoist !== "all" && isInTdz(variable, shadowed))
167
191
  ) {
192
+ const location = getDeclaredLocation(shadowed);
193
+ const messageId = location.global ? "noShadowGlobal" : "noShadow";
194
+ const data = { name: variable.name };
195
+
196
+ if (!location.global) {
197
+ data.shadowedLine = location.line;
198
+ data.shadowedColumn = location.column;
199
+ }
168
200
  context.report({
169
201
  node: variable.identifiers[0],
170
- messageId: "noShadow",
171
- data: variable
202
+ messageId,
203
+ data
172
204
  });
173
205
  }
174
206
  }
@@ -171,7 +171,7 @@ module.exports = {
171
171
  /**
172
172
  * Removes the top of stack item.
173
173
  *
174
- * And this treverses all segments of this code path then reports every
174
+ * And this traverses all segments of this code path then reports every
175
175
  * invalid node.
176
176
  * @param {CodePath} codePath A code path which was ended.
177
177
  * @returns {void}
@@ -109,9 +109,9 @@ module.exports = {
109
109
  * @returns {void}
110
110
  */
111
111
  function report(node, startOffset, character) {
112
- const start = sourceCode.getLocFromIndex(sourceCode.getIndexFromLoc(node.loc.start) + startOffset);
113
- const rangeStart = sourceCode.getIndexFromLoc(node.loc.start) + startOffset;
112
+ const rangeStart = node.range[0] + startOffset;
114
113
  const range = [rangeStart, rangeStart + 1];
114
+ const start = sourceCode.getLocFromIndex(rangeStart);
115
115
 
116
116
  context.report({
117
117
  node,
@@ -172,7 +172,7 @@ module.exports = {
172
172
  }
173
173
 
174
174
  if (isUnnecessaryEscape && !isQuoteEscape) {
175
- report(node, match.index + 1, match[0].slice(1));
175
+ report(node, match.index, match[0].slice(1));
176
176
  }
177
177
  }
178
178
 
@@ -206,7 +206,7 @@ module.exports = {
206
206
  return;
207
207
  }
208
208
 
209
- const value = isTemplateElement ? node.value.raw : node.raw.slice(1, -1);
209
+ const value = isTemplateElement ? sourceCode.getText(node) : node.raw;
210
210
  const pattern = /\\[^\d]/gu;
211
211
  let match;
212
212
 
@@ -5,6 +5,12 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ //------------------------------------------------------------------------------
9
+ // Requirements
10
+ //------------------------------------------------------------------------------
11
+
12
+ const astUtils = require("./utils/ast-utils");
13
+
8
14
  //------------------------------------------------------------------------------
9
15
  // Rule Definition
10
16
  //------------------------------------------------------------------------------
@@ -54,11 +60,10 @@ module.exports = {
54
60
  * Reports error for unnecessarily renamed assignments
55
61
  * @param {ASTNode} node node to report
56
62
  * @param {ASTNode} initial node with initial name value
57
- * @param {ASTNode} result node with new name value
58
63
  * @param {string} type the type of the offending node
59
64
  * @returns {void}
60
65
  */
61
- function reportError(node, initial, result, type) {
66
+ function reportError(node, initial, type) {
62
67
  const name = initial.type === "Identifier" ? initial.name : initial.value;
63
68
 
64
69
  return context.report({
@@ -69,18 +74,21 @@ module.exports = {
69
74
  type
70
75
  },
71
76
  fix(fixer) {
72
- if (sourceCode.commentsExistBetween(initial, result)) {
77
+ const replacementNode = node.type === "Property" ? node.value : node.local;
78
+
79
+ if (sourceCode.getCommentsInside(node).length > sourceCode.getCommentsInside(replacementNode).length) {
73
80
  return null;
74
81
  }
75
82
 
76
- const replacementText = result.type === "AssignmentPattern"
77
- ? sourceCode.getText(result)
78
- : name;
83
+ // Don't autofix code such as `({foo: (foo) = a} = obj);`, parens are not allowed in shorthand properties.
84
+ if (
85
+ replacementNode.type === "AssignmentPattern" &&
86
+ astUtils.isParenthesised(sourceCode, replacementNode.left)
87
+ ) {
88
+ return null;
89
+ }
79
90
 
80
- return fixer.replaceTextRange([
81
- initial.range[0],
82
- result.range[1]
83
- ], replacementText);
91
+ return fixer.replaceText(node, sourceCode.getText(replacementNode));
84
92
  }
85
93
  });
86
94
  }
@@ -97,19 +105,11 @@ module.exports = {
97
105
 
98
106
  for (const property of node.properties) {
99
107
 
100
- /*
101
- * TODO: Remove after babel-eslint removes ExperimentalRestProperty
102
- * https://github.com/eslint/eslint/issues/12335
103
- */
104
- if (property.type === "ExperimentalRestProperty") {
105
- continue;
106
- }
107
-
108
108
  /**
109
109
  * Properties using shorthand syntax and rest elements can not be renamed.
110
110
  * If the property is computed, we have no idea if a rename is useless or not.
111
111
  */
112
- if (property.shorthand || property.type === "RestElement" || property.computed) {
112
+ if (property.type !== "Property" || property.shorthand || property.computed) {
113
113
  continue;
114
114
  }
115
115
 
@@ -117,7 +117,7 @@ module.exports = {
117
117
  const renamedKey = property.value.type === "AssignmentPattern" ? property.value.left.name : property.value.name;
118
118
 
119
119
  if (key === renamedKey) {
120
- reportError(property, property.key, property.value, "Destructuring assignment");
120
+ reportError(property, property.key, "Destructuring assignment");
121
121
  }
122
122
  }
123
123
  }
@@ -134,7 +134,7 @@ module.exports = {
134
134
 
135
135
  if (node.imported.name === node.local.name &&
136
136
  node.imported.range[0] !== node.local.range[0]) {
137
- reportError(node, node.imported, node.local, "Import");
137
+ reportError(node, node.imported, "Import");
138
138
  }
139
139
  }
140
140
 
@@ -150,7 +150,7 @@ module.exports = {
150
150
 
151
151
  if (node.local.name === node.exported.name &&
152
152
  node.local.range[0] !== node.exported.range[0]) {
153
- reportError(node, node.local, node.exported, "Export");
153
+ reportError(node, node.local, "Export");
154
154
  }
155
155
 
156
156
  }
@@ -5,6 +5,25 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ //------------------------------------------------------------------------------
9
+ // Requirements
10
+ //------------------------------------------------------------------------------
11
+
12
+ const astUtils = require("./utils/ast-utils");
13
+
14
+ //------------------------------------------------------------------------------
15
+ // Helpers
16
+ //------------------------------------------------------------------------------
17
+
18
+ /**
19
+ * Determines whether the given node is in a statement list.
20
+ * @param {ASTNode} node node to check
21
+ * @returns {boolean} `true` if the given node is in a statement list
22
+ */
23
+ function isInStatementList(node) {
24
+ return astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type);
25
+ }
26
+
8
27
  //------------------------------------------------------------------------------
9
28
  // Rule Definition
10
29
  //------------------------------------------------------------------------------
@@ -268,8 +287,8 @@ module.exports = {
268
287
 
269
288
  /**
270
289
  * Fixer to join VariableDeclaration's into a single declaration
271
- * @param {VariableDeclarator[]} declarations The `VariableDeclaration` to join
272
- * @returns {Function} The fixer function
290
+ * @param {VariableDeclarator[]} declarations The `VariableDeclaration` to join
291
+ * @returns {Function} The fixer function
273
292
  */
274
293
  function joinDeclarations(declarations) {
275
294
  const declaration = declarations[0];
@@ -297,10 +316,17 @@ module.exports = {
297
316
 
298
317
  /**
299
318
  * Fixer to split a VariableDeclaration into individual declarations
300
- * @param {VariableDeclaration} declaration The `VariableDeclaration` to split
301
- * @returns {Function} The fixer function
319
+ * @param {VariableDeclaration} declaration The `VariableDeclaration` to split
320
+ * @returns {Function|null} The fixer function
302
321
  */
303
322
  function splitDeclarations(declaration) {
323
+ const { parent } = declaration;
324
+
325
+ // don't autofix code such as: if (foo) var x, y;
326
+ if (!isInStatementList(parent.type === "ExportNamedDeclaration" ? parent : declaration)) {
327
+ return null;
328
+ }
329
+
304
330
  return fixer => declaration.declarations.map(declarator => {
305
331
  const tokenAfterDeclarator = sourceCode.getTokenAfter(declarator);
306
332
 
@@ -5,6 +5,11 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ //------------------------------------------------------------------------------
9
+ // Requirements
10
+ //------------------------------------------------------------------------------
11
+
12
+ const FixTracker = require("./utils/fix-tracker");
8
13
  const astUtils = require("./utils/ast-utils");
9
14
 
10
15
  //------------------------------------------------------------------------------
@@ -451,10 +456,18 @@ module.exports = {
451
456
  messageId: "useConst",
452
457
  data: node,
453
458
  fix: shouldFix
454
- ? fixer => fixer.replaceText(
455
- sourceCode.getFirstToken(varDeclParent, t => t.value === varDeclParent.kind),
456
- "const"
457
- )
459
+ ? fixer => {
460
+ const letKeywordToken = sourceCode.getFirstToken(varDeclParent, t => t.value === varDeclParent.kind);
461
+
462
+ /**
463
+ * Extend the replacement range to the whole declaration,
464
+ * in order to prevent other fixes in the same pass
465
+ * https://github.com/eslint/eslint/issues/13899
466
+ */
467
+ return new FixTracker(fixer, sourceCode)
468
+ .retainRange(varDeclParent.range)
469
+ .replaceTextRange(letKeywordToken.range, "const");
470
+ }
458
471
  : null
459
472
  });
460
473
  });
@@ -279,7 +279,7 @@ module.exports = {
279
279
  * @param {ASTNode} node the AssignmentExpression node
280
280
  * @returns {void}
281
281
  */
282
- function checkAssigmentExpression(node) {
282
+ function checkAssignmentExpression(node) {
283
283
  if (node.operator === "=") {
284
284
  performCheck(node.left, node.right, node);
285
285
  }
@@ -291,7 +291,7 @@ module.exports = {
291
291
 
292
292
  return {
293
293
  VariableDeclarator: checkVariableDeclarator,
294
- AssignmentExpression: checkAssigmentExpression
294
+ AssignmentExpression: checkAssignmentExpression
295
295
  };
296
296
  }
297
297
  };
@@ -30,6 +30,7 @@ function doesBaseNeedParens(base) {
30
30
  astUtils.getPrecedence(base) <= PRECEDENCE_OF_EXPONENTIATION_EXPR ||
31
31
 
32
32
  // An unary operator cannot be used immediately before an exponentiation expression
33
+ base.type === "AwaitExpression" ||
33
34
  base.type === "UnaryExpression"
34
35
  );
35
36
  }
@@ -105,10 +105,10 @@ module.exports = {
105
105
  CallExpression(node) {
106
106
  const methodName = (node.callee.property || {}).name;
107
107
  const isReflectCall = (node.callee.object || {}).name === "Reflect";
108
- const hasReflectSubsitute = Object.prototype.hasOwnProperty.call(reflectSubstitutes, methodName);
108
+ const hasReflectSubstitute = Object.prototype.hasOwnProperty.call(reflectSubstitutes, methodName);
109
109
  const userConfiguredException = exceptions.indexOf(methodName) !== -1;
110
110
 
111
- if (hasReflectSubsitute && !isReflectCall && !userConfiguredException) {
111
+ if (hasReflectSubstitute && !isReflectCall && !userConfiguredException) {
112
112
  report(node, existingNames[methodName], reflectSubstitutes[methodName]);
113
113
  }
114
114
  },
@@ -113,6 +113,9 @@ class SegmentInfo {
113
113
 
114
114
  if (info) {
115
115
  info.freshReadVariableNames.add(variableName);
116
+
117
+ // If a variable is freshly read again, then it's no more out-dated.
118
+ info.outdatedReadVariableNames.delete(variableName);
116
119
  }
117
120
  }
118
121
  }
@@ -132,7 +132,9 @@ module.exports = {
132
132
 
133
133
  if (nonSpacedConsequentNode) {
134
134
  report(node, nonSpacedConsequentNode);
135
- } else if (nonSpacedAlternateNode) {
135
+ }
136
+
137
+ if (nonSpacedAlternateNode) {
136
138
  report(node, nonSpacedAlternateNode);
137
139
  }
138
140
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @fileoverview This rule shoud require or disallow spaces before or after unary operations.
2
+ * @fileoverview This rule should require or disallow spaces before or after unary operations.
3
3
  * @author Marcin Kumorek
4
4
  */
5
5
  "use strict";
@@ -82,7 +82,7 @@ function startsWithUpperCase(s) {
82
82
  /**
83
83
  * Checks whether or not a node is a constructor.
84
84
  * @param {ASTNode} node A function node to check.
85
- * @returns {boolean} Wehether or not a node is a constructor.
85
+ * @returns {boolean} Whether or not a node is a constructor.
86
86
  */
87
87
  function isES5Constructor(node) {
88
88
  return (node.id && startsWithUpperCase(node.id.name));
@@ -1574,7 +1574,7 @@ module.exports = {
1574
1574
  },
1575
1575
 
1576
1576
  /*
1577
- * Determine if a node has a possiblity to be an Error object
1577
+ * Determine if a node has a possibility to be an Error object
1578
1578
  * @param {ASTNode} node ASTNode to check
1579
1579
  * @returns {boolean} True if there is a chance it contains an Error obj
1580
1580
  */
@@ -15,7 +15,7 @@ const lodash = require("lodash");
15
15
  // Private
16
16
  //------------------------------------------------------------------------------
17
17
 
18
- // Defitions for deprecation warnings.
18
+ // Definitions for deprecation warnings.
19
19
  const deprecationWarningMessages = {
20
20
  ESLINT_LEGACY_ECMAFEATURES:
21
21
  "The 'ecmaFeatures' config file property is deprecated and has no effect.",
@@ -46,9 +46,9 @@ module.exports = {};
46
46
  /**
47
47
  * @typedef {Object} OverrideConfigData
48
48
  * @property {Record<string, boolean>} [env] The environment settings.
49
- * @property {string | string[]} [excludedFiles] The glob pattarns for excluded files.
49
+ * @property {string | string[]} [excludedFiles] The glob patterns for excluded files.
50
50
  * @property {string | string[]} [extends] The path to other config files or the package name of shareable configs.
51
- * @property {string | string[]} files The glob pattarns for target files.
51
+ * @property {string | string[]} files The glob patterns for target files.
52
52
  * @property {Record<string, GlobalConf>} [globals] The global variable settings.
53
53
  * @property {boolean} [noInlineConfig] The flag that disables directive comments.
54
54
  * @property {OverrideConfigData[]} [overrides] The override settings per kind of files.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint",
3
- "version": "7.15.0",
3
+ "version": "7.19.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,7 +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.2.2",
50
+ "@eslint/eslintrc": "^0.3.0",
51
51
  "ajv": "^6.10.0",
52
52
  "chalk": "^4.0.0",
53
53
  "cross-spawn": "^7.0.2",
@@ -71,7 +71,7 @@
71
71
  "js-yaml": "^3.13.1",
72
72
  "json-stable-stringify-without-jsonify": "^1.0.1",
73
73
  "levn": "^0.4.1",
74
- "lodash": "^4.17.19",
74
+ "lodash": "^4.17.20",
75
75
  "minimatch": "^3.0.4",
76
76
  "natural-compare": "^1.4.0",
77
77
  "optionator": "^0.9.1",
@@ -80,7 +80,7 @@
80
80
  "semver": "^7.2.1",
81
81
  "strip-ansi": "^6.0.0",
82
82
  "strip-json-comments": "^3.1.0",
83
- "table": "^5.2.3",
83
+ "table": "^6.0.4",
84
84
  "text-table": "^0.2.0",
85
85
  "v8-compile-cache": "^2.0.3"
86
86
  },