eslint 9.24.0 → 9.25.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 (35) hide show
  1. package/README.md +4 -3
  2. package/lib/cli-engine/formatters/html.js +3 -3
  3. package/lib/cli-engine/formatters/stylish.js +1 -1
  4. package/lib/languages/js/source-code/source-code.js +3 -3
  5. package/lib/languages/js/source-code/token-store/index.js +3 -3
  6. package/lib/linter/node-event-generator.js +3 -1
  7. package/lib/linter/report-translator.js +1 -1
  8. package/lib/linter/rule-fixer.js +13 -5
  9. package/lib/linter/source-code-fixer.js +2 -2
  10. package/lib/linter/timing.js +2 -2
  11. package/lib/rules/for-direction.js +4 -4
  12. package/lib/rules/func-name-matching.js +1 -1
  13. package/lib/rules/indent-legacy.js +13 -13
  14. package/lib/rules/indent.js +3 -3
  15. package/lib/rules/key-spacing.js +2 -2
  16. package/lib/rules/linebreak-style.js +9 -1
  17. package/lib/rules/max-len.js +2 -2
  18. package/lib/rules/max-statements.js +2 -2
  19. package/lib/rules/no-empty-function.js +53 -2
  20. package/lib/rules/no-global-assign.js +1 -1
  21. package/lib/rules/no-invalid-this.js +22 -0
  22. package/lib/rules/no-loop-func.js +2 -0
  23. package/lib/rules/no-native-reassign.js +1 -1
  24. package/lib/rules/no-nonoctal-decimal-escape.js +9 -1
  25. package/lib/rules/no-param-reassign.js +1 -1
  26. package/lib/rules/no-restricted-properties.js +42 -28
  27. package/lib/rules/no-return-await.js +0 -1
  28. package/lib/rules/no-trailing-spaces.js +10 -2
  29. package/lib/rules/no-unused-expressions.js +15 -0
  30. package/lib/rules/prefer-reflect.js +0 -1
  31. package/lib/rules/utils/ast-utils.js +16 -4
  32. package/lib/rules/utils/fix-tracker.js +10 -2
  33. package/lib/types/index.d.ts +23 -0
  34. package/lib/types/rules.d.ts +14 -0
  35. package/package.json +6 -6
package/README.md CHANGED
@@ -319,10 +319,11 @@ Percy Ma
319
319
  The following companies, organizations, and individuals support ESLint's ongoing maintenance and development. [Become a Sponsor](https://eslint.org/donate)
