eslint 8.56.0 → 9.0.0-alpha.1

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 (121) hide show
  1. package/README.md +7 -2
  2. package/conf/ecma-version.js +16 -0
  3. package/conf/rule-type-list.json +3 -1
  4. package/lib/api.js +1 -1
  5. package/lib/cli-engine/cli-engine.js +14 -3
  6. package/lib/cli-engine/formatters/formatters-meta.json +1 -29
  7. package/lib/cli-engine/lint-result-cache.js +2 -2
  8. package/lib/cli.js +46 -25
  9. package/lib/config/default-config.js +3 -0
  10. package/lib/config/flat-config-array.js +0 -20
  11. package/lib/config/flat-config-helpers.js +41 -20
  12. package/lib/config/flat-config-schema.js +35 -25
  13. package/lib/config/rule-validator.js +27 -4
  14. package/lib/eslint/eslint-helpers.js +32 -12
  15. package/lib/eslint/eslint.js +856 -373
  16. package/lib/eslint/index.js +2 -2
  17. package/lib/eslint/legacy-eslint.js +722 -0
  18. package/lib/linter/apply-disable-directives.js +35 -7
  19. package/lib/linter/code-path-analysis/code-path.js +5 -19
  20. package/lib/linter/code-path-analysis/fork-context.js +1 -1
  21. package/lib/linter/config-comment-parser.js +8 -11
  22. package/lib/linter/linter.js +196 -100
  23. package/lib/linter/report-translator.js +2 -2
  24. package/lib/linter/rules.js +6 -15
  25. package/lib/linter/source-code-fixer.js +1 -1
  26. package/lib/options.js +9 -1
  27. package/lib/rule-tester/rule-tester.js +234 -291
  28. package/lib/rules/array-bracket-newline.js +1 -1
  29. package/lib/rules/array-bracket-spacing.js +1 -1
  30. package/lib/rules/block-scoped-var.js +1 -1
  31. package/lib/rules/callback-return.js +2 -2
  32. package/lib/rules/comma-dangle.js +1 -1
  33. package/lib/rules/comma-style.js +2 -2
  34. package/lib/rules/complexity.js +1 -1
  35. package/lib/rules/constructor-super.js +1 -1
  36. package/lib/rules/default-case.js +1 -1
  37. package/lib/rules/eol-last.js +2 -2
  38. package/lib/rules/function-paren-newline.js +2 -2
  39. package/lib/rules/indent-legacy.js +5 -5
  40. package/lib/rules/indent.js +5 -5
  41. package/lib/rules/index.js +1 -2
  42. package/lib/rules/key-spacing.js +2 -2
  43. package/lib/rules/line-comment-position.js +1 -1
  44. package/lib/rules/lines-around-directive.js +2 -2
  45. package/lib/rules/max-depth.js +1 -1
  46. package/lib/rules/max-len.js +3 -3
  47. package/lib/rules/max-lines.js +3 -3
  48. package/lib/rules/max-nested-callbacks.js +1 -1
  49. package/lib/rules/max-params.js +1 -1
  50. package/lib/rules/max-statements.js +1 -1
  51. package/lib/rules/multiline-comment-style.js +7 -7
  52. package/lib/rules/new-cap.js +1 -1
  53. package/lib/rules/newline-after-var.js +1 -1
  54. package/lib/rules/newline-before-return.js +1 -1
  55. package/lib/rules/no-constant-binary-expression.js +6 -6
  56. package/lib/rules/no-constructor-return.js +2 -2
  57. package/lib/rules/no-dupe-class-members.js +2 -2
  58. package/lib/rules/no-else-return.js +1 -1
  59. package/lib/rules/no-empty-function.js +2 -2
  60. package/lib/rules/no-empty-static-block.js +1 -1
  61. package/lib/rules/no-extra-semi.js +1 -1
  62. package/lib/rules/no-fallthrough.js +1 -1
  63. package/lib/rules/no-implicit-coercion.js +17 -1
  64. package/lib/rules/no-inner-declarations.js +23 -2
  65. package/lib/rules/no-invalid-regexp.js +1 -1
  66. package/lib/rules/no-invalid-this.js +1 -1
  67. package/lib/rules/no-lone-blocks.js +2 -2
  68. package/lib/rules/no-loss-of-precision.js +1 -1
  69. package/lib/rules/no-misleading-character-class.js +174 -65
  70. package/lib/rules/no-mixed-spaces-and-tabs.js +1 -1
  71. package/lib/rules/no-multiple-empty-lines.js +1 -1
  72. package/lib/rules/no-new-native-nonconstructor.js +1 -1
  73. package/lib/rules/no-new-symbol.js +8 -1
  74. package/lib/rules/no-restricted-globals.js +1 -1
  75. package/lib/rules/no-restricted-imports.js +2 -2
  76. package/lib/rules/no-restricted-modules.js +2 -2
  77. package/lib/rules/no-return-await.js +1 -1
  78. package/lib/rules/no-sequences.js +1 -0
  79. package/lib/rules/no-trailing-spaces.js +2 -3
  80. package/lib/rules/no-unneeded-ternary.js +1 -1
  81. package/lib/rules/no-unsafe-optional-chaining.js +1 -1
  82. package/lib/rules/no-unused-private-class-members.js +1 -1
  83. package/lib/rules/no-unused-vars.js +6 -8
  84. package/lib/rules/no-useless-assignment.js +566 -0
  85. package/lib/rules/no-useless-backreference.js +1 -1
  86. package/lib/rules/object-curly-spacing.js +3 -3
  87. package/lib/rules/object-property-newline.js +1 -1
  88. package/lib/rules/one-var.js +5 -5
  89. package/lib/rules/padded-blocks.js +7 -7
  90. package/lib/rules/prefer-arrow-callback.js +3 -3
  91. package/lib/rules/prefer-reflect.js +1 -1
  92. package/lib/rules/prefer-regex-literals.js +1 -1
  93. package/lib/rules/prefer-template.js +1 -1
  94. package/lib/rules/radix.js +2 -2
  95. package/lib/rules/semi-style.js +1 -1
  96. package/lib/rules/sort-imports.js +1 -1
  97. package/lib/rules/sort-keys.js +1 -1
  98. package/lib/rules/sort-vars.js +1 -1
  99. package/lib/rules/space-unary-ops.js +1 -1
  100. package/lib/rules/strict.js +1 -1
  101. package/lib/rules/utils/ast-utils.js +7 -7
  102. package/lib/rules/yield-star-spacing.js +1 -1
  103. package/lib/shared/types.js +1 -1
  104. package/lib/source-code/source-code.js +5 -83
  105. package/lib/source-code/token-store/index.js +2 -2
  106. package/lib/unsupported-api.js +3 -5
  107. package/package.json +12 -14
  108. package/conf/config-schema.js +0 -93
  109. package/lib/cli-engine/formatters/checkstyle.js +0 -60
  110. package/lib/cli-engine/formatters/compact.js +0 -60
  111. package/lib/cli-engine/formatters/jslint-xml.js +0 -41
  112. package/lib/cli-engine/formatters/junit.js +0 -82
  113. package/lib/cli-engine/formatters/tap.js +0 -95
  114. package/lib/cli-engine/formatters/unix.js +0 -58
  115. package/lib/cli-engine/formatters/visualstudio.js +0 -63
  116. package/lib/eslint/flat-eslint.js +0 -1142
  117. package/lib/rule-tester/flat-rule-tester.js +0 -1122
  118. package/lib/rules/require-jsdoc.js +0 -122
  119. package/lib/rules/valid-jsdoc.js +0 -516
  120. package/lib/shared/config-validator.js +0 -347
  121. package/lib/shared/relative-module-resolver.js +0 -50
