eslint-plugin-unicorn 70.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.
Files changed (91) hide show
  1. package/package.json +26 -25
  2. package/readme.md +5 -1
  3. package/rules/ast/call-or-new-expression.js +2 -8
  4. package/rules/ast/is-member-expression.js +2 -8
  5. package/rules/comment-content.js +4 -4
  6. package/rules/consistent-boolean-name.js +94 -10
  7. package/rules/consistent-compound-words.js +1 -2
  8. package/rules/consistent-json-file-read.js +2 -5
  9. package/rules/dom-node-dataset.js +3 -7
  10. package/rules/escape-case.js +4 -4
  11. package/rules/expiring-todo-comments.js +2 -2
  12. package/rules/explicit-length-check.js +3 -3
  13. package/rules/filename-case.js +4 -4
  14. package/rules/fix/remove-argument.js +34 -8
  15. package/rules/fix/remove-statement.js +1 -3
  16. package/rules/id-match.js +2 -2
  17. package/rules/isolated-functions.js +47 -7
  18. package/rules/name-replacements.js +1 -2
  19. package/rules/no-anonymous-default-export.js +1 -3
  20. package/rules/no-array-callback-reference.js +2 -10
  21. package/rules/no-chained-comparison.js +1 -1
  22. package/rules/no-computed-property-existence-check.js +1 -4
  23. package/rules/no-declarations-before-early-exit.js +6 -5
  24. package/rules/no-error-property-assignment.js +3 -3
  25. package/rules/no-for-loop.js +4 -4
  26. package/rules/no-keyword-prefix.js +2 -2
  27. package/rules/no-mismatched-map-key.js +13 -20
  28. package/rules/no-named-default.js +2 -5
  29. package/rules/no-negated-array-predicate.js +4 -11
  30. package/rules/no-negated-comparison.js +7 -10
  31. package/rules/no-negation-in-equality-check.js +2 -5
  32. package/rules/no-process-exit.js +6 -6
  33. package/rules/no-static-only-class.js +2 -8
  34. package/rules/no-thenable.js +9 -15
  35. package/rules/no-undeclared-class-members.js +1 -5
  36. package/rules/no-unnecessary-array-flat-map.js +6 -5
  37. package/rules/no-unnecessary-global-this.js +5 -9
  38. package/rules/no-unused-properties.js +0 -1
  39. package/rules/no-useless-coercion.js +1 -2
  40. package/rules/no-useless-undefined.js +2 -2
  41. package/rules/prefer-array-find.js +2 -5
  42. package/rules/prefer-bigint-literals.js +1 -0
  43. package/rules/prefer-boolean-return.js +20 -3
  44. package/rules/prefer-default-parameters.js +2 -2
  45. package/rules/prefer-else-if.js +5 -9
  46. package/rules/prefer-has-check.js +6 -3
  47. package/rules/prefer-https.js +3 -3
  48. package/rules/prefer-identifier-import-export-specifiers.js +1 -3
  49. package/rules/prefer-minimal-ternary.js +4 -4
  50. package/rules/prefer-object-define-properties.js +1 -3
  51. package/rules/prefer-observer-apis.js +2 -5
  52. package/rules/prefer-private-class-fields.js +1 -3
  53. package/rules/prefer-simple-sort-comparator.js +6 -6
  54. package/rules/prefer-single-object-destructuring.js +2 -5
  55. package/rules/prefer-single-replace.js +2 -2
  56. package/rules/prefer-spread.js +22 -32
  57. package/rules/prefer-string-pad-start-end.js +1 -6
  58. package/rules/prefer-string-repeat.js +16 -9
  59. package/rules/prefer-string-replace-all.js +1 -1
  60. package/rules/prefer-ternary.js +5 -5
  61. package/rules/prefer-toggle-attribute.js +3 -3
  62. package/rules/prefer-top-level-await.js +6 -1
  63. package/rules/prefer-uint8array-base64.js +3 -1
  64. package/rules/require-proxy-trap-boolean-return.js +2 -2
  65. package/rules/rule/to-eslint-create.js +1 -2
  66. package/rules/rule/to-eslint-listener.js +1 -3
  67. package/rules/rule/to-eslint-problem.js +1 -3
  68. package/rules/rule/to-eslint-rule-fixer.js +1 -3
  69. package/rules/rule/to-eslint-rule.js +1 -3
  70. package/rules/rule/to-eslint-rules.js +1 -3
  71. package/rules/rule/unicorn-context.js +1 -3
  72. package/rules/rule/unicorn-listeners.js +1 -3
  73. package/rules/shared/no-array-mutate-rule.js +1 -3
  74. package/rules/shared/regexp-escape.js +4 -4
  75. package/rules/utils/can-tokens-be-adjacent.js +95 -0
  76. package/rules/utils/escape-string.js +2 -8
  77. package/rules/utils/get-available-variable-name.js +2 -13
  78. package/rules/utils/get-precedence.js +112 -0
  79. package/rules/utils/get-token-store.js +1 -3
  80. package/rules/utils/global-reference-tracker.js +3 -6
  81. package/rules/utils/index.js +4 -0
  82. package/rules/utils/is-boolean.js +90 -32
  83. package/rules/utils/is-identifier-name.js +5 -0
  84. package/rules/utils/is-promise-type.js +1 -3
  85. package/rules/utils/is-react-hook-name.js +5 -0
  86. package/rules/utils/parentheses/get-parent-syntax-opening-parenthesis.js +1 -3
  87. package/rules/utils/parentheses/iterate-surrounding-parentheses.js +1 -1
  88. package/rules/utils/should-add-parentheses-to-await-expression-argument.js +4 -9
  89. package/rules/utils/should-add-parentheses-to-call-expression-callee.js +6 -12
  90. package/rules/utils/should-add-parentheses-to-unary-expression.js +7 -14
  91. package/rules/utils/to-location.js +1 -3
