eslint-plugin-unicorn 69.0.0 → 71.0.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/package.json +26 -25
- package/readme.md +15 -1
- package/rules/ast/call-or-new-expression.js +2 -8
- package/rules/ast/is-member-expression.js +2 -8
- package/rules/comment-content.js +4 -4
- package/rules/consistent-boolean-name.js +727 -42
- package/rules/consistent-compound-words.js +1 -2
- package/rules/consistent-json-file-read.js +2 -5
- package/rules/dom-node-dataset.js +3 -7
- package/rules/escape-case.js +4 -4
- package/rules/expiring-todo-comments.js +25 -2
- package/rules/explicit-length-check.js +3 -3
- package/rules/filename-case.js +4 -4
- package/rules/fix/{add-parenthesizes-to-return-or-throw-expression.js → add-parentheses-to-return-or-throw-expression.js} +1 -1
- package/rules/fix/index.js +1 -1
- package/rules/fix/remove-argument.js +34 -8
- package/rules/fix/remove-statement.js +1 -3
- package/rules/fix/switch-new-expression-to-call-expression.js +2 -2
- package/rules/id-match.js +2 -2
- package/rules/index.js +10 -0
- package/rules/isolated-functions.js +203 -19
- package/rules/name-replacements.js +1 -2
- package/rules/no-anonymous-default-export.js +1 -3
- package/rules/no-array-callback-reference.js +2 -10
- package/rules/no-async-promise-finally.js +111 -0
- package/rules/no-chained-comparison.js +1 -1
- package/rules/no-collection-bracket-access.js +27 -4
- package/rules/no-computed-property-existence-check.js +1 -4
- package/rules/no-declarations-before-early-exit.js +6 -5
- package/rules/no-error-property-assignment.js +3 -3
- package/rules/no-for-loop.js +4 -4
- package/rules/no-keyword-prefix.js +2 -2
- package/rules/no-manually-wrapped-comments.js +5 -1
- package/rules/no-mismatched-map-key.js +13 -20
- package/rules/no-named-default.js +2 -5
- package/rules/no-negated-array-predicate.js +6 -13
- package/rules/no-negated-comparison.js +31 -71
- package/rules/no-negated-condition.js +2 -2
- package/rules/no-negation-in-equality-check.js +4 -7
- package/rules/no-non-function-verb-prefix.js +25 -2
- package/rules/no-process-exit.js +6 -6
- package/rules/no-return-array-push.js +9 -2
- package/rules/no-static-only-class.js +2 -8
- package/rules/no-thenable.js +9 -15
- package/rules/no-typeof-undefined.js +2 -2
- package/rules/no-undeclared-class-members.js +1 -5
- package/rules/no-unnecessary-array-flat-map.js +308 -0
- package/rules/no-unnecessary-await.js +2 -2
- package/rules/no-unnecessary-fetch-options.js +624 -0
- package/rules/no-unnecessary-global-this.js +5 -9
- package/rules/no-unsafe-promise-all-settled-values.js +865 -0
- package/rules/no-unused-properties.js +0 -1
- package/rules/no-useless-coercion.js +1 -2
- package/rules/no-useless-else.js +32 -1
- package/rules/no-useless-iterator-to-array.js +42 -16
- package/rules/no-useless-spread.js +2 -2
- package/rules/no-useless-undefined.js +2 -2
- package/rules/prefer-abort-signal-any.js +1391 -0
- package/rules/prefer-array-find.js +2 -5
- package/rules/prefer-array-flat-map.js +6 -11
- package/rules/prefer-array-from-range.js +98 -0
- package/rules/prefer-bigint-literals.js +1 -0
- package/rules/prefer-block-statement-over-iife.js +159 -0
- package/rules/prefer-boolean-return.js +20 -3
- package/rules/prefer-continue.js +6 -2
- package/rules/prefer-default-parameters.js +2 -2
- package/rules/prefer-early-return.js +3 -1
- package/rules/prefer-else-if.js +5 -9
- package/rules/prefer-group-by.js +576 -0
- package/rules/prefer-has-check.js +6 -3
- package/rules/prefer-https.js +3 -3
- package/rules/prefer-identifier-import-export-specifiers.js +1 -3
- package/rules/prefer-iterator-helpers.js +196 -0
- package/rules/prefer-minimal-ternary.js +4 -4
- package/rules/prefer-number-coercion.js +1 -1
- package/rules/prefer-object-define-properties.js +1 -3
- package/rules/prefer-object-iterable-methods.js +57 -14
- package/rules/prefer-observer-apis.js +2 -5
- package/rules/prefer-private-class-fields.js +1 -3
- package/rules/prefer-simple-sort-comparator.js +6 -6
- package/rules/prefer-simplified-conditions.js +584 -0
- package/rules/prefer-single-object-destructuring.js +2 -5
- package/rules/prefer-single-replace.js +2 -2
- package/rules/prefer-spread.js +25 -32
- package/rules/prefer-string-pad-start-end.js +1 -6
- package/rules/prefer-string-raw.js +2 -2
- package/rules/prefer-string-repeat.js +16 -9
- package/rules/prefer-string-replace-all.js +1 -1
- package/rules/prefer-ternary.js +5 -5
- package/rules/prefer-toggle-attribute.js +3 -3
- package/rules/prefer-top-level-await.js +6 -1
- package/rules/prefer-uint8array-base64.js +3 -1
- package/rules/require-proxy-trap-boolean-return.js +2 -2
- package/rules/rule/to-eslint-create.js +1 -2
- package/rules/rule/to-eslint-listener.js +1 -3
- package/rules/rule/to-eslint-problem.js +1 -3
- package/rules/rule/to-eslint-rule-fixer.js +1 -3
- package/rules/rule/to-eslint-rule.js +1 -3
- package/rules/rule/to-eslint-rules.js +1 -3
- package/rules/rule/unicorn-context.js +1 -3
- package/rules/rule/unicorn-listeners.js +1 -3
- package/rules/shared/array-range.js +66 -0
- package/rules/shared/iterator-helpers.js +43 -1
- package/rules/shared/no-array-mutate-rule.js +1 -3
- package/rules/shared/regexp-escape.js +4 -4
- package/rules/utils/can-tokens-be-adjacent.js +95 -0
- package/rules/utils/comparison.js +65 -0
- package/rules/utils/escape-string.js +2 -8
- package/rules/utils/get-available-variable-name.js +2 -13
- package/rules/utils/get-precedence.js +112 -0
- package/rules/utils/get-token-store.js +1 -3
- package/rules/utils/global-reference-tracker.js +3 -6
- package/rules/utils/index.js +4 -0
- package/rules/utils/is-boolean.js +103 -30
- package/rules/utils/is-identifier-name.js +5 -0
- package/rules/utils/is-promise-type.js +1 -3
- package/rules/utils/is-react-hook-name.js +5 -0
- package/rules/utils/parentheses/get-parent-syntax-opening-parenthesis.js +1 -3
- package/rules/utils/parentheses/iterate-surrounding-parentheses.js +1 -1
- package/rules/utils/should-add-parentheses-to-await-expression-argument.js +4 -9
- package/rules/utils/should-add-parentheses-to-call-expression-callee.js +6 -12
- package/rules/utils/should-add-parentheses-to-unary-expression.js +7 -14
- package/rules/utils/to-location.js +1 -3
- package/rules/utils/track-branch-exits.js +8 -7
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {isEmptyStringLiteral} from './ast/index.js';
|
|
1
2
|
import {
|
|
2
3
|
isBoolean,
|
|
3
4
|
isString,
|
|
@@ -25,8 +26,6 @@ const coercions = new Map([
|
|
|
25
26
|
['Number', {type: 'number', isType: (node, context) => isNumber(node, context.sourceCode.getScope(node))}],
|
|
26
27
|
]);
|
|
27
28
|
|
|
28
|
-
const isEmptyStringLiteral = node => node.type === 'Literal' && node.value === '';
|
|
29
|
-
|
|
30
29
|
/** @param {ESLint.Rule.RuleContext} context */
|
|
31
30
|
const create = context => {
|
|
32
31
|
const {sourceCode} = context;
|
package/rules/no-useless-else.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import {isMethodCall} from './ast/index.js';
|
|
1
2
|
import {
|
|
2
3
|
hasCommentInRange,
|
|
3
4
|
hasDirectBlockScopedDeclaration,
|
|
5
|
+
isGlobalIdentifier,
|
|
4
6
|
needsSemicolon,
|
|
5
7
|
trackBranchExits,
|
|
6
8
|
} from './utils/index.js';
|
|
@@ -42,6 +44,35 @@ const isJsxChildTextToken = (token, sourceCode) =>
|
|
|
42
44
|
token.type === 'JSXText'
|
|
43
45
|
&& sourceCode.getNodeByRangeIndex(sourceCode.getRange(token)[0]).type === 'JSXText';
|
|
44
46
|
|
|
47
|
+
const isProcessExitCall = (node, context) =>
|
|
48
|
+
isMethodCall(node, {
|
|
49
|
+
object: 'process',
|
|
50
|
+
method: 'exit',
|
|
51
|
+
optionalCall: false,
|
|
52
|
+
optionalMember: false,
|
|
53
|
+
})
|
|
54
|
+
&& isGlobalIdentifier(node.callee.object, context);
|
|
55
|
+
|
|
56
|
+
const isProcessExitStatement = (node, context) =>
|
|
57
|
+
node.type === 'ExpressionStatement'
|
|
58
|
+
&& isProcessExitCall(node.expression, context);
|
|
59
|
+
|
|
60
|
+
function branchExits(branch, context, branchAlwaysExits) {
|
|
61
|
+
if (branchAlwaysExits(branch) || isProcessExitStatement(branch, context)) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (branch.type === 'BlockStatement') {
|
|
66
|
+
const lastStatement = branch.body.at(-1);
|
|
67
|
+
return Boolean(lastStatement && branchExits(lastStatement, context, branchAlwaysExits));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return branch.type === 'IfStatement'
|
|
71
|
+
&& branch.alternate
|
|
72
|
+
&& branchExits(branch.consequent, context, branchAlwaysExits)
|
|
73
|
+
&& branchExits(branch.alternate, context, branchAlwaysExits);
|
|
74
|
+
}
|
|
75
|
+
|
|
45
76
|
// A multiline token's internal whitespace can be meaningful, so it can't be safely reindented.
|
|
46
77
|
// JSX child text is safe because JSX collapses line-leading and line-trailing whitespace at compile time.
|
|
47
78
|
const hasReindentUnsafeMultilineToken = (node, context) => {
|
|
@@ -192,7 +223,7 @@ const fix = (ifStatement, context) => fixer => {
|
|
|
192
223
|
/** @param {ESLint.Rule.RuleContext} context */
|
|
193
224
|
const create = context => {
|
|
194
225
|
const {sourceCode} = context;
|
|
195
|
-
const branchAlwaysExits = trackBranchExits(context);
|
|
226
|
+
const branchAlwaysExits = trackBranchExits(context, branch => branchExits(branch, context, branchAlwaysExits));
|
|
196
227
|
|
|
197
228
|
context.onExit('IfStatement', ifStatement => {
|
|
198
229
|
if (!(
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import typedArray from './shared/typed-array.js';
|
|
2
|
+
import {unwrapExpression} from './shared/iterator-helpers.js';
|
|
2
3
|
import {removeMethodCall} from './fix/index.js';
|
|
3
4
|
import {
|
|
4
5
|
isNewExpression,
|
|
@@ -33,9 +34,7 @@ const callbackOnlyIteratorMethods = [
|
|
|
33
34
|
'some',
|
|
34
35
|
];
|
|
35
36
|
|
|
36
|
-
// `reduce` — both Array and Iterator accept (callback, initialValue)
|
|
37
|
-
// but Array.reduce without initialValue uses the first element while
|
|
38
|
-
// Iterator.reduce without initialValue throws.
|
|
37
|
+
// `reduce` — both Array and Iterator accept (callback, initialValue).
|
|
39
38
|
const reduceMethod = 'reduce';
|
|
40
39
|
|
|
41
40
|
const isToArrayCall = node => isMethodCall(node, {
|
|
@@ -81,13 +80,17 @@ const getArrayFromProblem = (node, context) => {
|
|
|
81
80
|
}
|
|
82
81
|
|
|
83
82
|
const toArrayCall = node.arguments[0];
|
|
84
|
-
const fix = getRemoveToArrayFix(toArrayCall, context);
|
|
83
|
+
const fix = node.arguments.length === 1 ? getRemoveToArrayFix(toArrayCall, context) : undefined;
|
|
84
|
+
const suggestion = node.arguments.length > 1
|
|
85
|
+
? getRemoveToArraySuggestion(toArrayCall, context, MESSAGE_ID_SUGGESTION_ITERABLE_ACCEPTING)
|
|
86
|
+
: undefined;
|
|
85
87
|
|
|
86
88
|
return {
|
|
87
89
|
node: toArrayCall.callee.property,
|
|
88
90
|
messageId: MESSAGE_ID_ITERABLE_ACCEPTING,
|
|
89
91
|
data: {description: `${node.callee.object.name}.${node.callee.property.name}(…)`},
|
|
90
92
|
...(fix && {fix}),
|
|
93
|
+
...(suggestion && {suggest: [suggestion]}),
|
|
91
94
|
};
|
|
92
95
|
};
|
|
93
96
|
|
|
@@ -106,13 +109,17 @@ const getObjectFromEntriesProblem = (node, context) => {
|
|
|
106
109
|
}
|
|
107
110
|
|
|
108
111
|
const toArrayCall = node.arguments[0];
|
|
109
|
-
const fix = getRemoveToArrayFix(toArrayCall, context);
|
|
112
|
+
const fix = node.arguments.length === 1 ? getRemoveToArrayFix(toArrayCall, context) : undefined;
|
|
113
|
+
const suggestion = node.arguments.length > 1
|
|
114
|
+
? getRemoveToArraySuggestion(toArrayCall, context, MESSAGE_ID_SUGGESTION_ITERABLE_ACCEPTING)
|
|
115
|
+
: undefined;
|
|
110
116
|
|
|
111
117
|
return {
|
|
112
118
|
node: toArrayCall.callee.property,
|
|
113
119
|
messageId: MESSAGE_ID_ITERABLE_ACCEPTING,
|
|
114
120
|
data: {description: `${node.callee.object.name}.${node.callee.property.name}(…)`},
|
|
115
121
|
...(fix && {fix}),
|
|
122
|
+
...(suggestion && {suggest: [suggestion]}),
|
|
116
123
|
};
|
|
117
124
|
};
|
|
118
125
|
|
|
@@ -143,6 +150,28 @@ const getPromiseProblem = (node, context) => {
|
|
|
143
150
|
};
|
|
144
151
|
};
|
|
145
152
|
|
|
153
|
+
const canObserveArrayArgument = (callback, arrayParameterIndex, context) => {
|
|
154
|
+
if (!callback) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
callback = unwrapExpression(callback);
|
|
159
|
+
|
|
160
|
+
if (
|
|
161
|
+
callback.type === 'ArrowFunctionExpression'
|
|
162
|
+
|| callback.type === 'FunctionExpression'
|
|
163
|
+
) {
|
|
164
|
+
return callback.params.length > arrayParameterIndex
|
|
165
|
+
|| callback.params.at(-1)?.type === 'RestElement'
|
|
166
|
+
|| (
|
|
167
|
+
callback.type === 'FunctionExpression'
|
|
168
|
+
&& context.sourceCode.getTokens(callback).some(token => token.type === 'Identifier' && token.value === 'arguments')
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return false;
|
|
173
|
+
};
|
|
174
|
+
|
|
146
175
|
const getIteratorMethodProblem = (node, context) => {
|
|
147
176
|
if (
|
|
148
177
|
!(
|
|
@@ -154,7 +183,8 @@ const getIteratorMethodProblem = (node, context) => {
|
|
|
154
183
|
})
|
|
155
184
|
|| isMethodCall(node, {
|
|
156
185
|
method: reduceMethod,
|
|
157
|
-
|
|
186
|
+
minimumArguments: 1,
|
|
187
|
+
maximumArguments: 2,
|
|
158
188
|
optionalCall: false,
|
|
159
189
|
optionalMember: false,
|
|
160
190
|
})
|
|
@@ -170,15 +200,7 @@ const getIteratorMethodProblem = (node, context) => {
|
|
|
170
200
|
const method = node.callee.property.name;
|
|
171
201
|
const isReduceCall = method === reduceMethod;
|
|
172
202
|
const arrayParameterIndex = isReduceCall ? 3 : 2;
|
|
173
|
-
if (
|
|
174
|
-
callback
|
|
175
|
-
&& (callback.type === 'ArrowFunctionExpression' || callback.type === 'FunctionExpression')
|
|
176
|
-
&& (
|
|
177
|
-
callback.params.length > arrayParameterIndex
|
|
178
|
-
// A rest parameter can capture the trailing `array` argument too.
|
|
179
|
-
|| callback.params.at(-1)?.type === 'RestElement'
|
|
180
|
-
)
|
|
181
|
-
) {
|
|
203
|
+
if (canObserveArrayArgument(callback, arrayParameterIndex, context)) {
|
|
182
204
|
return;
|
|
183
205
|
}
|
|
184
206
|
|
|
@@ -208,13 +230,17 @@ const create = context => {
|
|
|
208
230
|
}
|
|
209
231
|
|
|
210
232
|
const toArrayCall = node.arguments[0];
|
|
211
|
-
const fix = getRemoveToArrayFix(toArrayCall, context);
|
|
233
|
+
const fix = node.arguments.length === 1 ? getRemoveToArrayFix(toArrayCall, context) : undefined;
|
|
234
|
+
const suggestion = node.arguments.length > 1
|
|
235
|
+
? getRemoveToArraySuggestion(toArrayCall, context, MESSAGE_ID_SUGGESTION_ITERABLE_ACCEPTING)
|
|
236
|
+
: undefined;
|
|
212
237
|
|
|
213
238
|
return {
|
|
214
239
|
node: toArrayCall.callee.property,
|
|
215
240
|
messageId: MESSAGE_ID_ITERABLE_ACCEPTING,
|
|
216
241
|
data: {description: `new ${node.callee.name}(…)`},
|
|
217
242
|
...(fix && {fix}),
|
|
243
|
+
...(suggestion && {suggest: [suggestion]}),
|
|
218
244
|
};
|
|
219
245
|
});
|
|
220
246
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {isCommaToken} from '@eslint-community/eslint-utils';
|
|
2
2
|
import typedArray from './shared/typed-array.js';
|
|
3
|
-
import {removeParentheses, fixSpaceAroundKeyword,
|
|
3
|
+
import {removeParentheses, fixSpaceAroundKeyword, addParenthesesToReturnOrThrowExpression} from './fix/index.js';
|
|
4
4
|
import {
|
|
5
5
|
isArray,
|
|
6
6
|
isKnownNonArray,
|
|
@@ -143,7 +143,7 @@ function * unwrapSingleArraySpread(fixer, arrayExpression, context) {
|
|
|
143
143
|
&& !isOnSameLine(openingBracketToken, thirdToken, context)
|
|
144
144
|
&& !isParenthesized(arrayExpression, context)
|
|
145
145
|
) {
|
|
146
|
-
yield
|
|
146
|
+
yield addParenthesesToReturnOrThrowExpression(fixer, parent, context);
|
|
147
147
|
return;
|
|
148
148
|
}
|
|
149
149
|
|
|
@@ -410,10 +410,10 @@ const create = context => {
|
|
|
410
410
|
return;
|
|
411
411
|
}
|
|
412
412
|
|
|
413
|
-
const
|
|
413
|
+
const isAccessWhenTestPasses = !isConsequentUndefined;
|
|
414
414
|
const testValidity = getIndexedAccessTestValidity(node.test, indexedAccess);
|
|
415
415
|
|
|
416
|
-
if (testValidity !==
|
|
416
|
+
if (testValidity !== isAccessWhenTestPasses) {
|
|
417
417
|
return;
|
|
418
418
|
}
|
|
419
419
|
|