@@ -12,7 +12,7 @@ const astUtils = require("./utils/ast-utils");
12
12
  //------------------------------------------------------------------------------
13
13
 
14
14
  const INDEX_OF_PATTERN = /^(?:i|lastI)ndexOf$/u;
15
- const ALLOWABLE_OPERATORS = ["~", "!!", "+", "*"];
15
+ const ALLOWABLE_OPERATORS = ["~", "!!", "+", "- -", "-", "*"];
16
16
 
17
17
  /**
18
18
  * Parses and normalizes an option object.
@@ -300,6 +300,14 @@ module.exports = {
300
300
 
301
301
  report(node, recommendation, true);
302
302
  }
303
+
304
+ // -(-foo)
305
+ operatorAllowed = options.allow.includes("- -");
306
+ if (!operatorAllowed && options.number && node.operator === "-" && node.argument.type === "UnaryExpression" && node.argument.operator === "-" && !isNumeric(node.argument.argument)) {
307
+ const recommendation = `Number(${sourceCode.getText(node.argument.argument)})`;
308
+
309
+ report(node, recommendation, false);
310
+ }
303
311
  },
304
312
 
305
313
  // Use `:exit` to prevent double reporting
@@ -317,6 +325,14 @@ module.exports = {
317
325
  report(node, recommendation, true);
318
326
  }
319
327
 
328
+ // foo - 0
329
+ operatorAllowed = options.allow.includes("-");
330
+ if (!operatorAllowed && options.number && node.operator === "-" && node.right.type === "Literal" && node.right.value === 0 && !isNumeric(node.left)) {
331
+ const recommendation = `Number(${sourceCode.getText(node.left)})`;
332
+
333
+ report(node, recommendation, true);
334
+ }
335
+
320
336
  // "" + foo
321
337
  operatorAllowed = options.allow.includes("+");
322
338
  if (!operatorAllowed && options.string && isConcatWithEmptyString(node)) {
@@ -49,13 +49,22 @@ module.exports = {
49
49
 
50
50
  docs: {
51
51
  description: "Disallow variable or `function` declarations in nested blocks",
52
- recommended: true,
52
+ recommended: false,
53
53
  url: "https://eslint.org/docs/latest/rules/no-inner-declarations"
54
54
  },
55
55
 
56
56
  schema: [
57
57
  {
58
58
  enum: ["functions", "both"]
59
+ },
60
+ {
61
+ type: "object",
62
+ properties: {
63
+ blockScopedFunctions: {
64
+ enum: ["allow", "disallow"]
65
+ }
66
+ },
67
+ additionalProperties: false
59
68
  }
60
69
  ],
61
70
 
@@ -66,6 +75,10 @@ module.exports = {
66
75
 
67
76
  create(context) {
68
77
 
78
+ const sourceCode = context.sourceCode;
79
+ const ecmaVersion = context.languageOptions.ecmaVersion;
80
+ const blockScopedFunctions = context.options[1]?.blockScopedFunctions ?? "allow";
81
+
69
82
  /**
70
83
  * Ensure that a given node is at a program or function body's root.
71
84
  * @param {ASTNode} node Declaration node to check.
@@ -97,7 +110,15 @@ module.exports = {
97
110
 
98
111
  return {
99
112
 
100
- FunctionDeclaration: check,
113
+ FunctionDeclaration(node) {
114
+ const isInStrictCode = sourceCode.getScope(node).upper.isStrict;
115
+
116
+ if (blockScopedFunctions === "allow" && ecmaVersion >= 2015 && isInStrictCode) {
117
+ return;
118
+ }
119
+
120
+ check(node);
121
+ },
101
122
  VariableDeclaration(node) {
102
123
  if (context.options[0] === "both" && node.kind === "var") {
103
124
  check(node);
@@ -55,7 +55,7 @@ module.exports = {
55
55
  const temp = options.allowConstructorFlags.join("").replace(validFlags, "");
56
56
 
57
57
  if (temp) {
58
- allowedFlags = new RegExp(`[${temp}]`, "giu");
58
+ allowedFlags = new RegExp(`[${temp}]`, "gu");
59
59
  }
60
60
  }
61
61
 
@@ -74,7 +74,7 @@ module.exports = {
74
74
  * an object which has a flag that whether or not `this` keyword is valid.
75
75
  */