320
320
  to get your logo on our READMEs and [website](https://eslint.org/sponsors).
321
321
 
322
- <h3>Platinum Sponsors</h3>
322
+ <h3>Diamond Sponsors</h3>
323
+ <p><a href="https://www.ag-grid.com/"><img src="https://images.opencollective.com/ag-grid/2c8d545/logo.png" alt="AG Grid" height="128"></a></p><h3>Platinum Sponsors</h3>
323
324
  <p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="128"></a> <a href="https://www.airbnb.com/"><img src="https://images.opencollective.com/airbnb/d327d66/logo.png" alt="Airbnb" height="128"></a></p><h3>Gold Sponsors</h3>
324
- <p><a href="https://qlty.sh/"><img src="https://images.opencollective.com/qltysh/33d157d/logo.png" alt="Qlty Software" height="96"></a> <a href="https://trunk.io/"><img src="https://images.opencollective.com/trunkio/fb92d60/avatar.png" alt="trunk.io" height="96"></a></p><h3>Silver Sponsors</h3>
325
- <p><a href="https://vite.dev/"><img src="https://images.opencollective.com/vite/e6d15e1/logo.png" alt="Vite" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a> <a href="https://stackblitz.com"><img src="https://avatars.githubusercontent.com/u/28635252" alt="StackBlitz" height="64"></a></p><h3>Bronze Sponsors</h3>
325
+ <p><a href="https://qlty.sh/"><img src="https://images.opencollective.com/qltysh/33d157d/logo.png" alt="Qlty Software" height="96"></a> <a href="https://trunk.io/"><img src="https://images.opencollective.com/trunkio/fb92d60/avatar.png" alt="trunk.io" height="96"></a> <a href="https://shopify.engineering/"><img src="https://avatars.githubusercontent.com/u/8085" alt="Shopify" height="96"></a></p><h3>Silver Sponsors</h3>
326
+ <p><a href="https://vite.dev/"><img src="https://images.opencollective.com/vite/e6d15e1/logo.png" alt="Vite" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/5c4fa84/logo.png" alt="Liftoff" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301" alt="American Express" height="64"></a> <a href="https://stackblitz.com"><img src="https://avatars.githubusercontent.com/u/28635252" alt="StackBlitz" height="64"></a></p><h3>Bronze Sponsors</h3>
326
327
  <p><a href="https://cybozu.co.jp/"><img src="https://images.opencollective.com/cybozu/933e46d/logo.png" alt="Cybozu" 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://icons8.com/"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8" 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://www.gitbook.com"><img src="https://avatars.githubusercontent.com/u/7111340" alt="GitBook" height="32"></a> <a href="https://nolebase.ayaka.io"><img src="https://avatars.githubusercontent.com/u/11081491" alt="Neko" height="32"></a> <a href="https://nx.dev"><img src="https://avatars.githubusercontent.com/u/23692104" alt="Nx" height="32"></a> <a href="https://opensource.mercedes-benz.com/"><img src="https://avatars.githubusercontent.com/u/34240465" alt="Mercedes-Benz Group" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774" alt="HeroCoders" height="32"></a> <a href="https://www.lambdatest.com"><img src="https://avatars.githubusercontent.com/u/171592363" alt="LambdaTest" height="32"></a></p>
327
328
  <h3>Technology Sponsors</h3>
328
329
  Technology sponsors allow us to use their products and services for free as part of a contribution to the open source ecosystem and our work.
@@ -182,7 +182,7 @@ function pageTemplate(it) {
182
182
  /**
183
183
  * Given a word and a count, append an s if count is not one.
184
184
  * @param {string} word A word in its singular form.
185
- * @param {int} count A number controlling whether word should be pluralized.
185
+ * @param {number} count A number controlling whether word should be pluralized.
186
186
  * @returns {string} The original word with an s on the end if count is not one.
187
187
  */
188
188
  function pluralize(word, count) {
@@ -209,7 +209,7 @@ function renderSummary(totalErrors, totalWarnings) {
209
209
  * Get the color based on whether there are errors/warnings...
210
210
  * @param {string} totalErrors Total errors
211
211
  * @param {string} totalWarnings Total warnings
212
- * @returns {int} The color code (0 = green, 1 = yellow, 2 = red)
212
+ * @returns {number} The color code (0 = green, 1 = yellow, 2 = red)
213
213
  */
214
214
  function renderColor(totalErrors, totalWarnings) {
215
215
  if (totalErrors !== 0) {
@@ -253,7 +253,7 @@ function messageTemplate(it) {
253
253
  /**
254
254
  * Get HTML (table rows) describing the messages.
255
255
  * @param {Array} messages Messages.
256
- * @param {int} parentIndex Index of the parent HTML row.
256
+ * @param {number} parentIndex Index of the parent HTML row.
257
257
  * @param {Object} rulesMeta Dictionary containing metadata for each rule executed by the analysis.
258
258
  * @returns {string} HTML (table rows) describing the messages.
259
259
  */
@@ -15,7 +15,7 @@ const chalk = require("chalk"),
15
15
  /**
16
16
  * Given a word and a count, append an s if count is not one.
17
17
  * @param {string} word A word in its singular form.
18
- * @param {int} count A number controlling whether word should be pluralized.
18
+ * @param {number} count A number controlling whether word should be pluralized.
19
19
  * @returns {string} The original word with an s on the end if count is not one.
20
20
  */
21
21
  function pluralize(word, count) {
@@ -511,8 +511,8 @@ class SourceCode extends TokenStore {
511
511
  /**
512
512
  * Gets the source code for the given node.
513
513
  * @param {ASTNode} [node] The AST node to get the text for.
514
- * @param {int} [beforeCount] The number of characters before the node to retrieve.
515
- * @param {int} [afterCount] The number of characters after the node to retrieve.
514
+ * @param {number} [beforeCount] The number of characters before the node to retrieve.
515
+ * @param {number} [afterCount] The number of characters after the node to retrieve.
516
516
  * @returns {string} The text representing the AST node.
517
517
  * @public
518
518
  */
@@ -627,7 +627,7 @@ class SourceCode extends TokenStore {
627
627
 
628
628
  /**
629
629
  * Gets the deepest node containing a range index.
630
- * @param {int} index Range index of the desired node.
630
+ * @param {number} index Range index of the desired node.
631
631
  * @returns {ASTNode} The node if found or null if not found.
632
632
  * @public
633
633
  */
@@ -605,8 +605,8 @@ module.exports = class TokenStore {
605
605
  /**
606
606
  * Gets all tokens that are related to the given node.
607
607
  * @param {ASTNode} node The AST node.
608
- * @param {int} [beforeCount=0] The number of tokens before the node to retrieve.
609
- * @param {int} [afterCount=0] The number of tokens after the node to retrieve.
608
+ * @param {number} [beforeCount=0] The number of tokens before the node to retrieve.
609
+ * @param {number} [afterCount=0] The number of tokens after the node to retrieve.
610
610
  * @returns {Token[]} Array of objects representing tokens.
611
611
  */
612
612
  getTokens(node, beforeCount, afterCount) {
@@ -635,7 +635,7 @@ module.exports = class TokenStore {
635
635
  * Gets all of the tokens between two non-overlapping nodes.
636
636
  * @param {ASTNode|Token|Comment} left Node before the desired token range.
637
637
  * @param {ASTNode|Token|Comment} right Node after the desired token range.
638
- * @param {int} [padding=0] Number of extra tokens on either side of center.
638
+ * @param {number} [padding=0] Number of extra tokens on either side of center.
639
639
  * @returns {Token[]} Tokens between left and right.
640
640
  */
641
641
  getTokensBetween(left, right, padding) {
@@ -346,11 +346,13 @@ class NodeEventGenerator {
346
346
  * @returns {void}
347
347
  */
348
348
  applySelectors(node, isExit) {
349
+ const nodeTypeKey = this.esqueryOptions?.nodeTypeKey || "type";
350
+
349
351
  const selectorsByNodeType =
350
352
  (isExit
351
353
  ? this.exitSelectorsByNodeType
352
354
  : this.enterSelectorsByNodeType
353
- ).get(node.type) || [];
355
+ ).get(node[nodeTypeKey]) || [];
354
356
  const anyTypeSelectors = isExit
355
357
  ? this.anyTypeExitSelectors
356
358
  : this.anyTypeEnterSelectors;
@@ -133,7 +133,7 @@ function assertValidFix(fix) {
133
133
  * Compares items in a fixes array by range.
134
134
  * @param {Fix} a The first message.
135
135
  * @param {Fix} b The second message.
136
- * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal.
136
+ * @returns {number} -1 if a comes before b, 1 if a comes after b, 0 if equal.
137
137
  * @private
138
138
  */
139
139
  function compareFixesByRange(a, b) {
@@ -4,6 +4,14 @@
4
4
  */
5
5
  "use strict";
6
6
 
7
+ //------------------------------------------------------------------------------
8
+ // Typedefs
9
+ //------------------------------------------------------------------------------
10
+
11
+ /**
12
+ * @import { SourceRange } from "@eslint/core";
13
+ */
14
+
7
15
  /* eslint class-methods-use-this: off -- Methods desired on instance */
8
16
 
9
17
  //------------------------------------------------------------------------------
@@ -18,7 +26,7 @@
18
26
 
19
27
  /**
20
28
  * Creates a fix command that inserts text at the specified index in the source text.
21
- * @param {int} index The 0-based index at which to insert the new text.
29
+ * @param {number} index The 0-based index at which to insert the new text.
22
30
  * @param {string} text The text to insert.
23
31
  * @returns {Object} The fix command.
24
32
  * @private
@@ -69,7 +77,7 @@ class RuleFixer {
69
77
  /**
70
78
  * Creates a fix command that inserts text after the specified range in the source text.
71
79
  * The fix is not applied until applyFixes() is called.
72
- * @param {int[]} range The range to replace, first item is start of range, second
80
+ * @param {SourceRange} range The range to replace, first item is start of range, second
73
81
  * is end of range.
74
82
  * @param {string} text The text to insert.
75
83
  * @returns {Object} The fix command.
@@ -94,7 +102,7 @@ class RuleFixer {
94
102
  /**
95
103
  * Creates a fix command that inserts text before the specified range in the source text.
96
104
  * The fix is not applied until applyFixes() is called.
97
- * @param {int[]} range The range to replace, first item is start of range, second
105
+ * @param {SourceRange} range The range to replace, first item is start of range, second
98
106
  * is end of range.
99
107
  * @param {string} text The text to insert.
100
108
  * @returns {Object} The fix command.
@@ -119,7 +127,7 @@ class RuleFixer {
119
127
  /**
120
128
  * Creates a fix command that replaces text at the specified range in the source text.
121
129
  * The fix is not applied until applyFixes() is called.
122
- * @param {int[]} range The range to replace, first item is start of range, second
130
+ * @param {SourceRange} range The range to replace, first item is start of range, second
123
131
  * is end of range.
124
132
  * @param {string} text The text to insert.
125
133
  * @returns {Object} The fix command.
@@ -146,7 +154,7 @@ class RuleFixer {
146
154
  /**
147
155
  * Creates a fix command that removes the specified range of text from the source.
148
156
  * The fix is not applied until applyFixes() is called.
149
- * @param {int[]} range The range to remove, first item is start of range, second
157
+ * @param {SourceRange} range The range to remove, first item is start of range, second
150
158
  * is end of range.
151
159
  * @returns {Object} The fix command.
152
160
  */
@@ -20,7 +20,7 @@ const BOM = "\uFEFF";
20
20
  * Compares items in a messages array by range.
21
21
  * @param {Message} a The first message.
22
22
  * @param {Message} b The second message.
23
- * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal.
23
+ * @returns {number} -1 if a comes before b, 1 if a comes after b, 0 if equal.
24
24
  * @private
25
25
  */
26
26
  function compareMessagesByFixRange(a, b) {
@@ -31,7 +31,7 @@ function compareMessagesByFixRange(a, b) {
31
31
  * Compares items in a messages array by line and column.
32
32
  * @param {Message} a The first message.
33
33
  * @param {Message} b The second message.
34
- * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal.
34
+ * @returns {number} -1 if a comes before b, 1 if a comes after b, 0 if equal.
35
35
  * @private
36
36
  */
37
37
  function compareMessagesByLocation(a, b) {
@@ -15,7 +15,7 @@ const { startTime, endTime } = require("../shared/stats");
15
15
  /**
16
16
  * Align the string to left
17
17
  * @param {string} str string to evaluate
18
- * @param {int} len length of the string
18
+ * @param {number} len length of the string
19
19
  * @param {string} ch delimiter character
20
20
  * @returns {string} modified string
21
21
  * @private
@@ -28,7 +28,7 @@ function alignLeft(str, len, ch) {
28
28
  /**
29
29
  * Align the string to right
30
30
  * @param {string} str string to evaluate
31
- * @param {int} len length of the string
31
+ * @param {number} len length of the string
32
32
  * @param {string} ch delimiter character
33
33
  * @returns {string} modified string
34
34
  * @private
@@ -54,8 +54,8 @@ module.exports = {
54
54
  /**
55
55
  * check the right side of the assignment
56
56
  * @param {ASTNode} update UpdateExpression to check
57
- * @param {int} dir expected direction that could either be turned around or invalidated
58
- * @returns {int} return dir, the negated dir, or zero if the counter does not change or the direction is not clear
57
+ * @param {number} dir expected direction that could either be turned around or invalidated
58
+ * @returns {number} return dir, the negated dir, or zero if the counter does not change or the direction is not clear
59
59
  */
60
60
  function getRightDirection(update, dir) {
61
61
  const staticValue = getStaticValue(
@@ -80,7 +80,7 @@ module.exports = {
80
80
  * check UpdateExpression add/sub the counter
81
81
  * @param {ASTNode} update UpdateExpression to check
82
82
  * @param {string} counter variable name to check
83
- * @returns {int} if add return 1, if sub return -1, if nochange, return 0
83
+ * @returns {number} if add return 1, if sub return -1, if nochange, return 0
84
84
  */
85
85
  function getUpdateDirection(update, counter) {
86
86
  if (
@@ -101,7 +101,7 @@ module.exports = {
101
101
  * check AssignmentExpression add/sub the counter
102
102
  * @param {ASTNode} update AssignmentExpression to check
103
103
  * @param {string} counter variable name to check
104
- * @returns {int} if add return 1, if sub return -1, if nochange, return 0
104
+ * @returns {number} if add return 1, if sub return -1, if nochange, return 0
105
105
  */
106
106
  function getAssignmentDirection(update, counter) {
107
107
  if (update.left.name === counter) {
@@ -49,7 +49,7 @@ function isModuleExports(pattern) {
49
49
  /**
50
50
  * Determines if a string name is a valid identifier
51
51
  * @param {string} name The string to be checked
52
- * @param {int} ecmaVersion The ECMAScript version if specified in the parserOptions config
52
+ * @param {number} ecmaVersion The ECMAScript version if specified in the parserOptions config
53
53
  * @returns {boolean} True if the string is a valid identifier
54
54
  */
55
55
  function isIdentifier(name, ecmaVersion) {
@@ -302,9 +302,9 @@ module.exports = {
302
302
 
303
303
  /**
304
304
  * Creates an error message for a line, given the expected/actual indentation.
305
- * @param {int} expectedAmount The expected amount of indentation characters for this line
306
- * @param {int} actualSpaces The actual number of indentation spaces that were found on this line
307
- * @param {int} actualTabs The actual number of indentation tabs that were found on this line
305
+ * @param {number} expectedAmount The expected amount of indentation characters for this line
306
+ * @param {number} actualSpaces The actual number of indentation spaces that were found on this line
307
+ * @param {number} actualTabs The actual number of indentation tabs that were found on this line
308
308
  * @returns {string} An error message for this line
309
309
  */
310
310
  function createErrorMessageData(
@@ -345,9 +345,9 @@ module.exports = {
345
345
  /**
346
346
  * Reports a given indent violation
347
347
  * @param {ASTNode} node Node violating the indent rule
348
- * @param {int} needed Expected indentation character count
349
- * @param {int} gottenSpaces Indentation space count in the actual node/code
350
- * @param {int} gottenTabs Indentation tab count in the actual node/code
348
+ * @param {number} needed Expected indentation character count
349
+ * @param {number} gottenSpaces Indentation space count in the actual node/code
350
+ * @param {number} gottenTabs Indentation tab count in the actual node/code
351
351
  * @param {Object} [loc] Error line and column location
352
352
  * @param {boolean} isLastNodeCheck Is the error for last node check
353
353
  * @returns {void}
@@ -449,7 +449,7 @@ module.exports = {
449
449
  /**
450
450
  * Check indent for node
451
451
  * @param {ASTNode} node Node to check
452
- * @param {int} neededIndent needed indent
452
+ * @param {number} neededIndent needed indent
453
453
  * @returns {void}
454
454
  */
455
455
  function checkNodeIndent(node, neededIndent) {
@@ -502,7 +502,7 @@ module.exports = {
502
502
  /**
503
503
  * Check indent for nodes list
504
504
  * @param {ASTNode[]} nodes list of node objects
505
- * @param {int} indent needed indent
505
+ * @param {number} indent needed indent
506
506
  * @returns {void}
507
507
  */
508
508
  function checkNodesIndent(nodes, indent) {
@@ -512,7 +512,7 @@ module.exports = {
512
512
  /**
513
513
  * Check last node line indent this detects, that block closed correctly
514
514
  * @param {ASTNode} node Node to examine
515
- * @param {int} lastLineIndent needed indent
515
+ * @param {number} lastLineIndent needed indent
516
516
  * @returns {void}
517
517
  */
518
518
  function checkLastNodeLineIndent(node, lastLineIndent) {
@@ -542,7 +542,7 @@ module.exports = {
542
542
  * Check last node line indent this detects, that block closed correctly
543
543
  * This function for more complicated return statement case, where closing parenthesis may be followed by ';'
544
544
  * @param {ASTNode} node Node to examine
545
- * @param {int} firstLineIndent first line needed indent
545
+ * @param {number} firstLineIndent first line needed indent
546
546
  * @returns {void}
547
547
  */
548
548
  function checkLastReturnStatementLineIndent(node, firstLineIndent) {
@@ -583,7 +583,7 @@ module.exports = {
583
583
  /**
584
584
  * Check first node line indent is correct
585
585
  * @param {ASTNode} node Node to examine
586
- * @param {int} firstLineIndent needed indent
586
+ * @param {number} firstLineIndent needed indent
587
587
  * @returns {void}
588
588
  */
589
589
  function checkFirstNodeLineIndent(node, firstLineIndent) {
@@ -1130,8 +1130,8 @@ module.exports = {
1130
1130
  /**
1131
1131
  * Returns the expected indentation for the case statement
1132
1132
  * @param {ASTNode} node node to examine
1133
- * @param {int} [providedSwitchIndent] indent for switch statement
1134
- * @returns {int} indent size
1133
+ * @param {number} [providedSwitchIndent] indent for switch statement
1134
+ * @returns {number} indent size
1135
1135
  */
1136
1136
  function expectedCaseIndent(node, providedSwitchIndent) {
1137
1137
  const switchNode =
@@ -743,9 +743,9 @@ module.exports = {
743
743
 
744
744
  /**
745
745
  * Creates an error message for a line, given the expected/actual indentation.
746
- * @param {int} expectedAmount The expected amount of indentation characters for this line
747
- * @param {int} actualSpaces The actual number of indentation spaces that were found on this line
748
- * @param {int} actualTabs The actual number of indentation tabs that were found on this line
746
+ * @param {number} expectedAmount The expected amount of indentation characters for this line
747
+ * @param {number} actualSpaces The actual number of indentation spaces that were found on this line
748
+ * @param {number} actualTabs The actual number of indentation tabs that were found on this line
749
749
  * @returns {string} An error message for this line
750
750
  */
751
751
  function createErrorMessageData(
@@ -489,7 +489,7 @@ module.exports = {
489
489
  * @param {ASTNode} property Key-value pair in an object literal.
490
490
  * @param {string} side Side being verified - either "key" or "value".
491
491
  * @param {string} whitespace Actual whitespace string.
492
- * @param {int} expected Expected whitespace length.
492
+ * @param {number} expected Expected whitespace length.
493
493
  * @param {string} mode Value of the mode as "strict" or "minimum"
494
494
  * @returns {void}
495
495
  */
@@ -591,7 +591,7 @@ module.exports = {
591
591
  * Gets the number of characters in a key, including quotes around string
592
592
  * keys and braces around computed property keys.
593
593
  * @param {ASTNode} property Property of on object literal.
594
- * @returns {int} Width of the key.
594
+ * @returns {number} Width of the key.
595
595
  */
596
596
  function getKeyWidth(property) {
597
597
  const startToken = sourceCode.getFirstToken(property);
@@ -6,6 +6,14 @@
6
6
 
7
7
  "use strict";
8
8
 
9
+ //------------------------------------------------------------------------------
10
+ // Typedefs
11
+ //------------------------------------------------------------------------------
12
+
13
+ /**
14
+ * @import { SourceRange } from "@eslint/core";
15
+ */
16
+
9
17
  //------------------------------------------------------------------------------
10
18
  // Requirements
11
19
  //------------------------------------------------------------------------------
@@ -70,7 +78,7 @@ module.exports = {
70
78
 
71
79
  /**
72
80
  * Builds a fix function that replaces text at the specified range in the source text.
73
- * @param {int[]} range The range to replace
81
+ * @param {SourceRange} range The range to replace
74
82
  * @param {string} text The text to insert.
75
83
  * @returns {Function} Fixer function
76
84
  * @private
@@ -125,8 +125,8 @@ module.exports = {
125
125
  * Computes the length of a line that may contain tabs. The width of each
126
126
  * tab will be the number of spaces to the next tab stop.
127
127
  * @param {string} line The line.
128
- * @param {int} tabWidth The width of each tab stop in spaces.
129
- * @returns {int} The computed line length.
128
+ * @param {number} tabWidth The width of each tab stop in spaces.
129
+ * @returns {number} The computed line length.
130
130
  * @private
131
131
  */
132
132
  function computeLineLength(line, tabWidth) {
@@ -92,8 +92,8 @@ module.exports = {
92
92
  /**
93
93
  * Reports a node if it has too many statements
94
94
  * @param {ASTNode} node node to evaluate
95
- * @param {int} count Number of statements in node
96
- * @param {int} max Maximum number of statements allowed
95
+ * @param {number} count Number of statements in node
96
+ * @param {number} max Maximum number of statements allowed
97
97
  * @returns {void}
98
98
  * @private
99
99
  */
@@ -26,6 +26,10 @@ const ALLOW_OPTIONS = Object.freeze([
26
26
  "constructors",
27
27
  "asyncFunctions",
28
28
  "asyncMethods",
29
+ "privateConstructors",
30
+ "protectedConstructors",
31
+ "decoratedFunctions",
32
+ "overrideMethods",
29
33
  ]);
30
34
 
31
35
  /**
@@ -83,6 +87,15 @@ function getKind(node) {
83
87
  return prefix + kind[0].toUpperCase() + kind.slice(1);
84
88
  }
85
89
 
90
+ /**
91
+ * Checks if a constructor function has parameter properties.
92
+ * @param {ASTNode} node The function node to examine.
93
+ * @returns {boolean} True if the constructor has parameter properties, false otherwise.
94
+ */
95
+ function isParameterPropertiesConstructor(node) {
96
+ return node.params.some(param => param.type === "TSParameterProperty");
97
+ }
98
+
86
99
  //------------------------------------------------------------------------------
87
100
  // Rule Definition
88
101
  //------------------------------------------------------------------------------
@@ -90,6 +103,8 @@ function getKind(node) {
90
103
  /** @type {import('../types').Rule.RuleModule} */
91
104
  module.exports = {
92
105
  meta: {
106
+ dialects: ["javascript", "typescript"],
107
+ language: "javascript",
93
108
  type: "suggestion",
94
109
 
95
110
  defaultOptions: [{ allow: [] }],
@@ -123,6 +138,43 @@ module.exports = {
123
138
  const [{ allow }] = context.options;
124
139
  const sourceCode = context.sourceCode;
125
140
 
141
+ /**
142
+ * Checks if the given function node is allowed to be empty.
143
+ * @param {ASTNode} node The function node to check.
144
+ * @returns {boolean} True if the function is allowed to be empty, false otherwise.
145
+ */
146
+ function isAllowedEmptyFunction(node) {
147
+ const kind = getKind(node);
148
+
149
+ if (allow.includes(kind)) {
150
+ return true;
151
+ }
152
+
153
+ if (kind === "constructors") {
154
+ if (
155
+ (node.parent.accessibility === "private" &&
156
+ allow.includes("privateConstructors")) ||
157
+ (node.parent.accessibility === "protected" &&
158
+ allow.includes("protectedConstructors")) ||
159
+ isParameterPropertiesConstructor(node)
160
+ ) {
161
+ return true;
162
+ }
163
+ }
164
+
165
+ if (/(g|s)etters|methods$/iu.test(kind)) {
166
+ if (
167
+ (node.parent.decorators?.length &&
168
+ allow.includes("decoratedFunctions")) ||
169
+ (node.parent.override && allow.includes("overrideMethods"))
170
+ ) {
171
+ return true;
172
+ }
173
+ }
174
+
175
+ return false;
176
+ }
177
+
126
178
  /**
127
179
  * Reports a given function node if the node matches the following patterns.
128
180
  *
@@ -135,7 +187,6 @@ module.exports = {
135
187
  * @returns {void}
136
188
  */
137
189
  function reportIfEmpty(node) {
138
- const kind = getKind(node);
139
190
  const name = astUtils.getFunctionNameWithKind(node);
140
191
  const innerComments = sourceCode.getTokens(node.body, {
141
192
  includeComments: true,
@@ -143,7 +194,7 @@ module.exports = {
143
194
  });
144
195
 
145
196
  if (
146
- !allow.includes(kind) &&
197
+ !isAllowedEmptyFunction(node) &&
147
198
  node.body.type === "BlockStatement" &&
148
199
  node.body.body.length === 0 &&
149
200
  innerComments.length === 0
@@ -50,7 +50,7 @@ module.exports = {
50
50
  /**
51
51
  * Reports write references.
52
52
  * @param {Reference} reference A reference to check.
53
- * @param {int} index The index of the reference in the references.
53
+ * @param {number} index The index of the reference in the references.
54
54
  * @param {Reference[]} references The array that the reference belongs to.
55
55
  * @returns {void}
56
56
  */
@@ -36,6 +36,8 @@ function isCodePathWithLexicalThis(codePath, node) {
36
36
  /** @type {import('../types').Rule.RuleModule} */
37
37
  module.exports = {
38
38
  meta: {
39
+ dialects: ["javascript", "typescript"],
40
+ language: "javascript",
39
41
  type: "suggestion",
40
42
 
41
43
  defaultOptions: [{ capIsConstructor: true }],
@@ -140,8 +142,28 @@ module.exports = {
140
142
  stack.pop();
141
143
  },
142
144
 
145
+ "AccessorProperty > *.value"(node) {
146
+ stack.push({
147
+ init: true,
148
+ node,
149
+ valid: true,
150
+ });
151
+ },
152
+
153
+ "AccessorProperty:exit"() {
154
+ stack.pop();
155
+ },
156
+
143
157
  // Reports if `this` of the current context is invalid.
144
158
  ThisExpression(node) {
159
+ // Special case: skip `this` if it's the value of an AccessorProperty
160
+ if (
161
+ node.parent.type === "AccessorProperty" &&
162
+ node.parent.value === node
163
+ ) {
164
+ return;
165
+ }
166
+
145
167
  const current = stack.getCurrent();
146
168
 
147
169
  if (current && !current.valid) {
@@ -32,6 +32,8 @@ function isIIFE(node) {
32
32
  module.exports = {
33
33
  meta: {
34
34
  type: "suggestion",
35
+ dialects: ["typescript", "javascript"],
36
+ language: "javascript",
35
37
 
36
38
  docs: {
37
39
  description:
@@ -65,7 +65,7 @@ module.exports = {
65
65
  /**
66
66
  * Reports write references.
67
67
  * @param {Reference} reference A reference to check.
68
- * @param {int} index The index of the reference in the references.
68
+ * @param {number} index The index of the reference in the references.
69
69
  * @param {Reference[]} references The array that the reference belongs to.
70
70
  * @returns {void}
71
71
  */
@@ -5,6 +5,14 @@
5
5
 
6
6
  "use strict";
7
7
 
8
+ //------------------------------------------------------------------------------
9
+ // Typedefs
10
+ //------------------------------------------------------------------------------
11
+
12
+ /**
13
+ * @import { SourceRange } from "@eslint/core";
14
+ */
15
+
8
16
  //------------------------------------------------------------------------------
9
17
  // Helpers
10
18
  //------------------------------------------------------------------------------
@@ -57,7 +65,7 @@ module.exports = {
57
65
  /**
58
66
  * Creates a new Suggestion object.
59
67
  * @param {string} messageId "refactor" or "escapeBackslash".
60
- * @param {int[]} range The range to replace.
68
+ * @param {SourceRange} range The range to replace.
61
69
  * @param {string} replacement New text for the range.
62
70
  * @returns {Object} Suggestion
63
71
  */
@@ -182,7 +182,7 @@ module.exports = {
182
182
  /**
183
183
  * Reports a reference if is non initializer and writable.
184
184
  * @param {Reference} reference A reference to check.
185
- * @param {int} index The index of the reference in the references.
185
+ * @param {number} index The index of the reference in the references.
186
186
  * @param {Reference[]} references The array that the reference belongs to.
187
187
  * @returns {void}
188
188
  */
@@ -25,41 +25,37 @@ module.exports = {
25
25
  schema: {
26
26
  type: "array",
27
27
  items: {
28
+ type: "object",
29
+ properties: {
30
+ object: {
31
+ type: "string",
32
+ },
33
+ property: {
34
+ type: "string",
35
+ },
36
+ allowObjects: {
37
+ type: "array",
38
+ items: {
39
+ type: "string",
40
+ },
41
+ uniqueItems: true,
42
+ },
43
+ message: {
44
+ type: "string",
45
+ },
46
+ },
28
47
  anyOf: [
29
- // `object` and `property` are both optional, but at least one of them must be provided.
30
48
  {
31
- type: "object",
32
- properties: {
33
- object: {
34
- type: "string",
35
- },
36
- property: {
37
- type: "string",
38
- },
39
- message: {
40
- type: "string",
41
- },
42
- },
43
- additionalProperties: false,
44
49
  required: ["object"],
45
50
  },
46
51
  {
47
- type: "object",
48
- properties: {
49
- object: {
50
- type: "string",
51
- },
52
- property: {
53
- type: "string",
54
- },
55
- message: {
56
- type: "string",
57
- },
58
- },
59
- additionalProperties: false,
60
52
  required: ["property"],
61
53
  },
62
54
  ],
55
+ not: {
56
+ required: ["allowObjects", "object"],
57
+ },
58
+ additionalProperties: false,
63
59
  },
64
60
  uniqueItems: true,
65
61
  },
@@ -91,6 +87,7 @@ module.exports = {
91
87
 
92
88
  if (typeof objectName === "undefined") {
93
89
  globallyRestrictedProperties.set(propertyName, {
90
+ allowObjects: option.allowObjects,
94
91
  message: option.message,
95
92
  });
96
93
  } else if (typeof propertyName === "undefined") {
@@ -108,6 +105,20 @@ module.exports = {
108
105
  }
109
106
  });
110
107
 
108
+ /**
109
+ * Checks if an object name is in the allowed objects list.
110
+ * @param {string} objectName The name of the object to check
111
+ * @param {string[]} [allowObjects] The list of objects to allow
112
+ * @returns {boolean} True if the object is allowed, false otherwise
113
+ */
114
+ function isAllowedObject(objectName, allowObjects) {
115
+ if (!allowObjects) {
116
+ return false;
117
+ }
118
+
119
+ return allowObjects.includes(objectName);
120
+ }
121
+
111
122
  /**
112
123
  * Checks to see whether a property access is restricted, and reports it if so.
113
124
  * @param {ASTNode} node The node to report
@@ -140,7 +151,10 @@ module.exports = {
140
151
  message,
141
152
  },
142
153
  });
143
- } else if (globalMatchedProperty) {
154
+ } else if (
155
+ globalMatchedProperty &&
156
+ !isAllowedObject(objectName, globalMatchedProperty.allowObjects)
157
+ ) {
144
158
  const message = globalMatchedProperty.message
145
159
  ? ` ${globalMatchedProperty.message}`
146
160
  : "";
@@ -30,7 +30,6 @@ module.exports = {
30
30
  deprecated: {
31
31
  message:
32
32
  "The original assumption of the rule no longer holds true because of engine optimization.",
33
- url: "https://eslint.org/docs/latest/rules/no-return-await",
34
33
  deprecatedSince: "8.46.0",
35
34
  availableUntil: null,
36
35
  replacedBy: [],
@@ -5,6 +5,14 @@
5
5
  */
6
6
  "use strict";
7
7
 
8
+ //------------------------------------------------------------------------------
9
+ // Typedefs
10
+ //------------------------------------------------------------------------------
11
+
12
+ /**
13
+ * @import { SourceLocation, SourceRange } from "@eslint/core";
14
+ */
15
+
8
16
  //------------------------------------------------------------------------------
9
17
  // Requirements
10
18
  //------------------------------------------------------------------------------
@@ -85,8 +93,8 @@ module.exports = {
85
93
  /**
86
94
  * Report the error message
87
95
  * @param {ASTNode} node node to report
88
- * @param {int[]} location range information
89
- * @param {int[]} fixRange Range based on the whole program
96
+ * @param {SourceLocation} location range information
97
+ * @param {SourceRange} fixRange Range based on the whole program
90
98
  * @returns {void}
91
99
  */
92
100
  function report(node, location, fixRange) {
@@ -29,6 +29,8 @@ function alwaysFalse() {
29
29
  /** @type {import('../types').Rule.RuleModule} */
30
30
  module.exports = {
31
31
  meta: {
32
+ dialects: ["javascript", "typescript"],
33
+ language: "javascript",
32
34
  type: "suggestion",
33
35
 
34
36
  docs: {
@@ -190,6 +192,19 @@ module.exports = {
190
192
  UnaryExpression(node) {
191
193
  return node.operator !== "void" && node.operator !== "delete";
192
194
  },
195
+ // TypeScript-specific node types
196
+ TSAsExpression(node) {
197
+ return Checker.isDisallowed(node.expression);
198
+ },
199
+ TSTypeAssertion(node) {
200
+ return Checker.isDisallowed(node.expression);
201
+ },
202
+ TSNonNullExpression(node) {
203
+ return Checker.isDisallowed(node.expression);
204
+ },
205
+ TSInstantiationExpression(node) {
206
+ return Checker.isDisallowed(node.expression);
207
+ },
193
208
  });
194
209
 
195
210
  return {
@@ -22,7 +22,6 @@ module.exports = {
22
22
 
23
23
  deprecated: {
24
24
  message: "The original intention of this rule was misguided.",
25
- url: "https://eslint.org/docs/latest/rules/prefer-reflect",
26
25
  deprecatedSince: "3.9.0",
27
26
  availableUntil: null,
28
27
  replacedBy: [],
@@ -65,7 +65,7 @@ const ECMASCRIPT_GLOBALS = globals[`es${LATEST_ECMA_VERSION}`];
65
65
  /**
66
66
  * Checks reference if is non initializer and writable.
67
67
  * @param {Reference} reference A reference to check.
68
- * @param {int} index The index of the reference in the references.
68
+ * @param {number} index The index of the reference in the references.
69
69
  * @param {Reference[]} references The array that the reference belongs to.
70
70
  * @returns {boolean} Success/Failure
71
71
  * @private
@@ -1088,13 +1088,13 @@ function isConstant(scope, node, inBooleanPosition) {
1088
1088
  }
1089
1089
 
1090
1090
  /**
1091
- * Checks whether a node is an ExpressionStatement at the top level of a file or function body.
1091
+ * Checks whether a node is an ExpressionStatement at the top level of a file, function body, or TypeScript module block.
1092
1092
  * A top-level ExpressionStatement node is a directive if it contains a single unparenthesized
1093
1093
  * string literal and if it occurs either as the first sibling or immediately after another
1094
1094
  * directive.
1095
1095
  * @param {ASTNode} node The node to check.
1096
1096
  * @returns {boolean} Whether or not the node is an ExpressionStatement at the top level of a
1097
- * file or function body.
1097
+ * file, function body, or TypeScript module block.
1098
1098
  */
1099
1099
  function isTopLevelExpressionStatement(node) {
1100
1100
  if (node.type !== "ExpressionStatement") {
@@ -1104,6 +1104,7 @@ function isTopLevelExpressionStatement(node) {
1104
1104
 
1105
1105
  return (
1106
1106
  parent.type === "Program" ||
1107
+ parent.type === "TSModuleBlock" ||
1107
1108
  (parent.type === "BlockStatement" && isFunction(parent.parent))
1108
1109
  );
1109
1110
  }
@@ -1488,6 +1489,17 @@ module.exports = {
1488
1489
  return false;
1489
1490
  }
1490
1491
 
1492
+ // Check if the function has a parameter named `this`.
1493
+ if (
1494
+ (node.type === "FunctionDeclaration" ||
1495
+ node.type === "FunctionExpression") &&
1496
+ node.params.some(
1497
+ param => param.type === "Identifier" && param.name === "this",
1498
+ )
1499
+ ) {
1500
+ return false;
1501
+ }
1502
+
1491
1503
  if (
1492
1504
  (capIsConstructor && isES5Constructor(node)) ||
1493
1505
  hasJSDocThisTag(node, sourceCode)
@@ -1662,7 +1674,7 @@ module.exports = {
1662
1674
  /**
1663
1675
  * Get the precedence level based on the node type
1664
1676
  * @param {ASTNode} node node to evaluate
1665
- * @returns {int} precedence level
1677
+ * @returns {number} precedence level
1666
1678
  * @private
1667
1679
  */
1668
1680
  getPrecedence(node) {
@@ -4,6 +4,14 @@
4
4
  */
5
5
  "use strict";
6
6
 
7
+ //------------------------------------------------------------------------------
8
+ // Typedefs
9
+ //------------------------------------------------------------------------------
10
+
11
+ /**
12
+ * @import { SourceRange } from "@eslint/core";
13
+ */
14
+
7
15
  //------------------------------------------------------------------------------
8
16
  // Requirements
9
17
  //------------------------------------------------------------------------------
@@ -34,7 +42,7 @@ class FixTracker {
34
42
  /**
35
43
  * Mark the given range as "retained", meaning that other fixes may not
36
44
  * may not modify this region in the same pass.
37
- * @param {int[]} range The range to retain.
45
+ * @param {SourceRange} range The range to retain.
38
46
  * @returns {FixTracker} The same RuleFixer, for chained calls.
39
47
  */
40
48
  retainRange(range) {
@@ -79,7 +87,7 @@ class FixTracker {
79
87
  /**
80
88
  * Create a fix command that replaces the given range with the given text,
81
89
  * accounting for any retained ranges.
82
- * @param {int[]} range The range to remove in the fix.
90
+ * @param {SourceRange} range The range to remove in the fix.
83
91
  * @param {string} text The text to insert in place of the range.
84
92
  * @returns {Object} The fix command.
85
93
  */
@@ -1262,6 +1262,29 @@ export namespace Rule {
1262
1262
  }
1263
1263
  }
1264
1264
 
1265
+ export type JSRuleDefinitionTypeOptions = {
1266
+ RuleOptions: unknown[];
1267
+ MessageIds: string;
1268
+ ExtRuleDocs: Record<string, unknown>;
1269
+ };
1270
+
1271
+ export type JSRuleDefinition<
1272
+ Options extends Partial<JSRuleDefinitionTypeOptions> = {},
1273
+ > = RuleDefinition<
1274
+ // Language specific type options (non-configurable)
1275
+ {
1276
+ LangOptions: Linter.LanguageOptions;
1277
+ Code: SourceCode;
1278
+ Visitor: Rule.NodeListener;
1279
+ Node: ESTree.Node;
1280
+ } & Required<
1281
+ // Rule specific type options (custom)
1282
+ Options &
1283
+ // Rule specific type options (defaults)
1284
+ Omit<JSRuleDefinitionTypeOptions, keyof Options>
1285
+ >
1286
+ >;
1287
+
1265
1288
  // #region Linter
1266
1289
 
1267
1290
  export class Linter {
@@ -422,6 +422,15 @@ export interface ESLintRules extends Linter.RulesRecord {
422
422
  [
423
423
  Partial<{
424
424
  exceptMethods: string[];
425
+ /**
426
+ * @default true
427
+ */
428
+ enforceForClassFields: boolean;
429
+ /**
430
+ * @default false
431
+ */
432
+ ignoreOverrideMethods: boolean;
433
+ ignoreClassesWithImplements: "all" | "public-fields";
425
434
  }>,
426
435
  ]
427
436
  >;
@@ -2350,6 +2359,10 @@ export interface ESLintRules extends Linter.RulesRecord {
2350
2359
  | "constructors"
2351
2360
  | "asyncFunctions"
2352
2361
  | "asyncMethods"
2362
+ | "privateConstructors"
2363
+ | "protectedConstructors"
2364
+ | "decoratedFunctions"
2365
+ | "overrideMethods"
2353
2366
  >;
2354
2367
  }>,
2355
2368
  ]
@@ -3430,6 +3443,7 @@ export interface ESLintRules extends Linter.RulesRecord {
3430
3443
  }
3431
3444
  | {
3432
3445
  property: string;
3446
+ allowObjects?: string[];
3433
3447
  message?: string | undefined;
3434
3448
  }
3435
3449
  >,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint",
3
- "version": "9.24.0",
3
+ "version": "9.25.1",
4
4
  "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
5
5
  "description": "An AST-based pattern checker for JavaScript.",
6
6
  "type": "commonjs",
@@ -107,11 +107,11 @@
107
107
  "@eslint-community/eslint-utils": "^4.2.0",
108
108
  "@eslint-community/regexpp": "^4.12.1",
109
109
  "@eslint/config-array": "^0.20.0",
110
- "@eslint/config-helpers": "^0.2.0",
111
- "@eslint/core": "^0.12.0",
110
+ "@eslint/config-helpers": "^0.2.1",
111
+ "@eslint/core": "^0.13.0",
112
112
  "@eslint/eslintrc": "^3.3.1",
113
- "@eslint/js": "9.24.0",
114
- "@eslint/plugin-kit": "^0.2.7",
113
+ "@eslint/js": "9.25.1",
114
+ "@eslint/plugin-kit": "^0.2.8",
115
115
  "@humanfs/node": "^0.16.6",
116
116
  "@humanwhocodes/module-importer": "^1.0.1",
117
117
  "@humanwhocodes/retry": "^0.4.2",
@@ -146,7 +146,7 @@
146
146
  "@babel/preset-env": "^7.4.3",
147
147
  "@cypress/webpack-preprocessor": "^6.0.2",
148
148
  "@eslint/json": "^0.11.0",
149
- "@trunkio/launcher": "^1.3.0",
149
+ "@trunkio/launcher": "^1.3.4",
150
150
  "@types/node": "^22.13.14",
151
151
  "@typescript-eslint/parser": "^8.4.0",
152
152
  "babel-loader": "^8.0.5",