eslint 7.0.0 → 7.1.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 +29 -0
- package/README.md +3 -4
- package/lib/init/config-initializer.js +1 -0
- package/lib/linter/linter.js +2 -1
- package/lib/rules/accessor-pairs.js +1 -1
- package/lib/rules/arrow-parens.js +19 -3
- package/lib/rules/block-spacing.js +19 -2
- package/lib/rules/callback-return.js +1 -1
- package/lib/rules/global-require.js +1 -1
- package/lib/rules/handle-callback-err.js +1 -1
- package/lib/rules/index.js +1 -0
- package/lib/rules/linebreak-style.js +8 -2
- package/lib/rules/max-lines-per-function.js +1 -1
- package/lib/rules/no-buffer-constructor.js +1 -1
- package/lib/rules/no-loss-of-precision.js +198 -0
- package/lib/rules/no-mixed-requires.js +1 -1
- package/lib/rules/no-new-func.js +22 -19
- package/lib/rules/no-new-require.js +1 -1
- package/lib/rules/no-new-symbol.js +2 -1
- package/lib/rules/no-path-concat.js +1 -1
- package/lib/rules/no-process-env.js +1 -1
- package/lib/rules/no-process-exit.js +1 -1
- package/lib/rules/no-restricted-modules.js +1 -1
- package/lib/rules/no-sync.js +1 -1
- package/lib/rules/one-var-declaration-per-line.js +1 -1
- package/lib/rules/padded-blocks.js +17 -4
- package/lib/rules/rest-spread-spacing.js +3 -6
- package/lib/rules/semi-spacing.js +32 -8
- package/lib/rules/utils/ast-utils.js +51 -6
- package/lib/source-code/source-code.js +1 -0
- 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 +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,32 @@
|
|
1
|
+
v7.1.0 - May 22, 2020
|
2
|
+
|
3
|
+
* [`a93083a`](https://github.com/eslint/eslint/commit/a93083af89c6f9714dcdd4a7f27c8655a0b0dba6) Fix: astUtils.getNextLocation returns invalid location after CRLF (#13275) (Milos Djermanovic)
|
4
|
+
* [`df01af1`](https://github.com/eslint/eslint/commit/df01af184d93b3d64b37cee786cad59bd0d7aacb) Update: padded-blocks loc position changes (refs #12334) (#13328) (Anix)
|
5
|
+
* [`bd3f092`](https://github.com/eslint/eslint/commit/bd3f092efa579944f75bfbc277b35f85e6d966ed) Fix: max-lines-per-function flagging arrow IIFEs (fixes #13332) (#13336) (cherryblossom000)
|
6
|
+
* [`25462b2`](https://github.com/eslint/eslint/commit/25462b23eac4ed1ded97eeae6187b5d8baa58e78) Update: block-spacing changed loc for extra (refs #12334) (#13314) (Anix)
|
7
|
+
* [`de0aab9`](https://github.com/eslint/eslint/commit/de0aab95005f172db72196fc3fd18e91ee9a5880) Fix: report end loc in one-var-declaration-per-line (refs #12334) (#13326) (YeonJuan)
|
8
|
+
* [`1710296`](https://github.com/eslint/eslint/commit/1710296082083602a904b080908657bb431fb56c) Fix: no-new-symbol false positive with Symbol as an argument (#13337) (Milos Djermanovic)
|
9
|
+
* [`cc01451`](https://github.com/eslint/eslint/commit/cc014514c29626e556acb0a528e3478b3725e284) Fix: arrow-parens no reporting for comments inside (fixes #12995) (#13312) (Anix)
|
10
|
+
* [`a195141`](https://github.com/eslint/eslint/commit/a19514193a42f4f00732559ff828b33a6ec9d7c5) Update: reporting location for semi-spacing (refs #12334) (#13285) (Anix)
|
11
|
+
* [`e3e4c41`](https://github.com/eslint/eslint/commit/e3e4c41ab625a5af8d4614d1c6d32c656f104f6b) Fix: fix false positives of no-new-func (#13333) (Pig Fang)
|
12
|
+
* [`611c676`](https://github.com/eslint/eslint/commit/611c676dfd671013d81810724f184e2a9c5ad5d7) Docs: Update new rules policies (#13343) (Nicholas C. Zakas)
|
13
|
+
* [`3a5fbb3`](https://github.com/eslint/eslint/commit/3a5fbb3d634be688615950c0a5fa8aead6ff08b5) Chore: correct fileoverview doc in accessor-pairs (#13335) (YeonJuan)
|
14
|
+
* [`b0a6b81`](https://github.com/eslint/eslint/commit/b0a6b8134e3b399beeb69432a02232a1037f7c46) Update: Improve report location for rest-spread-spacing (refs #12334) (#13313) (Milos Djermanovic)
|
15
|
+
* [`68c8ee3`](https://github.com/eslint/eslint/commit/68c8ee3ab70187972aef4c4e866bcf29da70a207) Fix: Stop path analyzer on unknown nodes (#13305) (Ilya Volodin)
|
16
|
+
* [`89e1081`](https://github.com/eslint/eslint/commit/89e10811c4df666216aae58bff5f855cd9df738b) Update: Improve report location for linebreak-style (refs #12334) (#13317) (Milos Djermanovic)
|
17
|
+
* [`0891379`](https://github.com/eslint/eslint/commit/08913798b4ec420b261b8fbc470504f9f248c840) Docs: Document the "correct" way to build an array with values (#13246) (Ed S)
|
18
|
+
* [`88127d7`](https://github.com/eslint/eslint/commit/88127d74d56b88cc5a0758856995716050021131) Chore: remove checkbox from PR template prerequesites (#13330) (Kai Cataldo)
|
19
|
+
* [`c636d57`](https://github.com/eslint/eslint/commit/c636d5708c461a8ff1ea55e5df56d4f76f9c4044) New: no-loss-of-precision (fixes #11279) (#12747) (jmoore914)
|
20
|
+
* [`72a4e10`](https://github.com/eslint/eslint/commit/72a4e1044592057c4a3f39dbb1dbe61b00ea8af6) Chore: Mark SourceCode getComments() method as deprecated (fixes #13293) (#13296) (SuperOleg39)
|
21
|
+
* [`7f14846`](https://github.com/eslint/eslint/commit/7f1484690665b4f4b9cd9680ca8bb7b5cf56e48a) Docs: fix broken link in Node.js API docs (#13307) (Kai Cataldo)
|
22
|
+
* [`02aeba1`](https://github.com/eslint/eslint/commit/02aeba19afb301140514097235a9f2a00a9acb2a) Sponsors: Sync README with website (ESLint Jenkins)
|
23
|
+
* [`1f17533`](https://github.com/eslint/eslint/commit/1f175338cba29960aab67a540f516051f9d428c8) Docs: Gitter -> Discord URL (refs #13039) (#13308) (Nicholas C. Zakas)
|
24
|
+
* [`82a448a`](https://github.com/eslint/eslint/commit/82a448a7deff24e9207f60dfe77622c00102bd99) Docs: improve documentation of no-return-await (#13215) (Linus Unnebäck)
|
25
|
+
* [`742941d`](https://github.com/eslint/eslint/commit/742941d7fdc3fd79ff8c5d2588413e0d3a5a525b) Update: added typescript-eslint/recommended configs for init (#13235) (Anix)
|
26
|
+
* [`3d03df0`](https://github.com/eslint/eslint/commit/3d03df08c8000403a85baffe2a000287f3335114) Sponsors: Sync README with website (ESLint Jenkins)
|
27
|
+
* [`f44a6b4`](https://github.com/eslint/eslint/commit/f44a6b4fd92602af8e2c75d5852f796ec064aa8e) Chore: fix invalid syntax in require-await tests (#13277) (Milos Djermanovic)
|
28
|
+
* [`2c778fb`](https://github.com/eslint/eslint/commit/2c778fb6e31b7943bb27a47a6e15dcbfd8336f39) Fix: remove custom plugins from replacedBy metadata (#13274) (Kai Cataldo)
|
29
|
+
* [`0db3b1d`](https://github.com/eslint/eslint/commit/0db3b1d5cc5e4e1de21462679581b7a4d89ff36e) Sponsors: Sync README with website (ESLint Jenkins)
|
1
30
|
v7.0.0 - May 8, 2020
|
2
31
|
|
3
32
|
* [`b98d8bd`](https://github.com/eslint/eslint/commit/b98d8bda4630fe8278c5aa2b6650630770568fe5) Upgrade: eslint-release@2.0.0 (#13271) (Kai Cataldo)
|
package/README.md
CHANGED
@@ -5,7 +5,6 @@
|
|
5
5
|
<br />
|
6
6
|
[](https://opencollective.com/eslint)
|
7
7
|
[](https://opencollective.com/eslint)
|
8
|
-
[](https://gitter.im/eslint/eslint?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
9
8
|
[](https://twitter.com/intent/user?screen_name=geteslint)
|
10
9
|
|
11
10
|
# ESLint
|
@@ -18,7 +17,7 @@
|
|
18
17
|
[Code of Conduct](https://js.foundation/community/code-of-conduct) |
|
19
18
|
[Twitter](https://twitter.com/geteslint) |
|
20
19
|
[Mailing List](https://groups.google.com/group/eslint) |
|
21
|
-
[Chat Room](https://
|
20
|
+
[Chat Room](https://eslint.org/chat)
|
22
21
|
|
23
22
|
ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code. In many ways, it is similar to JSLint and JSHint with a few exceptions:
|
24
23
|
|
@@ -134,7 +133,7 @@ Once a language feature has been adopted into the ECMAScript standard (stage 4 a
|
|
134
133
|
|
135
134
|
### Where to ask for help?
|
136
135
|
|
137
|
-
Join our [Mailing List](https://groups.google.com/group/eslint) or [Chatroom](https://
|
136
|
+
Join our [Mailing List](https://groups.google.com/group/eslint) or [Chatroom](https://eslint.org/chat).
|
138
137
|
|
139
138
|
## <a name="releases"></a>Releases
|
140
139
|
|
@@ -252,7 +251,7 @@ The following companies, organizations, and individuals support ESLint's ongoing
|
|
252
251
|
<h3>Gold Sponsors</h3>
|
253
252
|
<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>
|
254
253
|
<p><a href="https://www.ampproject.org/"><img src="https://images.opencollective.com/amp/c8a3b25/logo.png" alt="AMP Project" height="64"></a></p><h3>Bronze Sponsors</h3>
|
255
|
-
<p><a href="https://www.casinotop.com/"><img src="https://images.opencollective.com/casinotop-com/10fd95b/logo.png" alt="CasinoTop.com" height="32"></a> <a href="https://www.casinotopp.net/"><img src="https://images.opencollective.com/casino-topp/1dd399a/logo.png" alt="Casino Topp" height="32"></a> <a href="https://writersperhour.com/urgent-essay-writing-service"><img src="https://images.opencollective.com/writersperhour/5787d4b/logo.png" alt="Writers Per Hour" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://cooltechzone.com/netflix-vpn"><img src="https://images.opencollective.com/vpn-netflix/4850160/logo.png" alt="vpn netflix" height="32"></a> <a href="https://www.kasinot.fi"><img src="https://images.opencollective.com/kasinot-fi/e09aa2e/logo.png" alt="Kasinot.fi" height="32"></a> <a href="https://www.pelisivut.com"><img src="https://images.opencollective.com/pelisivut/04f08f2/logo.png" alt="Pelisivut" height="32"></a> <a href="https://www.nettikasinot.org"><img src="https://images.opencollective.com/nettikasinot-org/bbd887f/logo.png" alt="Nettikasinot.org" height="32"></a> <a href="https://www.bonus.com.de/freispiele"><img src="https://images.opencollective.com/bonusfinder-deutschland/646169e/logo.png" alt="BonusFinder Deutschland" height="32"></a> <a href="https://
|
254
|
+
<p><a href="https://bruce.agency"><img src="https://images.opencollective.com/brucemade/0c70c59/logo.png" alt="Bruce" height="32"></a> <a href="https://edubirdie.com/"><img src="https://images.opencollective.com/edubirdie2/b1d51ab/logo.png" alt="EduBirdie" height="32"></a> <a href="https://www.casinotop.com/"><img src="https://images.opencollective.com/casinotop-com/10fd95b/logo.png" alt="CasinoTop.com" height="32"></a> <a href="https://www.casinotopp.net/"><img src="https://images.opencollective.com/casino-topp/1dd399a/logo.png" alt="Casino Topp" height="32"></a> <a href="https://writersperhour.com/urgent-essay-writing-service"><img src="https://images.opencollective.com/writersperhour/5787d4b/logo.png" alt="Writers Per Hour" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://cooltechzone.com/netflix-vpn"><img src="https://images.opencollective.com/vpn-netflix/4850160/logo.png" alt="vpn netflix" height="32"></a> <a href="https://www.kasinot.fi"><img src="https://images.opencollective.com/kasinot-fi/e09aa2e/logo.png" alt="Kasinot.fi" height="32"></a> <a href="https://www.pelisivut.com"><img src="https://images.opencollective.com/pelisivut/04f08f2/logo.png" alt="Pelisivut" height="32"></a> <a href="https://www.nettikasinot.org"><img src="https://images.opencollective.com/nettikasinot-org/bbd887f/logo.png" alt="Nettikasinot.org" height="32"></a> <a href="https://www.bonus.com.de/freispiele"><img src="https://images.opencollective.com/bonusfinder-deutschland/646169e/logo.png" alt="BonusFinder Deutschland" height="32"></a> <a href="https://www.bugsnag.com/platforms?utm_source=Open Collective&utm_medium=Website&utm_content=open-source&utm_campaign=2019-community&utm_term="><img src="https://images.opencollective.com/bugsnag-stability-monitoring/c2cef36/logo.png" alt="Bugsnag Stability Monitoring" height="32"></a> <a href="https://mixpanel.com"><img src="https://images.opencollective.com/mixpanel/cd682f7/logo.png" alt="Mixpanel" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS Server" height="32"></a> <a href="https://icons8.com"><img src="https://images.opencollective.com/icons8/0b37d14/logo.png" alt="Free Icons by Icons8" height="32"></a> <a href="https://discordapp.com"><img src="https://images.opencollective.com/discordapp/7e3d9a9/logo.png" alt="Discord" height="32"></a> <a href="https://themeisle.com"><img src="https://images.opencollective.com/themeisle/d5592fe/logo.png" alt="ThemeIsle" height="32"></a> <a href="https://tekhattan.com"><img src="https://images.opencollective.com/tekhattan/bc73c28/logo.png" alt="TekHattan" height="32"></a> <a href="https://www.marfeel.com/"><img src="https://images.opencollective.com/marfeel/4b88e30/logo.png" alt="Marfeel" height="32"></a> <a href="http://www.firesticktricks.com"><img src="https://images.opencollective.com/fire-stick-tricks/b8fbe2c/logo.png" alt="Fire Stick Tricks" height="32"></a></p>
|
256
255
|
<!--sponsorsend-->
|
257
256
|
|
258
257
|
## <a name="technology-sponsors"></a>Technology Sponsors
|
@@ -326,6 +326,7 @@ function processAnswers(answers) {
|
|
326
326
|
}
|
327
327
|
if (answers.typescript && config.extends.includes("eslint:recommended")) {
|
328
328
|
config.extends.push("plugin:@typescript-eslint/eslint-recommended");
|
329
|
+
config.extends.push("plugin:@typescript-eslint/recommended");
|
329
330
|
}
|
330
331
|
|
331
332
|
// normalize extends
|
package/lib/linter/linter.js
CHANGED
@@ -938,7 +938,8 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parser
|
|
938
938
|
});
|
939
939
|
});
|
940
940
|
|
941
|
-
|
941
|
+
// only run code path analyzer if the top level node is "Program", skip otherwise
|
942
|
+
const eventGenerator = nodeQueue[0].node.type === "Program" ? new CodePathAnalyzer(new NodeEventGenerator(emitter)) : new NodeEventGenerator(emitter);
|
942
943
|
|
943
944
|
nodeQueue.forEach(traversalInfo => {
|
944
945
|
currentNode = traversalInfo.node;
|
@@ -105,10 +105,27 @@ module.exports = {
|
|
105
105
|
], `${shouldAddSpaceForAsync ? " " : ""}${paramToken.value}`);
|
106
106
|
}
|
107
107
|
|
108
|
+
/**
|
109
|
+
* Checks whether there are comments inside the params or not.
|
110
|
+
* @returns {boolean} `true` if there are comments inside of parens, else `false`
|
111
|
+
*/
|
112
|
+
function hasCommentsInParens() {
|
113
|
+
if (astUtils.isOpeningParenToken(firstTokenOfParam)) {
|
114
|
+
const closingParenToken = sourceCode.getTokenAfter(node.params[0], astUtils.isClosingParenToken);
|
115
|
+
|
116
|
+
return closingParenToken && sourceCode.commentsExistBetween(firstTokenOfParam, closingParenToken);
|
117
|
+
}
|
118
|
+
return false;
|
119
|
+
|
120
|
+
}
|
121
|
+
|
122
|
+
if (hasCommentsInParens()) {
|
123
|
+
return;
|
124
|
+
}
|
125
|
+
|
108
126
|
// "as-needed", { "requireForBlockBody": true }: x => x
|
109
127
|
if (
|
110
128
|
requireForBlockBody &&
|
111
|
-
node.params.length === 1 &&
|
112
129
|
node.params[0].type === "Identifier" &&
|
113
130
|
!node.params[0].typeAnnotation &&
|
114
131
|
node.body.type !== "BlockStatement" &&
|
@@ -144,7 +161,6 @@ module.exports = {
|
|
144
161
|
|
145
162
|
// "as-needed": x => x
|
146
163
|
if (asNeeded &&
|
147
|
-
node.params.length === 1 &&
|
148
164
|
node.params[0].type === "Identifier" &&
|
149
165
|
!node.params[0].typeAnnotation &&
|
150
166
|
!node.returnType
|
@@ -178,7 +194,7 @@ module.exports = {
|
|
178
194
|
}
|
179
195
|
|
180
196
|
return {
|
181
|
-
ArrowFunctionExpression: parens
|
197
|
+
"ArrowFunctionExpression[params.length=1]": parens
|
182
198
|
};
|
183
199
|
}
|
184
200
|
};
|
@@ -102,9 +102,18 @@ module.exports = {
|
|
102
102
|
|
103
103
|
// Check.
|
104
104
|
if (!isValid(openBrace, firstToken)) {
|
105
|
+
let loc = openBrace.loc;
|
106
|
+
|
107
|
+
if (messageId === "extra") {
|
108
|
+
loc = {
|
109
|
+
start: openBrace.loc.end,
|
110
|
+
end: firstToken.loc.start
|
111
|
+
};
|
112
|
+
}
|
113
|
+
|
105
114
|
context.report({
|
106
115
|
node,
|
107
|
-
loc
|
116
|
+
loc,
|
108
117
|
messageId,
|
109
118
|
data: {
|
110
119
|
location: "after",
|
@@ -120,9 +129,17 @@ module.exports = {
|
|
120
129
|
});
|
121
130
|
}
|
122
131
|
if (!isValid(lastToken, closeBrace)) {
|
132
|
+
let loc = closeBrace.loc;
|
133
|
+
|
134
|
+
if (messageId === "extra") {
|
135
|
+
loc = {
|
136
|
+
start: lastToken.loc.end,
|
137
|
+
end: closeBrace.loc.start
|
138
|
+
};
|
139
|
+
}
|
123
140
|
context.report({
|
124
141
|
node,
|
125
|
-
loc
|
142
|
+
loc,
|
126
143
|
messageId,
|
127
144
|
data: {
|
128
145
|
location: "before",
|
package/lib/rules/index.js
CHANGED
@@ -148,6 +148,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
|
|
148
148
|
"no-lone-blocks": () => require("./no-lone-blocks"),
|
149
149
|
"no-lonely-if": () => require("./no-lonely-if"),
|
150
150
|
"no-loop-func": () => require("./no-loop-func"),
|
151
|
+
"no-loss-of-precision": () => require("./no-loss-of-precision"),
|
151
152
|
"no-magic-numbers": () => require("./no-magic-numbers"),
|
152
153
|
"no-misleading-character-class": () => require("./no-misleading-character-class"),
|
153
154
|
"no-mixed-operators": () => require("./no-mixed-operators"),
|
@@ -86,8 +86,14 @@ module.exports = {
|
|
86
86
|
context.report({
|
87
87
|
node,
|
88
88
|
loc: {
|
89
|
-
|
90
|
-
|
89
|
+
start: {
|
90
|
+
line: i,
|
91
|
+
column: sourceCode.lines[i - 1].length
|
92
|
+
},
|
93
|
+
end: {
|
94
|
+
line: i + 1,
|
95
|
+
column: 0
|
96
|
+
}
|
91
97
|
},
|
92
98
|
messageId: expectedLF ? "expectedLF" : "expectedCRLF",
|
93
99
|
fix: createFix(range, expectedLFChars)
|
@@ -134,7 +134,7 @@ module.exports = {
|
|
134
134
|
* @returns {boolean} True if it's an IIFE
|
135
135
|
*/
|
136
136
|
function isIIFE(node) {
|
137
|
-
return node.type === "FunctionExpression" && node.parent && node.parent.type === "CallExpression" && node.parent.callee === node;
|
137
|
+
return (node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") && node.parent && node.parent.type === "CallExpression" && node.parent.callee === node;
|
138
138
|
}
|
139
139
|
|
140
140
|
/**
|
@@ -0,0 +1,198 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Rule to flag numbers that will lose significant figure precision at runtime
|
3
|
+
* @author Jacob Moore
|
4
|
+
*/
|
5
|
+
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
// Rule Definition
|
10
|
+
//------------------------------------------------------------------------------
|
11
|
+
|
12
|
+
module.exports = {
|
13
|
+
meta: {
|
14
|
+
type: "problem",
|
15
|
+
|
16
|
+
docs: {
|
17
|
+
description: "disallow literal numbers that lose precision",
|
18
|
+
category: "Possible Errors",
|
19
|
+
recommended: false,
|
20
|
+
url: "https://eslint.org/docs/rules/no-loss-of-precision"
|
21
|
+
},
|
22
|
+
schema: [],
|
23
|
+
messages: {
|
24
|
+
noLossOfPrecision: "This number literal will lose precision at runtime."
|
25
|
+
}
|
26
|
+
},
|
27
|
+
|
28
|
+
create(context) {
|
29
|
+
|
30
|
+
/**
|
31
|
+
* Returns whether the node is number literal
|
32
|
+
* @param {Node} node the node literal being evaluated
|
33
|
+
* @returns {boolean} true if the node is a number literal
|
34
|
+
*/
|
35
|
+
function isNumber(node) {
|
36
|
+
return typeof node.value === "number";
|
37
|
+
}
|
38
|
+
|
39
|
+
|
40
|
+
/**
|
41
|
+
* Checks whether the number is base ten
|
42
|
+
* @param {ASTNode} node the node being evaluated
|
43
|
+
* @returns {boolean} true if the node is in base ten
|
44
|
+
*/
|
45
|
+
function isBaseTen(node) {
|
46
|
+
const prefixes = ["0x", "0X", "0b", "0B", "0o", "0O"];
|
47
|
+
|
48
|
+
return prefixes.every(prefix => !node.raw.startsWith(prefix)) &&
|
49
|
+
!/^0[0-7]+$/u.test(node.raw);
|
50
|
+
}
|
51
|
+
|
52
|
+
/**
|
53
|
+
* Checks that the user-intended non-base ten number equals the actual number after is has been converted to the Number type
|
54
|
+
* @param {Node} node the node being evaluated
|
55
|
+
* @returns {boolean} true if they do not match
|
56
|
+
*/
|
57
|
+
function notBaseTenLosesPrecision(node) {
|
58
|
+
const rawString = node.raw.toUpperCase();
|
59
|
+
let base = 0;
|
60
|
+
|
61
|
+
if (rawString.startsWith("0B")) {
|
62
|
+
base = 2;
|
63
|
+
} else if (rawString.startsWith("0X")) {
|
64
|
+
base = 16;
|
65
|
+
} else {
|
66
|
+
base = 8;
|
67
|
+
}
|
68
|
+
|
69
|
+
return !rawString.endsWith(node.value.toString(base).toUpperCase());
|
70
|
+
}
|
71
|
+
|
72
|
+
/**
|
73
|
+
* Adds a decimal point to the numeric string at index 1
|
74
|
+
* @param {string} stringNumber the numeric string without any decimal point
|
75
|
+
* @returns {string} the numeric string with a decimal point in the proper place
|
76
|
+
*/
|
77
|
+
function addDecimalPointToNumber(stringNumber) {
|
78
|
+
return `${stringNumber.slice(0, 1)}.${stringNumber.slice(1)}`;
|
79
|
+
}
|
80
|
+
|
81
|
+
/**
|
82
|
+
* Returns the number stripped of leading zeros
|
83
|
+
* @param {string} numberAsString the string representation of the number
|
84
|
+
* @returns {string} the stripped string
|
85
|
+
*/
|
86
|
+
function removeLeadingZeros(numberAsString) {
|
87
|
+
return numberAsString.replace(/^0*/u, "");
|
88
|
+
}
|
89
|
+
|
90
|
+
/**
|
91
|
+
* Returns the number stripped of trailing zeros
|
92
|
+
* @param {string} numberAsString the string representation of the number
|
93
|
+
* @returns {string} the stripped string
|
94
|
+
*/
|
95
|
+
function removeTrailingZeros(numberAsString) {
|
96
|
+
return numberAsString.replace(/0*$/u, "");
|
97
|
+
}
|
98
|
+
|
99
|
+
/**
|
100
|
+
* Converts an integer to to an object containing the the integer's coefficient and order of magnitude
|
101
|
+
* @param {string} stringInteger the string representation of the integer being converted
|
102
|
+
* @returns {Object} the object containing the the integer's coefficient and order of magnitude
|
103
|
+
*/
|
104
|
+
function normalizeInteger(stringInteger) {
|
105
|
+
const significantDigits = removeTrailingZeros(removeLeadingZeros(stringInteger));
|
106
|
+
|
107
|
+
return {
|
108
|
+
magnitude: stringInteger.startsWith("0") ? stringInteger.length - 2 : stringInteger.length - 1,
|
109
|
+
coefficient: addDecimalPointToNumber(significantDigits)
|
110
|
+
};
|
111
|
+
}
|
112
|
+
|
113
|
+
/**
|
114
|
+
*
|
115
|
+
* Converts a float to to an object containing the the floats's coefficient and order of magnitude
|
116
|
+
* @param {string} stringFloat the string representation of the float being converted
|
117
|
+
* @returns {Object} the object containing the the integer's coefficient and order of magnitude
|
118
|
+
*/
|
119
|
+
function normalizeFloat(stringFloat) {
|
120
|
+
const trimmedFloat = removeLeadingZeros(stringFloat);
|
121
|
+
|
122
|
+
if (trimmedFloat.startsWith(".")) {
|
123
|
+
const decimalDigits = trimmedFloat.split(".").pop();
|
124
|
+
const significantDigits = removeLeadingZeros(decimalDigits);
|
125
|
+
|
126
|
+
return {
|
127
|
+
magnitude: significantDigits.length - decimalDigits.length - 1,
|
128
|
+
coefficient: addDecimalPointToNumber(significantDigits)
|
129
|
+
};
|
130
|
+
|
131
|
+
}
|
132
|
+
return {
|
133
|
+
magnitude: trimmedFloat.indexOf(".") - 1,
|
134
|
+
coefficient: addDecimalPointToNumber(trimmedFloat.replace(".", ""))
|
135
|
+
|
136
|
+
};
|
137
|
+
}
|
138
|
+
|
139
|
+
|
140
|
+
/**
|
141
|
+
* Converts a base ten number to proper scientific notation
|
142
|
+
* @param {string} stringNumber the string representation of the base ten number to be converted
|
143
|
+
* @returns {string} the number converted to scientific notation
|
144
|
+
*/
|
145
|
+
function convertNumberToScientificNotation(stringNumber) {
|
146
|
+
const splitNumber = stringNumber.replace("E", "e").split("e");
|
147
|
+
const originalCoefficient = splitNumber[0];
|
148
|
+
const normalizedNumber = stringNumber.includes(".") ? normalizeFloat(originalCoefficient)
|
149
|
+
: normalizeInteger(originalCoefficient);
|
150
|
+
const normalizedCoefficient = normalizedNumber.coefficient;
|
151
|
+
const magnitude = splitNumber.length > 1 ? (parseInt(splitNumber[1], 10) + normalizedNumber.magnitude)
|
152
|
+
: normalizedNumber.magnitude;
|
153
|
+
|
154
|
+
return `${normalizedCoefficient}e${magnitude}`;
|
155
|
+
|
156
|
+
}
|
157
|
+
|
158
|
+
/**
|
159
|
+
* Checks that the user-intended base ten number equals the actual number after is has been converted to the Number type
|
160
|
+
* @param {Node} node the node being evaluated
|
161
|
+
* @returns {boolean} true if they do not match
|
162
|
+
*/
|
163
|
+
function baseTenLosesPrecision(node) {
|
164
|
+
const normalizedRawNumber = convertNumberToScientificNotation(node.raw);
|
165
|
+
const requestedPrecision = normalizedRawNumber.split("e")[0].replace(".", "").length;
|
166
|
+
|
167
|
+
if (requestedPrecision > 100) {
|
168
|
+
return true;
|
169
|
+
}
|
170
|
+
const storedNumber = node.value.toPrecision(requestedPrecision);
|
171
|
+
const normalizedStoredNumber = convertNumberToScientificNotation(storedNumber);
|
172
|
+
|
173
|
+
return normalizedRawNumber !== normalizedStoredNumber;
|
174
|
+
}
|
175
|
+
|
176
|
+
|
177
|
+
/**
|
178
|
+
* Checks that the user-intended number equals the actual number after is has been converted to the Number type
|
179
|
+
* @param {Node} node the node being evaluated
|
180
|
+
* @returns {boolean} true if they do not match
|
181
|
+
*/
|
182
|
+
function losesPrecision(node) {
|
183
|
+
return isBaseTen(node) ? baseTenLosesPrecision(node) : notBaseTenLosesPrecision(node);
|
184
|
+
}
|
185
|
+
|
186
|
+
|
187
|
+
return {
|
188
|
+
Literal(node) {
|
189
|
+
if (node.value && isNumber(node) && losesPrecision(node)) {
|
190
|
+
context.report({
|
191
|
+
messageId: "noLossOfPrecision",
|
192
|
+
node
|
193
|
+
});
|
194
|
+
}
|
195
|
+
}
|
196
|
+
};
|
197
|
+
}
|
198
|
+
};
|
package/lib/rules/no-new-func.js
CHANGED
@@ -29,26 +29,29 @@ module.exports = {
|
|
29
29
|
|
30
30
|
create(context) {
|
31
31
|
|
32
|
-
//--------------------------------------------------------------------------
|
33
|
-
// Helpers
|
34
|
-
//--------------------------------------------------------------------------
|
35
|
-
|
36
|
-
/**
|
37
|
-
* Reports a node.
|
38
|
-
* @param {ASTNode} node The node to report
|
39
|
-
* @returns {void}
|
40
|
-
* @private
|
41
|
-
*/
|
42
|
-
function report(node) {
|
43
|
-
context.report({
|
44
|
-
node,
|
45
|
-
messageId: "noFunctionConstructor"
|
46
|
-
});
|
47
|
-
}
|
48
|
-
|
49
32
|
return {
|
50
|
-
"
|
51
|
-
|
33
|
+
"Program:exit"() {
|
34
|
+
const globalScope = context.getScope();
|
35
|
+
const variable = globalScope.set.get("Function");
|
36
|
+
|
37
|
+
if (variable && variable.defs.length === 0) {
|
38
|
+
variable.references.forEach(ref => {
|
39
|
+
const node = ref.identifier;
|
40
|
+
const { parent } = node;
|
41
|
+
|
42
|
+
if (
|
43
|
+
parent &&
|
44
|
+
(parent.type === "NewExpression" || parent.type === "CallExpression") &&
|
45
|
+
node === parent.callee
|
46
|
+
) {
|
47
|
+
context.report({
|
48
|
+
node: parent,
|
49
|
+
messageId: "noFunctionConstructor"
|
50
|
+
});
|
51
|
+
}
|
52
|
+
});
|
53
|
+
}
|
54
|
+
}
|
52
55
|
};
|
53
56
|
|
54
57
|
}
|
@@ -37,8 +37,9 @@ module.exports = {
|
|
37
37
|
if (variable && variable.defs.length === 0) {
|
38
38
|
variable.references.forEach(ref => {
|
39
39
|
const node = ref.identifier;
|
40
|
+
const parent = node.parent;
|
40
41
|
|
41
|
-
if (
|
42
|
+
if (parent && parent.type === "NewExpression" && parent.callee === node) {
|
42
43
|
context.report({
|
43
44
|
node,
|
44
45
|
messageId: "noNewSymbol"
|
package/lib/rules/no-sync.js
CHANGED
@@ -203,10 +203,14 @@ module.exports = {
|
|
203
203
|
}
|
204
204
|
|
205
205
|
if (requirePaddingFor(node)) {
|
206
|
+
|
206
207
|
if (!blockHasTopPadding) {
|
207
208
|
context.report({
|
208
209
|
node,
|
209
|
-
loc: {
|
210
|
+
loc: {
|
211
|
+
start: tokenBeforeFirst.loc.start,
|
212
|
+
end: firstBlockToken.loc.start
|
213
|
+
},
|
210
214
|
fix(fixer) {
|
211
215
|
return fixer.insertTextAfter(tokenBeforeFirst, "\n");
|
212
216
|
},
|
@@ -216,7 +220,10 @@ module.exports = {
|
|
216
220
|
if (!blockHasBottomPadding) {
|
217
221
|
context.report({
|
218
222
|
node,
|
219
|
-
loc: {
|
223
|
+
loc: {
|
224
|
+
end: tokenAfterLast.loc.start,
|
225
|
+
start: lastBlockToken.loc.end
|
226
|
+
},
|
220
227
|
fix(fixer) {
|
221
228
|
return fixer.insertTextBefore(tokenAfterLast, "\n");
|
222
229
|
},
|
@@ -228,7 +235,10 @@ module.exports = {
|
|
228
235
|
|
229
236
|
context.report({
|
230
237
|
node,
|
231
|
-
loc: {
|
238
|
+
loc: {
|
239
|
+
start: tokenBeforeFirst.loc.start,
|
240
|
+
end: firstBlockToken.loc.start
|
241
|
+
},
|
232
242
|
fix(fixer) {
|
233
243
|
return fixer.replaceTextRange([tokenBeforeFirst.range[1], firstBlockToken.range[0] - firstBlockToken.loc.start.column], "\n");
|
234
244
|
},
|
@@ -240,7 +250,10 @@ module.exports = {
|
|
240
250
|
|
241
251
|
context.report({
|
242
252
|
node,
|
243
|
-
loc: {
|
253
|
+
loc: {
|
254
|
+
end: tokenAfterLast.loc.start,
|
255
|
+
start: lastBlockToken.loc.end
|
256
|
+
},
|
244
257
|
messageId: "neverPadBlock",
|
245
258
|
fix(fixer) {
|
246
259
|
return fixer.replaceTextRange([lastBlockToken.range[1], tokenAfterLast.range[0] - tokenAfterLast.loc.start.column], "\n");
|
@@ -79,10 +79,7 @@ module.exports = {
|
|
79
79
|
if (alwaysSpace && !hasWhitespace) {
|
80
80
|
context.report({
|
81
81
|
node,
|
82
|
-
loc:
|
83
|
-
line: operator.loc.end.line,
|
84
|
-
column: operator.loc.end.column
|
85
|
-
},
|
82
|
+
loc: operator.loc,
|
86
83
|
messageId: "expectedWhitespace",
|
87
84
|
data: {
|
88
85
|
type
|
@@ -95,8 +92,8 @@ module.exports = {
|
|
95
92
|
context.report({
|
96
93
|
node,
|
97
94
|
loc: {
|
98
|
-
|
99
|
-
|
95
|
+
start: operator.loc.end,
|
96
|
+
end: nextToken.loc.start
|
100
97
|
},
|
101
98
|
messageId: "unexpectedWhitespace",
|
102
99
|
data: {
|
@@ -117,6 +117,18 @@ module.exports = {
|
|
117
117
|
}
|
118
118
|
|
119
119
|
/**
|
120
|
+
* Report location example :
|
121
|
+
*
|
122
|
+
* for unexpected space `before`
|
123
|
+
*
|
124
|
+
* var a = 'b' ;
|
125
|
+
* ^^^
|
126
|
+
*
|
127
|
+
* for unexpected space `after`
|
128
|
+
*
|
129
|
+
* var a = 'b'; c = 10;
|
130
|
+
* ^^
|
131
|
+
*
|
120
132
|
* Reports if the given token has invalid spacing.
|
121
133
|
* @param {Token} token The semicolon token to check.
|
122
134
|
* @param {ASTNode} node The corresponding node of the token.
|
@@ -124,16 +136,19 @@ module.exports = {
|
|
124
136
|
*/
|
125
137
|
function checkSemicolonSpacing(token, node) {
|
126
138
|
if (astUtils.isSemicolonToken(token)) {
|
127
|
-
const location = token.loc.start;
|
128
|
-
|
129
139
|
if (hasLeadingSpace(token)) {
|
130
140
|
if (!requireSpaceBefore) {
|
141
|
+
const tokenBefore = sourceCode.getTokenBefore(token);
|
142
|
+
const loc = {
|
143
|
+
start: tokenBefore.loc.end,
|
144
|
+
end: token.loc.start
|
145
|
+
};
|
146
|
+
|
131
147
|
context.report({
|
132
148
|
node,
|
133
|
-
loc
|
149
|
+
loc,
|
134
150
|
messageId: "unexpectedWhitespaceBefore",
|
135
151
|
fix(fixer) {
|
136
|
-
const tokenBefore = sourceCode.getTokenBefore(token);
|
137
152
|
|
138
153
|
return fixer.removeRange([tokenBefore.range[1], token.range[0]]);
|
139
154
|
}
|
@@ -141,9 +156,11 @@ module.exports = {
|
|
141
156
|
}
|
142
157
|
} else {
|
143
158
|
if (requireSpaceBefore) {
|
159
|
+
const loc = token.loc;
|
160
|
+
|
144
161
|
context.report({
|
145
162
|
node,
|
146
|
-
loc
|
163
|
+
loc,
|
147
164
|
messageId: "missingWhitespaceBefore",
|
148
165
|
fix(fixer) {
|
149
166
|
return fixer.insertTextBefore(token, " ");
|
@@ -155,12 +172,17 @@ module.exports = {
|
|
155
172
|
if (!isFirstTokenInCurrentLine(token) && !isLastTokenInCurrentLine(token) && !isBeforeClosingParen(token)) {
|
156
173
|
if (hasTrailingSpace(token)) {
|
157
174
|
if (!requireSpaceAfter) {
|
175
|
+
const tokenAfter = sourceCode.getTokenAfter(token);
|
176
|
+
const loc = {
|
177
|
+
start: token.loc.end,
|
178
|
+
end: tokenAfter.loc.start
|
179
|
+
};
|
180
|
+
|
158
181
|
context.report({
|
159
182
|
node,
|
160
|
-
loc
|
183
|
+
loc,
|
161
184
|
messageId: "unexpectedWhitespaceAfter",
|
162
185
|
fix(fixer) {
|
163
|
-
const tokenAfter = sourceCode.getTokenAfter(token);
|
164
186
|
|
165
187
|
return fixer.removeRange([token.range[1], tokenAfter.range[0]]);
|
166
188
|
}
|
@@ -168,9 +190,11 @@ module.exports = {
|
|
168
190
|
}
|
169
191
|
} else {
|
170
192
|
if (requireSpaceAfter) {
|
193
|
+
const loc = token.loc;
|
194
|
+
|
171
195
|
context.report({
|
172
196
|
node,
|
173
|
-
loc
|
197
|
+
loc,
|
174
198
|
messageId: "missingWhitespaceAfter",
|
175
199
|
fix(fixer) {
|
176
200
|
return fixer.insertTextAfter(token, " ");
|
@@ -1243,19 +1243,64 @@ module.exports = {
|
|
1243
1243
|
|
1244
1244
|
/**
|
1245
1245
|
* Gets next location when the result is not out of bound, otherwise returns null.
|
1246
|
+
*
|
1247
|
+
* Assumptions:
|
1248
|
+
*
|
1249
|
+
* - The given location represents a valid location in the given source code.
|
1250
|
+
* - Columns are 0-based.
|
1251
|
+
* - Lines are 1-based.
|
1252
|
+
* - Column immediately after the last character in a line (not incl. linebreaks) is considered to be a valid location.
|
1253
|
+
* - If the source code ends with a linebreak, `sourceCode.lines` array will have an extra element (empty string) at the end.
|
1254
|
+
* The start (column 0) of that extra line is considered to be a valid location.
|
1255
|
+
*
|
1256
|
+
* Examples of successive locations (line, column):
|
1257
|
+
*
|
1258
|
+
* code: foo
|
1259
|
+
* locations: (1, 0) -> (1, 1) -> (1, 2) -> (1, 3) -> null
|
1260
|
+
*
|
1261
|
+
* code: foo<LF>
|
1262
|
+
* locations: (1, 0) -> (1, 1) -> (1, 2) -> (1, 3) -> (2, 0) -> null
|
1263
|
+
*
|
1264
|
+
* code: foo<CR><LF>
|
1265
|
+
* locations: (1, 0) -> (1, 1) -> (1, 2) -> (1, 3) -> (2, 0) -> null
|
1266
|
+
*
|
1267
|
+
* code: a<LF>b
|
1268
|
+
* locations: (1, 0) -> (1, 1) -> (2, 0) -> (2, 1) -> null
|
1269
|
+
*
|
1270
|
+
* code: a<LF>b<LF>
|
1271
|
+
* locations: (1, 0) -> (1, 1) -> (2, 0) -> (2, 1) -> (3, 0) -> null
|
1272
|
+
*
|
1273
|
+
* code: a<CR><LF>b<CR><LF>
|
1274
|
+
* locations: (1, 0) -> (1, 1) -> (2, 0) -> (2, 1) -> (3, 0) -> null
|
1275
|
+
*
|
1276
|
+
* code: a<LF><LF>
|
1277
|
+
* locations: (1, 0) -> (1, 1) -> (2, 0) -> (3, 0) -> null
|
1278
|
+
*
|
1279
|
+
* code: <LF>
|
1280
|
+
* locations: (1, 0) -> (2, 0) -> null
|
1281
|
+
*
|
1282
|
+
* code:
|
1283
|
+
* locations: (1, 0) -> null
|
1246
1284
|
* @param {SourceCode} sourceCode The sourceCode
|
1247
1285
|
* @param {{line: number, column: number}} location The location
|
1248
1286
|
* @returns {{line: number, column: number} | null} Next location
|
1249
1287
|
*/
|
1250
|
-
getNextLocation(sourceCode,
|
1251
|
-
|
1288
|
+
getNextLocation(sourceCode, { line, column }) {
|
1289
|
+
if (column < sourceCode.lines[line - 1].length) {
|
1290
|
+
return {
|
1291
|
+
line,
|
1292
|
+
column: column + 1
|
1293
|
+
};
|
1294
|
+
}
|
1252
1295
|
|
1253
|
-
|
1254
|
-
|
1255
|
-
|
1296
|
+
if (line < sourceCode.lines.length) {
|
1297
|
+
return {
|
1298
|
+
line: line + 1,
|
1299
|
+
column: 0
|
1300
|
+
};
|
1256
1301
|
}
|
1257
1302
|
|
1258
|
-
return
|
1303
|
+
return null;
|
1259
1304
|
},
|
1260
1305
|
|
1261
1306
|
/**
|
@@ -305,6 +305,7 @@ class SourceCode extends TokenStore {
|
|
305
305
|
* @returns {Object} An object containing a leading and trailing array
|
306
306
|
* of comments indexed by their position.
|
307
307
|
* @public
|
308
|
+
* @deprecated replaced by getCommentsBefore(), getCommentsAfter(), and getCommentsInside().
|
308
309
|
*/
|
309
310
|
getComments(node) {
|
310
311
|
if (this._commentCache.has(node)) {
|
@@ -2,4 +2,4 @@ ESLint couldn't find the config "<%- configName %>" to extend from. Please check
|
|
2
2
|
|
3
3
|
The config "<%- configName %>" was referenced from the config file in "<%- importerName %>".
|
4
4
|
|
5
|
-
If you still have problems, please stop by https://
|
5
|
+
If you still have problems, please stop by https://eslint.org/chat to chat with the team.
|
@@ -4,4 +4,4 @@ ESLint couldn't find a configuration file. To set up a configuration file for th
|
|
4
4
|
|
5
5
|
ESLint looked for configuration files in <%= directoryPath %> and its ancestors. If it found none, it then looked in your home directory.
|
6
6
|
|
7
|
-
If you think you already have a configuration file or if you need more help, please stop by the ESLint chat room: https://
|
7
|
+
If you think you already have a configuration file or if you need more help, please stop by the ESLint chat room: https://eslint.org/chat
|
@@ -4,4 +4,4 @@ ESLint couldn't determine the plugin "<%- pluginId %>" uniquely.
|
|
4
4
|
|
5
5
|
Please remove the "plugins" setting from either config or remove either plugin installation.
|
6
6
|
|
7
|
-
If you still can't figure out the problem, please stop by https://
|
7
|
+
If you still can't figure out the problem, please stop by https://eslint.org/chat to chat with the team.
|
@@ -8,4 +8,4 @@ It's likely that the plugin isn't installed correctly. Try reinstalling by runni
|
|
8
8
|
|
9
9
|
The plugin "<%- pluginName %>" was referenced from the config file in "<%- importerName %>".
|
10
10
|
|
11
|
-
If you still can't figure out the problem, please stop by https://
|
11
|
+
If you still can't figure out the problem, please stop by https://eslint.org/chat to chat with the team.
|
@@ -1,3 +1,3 @@
|
|
1
1
|
ESLint couldn't find the plugin "<%- pluginName %>". because there is whitespace in the name. Please check your configuration and remove all whitespace from the plugin name.
|
2
2
|
|
3
|
-
If you still can't figure out the problem, please stop by https://
|
3
|
+
If you still can't figure out the problem, please stop by https://eslint.org/chat to chat with the team.
|