76
76
  stack.getCurrent = function() {
77
- const current = this[this.length - 1];
77
+ const current = this.at(-1);
78
78
 
79
79
  if (!current.init) {
80
80
  current.init = true;
@@ -78,7 +78,7 @@ module.exports = {
78
78
 
79
79
  const block = node.parent;
80
80
 
81
- if (loneBlocks[loneBlocks.length - 1] === block) {
81
+ if (loneBlocks.at(-1) === block) {
82
82
  loneBlocks.pop();
83
83
  }
84
84
  }
@@ -101,7 +101,7 @@ module.exports = {
101
101
  }
102
102
  },
103
103
  "BlockStatement:exit"(node) {
104
- if (loneBlocks.length > 0 && loneBlocks[loneBlocks.length - 1] === node) {
104
+ if (loneBlocks.length > 0 && loneBlocks.at(-1) === node) {
105
105
  loneBlocks.pop();
106
106
  report(node);
107
107
  } else if (
@@ -64,7 +64,7 @@ module.exports = {
64
64
  */
65
65
  function notBaseTenLosesPrecision(node) {
66
66
  const rawString = getRaw(node).toUpperCase();
67
- let base = 0;
67
+ let base;
68
68
 
69
69
  if (rawString.startsWith("0B")) {
70
70
  base = 2;
@@ -62,7 +62,6 @@ function *iterateCharacterSequence(nodes) {
62
62
  }
63
63
  }
64
64
 
65
-
66
65
  /**
67
66
  * Checks whether the given character node is a Unicode code point escape or not.
68
67
  * @param {Character} char the character node to check.
@@ -73,80 +72,126 @@ function isUnicodeCodePointEscape(char) {
73
72
  }
74
73
 
75
74
  /**
76
- * Each function returns `true` if it detects that kind of problem.
77
- * @type {Record<string, (chars: Character[]) => boolean>}
75
+ * Each function returns matched characters if it detects that kind of problem.
76
+ * @type {Record<string, (chars: Character[]) => IterableIterator<Character[]>>}
78
77
  */
79
- const hasCharacterSequence = {
80
- surrogatePairWithoutUFlag(chars) {
81
- return chars.some((c, i) => {
82
- if (i === 0) {
83
- return false;
78
+ const findCharacterSequences = {
79
+ *surrogatePairWithoutUFlag(chars) {
80
+ for (const [index, char] of chars.entries()) {
81
+ if (index === 0) {
82
+ continue;
83
+ }
84
+ const previous = chars[index - 1];
85
+
86
+ if (
87
+ isSurrogatePair(previous.value, char.value) &&
88
+ !isUnicodeCodePointEscape(previous) &&
89
+ !isUnicodeCodePointEscape(char)
90
+ ) {
91
+ yield [previous, char];
84
92
  }
85
- const c1 = chars[i - 1];
86
-
87
- return (
88
- isSurrogatePair(c1.value, c.value) &&
89
- !isUnicodeCodePointEscape(c1) &&
90
- !isUnicodeCodePointEscape(c)
91
- );
92
- });
93
+ }
93
94
  },
94
95
 
95
- surrogatePair(chars) {
96
- return chars.some((c, i) => {
97
- if (i === 0) {
98
- return false;
96
+ *surrogatePair(chars) {
97
+ for (const [index, char] of chars.entries()) {
98
+ if (index === 0) {
99
+ continue;
99
100
  }
100
- const c1 = chars[i - 1];
101
+ const previous = chars[index - 1];
101
102
 
102
- return (
103
- isSurrogatePair(c1.value, c.value) &&
103
+ if (
104
+ isSurrogatePair(previous.value, char.value) &&
104
105
  (
105
- isUnicodeCodePointEscape(c1) ||
106
- isUnicodeCodePointEscape(c)
106
+ isUnicodeCodePointEscape(previous) ||
107
+ isUnicodeCodePointEscape(char)
107
108
  )
108
- );
109
- });
109
+ ) {
110
+ yield [previous, char];
111
+ }
112
+ }
110
113
  },
111
114
 
112
- combiningClass(chars) {
113
- return chars.some((c, i) => (
114
- i !== 0 &&
115
- isCombiningCharacter(c.value) &&
116
- !isCombiningCharacter(chars[i - 1].value)
117
- ));
115
+ *combiningClass(chars) {
116
+ for (const [index, char] of chars.entries()) {
117
+ if (index === 0) {
118
+ continue;
119
+ }
120
+ const previous = chars[index - 1];
121
+
122
+ if (
123
+ isCombiningCharacter(char.value) &&
124
+ !isCombiningCharacter(previous.value)
125
+ ) {
126
+ yield [previous, char];
127
+ }
128
+ }
118
129
  },
119
130
 
120
- emojiModifier(chars) {
121
- return chars.some((c, i) => (
122
- i !== 0 &&
123
- isEmojiModifier(c.value) &&
124
- !isEmojiModifier(chars[i - 1].value)
125
- ));
131
+ *emojiModifier(chars) {
132
+ for (const [index, char] of chars.entries()) {
133
+ if (index === 0) {
134
+ continue;
135
+ }
136
+ const previous = chars[index - 1];
137
+
138
+ if (
139
+ isEmojiModifier(char.value) &&
140
+ !isEmojiModifier(previous.value)
141
+ ) {
142
+ yield [previous, char];
143
+ }
144
+ }
126
145
  },
127
146
 
128
- regionalIndicatorSymbol(chars) {
129
- return chars.some((c, i) => (
130
- i !== 0 &&
131
- isRegionalIndicatorSymbol(c.value) &&
132
- isRegionalIndicatorSymbol(chars[i - 1].value)
133
- ));
147
+ *regionalIndicatorSymbol(chars) {
148
+ for (const [index, char] of chars.entries()) {
149
+ if (index === 0) {
150
+ continue;
151
+ }
152
+ const previous = chars[index - 1];
153
+
154
+ if (
155
+ isRegionalIndicatorSymbol(char.value) &&
156
+ isRegionalIndicatorSymbol(previous.value)
157
+ ) {
158
+ yield [previous, char];
159
+ }
160
+ }
134
161
  },
135
162
 
136
- zwj(chars) {
137
- const lastIndex = chars.length - 1;
163
+ *zwj(chars) {
164
+ let sequence = null;
138
165
 
139
- return chars.some((c, i) => (
140
- i !== 0 &&
141
- i !== lastIndex &&
142
- c.value === 0x200d &&
143
- chars[i - 1].value !== 0x200d &&
144
- chars[i + 1].value !== 0x200d
145
- ));
166
+ for (const [index, char] of chars.entries()) {
167
+ if (index === 0 || index === chars.length - 1) {
168
+ continue;
169
+ }
170
+ if (
171
+ char.value === 0x200d &&
172
+ chars[index - 1].value !== 0x200d &&
173
+ chars[index + 1].value !== 0x200d
174
+ ) {
175
+ if (sequence) {
176
+ if (sequence.at(-1) === chars[index - 1]) {
177
+ sequence.push(char, chars[index + 1]); // append to the sequence
178
+ } else {
179
+ yield sequence;
180
+ sequence = chars.slice(index - 1, index + 2);
181
+ }
182
+ } else {
183
+ sequence = chars.slice(index - 1, index + 2);
184
+ }
185
+ }
186
+ }
187
+
188
+ if (sequence) {
189
+ yield sequence;
190
+ }
146
191
  }
147
192
  };
148
193
 
149
- const kinds = Object.keys(hasCharacterSequence);
194
+ const kinds = Object.keys(findCharacterSequences);
150
195
 
151
196
  //------------------------------------------------------------------------------
152
197
  // Rule Definition
@@ -181,6 +226,62 @@ module.exports = {
181
226
  const sourceCode = context.sourceCode;
182
227
  const parser = new RegExpParser();
183
228
 
229
+ /**
230
+ * Generates a granular loc for context.report, if directly calculable.
231
+ * @param {Character[]} chars Individual characters being reported on.
232
+ * @param {Node} node Parent string node to report within.
233
+ * @returns {Object | null} Granular loc for context.report, if directly calculable.
234
+ * @see https://github.com/eslint/eslint/pull/17515
235
+ */
236
+ function generateReportLocation(chars, node) {
237
+
238
+ // Limit to to literals and expression-less templates with raw values === their value.
239
+ switch (node.type) {
240
+ case "TemplateLiteral":
241
+ if (node.expressions.length || sourceCode.getText(node).slice(1, -1) !== node.quasis[0].value.cooked) {
242
+ return null;
243
+ }
244
+ break;
245
+
246
+ case "Literal":
247
+ if (typeof node.value === "string" && node.value !== node.raw.slice(1, -1)) {
248
+ return null;
249
+ }
250
+ break;
251
+
252
+ default:
253
+ return null;
254
+ }
255
+
256
+ return {
257
+ start: sourceCode.getLocFromIndex(node.range[0] + 1 + chars[0].start),
258
+ end: sourceCode.getLocFromIndex(node.range[0] + 1 + chars.at(-1).end)
259
+ };
260
+ }
261
+
262
+ /**
263
+ * Finds the report loc(s) for a range of matches.
264
+ * @param {Character[][]} matches Characters that should trigger a report.
265
+ * @param {Node} node The node to report.
266
+ * @returns {Object | null} Node loc(s) for context.report.
267
+ */
268
+ function getNodeReportLocations(matches, node) {
269
+ const locs = [];
270
+
271
+ for (const chars of matches) {
272
+ const loc = generateReportLocation(chars, node);
273
+
274
+ // If a report can't match to a range, don't report any others
275
+ if (!loc) {
276
+ return [node.loc];
277
+ }
278
+
279
+ locs.push(loc);
280
+ }
281
+
282
+ return locs;
283
+ }
284
+
184
285
  /**
185
286
  * Verify a given regular expression.
186
287
  * @param {Node} node The node to report.
@@ -208,21 +309,24 @@ module.exports = {
208
309
  return;
209
310
  }
210
311
 
211
- const foundKinds = new Set();
312
+ const foundKindMatches = new Map();
212
313
 
213
314
  visitRegExpAST(patternNode, {
214
315
  onCharacterClassEnter(ccNode) {
215
316
  for (const chars of iterateCharacterSequence(ccNode.elements)) {
216
317
  for (const kind of kinds) {
217
- if (hasCharacterSequence[kind](chars)) {
218
- foundKinds.add(kind);
318
+ if (foundKindMatches.has(kind)) {
319
+ foundKindMatches.get(kind).push(...findCharacterSequences[kind](chars));
320
+ } else {
321
+ foundKindMatches.set(kind, [...findCharacterSequences[kind](chars)]);
219
322
  }
323
+
220
324
  }
221
325
  }
222
326
  }
223
327
  });
224
328
 
225
- for (const kind of foundKinds) {
329
+ for (const [kind, matches] of foundKindMatches) {
226
330
  let suggest;
227
331
 
228
332
  if (kind === "surrogatePairWithoutUFlag") {
@@ -232,11 +336,16 @@ module.exports = {
232
336
  }];
233
337
  }
234
338
 
235
- context.report({
236
- node,
237
- messageId: kind,
238
- suggest
239
- });
339
+ const locs = getNodeReportLocations(matches, node);
340
+
341
+ for (const loc of locs) {
342
+ context.report({
343
+ node,
344
+ loc,
345
+ messageId: kind,
346
+ suggest
347
+ });
348
+ }
240
349
  }
241
350
  }
242
351
 
@@ -267,7 +376,7 @@ module.exports = {
267
376
  const flags = getStringIfConstant(flagsNode, scope);
268
377
 
269
378
  if (typeof pattern === "string") {
270
- verify(refNode, pattern, flags || "", fixer => {
379
+ verify(patternNode, pattern, flags || "", fixer => {
271
380
 
272
381
  if (!isValidWithUnicodeFlag(context.languageOptions.ecmaVersion, pattern)) {
273
382
  return null;
@@ -18,7 +18,7 @@ module.exports = {
18
18
 
19
19
  docs: {
20
20
  description: "Disallow mixed spaces and tabs for indentation",
21
- recommended: true,
21
+ recommended: false,
22
22
  url: "https://eslint.org/docs/latest/rules/no-mixed-spaces-and-tabs"
23
23
  },
24
24
 
@@ -70,7 +70,7 @@ module.exports = {
70
70
  const sourceCode = context.sourceCode;
71
71
 
72
72
  // Swallow the final newline, as some editors add it automatically and we don't want it to cause an issue
73
- const allLines = sourceCode.lines[sourceCode.lines.length - 1] === "" ? sourceCode.lines.slice(0, -1) : sourceCode.lines;
73
+ const allLines = sourceCode.lines.at(-1) === "" ? sourceCode.lines.slice(0, -1) : sourceCode.lines;
74
74
  const templateLiteralLines = new Set();
75
75
 
76
76
  //--------------------------------------------------------------------------
@@ -22,7 +22,7 @@ module.exports = {
22
22
 
23
23
  docs: {
24
24
  description: "Disallow `new` operators with global non-constructor functions",
25
- recommended: false,
25
+ recommended: true,
26
26
  url: "https://eslint.org/docs/latest/rules/no-new-native-nonconstructor"
27
27
  },
28
28
 
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @fileoverview Rule to disallow use of the new operator with the `Symbol` object
3
3
  * @author Alberto Rodríguez
4
+ * @deprecated in ESLint v9.0.0
4
5
  */
5
6
 
6
7
  "use strict";
@@ -16,10 +17,16 @@ module.exports = {
16
17
 
17
18
  docs: {
18
19
  description: "Disallow `new` operators with the `Symbol` object",
19
- recommended: true,
20
+ recommended: false,
20
21
  url: "https://eslint.org/docs/latest/rules/no-new-symbol"
21
22
  },
22
23
 
24
+ deprecated: true,
25
+
26
+ replacedBy: [
27
+ "no-new-native-nonconstructor"
28
+ ],
29
+
23
30
  schema: [],
24
31
 
25
32
  messages: {
@@ -97,7 +97,7 @@ module.exports = {
97
97
  * @private
98
98
  */
99
99
  function isRestricted(name) {
100
- return Object.prototype.hasOwnProperty.call(restrictedGlobalMessages, name);
100
+ return Object.hasOwn(restrictedGlobalMessages, name);
101
101
  }
102
102
 
103
103
  return {
@@ -158,7 +158,7 @@ module.exports = {
158
158
  const options = Array.isArray(context.options) ? context.options : [];
159
159
  const isPathAndPatternsObject =
160
160
  typeof options[0] === "object" &&
161
- (Object.prototype.hasOwnProperty.call(options[0], "paths") || Object.prototype.hasOwnProperty.call(options[0], "patterns"));
161
+ (Object.hasOwn(options[0], "paths") || Object.hasOwn(options[0], "patterns"));
162
162
 
163
163
  const restrictedPaths = (isPathAndPatternsObject ? options[0].paths : context.options) || [];
164
164
  const restrictedPathMessages = restrictedPaths.reduce((memo, importSource) => {
@@ -203,7 +203,7 @@ module.exports = {
203
203
  * @private
204
204
  */
205
205
  function checkRestrictedPathAndReport(importSource, importNames, node) {
206
- if (!Object.prototype.hasOwnProperty.call(restrictedPathMessages, importSource)) {
206
+ if (!Object.hasOwn(restrictedPathMessages, importSource)) {
207
207
  return;
208
208
  }
209
209
 
@@ -90,7 +90,7 @@ module.exports = {
90
90
  const options = Array.isArray(context.options) ? context.options : [];
91
91
  const isPathAndPatternsObject =
92
92
  typeof options[0] === "object" &&
93
- (Object.prototype.hasOwnProperty.call(options[0], "paths") || Object.prototype.hasOwnProperty.call(options[0], "patterns"));
93
+ (Object.hasOwn(options[0], "paths") || Object.hasOwn(options[0], "patterns"));
94
94
 
95
95
  const restrictedPaths = (isPathAndPatternsObject ? options[0].paths : context.options) || [];
96
96
  const restrictedPatterns = (isPathAndPatternsObject ? options[0].patterns : []) || [];
@@ -178,7 +178,7 @@ module.exports = {
178
178
  * @private
179
179
  */
180
180
  function isRestrictedPath(name) {
181
- return Object.prototype.hasOwnProperty.call(restrictedPathMessages, name);
181
+ return Object.hasOwn(restrictedPathMessages, name);
182
182
  }
183
183
 
184
184
  return {
@@ -118,7 +118,7 @@ module.exports = {
118
118
  if (node.parent.type === "LogicalExpression" && node === node.parent.right) {
119
119
  return isInTailCallPosition(node.parent);
120
120
  }
121
- if (node.parent.type === "SequenceExpression" && node === node.parent.expressions[node.parent.expressions.length - 1]) {
121
+ if (node.parent.type === "SequenceExpression" && node === node.parent.expressions.at(-1)) {
122
122
  return isInTailCallPosition(node.parent);
123
123
  }
124
124
  return false;
@@ -35,6 +35,7 @@ module.exports = {
35
35
  },
36
36
 
37
37
  schema: [{
38
+ type: "object",
38
39
  properties: {
39
40
  allowInParentheses: {
40
41
  type: "boolean",
@@ -129,8 +129,7 @@ module.exports = {
129
129
  comments = sourceCode.getAllComments(),
130
130
  commentLineNumbers = getCommentLineNumbers(comments);
131
131
 
132
- let totalLength = 0,
133
- fixRange = [];
132
+ let totalLength = 0;
134
133
 
135
134
  for (let i = 0, ii = lines.length; i < ii; i++) {
136
135
  const lineNumber = i + 1;
@@ -177,7 +176,7 @@ module.exports = {
177
176
  continue;
178
177
  }
179
178
 
180
- fixRange = [rangeStart, rangeEnd];
179
+ const fixRange = [rangeStart, rangeEnd];
181
180
 
182
181
  if (!ignoreComments || !commentLineNumbers.has(lineNumber)) {
183
182
  report(node, location, fixRange);
@@ -76,7 +76,7 @@ module.exports = {
76
76
  * @returns {string} A string representing an inverted expression
77
77
  */
78
78
  function invertExpression(node) {
79
- if (node.type === "BinaryExpression" && Object.prototype.hasOwnProperty.call(OPERATOR_INVERSES, node.operator)) {
79
+ if (node.type === "BinaryExpression" && Object.hasOwn(OPERATOR_INVERSES, node.operator)) {
80
80
  const operatorToken = sourceCode.getFirstTokenBetween(
81
81
  node.left,
82
82
  node.right,
@@ -94,7 +94,7 @@ module.exports = {
94
94
  break;
95
95
  case "SequenceExpression":
96
96
  checkUndefinedShortCircuit(
97
- node.expressions[node.expressions.length - 1],
97
+ node.expressions.at(-1),
98
98
  reportFunc
99
99
  );
100
100
  break;
@@ -16,7 +16,7 @@ module.exports = {
16
16
 
17
17
  docs: {
18
18
  description: "Disallow unused private class members",
19
- recommended: false,
19
+ recommended: true,
20
20
  url: "https://eslint.org/docs/latest/rules/no-unused-private-class-members"
21
21
  },
22
22