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.
- package/README.md +1 -1
- package/conf/ecma-version.js +1 -1
- package/conf/globals.js +10 -0
- package/lib/cli.js +20 -23
- package/lib/config/config-loader.js +32 -21
- package/lib/config/config.js +34 -11
- package/lib/eslint/eslint.js +18 -21
- package/lib/languages/js/source-code/source-code.js +104 -27
- package/lib/linter/apply-disable-directives.js +2 -4
- package/lib/linter/code-path-analysis/code-path-analyzer.js +8 -9
- package/lib/linter/linter.js +30 -61
- package/lib/linter/source-code-traverser.js +327 -0
- package/lib/linter/source-code-visitor.js +81 -0
- package/lib/options.js +7 -0
- package/lib/rules/class-methods-use-this.js +7 -0
- package/lib/rules/func-style.js +57 -7
- package/lib/rules/no-implicit-globals.js +31 -15
- package/lib/rules/no-magic-numbers.js +98 -5
- package/lib/rules/no-promise-executor-return.js +4 -35
- package/lib/rules/no-restricted-globals.js +35 -2
- package/lib/rules/no-restricted-properties.js +24 -10
- package/lib/rules/no-setter-return.js +13 -48
- package/lib/rules/no-shadow.js +262 -6
- package/lib/rules/no-unassigned-vars.js +14 -6
- package/lib/rules/no-use-before-define.js +99 -1
- package/lib/rules/no-var.js +14 -2
- package/lib/rules/prefer-arrow-callback.js +9 -0
- package/lib/rules/prefer-regex-literals.js +1 -18
- package/lib/services/suppressions-service.js +8 -0
- package/lib/services/warning-service.js +85 -0
- package/lib/shared/naming.js +109 -0
- package/lib/shared/relative-module-resolver.js +28 -0
- package/lib/types/index.d.ts +18 -7
- package/lib/types/rules.d.ts +52 -2
- package/package.json +12 -10
- package/lib/linter/node-event-generator.js +0 -256
- 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
|
-
};
|