eslint 9.27.0 → 9.29.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 (37) hide show
  1. package/README.md +1 -1
  2. package/conf/ecma-version.js +1 -1
  3. package/conf/globals.js +10 -0
  4. package/lib/cli.js +20 -23
  5. package/lib/config/config-loader.js +32 -21
  6. package/lib/config/config.js +34 -11
  7. package/lib/eslint/eslint.js +18 -21
  8. package/lib/languages/js/source-code/source-code.js +104 -27
  9. package/lib/linter/apply-disable-directives.js +2 -4
  10. package/lib/linter/code-path-analysis/code-path-analyzer.js +8 -9
  11. package/lib/linter/linter.js +30 -61
  12. package/lib/linter/source-code-traverser.js +327 -0
  13. package/lib/linter/source-code-visitor.js +81 -0
  14. package/lib/options.js +7 -0
  15. package/lib/rules/class-methods-use-this.js +7 -0
  16. package/lib/rules/func-style.js +57 -7
  17. package/lib/rules/no-implicit-globals.js +31 -15
  18. package/lib/rules/no-magic-numbers.js +98 -5
  19. package/lib/rules/no-promise-executor-return.js +4 -35
  20. package/lib/rules/no-restricted-globals.js +35 -2
  21. package/lib/rules/no-restricted-properties.js +24 -10
  22. package/lib/rules/no-setter-return.js +13 -48
  23. package/lib/rules/no-shadow.js +262 -6
  24. package/lib/rules/no-unassigned-vars.js +14 -6
  25. package/lib/rules/no-use-before-define.js +99 -1
  26. package/lib/rules/no-var.js +14 -2
  27. package/lib/rules/prefer-arrow-callback.js +9 -0
  28. package/lib/rules/prefer-regex-literals.js +1 -18
  29. package/lib/services/suppressions-service.js +8 -0
  30. package/lib/services/warning-service.js +85 -0
  31. package/lib/shared/naming.js +109 -0
  32. package/lib/shared/relative-module-resolver.js +28 -0
  33. package/lib/types/index.d.ts +18 -7
  34. package/lib/types/rules.d.ts +52 -2
  35. package/package.json +12 -10
  36. package/lib/linter/node-event-generator.js +0 -256
  37. package/lib/linter/safe-emitter.js +0 -52