@@ -98,13 +98,51 @@ const create = context => {
98
98
 
99
99
  options.comments = options.comments.map(comment => comment.toLowerCase());
100
100
 
101
- const allowedGlobals = {
101
+ const configuredGlobals = {
102
102
  ...(globals[`es${context.languageOptions.ecmaVersion}`] ?? globals.builtins),
103
103
  ...context.languageOptions.globals,
104
- ...options.overrideGlobals,
105
104
  };
106
105
  const checked = new WeakSet();
107
106
 
107
+ const getAllowedGlobalValue = reference => {
108
+ const {identifier, resolved} = reference;
109
+ const {name} = identifier;
110
+
111
+ if (Object.hasOwn(options.overrideGlobals, name)) {
112
+ const overrideGlobalValue = options.overrideGlobals[name];
113
+
114
+ if (overrideGlobalValue === 'off') {
115
+ return 'off';
116
+ }
117
+
118
+ if (resolved && !sourceCode.isGlobalReference(identifier)) {
119
+ return;
120
+ }
121
+
122
+ return overrideGlobalValue;
123
+ }
124
+
125
+ if (
126
+ Object.hasOwn(configuredGlobals, name)
127
+ && configuredGlobals[name] === 'off'
128
+ ) {
129
+ return 'off';
130
+ }
131
+
132
+ if (!sourceCode.isGlobalReference(identifier)) {
133
+ return;
134
+ }
135
+
136
+ if (
137
+ !Object.hasOwn(configuredGlobals, name)
138
+ && !resolved?.eslintExplicitGlobal
139
+ ) {
140
+ return;
141
+ }
142
+
143
+ return resolved?.writeable ? 'writable' : 'readonly';
144
+ };
145
+
108
146
  function * getFunctionContextProblems(node, reason, root = node) {
109
147
  const messageId = functionContextReferenceMessageIds.get(node.type);
110
148
  if (messageId) {
@@ -173,18 +211,20 @@ const create = context => {
173
211
  continue;
174
212
  }
175
213
 
176
- if (Object.hasOwn(allowedGlobals, identifier.name) && allowedGlobals[identifier.name] !== 'off') {
214
+ const allowedGlobalValue = getAllowedGlobalValue(reference);
215
+ let problemReason = reason;
216
+
217
+ if (allowedGlobalValue !== undefined && allowedGlobalValue !== 'off') {
177
218
  if (reference.isReadOnly()) {
178
219
  continue;
179
220
  }
180
221
 
181
- const globalsValue = allowedGlobals[identifier.name];
182
- const isGlobalWritable = [true, 'writable', 'writeable'].includes(globalsValue);
222
+ const isGlobalWritable = [true, 'writable', 'writeable'].includes(allowedGlobalValue);
183
223
  if (isGlobalWritable) {
184
224
  continue;
185
225
  }
186
226
 
187
- reason += ' (global variable is not writable)';
227
+ problemReason += ' (global variable is not writable)';
188
228
  }
189
229
 
190
230
  // Could consider checking for typeof operator here, like in no-undef?
@@ -192,7 +232,7 @@ const create = context => {
192
232
  context.report({
193
233
  node: identifier,
194
234
  messageId: MESSAGE_ID_EXTERNALLY_SCOPED_VARIABLE,
195
- data: {name: identifier.name, reason},
235
+ data: {name: identifier.name, reason: problemReason},
196
236
  });
197
237
  }
198
238
 
@@ -1,6 +1,5 @@
1
1
  import path from 'node:path';
2
2
  import {isRegExp} from 'node:util/types';
3
- import helperValidatorIdentifier from '@babel/helper-validator-identifier';
4
3
  import {
5
4
  getAvailableVariableName,
6
5
  cartesianProductSamples,
@@ -9,6 +8,7 @@ import {
9
8
  upperFirst,
10
9
  lowerFirst,
11
10
  isVirtualFilename,
11
+ isIdentifierName,
12
12
  } from './utils/index.js';
13
13
  import {defaultReplacements, defaultAllowList, defaultIgnore} from './shared/name-replacements.js';
14
14
  import {
@@ -24,7 +24,6 @@ import {functionTypes} from './ast/index.js';
24
24
  const MESSAGE_ID_REPLACE = 'replace';
25
25
  const MESSAGE_ID_SUGGESTION = 'suggestion';
26
26
  const MESSAGE_ID_RENAME = 'rename';
27
- const {isIdentifierName} = helperValidatorIdentifier;
28
27
  const anotherNameMessage = 'A more descriptive name will do too.';
29
28
  const messages = {
30
29
  [MESSAGE_ID_REPLACE]: `The {{nameTypeText}} \`{{discouragedName}}\` should be named \`{{replacement}}\`. ${anotherNameMessage}`,
@@ -1,6 +1,5 @@
1
1
  import path from 'node:path';
2
2
  import {getFunctionHeadLocation, getFunctionNameWithKind, isOpeningParenToken} from '@eslint-community/eslint-utils';
3
- import helperValidatorIdentifier from '@babel/helper-validator-identifier';
4
3
  import {camelCase} from 'change-case';
5
4
  import {
6
5
  getClassHeadLocation,
@@ -9,11 +8,10 @@ import {
9
8
  getAvailableVariableName,
10
9
  upperFirst,
11
10
  isVirtualFilename,
11
+ isIdentifierName,
12
12
  } from './utils/index.js';
13
13
  import {isMemberExpression} from './ast/index.js';
14
14
 
15
- const {isIdentifierName} = helperValidatorIdentifier;
16
-
17
15
  const MESSAGE_ID_ERROR = 'no-anonymous-default-export/error';
18
16
  const MESSAGE_ID_SUGGESTION = 'no-anonymous-default-export/suggestion';
19
17
  const messages = {
@@ -1,4 +1,4 @@
1
- import helperValidatorIdentifier from '@babel/helper-validator-identifier';
1
+ import isIdentifier from 'is-identifier';
2
2
  import {findVariable} from '@eslint-community/eslint-utils';
3
3
  import typedArray from './shared/typed-array.js';
4
4
  import {isMethodCall, isUndefined} from './ast/index.js';
@@ -22,11 +22,6 @@ const ERROR_WITH_NAME_MESSAGE_ID = 'error-with-name';
22
22
  const ERROR_WITHOUT_NAME_MESSAGE_ID = 'error-without-name';
23
23
  const REPLACE_WITH_NAME_MESSAGE_ID = 'replace-with-name';
24
24
  const REPLACE_WITHOUT_NAME_MESSAGE_ID = 'replace-without-name';
25
- const {
26
- isIdentifierName,
27
- isKeyword,
28
- isStrictBindReservedWord,
29
- } = helperValidatorIdentifier;
30
25
  const messages = {
31
26
  [ERROR_WITH_NAME_MESSAGE_ID]: 'Do not pass function `{{name}}` directly to `.{{method}}(…)`.',
32
27
  [ERROR_WITHOUT_NAME_MESSAGE_ID]: 'Do not pass function directly to `.{{method}}(…)`.',
@@ -301,10 +296,7 @@ function isDefinitelyNotFunctionValue(node, context, visitedVariables = new Set(
301
296
  : false;
302
297
  }
303
298
 
304
- const isValidParameterName = name =>
305
- isIdentifierName(name)
306
- && !isKeyword(name)
307
- && !isStrictBindReservedWord(name, true);
299
+ const isValidParameterName = isIdentifier;
308
300
 
309
301
  function getSuggestionParameters(callExpression, callback, parameters) {
310
302
  if (callback.type !== 'Identifier') {
@@ -1,4 +1,5 @@
1
1
  import {hasSideEffect} from '@eslint-community/eslint-utils';
2
+ import {isBooleanLiteral} from './ast/index.js';
2
3
  import {getParenthesizedText, isParenthesized, isBoolean} from './utils/index.js';
3
4
 
4
5
  const MESSAGE_ID_ERROR = 'no-chained-comparison/error';
@@ -13,7 +14,6 @@ const equalityOperators = new Set(['===', '!==', '==', '!=']);
13
14
  const comparisonOperators = orderingOperators.union(equalityOperators);
14
15
 
15
16
  const isComparison = node => node.type === 'BinaryExpression' && comparisonOperators.has(node.operator);
16
- const isBooleanLiteral = node => node.type === 'Literal' && typeof node.value === 'boolean';
17
17
 
18
18
  // The `&&` rewrite is a `LogicalExpression`, which binds looser than any comparison. It can only
19
19
  // replace `node` where a surrounding operator won't recapture it: at the top of an expression or
@@ -134,10 +134,7 @@ const create = context => {
134
134
  });
135
135
 
136
136
  context.on('BinaryExpression', node => {
137
- if (!(
138
- node.operator === 'in'
139
- && !isStaticPropertyKey(node.left)
140
- )) {
137
+ if (node.operator !== 'in' || isStaticPropertyKey(node.left)) {
141
138
  return;
142
139
  }
143
140
 
@@ -1,5 +1,10 @@
1
1
  import {isCommentToken, hasSideEffect} from '@eslint-community/eslint-utils';
2
- import {containsSuspensionPoint, getReferences, trackBranchExits} from './utils/index.js';
2
+ import {
3
+ containsSuspensionPoint,
4
+ getReferences,
5
+ isReactHookName,
6
+ trackBranchExits,
7
+ } from './utils/index.js';
3
8
 
4
9
  const MESSAGE_ID = 'no-declarations-before-early-exit';
5
10
  const messages = {
@@ -23,10 +28,6 @@ function isGuardStatement(node, branchAlwaysExits) {
23
28
  return consequentExits !== alternateExits;
24
29
  }
25
30
 
26
- // https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/src/rules/RulesOfHooks.ts
27
- const isReactHookName = name =>
28
- name === 'use' || /^use[\dA-Z]/.test(name);
29
-
30
31
  // Matches `useFoo(…)` and `Namespace.useFoo(…)` (for example, `React.useMemo(…)`).
31
32
  const isReactHookCall = node => {
32
33
  if (node?.type !== 'CallExpression') {
@@ -142,7 +142,7 @@ const getLocalUpdateFrame = knownErrorVariableFrames =>
142
142
  ?? knownErrorVariableFrames.at(-1);
143
143
 
144
144
  const updateExistingKnownErrorVariable = (knownErrorVariableFrames, variable, constructorName) => {
145
- let crossesFunctionBoundary = false;
145
+ let isCrossesFunctionBoundary = false;
146
146
 
147
147
  for (const frame of knownErrorVariableFrames.toReversed()) {
148
148
  if (frame.knownErrorVariables.has(variable)) {
@@ -151,7 +151,7 @@ const updateExistingKnownErrorVariable = (knownErrorVariableFrames, variable, co
151
151
  return true;
152
152
  }
153
153
 
154
- if (!crossesFunctionBoundary) {
154
+ if (!isCrossesFunctionBoundary) {
155
155
  frame.knownErrorVariables.set(variable, undefined);
156
156
  }
157
157
 
@@ -160,7 +160,7 @@ const updateExistingKnownErrorVariable = (knownErrorVariableFrames, variable, co
160
160
  }
161
161
 
162
162
  if (frame.isFunctionBoundary) {
163
- crossesFunctionBoundary = true;
163
+ isCrossesFunctionBoundary = true;
164
164
  }
165
165
  }
166
166
 
@@ -876,14 +876,14 @@ const create = context => {
876
876
 
877
877
  let declarationElement = element;
878
878
  let declarationType = 'const';
879
- let removeDeclaration = true;
879
+ let isRemoveDeclaration = true;
880
880
 
881
881
  if (elementNode) {
882
882
  if (elementNode.id.type === 'ObjectPattern' || elementNode.id.type === 'ArrayPattern') {
883
- removeDeclaration = arrayReferences.length === 1;
883
+ isRemoveDeclaration = arrayReferences.length === 1;
884
884
  }
885
885
 
886
- if (removeDeclaration) {
886
+ if (isRemoveDeclaration) {
887
887
  declarationType = elementNode.parent.kind;
888
888
  declarationElement = sourceCode.getText(elementNode.id);
889
889
  }
@@ -911,7 +911,7 @@ const create = context => {
911
911
  }
912
912
 
913
913
  if (elementNode) {
914
- yield removeDeclaration
914
+ yield isRemoveDeclaration
915
915
  ? fixer.removeRange(getRemovalRange(elementNode, sourceCode))
916
916
  : fixer.replaceText(elementNode.init, element);
917
917
  }
@@ -90,12 +90,12 @@ function reportObjectPatternAndShouldSkipPropertyCheck(report, node, options) {
90
90
  return true;
91
91
  }
92
92
 
93
- const assignmentKeyEqualsValue = parent.key.name === parent.value.name;
93
+ const isAssignmentKeyEqualsValue = parent.key.name === parent.value.name;
94
94
 
95
95
  const valueIsInvalid = parent.value.name && Boolean(keyword);
96
96
 
97
97
  // Ignore destructuring if the option is set, unless a new identifier is created
98
- if (valueIsInvalid && !assignmentKeyEqualsValue) {
98
+ if (valueIsInvalid && !isAssignmentKeyEqualsValue) {
99
99
  report(node, keyword);
100
100
  }
101
101
 
@@ -1,7 +1,7 @@
1
1
  import {findVariable, getStaticValue} from '@eslint-community/eslint-utils';
2
2
  import {isMethodCall} from './ast/index.js';
3
3
  import {isReference, isSame, unwrapExpression} from './utils/comparison.js';
4
- import {isKnownNonMap} from './utils/index.js';
4
+ import {isComparableStaticValue, isKnownNonMap} from './utils/index.js';
5
5
 
6
6
  /**
7
7
  @import {TSESTree as ESTree} from '@typescript-eslint/types';
@@ -21,13 +21,6 @@ const skippedNodeTypes = new Set([
21
21
  'FunctionExpression',
22
22
  ]);
23
23
 
24
- const isComparableStaticValue = value =>
25
- value === null
26
- || (
27
- typeof value !== 'object'
28
- && typeof value !== 'function'
29
- );
30
-
31
24
  const isSameValueZero = (left, right) =>
32
25
  left === right
33
26
  || (
@@ -132,7 +125,7 @@ function patternContainsSameBinding(node, mapHasRoot, context) {
132
125
 
133
126
  function hasCallExpression(node, context) {
134
127
  const {visitorKeys} = context.sourceCode;
135
- let result = false;
128
+ let isResult = false;
136
129
 
137
130
  function visit(node) {
138
131
  if (!node) {
@@ -142,14 +135,14 @@ function hasCallExpression(node, context) {
142
135
  node = unwrapExpression(node);
143
136
 
144
137
  if (
145
- result
138
+ isResult
146
139
  || skippedNodeTypes.has(node.type)
147
140
  ) {
148
141
  return;
149
142
  }
150
143
 
151
144
  if (node.type === 'CallExpression') {
152
- result = true;
145
+ isResult = true;
153
146
  return;
154
147
  }
155
148
 
@@ -170,7 +163,7 @@ function hasCallExpression(node, context) {
170
163
 
171
164
  visit(node);
172
165
 
173
- return result;
166
+ return isResult;
174
167
  }
175
168
 
176
169
  function areDifferentKeys(left, right, context) {
@@ -353,11 +346,11 @@ function isNestedMapHasGuard(node, mapHasCall, context) {
353
346
 
354
347
  function hasSameMapHasCall(node, mapHasCall, context) {
355
348
  const {visitorKeys} = context.sourceCode;
356
- let result = false;
349
+ let isResult = false;
357
350
 
358
351
  function visit(node) {
359
352
  if (
360
- result
353
+ isResult
361
354
  || !node
362
355
  || skippedNodeTypes.has(node.type)
363
356
  ) {
@@ -370,7 +363,7 @@ function hasSameMapHasCall(node, mapHasCall, context) {
370
363
  nestedMapHasCall
371
364
  && isSameMapReceiver(unwrapExpression(mapHasCall).callee.object, unwrapExpression(nestedMapHasCall).callee.object, context)
372
365
  ) {
373
- result = true;
366
+ isResult = true;
374
367
  return;
375
368
  }
376
369
 
@@ -391,16 +384,16 @@ function hasSameMapHasCall(node, mapHasCall, context) {
391
384
 
392
385
  visit(node);
393
386
 
394
- return result;
387
+ return isResult;
395
388
  }
396
389
 
397
390
  function hasMapReceiverWrite(node, mapHasCall, context) {
398
391
  const {visitorKeys} = context.sourceCode;
399
- let result = false;
392
+ let isResult = false;
400
393
 
401
394
  function visit(node) {
402
395
  if (
403
- result
396
+ isResult
404
397
  || !node
405
398
  || skippedNodeTypes.has(node.type)
406
399
  || isNestedMapHasGuard(node, mapHasCall, context)
@@ -409,7 +402,7 @@ function hasMapReceiverWrite(node, mapHasCall, context) {
409
402
  }
410
403
 
411
404
  if (isMapReceiverWrite(node, mapHasCall, context)) {
412
- result = true;
405
+ isResult = true;
413
406
  return;
414
407
  }
415
408
 
@@ -430,7 +423,7 @@ function hasMapReceiverWrite(node, mapHasCall, context) {
430
423
 
431
424
  visit(node);
432
425
 
433
- return result;
426
+ return isResult;
434
427
  }
435
428
 
436
429
  function getMapAccessProblems(node, mapHasCall, context, reportedAccessKeys) {
@@ -97,12 +97,9 @@ const create = context => {
97
97
  });
98
98
 
99
99
  context.on('ExportSpecifier', specifier => {
100
- if (!(
101
- isValueExport(specifier)
100
+ if (!(isValueExport(specifier)
102
101
  && specifier.exported.name === 'default'
103
- && isValueExport(specifier.parent)
104
- && !specifier.parent.source
105
- )) {
102
+ && isValueExport(specifier.parent)) || specifier.parent.source) {
106
103
  return;
107
104
  }
108
105
 
@@ -24,13 +24,6 @@ const replacementMethod = new Map([
24
24
  ]);
25
25
  const methods = replacementMethod.keys().toArray();
26
26
 
27
- const predicateBodyTypesRequiringParentheses = new Set([
28
- 'TSAsExpression',
29
- 'TSNonNullExpression',
30
- 'TSSatisfiesExpression',
31
- 'TSTypeAssertion',
32
- ]);
33
-
34
27
  const needsParenthesesInConciseArrowBody = (node, text) =>
35
28
  node.parent.type === 'ArrowFunctionExpression'
36
29
  && node.parent.body === node
@@ -75,7 +68,7 @@ function getReplacementPredicateText(node, context) {
75
68
  }
76
69
 
77
70
  const text = context.sourceCode.getText(node);
78
- const needsParentheses = predicateBodyTypesRequiringParentheses.has(node.type) || shouldAddParenthesesToUnaryExpressionArgument(node, '!');
71
+ const needsParentheses = shouldAddParenthesesToUnaryExpressionArgument(node, '!');
79
72
 
80
73
  return {
81
74
  node,
@@ -158,7 +151,7 @@ const create = context => {
158
151
  replacement,
159
152
  },
160
153
  * fix(fixer) {
161
- const needsReturnOrThrowParentheses = (
154
+ const isNeedsReturnOrThrowParentheses = (
162
155
  (parent.type === 'ReturnStatement' || parent.type === 'ThrowStatement')
163
156
  && parent.argument === unaryExpression
164
157
  && !isOnSameLine(bangToken, tokenAfterBang, context)
@@ -171,12 +164,12 @@ const create = context => {
171
164
 
172
165
  if (
173
166
  tokenStore === sourceCode
174
- && !needsReturnOrThrowParentheses
167
+ && !isNeedsReturnOrThrowParentheses
175
168
  ) {
176
169
  yield fixSpaceAroundKeyword(fixer, unaryExpression, context);
177
170
  }
178
171
 
179
- if (needsReturnOrThrowParentheses) {
172
+ if (isNeedsReturnOrThrowParentheses) {
180
173
  yield addParenthesesToReturnOrThrowExpression(fixer, parent, context);
181
174
  return;
182
175
  }
@@ -98,14 +98,14 @@ function * fix({
98
98
  const tokenAfterBangIncludingComments = sourceCode.getTokenAfter(bangToken, {includeComments: true});
99
99
  const operatorToken = getPunctuatorBinaryExpressionOperatorToken(comparison, context);
100
100
  const {parent} = unaryExpression;
101
- const needsReturnOrThrowParentheses = (
101
+ const isNeedsReturnOrThrowParentheses = (
102
102
  (parent.type === 'ReturnStatement' || parent.type === 'ThrowStatement')
103
103
  && parent.argument === unaryExpression
104
104
  && !isOnSameLine(bangToken, tokenAfterBang, context)
105
105
  && !isParenthesized(unaryExpression, context)
106
106
  );
107
107
 
108
- if (!needsReturnOrThrowParentheses) {
108
+ if (!isNeedsReturnOrThrowParentheses) {
109
109
  yield fixSpaceAroundKeyword(fixer, unaryExpression, context);
110
110
  }
111
111
 
@@ -117,16 +117,13 @@ function * fix({
117
117
  yield fixer.insertTextAfter(tokenAfterBangIncludingComments, ' ');
118
118
  }
119
119
 
120
- if (!(
121
- parentNeedsGroupedComparison(parent)
122
- && !isParenthesized(unaryExpression, context)
123
- )) {
120
+ if (!parentNeedsGroupedComparison(parent) || isParenthesized(unaryExpression, context)) {
124
121
  yield removeParentheses(comparison, fixer, context);
125
122
  }
126
123
 
127
124
  yield fixer.replaceText(operatorToken, replacementOperator);
128
125
 
129
- if (needsReturnOrThrowParentheses) {
126
+ if (isNeedsReturnOrThrowParentheses) {
130
127
  yield addParenthesesToReturnOrThrowExpression(fixer, parent, context);
131
128
  return;
132
129
  }
@@ -178,21 +175,21 @@ function * fixLogical({
178
175
  const bangToken = sourceCode.getFirstToken(unaryExpression);
179
176
  const tokenAfterBang = sourceCode.getTokenAfter(bangToken);
180
177
  const {parent} = unaryExpression;
181
- const needsReturnOrThrowParentheses = (
178
+ const isNeedsReturnOrThrowParentheses = (
182
179
  (parent.type === 'ReturnStatement' || parent.type === 'ThrowStatement')
183
180
  && parent.argument === unaryExpression
184
181
  && !isOnSameLine(bangToken, tokenAfterBang, context)
185
182
  && !isParenthesized(unaryExpression, context)
186
183
  );
187
184
 
188
- if (!needsReturnOrThrowParentheses) {
185
+ if (!isNeedsReturnOrThrowParentheses) {
189
186
  yield fixSpaceAroundKeyword(fixer, unaryExpression, context);
190
187
  }
191
188
 
192
189
  yield fixer.remove(bangToken);
193
190
  yield fixer.replaceText(logicalExpression, getFixedLogicalExpressionText(logicalExpression, context));
194
191
 
195
- if (needsReturnOrThrowParentheses) {
192
+ if (isNeedsReturnOrThrowParentheses) {
196
193
  yield addParenthesesToReturnOrThrowExpression(fixer, parent, context);
197
194
  return;
198
195
  }
@@ -23,11 +23,8 @@ const create = context => {
23
23
  context.on('BinaryExpression', binaryExpression => {
24
24
  const {operator, left} = binaryExpression;
25
25
 
26
- if (!(
27
- isEqualityCheck(binaryExpression)
28
- && isNegatedExpression(left)
29
- && !isNegatedExpression(left.argument)
30
- )) {
26
+ if (!(isEqualityCheck(binaryExpression)
27
+ && isNegatedExpression(left)) || isNegatedExpression(left.argument)) {
31
28
  return;
32
29
  }
33
30
 
@@ -11,9 +11,9 @@ const isWorkerThreads = node =>
11
11
 
12
12
  /** @param {import('eslint').Rule.RuleContext} context */
13
13
  const create = context => {
14
- const startsWithHashBang = context.sourceCode.lines[0].indexOf('#!') === 0;
14
+ const isStartsWithHashBang = context.sourceCode.lines[0].indexOf('#!') === 0;
15
15
 
16
- if (startsWithHashBang) {
16
+ if (isStartsWithHashBang) {
17
17
  return;
18
18
  }
19
19
 
@@ -22,7 +22,7 @@ const create = context => {
22
22
  let processEventHandlerDepth = 0;
23
23
 
24
24
  // Only report if it's outside a worker thread context. See #328.
25
- let requiredWorkerThreadsModule = false;
25
+ let isRequiredWorkerThreadsModule = false;
26
26
  const problemNodes = [];
27
27
 
28
28
  const isProcessEventHandler = node => isMethodCall(node, {
@@ -39,7 +39,7 @@ const create = context => {
39
39
  isStaticRequire(callExpression)
40
40
  && isWorkerThreads(callExpression.arguments[0])
41
41
  ) {
42
- requiredWorkerThreadsModule = true;
42
+ isRequiredWorkerThreadsModule = true;
43
43
  }
44
44
  });
45
45
 
@@ -49,7 +49,7 @@ const create = context => {
49
49
  importDeclaration.source.type === 'Literal'
50
50
  && isWorkerThreads(importDeclaration.source)
51
51
  ) {
52
- requiredWorkerThreadsModule = true;
52
+ isRequiredWorkerThreadsModule = true;
53
53
  }
54
54
  });
55
55
 
@@ -81,7 +81,7 @@ const create = context => {
81
81
  });
82
82
 
83
83
  context.onExit('Program', function * () {
84
- if (requiredWorkerThreadsModule) {
84
+ if (isRequiredWorkerThreadsModule) {
85
85
  return;
86
86
  }
87
87
 
@@ -38,16 +38,10 @@ function isStaticMember(node) {
38
38
  }
39
39
 
40
40
  // TypeScript class
41
- if (
42
- isDeclare
41
+ return !(isDeclare
43
42
  || isReadonly
44
43
  || accessibility !== undefined
45
- || (Array.isArray(decorators) && decorators.length > 0)
46
- ) {
47
- return false;
48
- }
49
-
50
- return true;
44
+ || (Array.isArray(decorators) && decorators.length > 0));
51
45
  }
52
46
 
53
47
  function * switchClassMemberToObjectProperty(node, context, fixer) {
@@ -79,16 +79,13 @@ const cases = [
79
79
  {
80
80
  selector: 'CallExpression',
81
81
  * getNodes(node, context) {
82
- if (!(
83
- isMethodCall(node, {
84
- objects: ['Object', 'Reflect'],
85
- method: 'defineProperty',
86
- minimumArguments: 3,
87
- optionalCall: false,
88
- optionalMember: false,
89
- })
90
- && node.arguments[0].type !== 'SpreadElement'
91
- )) {
82
+ if (!isMethodCall(node, {
83
+ objects: ['Object', 'Reflect'],
84
+ method: 'defineProperty',
85
+ minimumArguments: 3,
86
+ optionalCall: false,
87
+ optionalMember: false,
88
+ }) || node.arguments[0].type === 'SpreadElement') {
92
89
  return;
93
90
  }
94
91
 
@@ -117,11 +114,8 @@ const cases = [
117
114
  }
118
115
 
119
116
  for (const pairs of node.arguments[0].elements) {
120
- if (!(
121
- pairs?.type === 'ArrayExpression'
122
- && pairs.elements[0]
123
- && pairs.elements[0].type !== 'SpreadElement'
124
- )) {
117
+ if (!(pairs?.type === 'ArrayExpression'
118
+ && pairs.elements[0]) || pairs.elements[0].type === 'SpreadElement') {
125
119
  continue;
126
120
  }
127
121
 
@@ -179,11 +179,7 @@ const getDeclaredClassMemberNames = (classBody, sourceCode) => {
179
179
  const names = new Set(['constructor']);
180
180
 
181
181
  for (const member of classBody.body) {
182
- if (!(
183
- classMemberTypes.has(member.type)
184
- && member.static !== true
185
- && member.kind !== 'constructor'
186
- )) {
182
+ if (!classMemberTypes.has(member.type) || member.static === true || member.kind === 'constructor') {
187
183
  continue;
188
184
  }
189
185