eslint 8.13.0 → 8.17.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/README.md +17 -12
- package/bin/eslint.js +1 -1
- package/lib/cli-engine/cli-engine.js +2 -4
- package/lib/cli-engine/lint-result-cache.js +1 -1
- package/lib/eslint/eslint.js +3 -3
- package/lib/linter/code-path-analysis/code-path-segment.js +1 -1
- package/lib/linter/code-path-analysis/code-path-state.js +1 -1
- package/lib/linter/code-path-analysis/code-path.js +1 -1
- package/lib/rules/accessor-pairs.js +4 -4
- package/lib/rules/callback-return.js +2 -2
- package/lib/rules/capitalized-comments.js +1 -1
- package/lib/rules/consistent-this.js +1 -1
- package/lib/rules/dot-notation.js +2 -2
- package/lib/rules/function-paren-newline.js +8 -5
- package/lib/rules/global-require.js +3 -3
- package/lib/rules/indent-legacy.js +2 -2
- package/lib/rules/indent.js +45 -13
- package/lib/rules/index.js +1 -0
- package/lib/rules/jsx-quotes.js +1 -1
- package/lib/rules/lines-around-comment.js +3 -3
- package/lib/rules/max-lines.js +2 -2
- package/lib/rules/max-statements.js +1 -1
- package/lib/rules/newline-before-return.js +1 -1
- package/lib/rules/no-bitwise.js +2 -2
- package/lib/rules/no-console.js +1 -1
- package/lib/rules/no-constant-binary-expression.js +500 -0
- package/lib/rules/no-constant-condition.js +4 -197
- package/lib/rules/no-control-regex.js +23 -10
- package/lib/rules/no-empty-function.js +1 -1
- package/lib/rules/no-extra-boolean-cast.js +3 -3
- package/lib/rules/no-extra-semi.js +1 -1
- package/lib/rules/no-global-assign.js +1 -1
- package/lib/rules/no-implicit-coercion.js +8 -8
- package/lib/rules/no-loop-func.js +1 -1
- package/lib/rules/no-magic-numbers.js +3 -3
- package/lib/rules/no-misleading-character-class.js +90 -17
- package/lib/rules/no-mixed-operators.js +1 -1
- package/lib/rules/no-mixed-requires.js +1 -1
- package/lib/rules/no-multi-spaces.js +1 -1
- package/lib/rules/no-native-reassign.js +1 -1
- package/lib/rules/no-new-object.js +1 -1
- package/lib/rules/no-new-wrappers.js +1 -1
- package/lib/rules/no-octal.js +2 -2
- package/lib/rules/no-prototype-builtins.js +3 -3
- package/lib/rules/no-shadow.js +5 -5
- package/lib/rules/no-sparse-arrays.js +1 -1
- package/lib/rules/no-underscore-dangle.js +31 -2
- package/lib/rules/no-unused-expressions.js +1 -1
- package/lib/rules/no-unused-vars.js +1 -1
- package/lib/rules/no-use-before-define.js +15 -2
- package/lib/rules/operator-assignment.js +2 -2
- package/lib/rules/prefer-const.js +1 -1
- package/lib/rules/prefer-reflect.js +2 -2
- package/lib/rules/prefer-regex-literals.js +3 -3
- package/lib/rules/quote-props.js +2 -2
- package/lib/rules/quotes.js +1 -1
- package/lib/rules/spaced-comment.js +1 -1
- package/lib/rules/utils/ast-utils.js +203 -7
- package/lib/rules/valid-jsdoc.js +1 -1
- package/lib/rules/valid-typeof.js +4 -4
- package/lib/rules/yoda.js +1 -1
- package/lib/shared/types.js +1 -1
- package/package.json +25 -8
package/README.md
CHANGED
@@ -235,15 +235,15 @@ Milos Djermanovic
|
|
235
235
|
The people who review and implement new features.
|
236
236
|
|
237
237
|
<table><tbody><tr><td align="center" valign="top" width="11%">
|
238
|
-
<a href="https://github.com/mysticatea">
|
239
|
-
<img src="https://github.com/mysticatea.png?s=75" width="75" height="75"><br />
|
240
|
-
Toru Nagashima
|
241
|
-
</a>
|
242
|
-
</td><td align="center" valign="top" width="11%">
|
243
238
|
<a href="https://github.com/aladdin-add">
|
244
239
|
<img src="https://github.com/aladdin-add.png?s=75" width="75" height="75"><br />
|
245
240
|
唯然
|
246
241
|
</a>
|
242
|
+
</td><td align="center" valign="top" width="11%">
|
243
|
+
<a href="https://github.com/snitin315">
|
244
|
+
<img src="https://github.com/snitin315.png?s=75" width="75" height="75"><br />
|
245
|
+
Nitin Kumar
|
246
|
+
</a>
|
247
247
|
</td></tr></tbody></table>
|
248
248
|
|
249
249
|
### Committers
|
@@ -261,6 +261,16 @@ Brett Zamir
|
|
261
261
|
Bryan Mishkin
|
262
262
|
</a>
|
263
263
|
</td><td align="center" valign="top" width="11%">
|
264
|
+
<a href="https://github.com/mysticatea">
|
265
|
+
<img src="https://github.com/mysticatea.png?s=75" width="75" height="75"><br />
|
266
|
+
Toru Nagashima
|
267
|
+
</a>
|
268
|
+
</td><td align="center" valign="top" width="11%">
|
269
|
+
<a href="https://github.com/SaraSoueidan">
|
270
|
+
<img src="https://github.com/SaraSoueidan.png?s=75" width="75" height="75"><br />
|
271
|
+
Sara Soueidan
|
272
|
+
</a>
|
273
|
+
</td><td align="center" valign="top" width="11%">
|
264
274
|
<a href="https://github.com/g-plane">
|
265
275
|
<img src="https://github.com/g-plane.png?s=75" width="75" height="75"><br />
|
266
276
|
Pig Fang
|
@@ -275,11 +285,6 @@ Anix
|
|
275
285
|
<img src="https://github.com/yeonjuan.png?s=75" width="75" height="75"><br />
|
276
286
|
YeonJuan
|
277
287
|
</a>
|
278
|
-
</td><td align="center" valign="top" width="11%">
|
279
|
-
<a href="https://github.com/snitin315">
|
280
|
-
<img src="https://github.com/snitin315.png?s=75" width="75" height="75"><br />
|
281
|
-
Nitin Kumar
|
282
|
-
</a>
|
283
288
|
</td></tr></tbody></table>
|
284
289
|
|
285
290
|
<!--teamend-->
|
@@ -292,9 +297,9 @@ The following companies, organizations, and individuals support ESLint's ongoing
|
|
292
297
|
<!--sponsorsstart-->
|
293
298
|
<h3>Platinum Sponsors</h3>
|
294
299
|
<p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="undefined"></a></p><h3>Gold Sponsors</h3>
|
295
|
-
<p><a href="https://
|
300
|
+
<p><a href="https://www.salesforce.com"><img src="https://images.opencollective.com/salesforce/ca8f997/logo.png" alt="Salesforce" height="96"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="96"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301?v=4" alt="American Express" height="96"></a> <a href="https://substack.com/"><img src="https://avatars.githubusercontent.com/u/53023767?v=4" alt="Substack" height="96"></a></p><h3>Silver Sponsors</h3>
|
296
301
|
<p><a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a></p><h3>Bronze Sponsors</h3>
|
297
|
-
<p><a href="https://launchdarkly.com"><img src="https://images.opencollective.com/launchdarkly/574bb9e/logo.png" alt="launchdarkly" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS" 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://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/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.ignitionapp.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Ignition" height="32"></a></p>
|
302
|
+
<p><a href="https://launchdarkly.com"><img src="https://images.opencollective.com/launchdarkly/574bb9e/logo.png" alt="launchdarkly" height="32"></a> <a href="https://nx.dev"><img src="https://images.opencollective.com/nx/0efbe42/logo.png" alt="Nx (by Nrwl)" height="32"></a> <a href="https://www.crosswordsolver.org/anagram-solver/"><img src="https://images.opencollective.com/anagram-solver/2666271/logo.png" alt="Anagram Solver" height="32"></a> <a href="https://www.vpsserver.com"><img src="https://images.opencollective.com/vpsservercom/logo.png" alt="VPS" 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://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/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.ignitionapp.com"><img src="https://avatars.githubusercontent.com/u/5753491?v=4" alt="Ignition" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774?v=4" alt="HeroCoders" height="32"></a></p>
|
298
303
|
<!--sponsorsend-->
|
299
304
|
|
300
305
|
## <a name="technology-sponsors"></a>Technology Sponsors
|
package/bin/eslint.js
CHANGED
@@ -69,7 +69,7 @@ function getErrorMessage(error) {
|
|
69
69
|
// Lazy loading because this is used only if an error happened.
|
70
70
|
const util = require("util");
|
71
71
|
|
72
|
-
// Foolproof --
|
72
|
+
// Foolproof -- third-party module might throw non-object.
|
73
73
|
if (typeof error !== "object" || error === null) {
|
74
74
|
return String(error);
|
75
75
|
}
|
@@ -366,9 +366,7 @@ function *iterateRuleDeprecationWarnings(usedConfigArrays) {
|
|
366
366
|
|
367
367
|
// Flatten used configs.
|
368
368
|
/** @type {ExtractedConfig[]} */
|
369
|
-
const configs =
|
370
|
-
...usedConfigArrays.map(getUsedExtractedConfigs)
|
371
|
-
);
|
369
|
+
const configs = usedConfigArrays.flatMap(getUsedExtractedConfigs);
|
372
370
|
|
373
371
|
// Traverse rule configs.
|
374
372
|
for (const config of configs) {
|
@@ -1023,7 +1021,7 @@ class CLIEngine {
|
|
1023
1021
|
let formatterPath;
|
1024
1022
|
|
1025
1023
|
// if there's a slash, then it's a file (TODO: this check seems dubious for scoped npm packages)
|
1026
|
-
if (!namespace && normalizedFormatName.
|
1024
|
+
if (!namespace && normalizedFormatName.includes("/")) {
|
1027
1025
|
formatterPath = path.resolve(cwd, normalizedFormatName);
|
1028
1026
|
} else {
|
1029
1027
|
try {
|
@@ -36,7 +36,7 @@ const invalidCacheStrategyErrorMessage = `Cache strategy must be one of: ${valid
|
|
36
36
|
*/
|
37
37
|
function isValidCacheStrategy(cacheStrategy) {
|
38
38
|
return (
|
39
|
-
validCacheStrategies.
|
39
|
+
validCacheStrategies.includes(cacheStrategy)
|
40
40
|
);
|
41
41
|
}
|
42
42
|
|
package/lib/eslint/eslint.js
CHANGED
@@ -104,9 +104,9 @@ function isNonEmptyString(x) {
|
|
104
104
|
}
|
105
105
|
|
106
106
|
/**
|
107
|
-
* Check if a given value is an array of non-empty
|
107
|
+
* Check if a given value is an array of non-empty strings or not.
|
108
108
|
* @param {any} x The value to check.
|
109
|
-
* @returns {boolean} `true` if `x` is an array of non-empty
|
109
|
+
* @returns {boolean} `true` if `x` is an array of non-empty strings.
|
110
110
|
*/
|
111
111
|
function isArrayOfNonEmptyString(x) {
|
112
112
|
return Array.isArray(x) && x.every(isNonEmptyString);
|
@@ -599,7 +599,7 @@ class ESLint {
|
|
599
599
|
* The following values are allowed:
|
600
600
|
* - `undefined` ... Load `stylish` builtin formatter.
|
601
601
|
* - A builtin formatter name ... Load the builtin formatter.
|
602
|
-
* - A
|
602
|
+
* - A third-party formatter name:
|
603
603
|
* - `foo` → `eslint-formatter-foo`
|
604
604
|
* - `@foo` → `@foo/eslint-formatter`
|
605
605
|
* - `@foo/bar` → `@foo/eslint-formatter-bar`
|
@@ -100,7 +100,7 @@ class CodePathSegment {
|
|
100
100
|
* @returns {boolean} `true` if the segment is coming from the end of a loop.
|
101
101
|
*/
|
102
102
|
isLoopedPrevSegment(segment) {
|
103
|
-
return this.internal.loopedPrevSegments.
|
103
|
+
return this.internal.loopedPrevSegments.includes(segment);
|
104
104
|
}
|
105
105
|
|
106
106
|
/**
|
@@ -212,7 +212,7 @@ class CodePath {
|
|
212
212
|
}
|
213
213
|
|
214
214
|
// Reset the flag of skipping if all branches have been skipped.
|
215
|
-
if (skippedSegment && segment.prevSegments.
|
215
|
+
if (skippedSegment && segment.prevSegments.includes(skippedSegment)) {
|
216
216
|
skippedSegment = null;
|
217
217
|
}
|
218
218
|
visited[segment.id] = true;
|
@@ -299,12 +299,12 @@ module.exports = {
|
|
299
299
|
* @private
|
300
300
|
*/
|
301
301
|
function checkPropertyDescriptor(node) {
|
302
|
-
const namesToCheck = node.properties
|
302
|
+
const namesToCheck = new Set(node.properties
|
303
303
|
.filter(p => p.type === "Property" && p.kind === "init" && !p.computed)
|
304
|
-
.map(({ key }) => key.name);
|
304
|
+
.map(({ key }) => key.name));
|
305
305
|
|
306
|
-
const hasGetter = namesToCheck.
|
307
|
-
const hasSetter = namesToCheck.
|
306
|
+
const hasGetter = namesToCheck.has("get");
|
307
|
+
const hasSetter = namesToCheck.has("set");
|
308
308
|
|
309
309
|
if (checkSetWithoutGet && hasSetter && !hasGetter) {
|
310
310
|
report(node, "missingGetter");
|
@@ -53,7 +53,7 @@ module.exports = {
|
|
53
53
|
if (!node.parent) {
|
54
54
|
return null;
|
55
55
|
}
|
56
|
-
if (types.
|
56
|
+
if (!types.includes(node.parent.type)) {
|
57
57
|
return findClosestParentOfType(node.parent, types);
|
58
58
|
}
|
59
59
|
return node.parent;
|
@@ -87,7 +87,7 @@ module.exports = {
|
|
87
87
|
* @returns {boolean} Whether or not this function matches our callback name.
|
88
88
|
*/
|
89
89
|
function isCallback(node) {
|
90
|
-
return containsOnlyIdentifiers(node.callee) && callbacks.
|
90
|
+
return containsOnlyIdentifiers(node.callee) && callbacks.includes(sourceCode.getText(node.callee));
|
91
91
|
}
|
92
92
|
|
93
93
|
/**
|
@@ -65,7 +65,7 @@ module.exports = {
|
|
65
65
|
function checkAssignment(node, name, value) {
|
66
66
|
const isThis = value.type === "ThisExpression";
|
67
67
|
|
68
|
-
if (aliases.
|
68
|
+
if (aliases.includes(name)) {
|
69
69
|
if (!isThis || node.operator && node.operator !== "=") {
|
70
70
|
reportBadAssignment(node, name);
|
71
71
|
}
|
@@ -76,7 +76,7 @@ module.exports = {
|
|
76
76
|
function checkComputedProperty(node, value) {
|
77
77
|
if (
|
78
78
|
validIdentifier.test(value) &&
|
79
|
-
(allowKeywords || keywords.
|
79
|
+
(allowKeywords || !keywords.includes(String(value))) &&
|
80
80
|
!(allowPattern && allowPattern.test(value))
|
81
81
|
) {
|
82
82
|
const formattedValue = node.property.type === "Literal" ? JSON.stringify(value) : `\`${value}\``;
|
@@ -142,7 +142,7 @@ module.exports = {
|
|
142
142
|
!allowKeywords &&
|
143
143
|
!node.computed &&
|
144
144
|
node.property.type === "Identifier" &&
|
145
|
-
keywords.
|
145
|
+
keywords.includes(String(node.property.name))
|
146
146
|
) {
|
147
147
|
context.report({
|
148
148
|
node: node.property,
|
@@ -183,7 +183,7 @@ module.exports = {
|
|
183
183
|
/**
|
184
184
|
* Gets the left paren and right paren tokens of a node.
|
185
185
|
* @param {ASTNode} node The node with parens
|
186
|
-
* @throws {TypeError}
|
186
|
+
* @throws {TypeError} Unexpected node type.
|
187
187
|
* @returns {Object} An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token.
|
188
188
|
* Can also return `null` if an expression has no parens (e.g. a NewExpression with no arguments, or an ArrowFunctionExpression
|
189
189
|
* with a single parameter)
|
@@ -191,10 +191,13 @@ module.exports = {
|
|
191
191
|
function getParenTokens(node) {
|
192
192
|
switch (node.type) {
|
193
193
|
case "NewExpression":
|
194
|
-
if (!node.arguments.length &&
|
195
|
-
|
196
|
-
|
197
|
-
|
194
|
+
if (!node.arguments.length &&
|
195
|
+
!(
|
196
|
+
astUtils.isOpeningParenToken(sourceCode.getLastToken(node, { skip: 1 })) &&
|
197
|
+
astUtils.isClosingParenToken(sourceCode.getLastToken(node)) &&
|
198
|
+
node.callee.range[1] < node.range[1]
|
199
|
+
)
|
200
|
+
) {
|
198
201
|
|
199
202
|
// If the NewExpression does not have parens (e.g. `new Foo`), return null.
|
200
203
|
return null;
|
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
"use strict";
|
8
8
|
|
9
|
-
const ACCEPTABLE_PARENTS = [
|
9
|
+
const ACCEPTABLE_PARENTS = new Set([
|
10
10
|
"AssignmentExpression",
|
11
11
|
"VariableDeclarator",
|
12
12
|
"MemberExpression",
|
@@ -16,7 +16,7 @@ const ACCEPTABLE_PARENTS = [
|
|
16
16
|
"Program",
|
17
17
|
"VariableDeclaration",
|
18
18
|
"ChainExpression"
|
19
|
-
];
|
19
|
+
]);
|
20
20
|
|
21
21
|
/**
|
22
22
|
* Finds the eslint-scope reference in the given scope.
|
@@ -75,7 +75,7 @@ module.exports = {
|
|
75
75
|
const currentScope = context.getScope();
|
76
76
|
|
77
77
|
if (node.callee.name === "require" && !isShadowed(currentScope, node.callee)) {
|
78
|
-
const isGoodRequire = context.getAncestors().every(parent => ACCEPTABLE_PARENTS.
|
78
|
+
const isGoodRequire = context.getAncestors().every(parent => ACCEPTABLE_PARENTS.has(parent.type));
|
79
79
|
|
80
80
|
if (!isGoodRequire) {
|
81
81
|
context.report({ node, messageId: "unexpected" });
|
@@ -753,7 +753,7 @@ module.exports = {
|
|
753
753
|
if (typeof options.CallExpression.arguments === "number") {
|
754
754
|
nodeIndent += options.CallExpression.arguments * indentSize;
|
755
755
|
} else if (options.CallExpression.arguments === "first") {
|
756
|
-
if (parent.arguments.
|
756
|
+
if (parent.arguments.includes(node)) {
|
757
757
|
nodeIndent = parent.arguments[0].loc.start.column;
|
758
758
|
}
|
759
759
|
} else {
|
@@ -840,7 +840,7 @@ module.exports = {
|
|
840
840
|
"IfStatement", "WhileStatement", "ForStatement", "ForInStatement", "ForOfStatement", "DoWhileStatement", "ClassDeclaration", "TryStatement"
|
841
841
|
];
|
842
842
|
|
843
|
-
if (node.parent && statementsWithProperties.
|
843
|
+
if (node.parent && statementsWithProperties.includes(node.parent.type) && isNodeBodyBlock(node)) {
|
844
844
|
indent = getNodeIndent(node.parent).goodChar;
|
845
845
|
} else if (node.parent && node.parent.type === "CatchClause") {
|
846
846
|
indent = getNodeIndent(node.parent.parent).goodChar;
|
package/lib/rules/indent.js
CHANGED
@@ -796,7 +796,7 @@ module.exports = {
|
|
796
796
|
let statement = node.parent && node.parent.parent;
|
797
797
|
|
798
798
|
while (
|
799
|
-
statement.type === "UnaryExpression" && ["!", "~", "+", "-"].
|
799
|
+
statement.type === "UnaryExpression" && ["!", "~", "+", "-"].includes(statement.operator) ||
|
800
800
|
statement.type === "AssignmentExpression" ||
|
801
801
|
statement.type === "LogicalExpression" ||
|
802
802
|
statement.type === "SequenceExpression" ||
|
@@ -916,18 +916,6 @@ module.exports = {
|
|
916
916
|
}
|
917
917
|
|
918
918
|
offsets.setDesiredOffsets([firstBodyToken.range[0], lastBodyToken.range[1]], lastParentToken, 1);
|
919
|
-
|
920
|
-
/*
|
921
|
-
* For blockless nodes with semicolon-first style, don't indent the semicolon.
|
922
|
-
* e.g.
|
923
|
-
* if (foo) bar()
|
924
|
-
* ; [1, 2, 3].map(foo)
|
925
|
-
*/
|
926
|
-
const lastToken = sourceCode.getLastToken(node);
|
927
|
-
|
928
|
-
if (node.type !== "EmptyStatement" && astUtils.isSemicolonToken(lastToken)) {
|
929
|
-
offsets.setDesiredOffset(lastToken, lastParentToken, 0);
|
930
|
-
}
|
931
919
|
}
|
932
920
|
}
|
933
921
|
|
@@ -1271,6 +1259,50 @@ module.exports = {
|
|
1271
1259
|
}
|
1272
1260
|
},
|
1273
1261
|
|
1262
|
+
/*
|
1263
|
+
* For blockless nodes with semicolon-first style, don't indent the semicolon.
|
1264
|
+
* e.g.
|
1265
|
+
* if (foo)
|
1266
|
+
* bar()
|
1267
|
+
* ; [1, 2, 3].map(foo)
|
1268
|
+
*
|
1269
|
+
* Traversal into the node sets indentation of the semicolon, so we need to override it on exit.
|
1270
|
+
*/
|
1271
|
+
":matches(DoWhileStatement, ForStatement, ForInStatement, ForOfStatement, IfStatement, WhileStatement):exit"(node) {
|
1272
|
+
let nodesToCheck;
|
1273
|
+
|
1274
|
+
if (node.type === "IfStatement") {
|
1275
|
+
nodesToCheck = [node.consequent];
|
1276
|
+
if (node.alternate) {
|
1277
|
+
nodesToCheck.push(node.alternate);
|
1278
|
+
}
|
1279
|
+
} else {
|
1280
|
+
nodesToCheck = [node.body];
|
1281
|
+
}
|
1282
|
+
|
1283
|
+
for (const nodeToCheck of nodesToCheck) {
|
1284
|
+
const lastToken = sourceCode.getLastToken(nodeToCheck);
|
1285
|
+
|
1286
|
+
if (astUtils.isSemicolonToken(lastToken)) {
|
1287
|
+
const tokenBeforeLast = sourceCode.getTokenBefore(lastToken);
|
1288
|
+
const tokenAfterLast = sourceCode.getTokenAfter(lastToken);
|
1289
|
+
|
1290
|
+
// override indentation of `;` only if its line looks like a semicolon-first style line
|
1291
|
+
if (
|
1292
|
+
!astUtils.isTokenOnSameLine(tokenBeforeLast, lastToken) &&
|
1293
|
+
tokenAfterLast &&
|
1294
|
+
astUtils.isTokenOnSameLine(lastToken, tokenAfterLast)
|
1295
|
+
) {
|
1296
|
+
offsets.setDesiredOffset(
|
1297
|
+
lastToken,
|
1298
|
+
sourceCode.getFirstToken(node),
|
1299
|
+
0
|
1300
|
+
);
|
1301
|
+
}
|
1302
|
+
}
|
1303
|
+
}
|
1304
|
+
},
|
1305
|
+
|
1274
1306
|
ImportDeclaration(node) {
|
1275
1307
|
if (node.specifiers.some(specifier => specifier.type === "ImportSpecifier")) {
|
1276
1308
|
const openingCurly = sourceCode.getFirstToken(node, astUtils.isOpeningBraceToken);
|
package/lib/rules/index.js
CHANGED
@@ -103,6 +103,7 @@ module.exports = new LazyLoadingRuleMap(Object.entries({
|
|
103
103
|
"no-confusing-arrow": () => require("./no-confusing-arrow"),
|
104
104
|
"no-console": () => require("./no-console"),
|
105
105
|
"no-const-assign": () => require("./no-const-assign"),
|
106
|
+
"no-constant-binary-expression": () => require("./no-constant-binary-expression"),
|
106
107
|
"no-constant-condition": () => require("./no-constant-condition"),
|
107
108
|
"no-constructor-return": () => require("./no-constructor-return"),
|
108
109
|
"no-continue": () => require("./no-continue"),
|
package/lib/rules/jsx-quotes.js
CHANGED
@@ -70,7 +70,7 @@ module.exports = {
|
|
70
70
|
* @public
|
71
71
|
*/
|
72
72
|
function usesExpectedQuotes(node) {
|
73
|
-
return node.value.
|
73
|
+
return node.value.includes(setting.quote) || astUtils.isSurroundedBy(node.raw, setting.quote);
|
74
74
|
}
|
75
75
|
|
76
76
|
return {
|
@@ -141,7 +141,7 @@ module.exports = {
|
|
141
141
|
comments = sourceCode.getAllComments(),
|
142
142
|
commentLines = getCommentLineNums(comments),
|
143
143
|
emptyLines = getEmptyLineNums(lines),
|
144
|
-
commentAndEmptyLines = commentLines.concat(emptyLines);
|
144
|
+
commentAndEmptyLines = new Set(commentLines.concat(emptyLines));
|
145
145
|
|
146
146
|
/**
|
147
147
|
* Returns whether or not comments are on lines starting with or ending with code
|
@@ -393,7 +393,7 @@ module.exports = {
|
|
393
393
|
const nextTokenOrComment = sourceCode.getTokenAfter(token, { includeComments: true });
|
394
394
|
|
395
395
|
// check for newline before
|
396
|
-
if (!exceptionStartAllowed && before && !commentAndEmptyLines.
|
396
|
+
if (!exceptionStartAllowed && before && !commentAndEmptyLines.has(prevLineNum) &&
|
397
397
|
!(astUtils.isCommentToken(previousTokenOrComment) && astUtils.isTokenOnSameLine(previousTokenOrComment, token))) {
|
398
398
|
const lineStart = token.range[0] - token.loc.start.column;
|
399
399
|
const range = [lineStart, lineStart];
|
@@ -408,7 +408,7 @@ module.exports = {
|
|
408
408
|
}
|
409
409
|
|
410
410
|
// check for newline after
|
411
|
-
if (!exceptionEndAllowed && after && !commentAndEmptyLines.
|
411
|
+
if (!exceptionEndAllowed && after && !commentAndEmptyLines.has(nextLineNum) &&
|
412
412
|
!(astUtils.isCommentToken(nextTokenOrComment) && astUtils.isTokenOnSameLine(token, nextTokenOrComment))) {
|
413
413
|
context.report({
|
414
414
|
node: token,
|
package/lib/rules/max-lines.js
CHANGED
@@ -159,10 +159,10 @@ module.exports = {
|
|
159
159
|
if (skipComments) {
|
160
160
|
const comments = sourceCode.getAllComments();
|
161
161
|
|
162
|
-
const commentLines = comments.flatMap(getLinesWithoutCode);
|
162
|
+
const commentLines = new Set(comments.flatMap(getLinesWithoutCode));
|
163
163
|
|
164
164
|
lines = lines.filter(
|
165
|
-
l => !commentLines.
|
165
|
+
l => !commentLines.has(l.lineNumber)
|
166
166
|
);
|
167
167
|
}
|
168
168
|
|
@@ -126,7 +126,7 @@ module.exports = {
|
|
126
126
|
|
127
127
|
/*
|
128
128
|
* This rule does not apply to class static blocks, but we have to track them so
|
129
|
-
* that
|
129
|
+
* that statements in them do not count as statements in the enclosing function.
|
130
130
|
*/
|
131
131
|
if (node.type === "StaticBlock") {
|
132
132
|
return;
|
package/lib/rules/no-bitwise.js
CHANGED
@@ -76,7 +76,7 @@ module.exports = {
|
|
76
76
|
* @returns {boolean} Whether or not the node has a bitwise operator.
|
77
77
|
*/
|
78
78
|
function hasBitwiseOperator(node) {
|
79
|
-
return BITWISE_OPERATORS.
|
79
|
+
return BITWISE_OPERATORS.includes(node.operator);
|
80
80
|
}
|
81
81
|
|
82
82
|
/**
|
@@ -85,7 +85,7 @@ module.exports = {
|
|
85
85
|
* @returns {boolean} Whether or not the node has a bitwise operator.
|
86
86
|
*/
|
87
87
|
function allowedOperator(node) {
|
88
|
-
return allowed.
|
88
|
+
return allowed.includes(node.operator);
|
89
89
|
}
|
90
90
|
|
91
91
|
/**
|
package/lib/rules/no-console.js
CHANGED