@@ -1,256 +0,0 @@
1
- /**
2
- * @fileoverview The event generator for AST nodes.
3
- * @author Toru Nagashima
4
- */
5
-
6
- "use strict";
7
-
8
- //------------------------------------------------------------------------------
9
- // Requirements
10
- //------------------------------------------------------------------------------
11
-
12
- const { parse, matches } = require("./esquery");
13
-
14
- //-----------------------------------------------------------------------------
15
- // Typedefs
16
- //-----------------------------------------------------------------------------
17
-
18
- /**
19
- * @import { ESQueryParsedSelector } from "./esquery.js";
20
- */
21
-
22
- //-----------------------------------------------------------------------------
23
- // Helpers
24
- //-----------------------------------------------------------------------------
25
-
26
- /**
27
- * Compares two ESQuery selectors by specificity.
28
- * @param {ESQueryParsedSelector} a The first selector to compare.
29
- * @param {ESQueryParsedSelector} b The second selector to compare.
30
- * @returns {number} A negative number if `a` is less specific than `b` or they are equally specific and `a` <= `b` alphabetically, a positive number if `a` is more specific than `b`.
31
- */
32
- function compareSpecificity(a, b) {
33
- return a.compare(b);
34
- }
35
-
36
- //------------------------------------------------------------------------------
37
- // Public Interface
38
- //------------------------------------------------------------------------------
39
-
40
- /**
41
- * The event generator for AST nodes.
42
- * This implements below interface.
43
- *
44
- * ```ts
45
- * interface EventGenerator {
46
- * emitter: SafeEmitter;
47
- * enterNode(node: ASTNode): void;
48
- * leaveNode(node: ASTNode): void;
49
- * }
50
- * ```
51
- */
52
- class NodeEventGenerator {
53
- /**
54
- * The emitter to use during traversal.
55
- * @type {SafeEmitter}
56
- */
57
- emitter;
58
-
59
- /**
60
- * The options for `esquery` to use during matching.
61
- * @type {ESQueryOptions}
62
- */
63
- esqueryOptions;
64
-
65
- /**
66
- * The ancestry of the currently visited node.
67
- * @type {ASTNode[]}
68
- */
69
- currentAncestry = [];
70
-
71
- /**
72
- * A map of node type to selectors targeting that node type on the
73
- * enter phase of traversal.
74
- * @type {Map<string, ESQueryParsedSelector[]>}
75
- */
76
- enterSelectorsByNodeType = new Map();
77
-
78
- /**
79
- * A map of node type to selectors targeting that node type on the
80
- * exit phase of traversal.
81
- * @type {Map<string, ESQueryParsedSelector[]>}
82
- */
83
- exitSelectorsByNodeType = new Map();
84
-
85
- /**
86
- * An array of selectors that match any node type on the
87
- * enter phase of traversal.
88
- * @type {ESQueryParsedSelector[]}
89
- */
90
- anyTypeEnterSelectors = [];
91
-
92
- /**
93
- * An array of selectors that match any node type on the
94
- * exit phase of traversal.
95
- * @type {ESQueryParsedSelector[]}
96
- */
97
- anyTypeExitSelectors = [];
98
-
99
- /**
100
- * @param {SafeEmitter} emitter
101
- * An SafeEmitter which is the destination of events. This emitter must already
102
- * have registered listeners for all of the events that it needs to listen for.
103
- * (See lib/linter/safe-emitter.js for more details on `SafeEmitter`.)
104
- * @param {ESQueryOptions} esqueryOptions `esquery` options for traversing custom nodes.
105
- * @returns {NodeEventGenerator} new instance
106
- */
107
- constructor(emitter, esqueryOptions) {
108
- this.emitter = emitter;
109
- this.esqueryOptions = esqueryOptions;
110
-
111
- emitter.eventNames().forEach(rawSelector => {
112
- const selector = parse(rawSelector);
113
-
114
- /*
115
- * If this selector has identified specific node types,
116
- * add it to the map for these node types for faster lookup.
117
- */
118
- if (selector.nodeTypes) {
119
- const typeMap = selector.isExit
120
- ? this.exitSelectorsByNodeType
121
- : this.enterSelectorsByNodeType;
122
-
123
- selector.nodeTypes.forEach(nodeType => {
124
- if (!typeMap.has(nodeType)) {
125
- typeMap.set(nodeType, []);
126
- }
127
- typeMap.get(nodeType).push(selector);
128
- });
129
- return;
130
- }
131
-
132
- /*
133
- * Remaining selectors are added to the "any type" selectors
134
- * list for the appropriate phase of traversal. This ensures
135
- * that all selectors will still be applied even if no
136
- * specific node type is matched.
137
- */
138
- const selectors = selector.isExit
139
- ? this.anyTypeExitSelectors
140
- : this.anyTypeEnterSelectors;
141
-
142
- selectors.push(selector);
143
- });
144
-
145
- // sort all selectors by specificity for prioritizing call order
146
- this.anyTypeEnterSelectors.sort(compareSpecificity);
147
- this.anyTypeExitSelectors.sort(compareSpecificity);
148
- this.enterSelectorsByNodeType.forEach(selectorList =>
149
- selectorList.sort(compareSpecificity),
150
- );
151
- this.exitSelectorsByNodeType.forEach(selectorList =>
152
- selectorList.sort(compareSpecificity),
153
- );
154
- }
155
-
156
- /**
157
- * Checks a selector against a node, and emits it if it matches
158
- * @param {ASTNode} node The node to check
159
- * @param {ESQueryParsedSelector} selector An AST selector descriptor
160
- * @returns {void}
161
- */
162
- applySelector(node, selector) {
163
- if (
164
- matches(
165
- node,
166
- selector.root,
167
- this.currentAncestry,
168
- this.esqueryOptions,
169
- )
170
- ) {
171
- this.emitter.emit(selector.source, node);
172
- }
173
- }
174
-
175
- /**
176
- * Applies all appropriate selectors to a node, in specificity order
177
- * @param {ASTNode} node The node to check
178
- * @param {boolean} isExit `false` if the node is currently being entered, `true` if it's currently being exited
179
- * @returns {void}
180
- */
181
- applySelectors(node, isExit) {
182
- const nodeTypeKey = this.esqueryOptions?.nodeTypeKey || "type";
183
-
184
- /*
185
- * Get the selectors that may match this node. First, check
186
- * to see if the node type has specific selectors,
187
- * then gather the "any type" selectors.
188
- */
189
- const selectorsByNodeType =
190
- (isExit
191
- ? this.exitSelectorsByNodeType
192
- : this.enterSelectorsByNodeType
193
- ).get(node[nodeTypeKey]) || [];
194
- const anyTypeSelectors = isExit
195
- ? this.anyTypeExitSelectors
196
- : this.anyTypeEnterSelectors;
197
-
198
- /*
199
- * selectorsByNodeType and anyTypeSelectors were already sorted by specificity in the constructor.
200
- * Iterate through each of them, applying selectors in the right order.
201
- */
202
- let selectorsByNodeTypeIndex = 0;
203
- let anyTypeSelectorsIndex = 0;
204
-
205
- while (
206
- selectorsByNodeTypeIndex < selectorsByNodeType.length ||
207
- anyTypeSelectorsIndex < anyTypeSelectors.length
208
- ) {
209
- /*
210
- * If we've already exhausted the selectors for this node type,
211
- * or if the next any type selector is more specific than the
212
- * next selector for this node type, apply the any type selector.
213
- */
214
- if (
215
- selectorsByNodeTypeIndex >= selectorsByNodeType.length ||
216
- (anyTypeSelectorsIndex < anyTypeSelectors.length &&
217
- anyTypeSelectors[anyTypeSelectorsIndex].compare(
218
- selectorsByNodeType[selectorsByNodeTypeIndex],
219
- ) < 0)
220
- ) {
221
- this.applySelector(
222
- node,
223
- anyTypeSelectors[anyTypeSelectorsIndex++],
224
- );
225
- } else {
226
- // otherwise apply the node type selector
227
- this.applySelector(
228
- node,
229
- selectorsByNodeType[selectorsByNodeTypeIndex++],
230
- );
231
- }
232
- }
233
- }
234
-
235
- /**
236
- * Emits an event of entering AST node.
237
- * @param {ASTNode} node A node which was entered.
238
- * @returns {void}
239
- */
240
- enterNode(node) {
241
- this.applySelectors(node, false);
242
- this.currentAncestry.unshift(node);
243
- }
244
-
245
- /**
246
- * Emits an event of leaving AST node.
247
- * @param {ASTNode} node A node which was left.
248
- * @returns {void}
249
- */
250
- leaveNode(node) {
251
- this.currentAncestry.shift();
252
- this.applySelectors(node, true);
253
- }
254
- }
255
-
256
- module.exports = NodeEventGenerator;
@@ -1,52 +0,0 @@
1
- /**
2
- * @fileoverview A variant of EventEmitter which does not give listeners information about each other
3
- * @author Teddy Katz
4
- */
5
-
6
- "use strict";
7
-
8
- //------------------------------------------------------------------------------
9
- // Typedefs
10
- //------------------------------------------------------------------------------
11
-
12
- /**
13
- * An event emitter
14
- * @typedef {Object} SafeEmitter
15
- * @property {(eventName: string, listenerFunc: Function) => void} on Adds a listener for a given event name
16
- * @property {(eventName: string, arg1?: any, arg2?: any, arg3?: any) => void} emit Emits an event with a given name.
17
- * This calls all the listeners that were listening for that name, with `arg1`, `arg2`, and `arg3` as arguments.
18
- * @property {function(): string[]} eventNames Gets the list of event names that have registered listeners.
19
- */
20
-
21
- /**
22
- * Creates an object which can listen for and emit events.
23
- * This is similar to the EventEmitter API in Node's standard library, but it has a few differences.
24
- * The goal is to allow multiple modules to attach arbitrary listeners to the same emitter, without
25
- * letting the modules know about each other at all.
26
- * 1. It has no special keys like `error` and `newListener`, which would allow modules to detect when
27
- * another module throws an error or registers a listener.
28
- * 2. It calls listener functions without any `this` value. (`EventEmitter` calls listeners with a
29
- * `this` value of the emitter instance, which would give listeners access to other listeners.)
30
- * @returns {SafeEmitter} An emitter
31
- */
32
- module.exports = () => {
33
- const listeners = Object.create(null);
34
-
35
- return Object.freeze({
36
- on(eventName, listener) {
37
- if (eventName in listeners) {
38
- listeners[eventName].push(listener);
39
- } else {
40
- listeners[eventName] = [listener];
41
- }
42
- },
43
- emit(eventName, ...args) {
44
- if (eventName in listeners) {
45
- listeners[eventName].forEach(listener => listener(...args));
46
- }
47
- },
48
- eventNames() {
49
- return Object.keys(listeners);
50
- },
51
- });
52
- };