mm_eslint 1.4.3 → 1.4.5
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 +336 -0
- package/README_EN.md +336 -0
- package/config.js +626 -573
- package/corrector.js +375 -0
- package/detector.js +1040 -3413
- package/eslint.config.js +25 -0
- package/fix.js +441 -0
- package/handler.js +993 -0
- package/index.js +211 -1164
- package/package.json +59 -49
- package/tip.js +85 -0
- package/util.js +241 -0
- package/validator.js +266 -0
package/handler.js
ADDED
|
@@ -0,0 +1,993 @@
|
|
|
1
|
+
const { Detector } = require('./detector');
|
|
2
|
+
const { Fix } = require('./fix');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 规则处理器类
|
|
6
|
+
* 负责处理特定AST节点类型的检测逻辑
|
|
7
|
+
*/
|
|
8
|
+
class Handler {
|
|
9
|
+
/**
|
|
10
|
+
* 构造函数
|
|
11
|
+
* @param {object} config 配置对象
|
|
12
|
+
*/
|
|
13
|
+
constructor(config) {
|
|
14
|
+
this.config = config;
|
|
15
|
+
this.detector = new Detector(config);
|
|
16
|
+
this.fix = new Fix(config);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 处理类声明节点
|
|
23
|
+
* @param {object} context ESLint上下文
|
|
24
|
+
* @param {object} full_node 完整的AST节点
|
|
25
|
+
* @param {object} node AST节点
|
|
26
|
+
* @param {string} rule_type 规则类型
|
|
27
|
+
*/
|
|
28
|
+
handleClassDeclaration(context, full_node, node, rule_type) {
|
|
29
|
+
// 检测类名
|
|
30
|
+
if (node.id && node.id.type === 'Identifier') {
|
|
31
|
+
// 先检测节点类型
|
|
32
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
33
|
+
|
|
34
|
+
// 根据规则类型进行过滤
|
|
35
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
var result = this.detector.detect(node, node.id.name);
|
|
40
|
+
if (result) {
|
|
41
|
+
result.node = full_node;
|
|
42
|
+
result.fix = this.fix.createClassFixFunction(context, full_node, result);
|
|
43
|
+
context.report(result);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 检测继承的父类名
|
|
48
|
+
if (node.superClass && node.superClass.type === 'Identifier') {
|
|
49
|
+
// 父类名应该使用PascalCase
|
|
50
|
+
var parent_class_result = this.detector.detect(node, node.superClass.name);
|
|
51
|
+
if (parent_class_result) {
|
|
52
|
+
parent_class_result.node = full_node;
|
|
53
|
+
parent_class_result.fix = this.fix.createClassFixFunction(context, full_node, parent_class_result);
|
|
54
|
+
context.report(parent_class_result);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 处理变量声明节点
|
|
61
|
+
* @param {object} context ESLint上下文
|
|
62
|
+
* @param {object} full_node 完整的AST节点
|
|
63
|
+
* @param {object} node AST节点
|
|
64
|
+
* @param {string} rule_type 规则类型
|
|
65
|
+
*/
|
|
66
|
+
handleVariableDeclaration(context, full_node, node, rule_type) {
|
|
67
|
+
for (var i = 0; i < node.declarations.length; i++) {
|
|
68
|
+
var decl = node.declarations[i];
|
|
69
|
+
|
|
70
|
+
// 跳过解构赋值
|
|
71
|
+
if (decl.init && decl.init.type === 'ObjectPattern') {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 检测变量名
|
|
76
|
+
if (decl.id && decl.id.type === 'Identifier') {
|
|
77
|
+
// 先检测节点类型
|
|
78
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
79
|
+
|
|
80
|
+
// 根据规则类型进行过滤
|
|
81
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 使用detect方法,它会自动检测类型
|
|
86
|
+
var result = this.detector.detect(node, decl.id.name);
|
|
87
|
+
if (result) {
|
|
88
|
+
// 再次检查过滤条件,确保检测到的类型和规则匹配
|
|
89
|
+
if (this._shouldSkipDetection(rule_type, result.original_type)) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
result.node = full_node;
|
|
93
|
+
|
|
94
|
+
// 根据检测到的类型选择正确的修复函数
|
|
95
|
+
if (result.original_type === 'class' && decl.init && decl.init.type === 'ClassExpression') {
|
|
96
|
+
// 对于类表达式,传递VariableDeclarator节点而不是ClassExpression节点
|
|
97
|
+
// 因为需要修复的是变量名,而不是类名
|
|
98
|
+
result.node = decl;
|
|
99
|
+
result.fix = this.fix.createVariableFixFunction(context, decl, result);
|
|
100
|
+
} else if (result.original_type.includes('class-instance')) {
|
|
101
|
+
// 对于类实例,传递VariableDeclarator节点而不是VariableDeclaration节点
|
|
102
|
+
result.node = decl;
|
|
103
|
+
result.fix = this.fix.createVariableFixFunction(context, decl, result);
|
|
104
|
+
} else if (result.original_type.includes('function')) {
|
|
105
|
+
// 对于函数类型,使用函数修复函数
|
|
106
|
+
// 对于箭头函数赋值,传递VariableDeclarator节点而不是VariableDeclaration节点
|
|
107
|
+
if (decl.init && (decl.init.type === 'FunctionExpression' || decl.init.type === 'ArrowFunctionExpression')) {
|
|
108
|
+
result.node = decl;
|
|
109
|
+
result.fix = this.fix.createFunctionFixFunction(context, decl, result);
|
|
110
|
+
} else {
|
|
111
|
+
result.fix = this.fix.createFunctionFixFunction(context, full_node, result);
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
// 其他情况使用变量修复函数
|
|
115
|
+
result.fix = this.fix.createVariableFixFunction(context, full_node, result);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
context.report(result);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// 检测类表达式内部的类名(新增逻辑)
|
|
123
|
+
if (decl.init && decl.init.type === 'ClassExpression' && decl.init.id && decl.init.id.type === 'Identifier') {
|
|
124
|
+
// 先检测节点类型
|
|
125
|
+
var class_detected_type = this.detector.detectTypeOnly(decl.init);
|
|
126
|
+
|
|
127
|
+
// 根据规则类型进行过滤
|
|
128
|
+
if (this._shouldSkipDetection(rule_type, class_detected_type)) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 使用detect方法检测类表达式内部的类名
|
|
133
|
+
var class_result = this.detector.detect(decl.init, decl.init.id.name);
|
|
134
|
+
if (class_result) {
|
|
135
|
+
// 再次检查过滤条件,确保检测到的类型和规则匹配
|
|
136
|
+
if (this._shouldSkipDetection(rule_type, class_result.original_type)) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
class_result.node = decl.init;
|
|
140
|
+
class_result.fix = this.fix.createClassFixFunction(context, decl.init, class_result);
|
|
141
|
+
context.report(class_result);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* 处理属性节点
|
|
149
|
+
* @param {object} context ESLint上下文
|
|
150
|
+
* @param {object} full_node 完整的AST节点
|
|
151
|
+
* @param {object} node AST节点
|
|
152
|
+
* @param {string} rule_type 规则类型
|
|
153
|
+
*/
|
|
154
|
+
handleProperty(context, full_node, node, rule_type) {
|
|
155
|
+
if (node.key && node.key.type === 'Identifier') {
|
|
156
|
+
// 跳过解构赋值中的属性
|
|
157
|
+
if (this._isDestructuringProperty(node)) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// 跳过函数参数引用
|
|
162
|
+
if (this._isParameterReference(node)) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// 跳过module.exports中的属性
|
|
167
|
+
if (this._isModuleExportsProperty(node)) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// 先检测节点类型
|
|
172
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
173
|
+
|
|
174
|
+
// 根据规则类型进行过滤
|
|
175
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// 使用detect方法,它会自动检测类型
|
|
180
|
+
var result = this.detector.detect(node, node.key.name);
|
|
181
|
+
if (result) {
|
|
182
|
+
// 再次检查过滤条件,确保检测到的类型和规则匹配
|
|
183
|
+
if (this._shouldSkipDetection(rule_type, result.original_type)) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
result.node = full_node;
|
|
187
|
+
result.fix = this.fix.createPropertyFixFunction(context, full_node, result);
|
|
188
|
+
context.report(result);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* 处理赋值表达式节点
|
|
195
|
+
* @param {object} context ESLint上下文
|
|
196
|
+
* @param {object} full_node 完整的AST节点
|
|
197
|
+
* @param {object} node AST节点
|
|
198
|
+
* @param {string} rule_type 规则类型
|
|
199
|
+
*/
|
|
200
|
+
handleAssignmentExpression(context, full_node, node, rule_type) {
|
|
201
|
+
// 处理数组中的赋值表达式(如 [User = new UserClass()])
|
|
202
|
+
if (node.parent && node.parent.type === 'ArrayExpression' &&
|
|
203
|
+
node.left && node.left.type === 'Identifier') {
|
|
204
|
+
|
|
205
|
+
// 先检测节点类型
|
|
206
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
207
|
+
|
|
208
|
+
// 根据规则类型进行过滤
|
|
209
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
var result = this.detector.detect(node, node.left.name);
|
|
213
|
+
if (result) {
|
|
214
|
+
result.node = full_node;
|
|
215
|
+
result.fix = this.fix.createVariableFixFunction(context, full_node, result);
|
|
216
|
+
context.report(result);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// 处理 exports.XXX = ... 形式的导出
|
|
221
|
+
if (node.left &&
|
|
222
|
+
node.left.type === 'MemberExpression' &&
|
|
223
|
+
node.left.object &&
|
|
224
|
+
node.left.object.type === 'Identifier' &&
|
|
225
|
+
node.left.object.name === 'exports' &&
|
|
226
|
+
node.left.property &&
|
|
227
|
+
node.left.property.type === 'Identifier') {
|
|
228
|
+
|
|
229
|
+
// 先检测节点类型
|
|
230
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
231
|
+
|
|
232
|
+
// 根据规则类型进行过滤
|
|
233
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
var result = this.detector.detect(node, node.left.property.name);
|
|
238
|
+
if (result) {
|
|
239
|
+
result.node = full_node;
|
|
240
|
+
result.fix = this.fix.createPropertyFixFunction(context, full_node, result);
|
|
241
|
+
context.report(result);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// 处理原型方法(如 Usersb.prototype._GetUserpe = function() {})
|
|
246
|
+
if (node.left &&
|
|
247
|
+
node.left.type === 'MemberExpression' &&
|
|
248
|
+
node.left.property &&
|
|
249
|
+
node.left.property.type === 'Identifier' &&
|
|
250
|
+
node.right &&
|
|
251
|
+
(node.right.type === 'FunctionExpression' || node.right.type === 'ArrowFunctionExpression')) {
|
|
252
|
+
|
|
253
|
+
// 先检测节点类型
|
|
254
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
255
|
+
|
|
256
|
+
// 根据规则类型进行过滤
|
|
257
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
var result = this.detector.detect(node, node.left.property.name);
|
|
262
|
+
if (result) {
|
|
263
|
+
result.node = full_node;
|
|
264
|
+
result.fix = this.fix.createPropertyFixFunction(context, full_node, result);
|
|
265
|
+
context.report(result);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// 处理 module.exports = { ... } 形式的导出
|
|
270
|
+
if (node.left &&
|
|
271
|
+
node.left.type === 'MemberExpression' &&
|
|
272
|
+
node.left.object &&
|
|
273
|
+
node.left.object.type === 'Identifier' &&
|
|
274
|
+
node.left.object.name === 'module' &&
|
|
275
|
+
node.left.property &&
|
|
276
|
+
node.left.property.type === 'Identifier' &&
|
|
277
|
+
node.left.property.name === 'exports' &&
|
|
278
|
+
node.right &&
|
|
279
|
+
node.right.type === 'ObjectExpression') {
|
|
280
|
+
|
|
281
|
+
// 检测对象字面量中的属性
|
|
282
|
+
for (var i = 0; i < node.right.properties.length; i++) {
|
|
283
|
+
var property = node.right.properties[i];
|
|
284
|
+
|
|
285
|
+
// 处理简写属性(如 { AdminManager })
|
|
286
|
+
if (property.shorthand && property.key && property.key.type === 'Identifier') {
|
|
287
|
+
// 先检测节点类型 - 使用属性节点而不是赋值表达式节点
|
|
288
|
+
var detected_type = this.detector.detectTypeOnly(property);
|
|
289
|
+
|
|
290
|
+
// 根据规则类型进行过滤
|
|
291
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
var result = this.detector.detect(property, property.key.name);
|
|
296
|
+
if (result) {
|
|
297
|
+
result.node = property;
|
|
298
|
+
result.fix = this.fix.createPropertyFixFunction(context, property, result);
|
|
299
|
+
context.report(result);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// 处理普通属性(如 { AdminManager: AdminManager })
|
|
304
|
+
if (!property.shorthand && property.key && property.key.type === 'Identifier') {
|
|
305
|
+
// 先检测节点类型 - 使用属性节点而不是赋值表达式节点
|
|
306
|
+
var detected_type_normal = this.detector.detectTypeOnly(property);
|
|
307
|
+
|
|
308
|
+
// 根据规则类型进行过滤
|
|
309
|
+
if (this._shouldSkipDetection(rule_type, detected_type_normal)) {
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
var result_normal = this.detector.detect(property, property.key.name);
|
|
314
|
+
if (result_normal) {
|
|
315
|
+
result_normal.node = property;
|
|
316
|
+
result_normal.fix = this.fix.createPropertyFixFunction(context, property, result_normal);
|
|
317
|
+
context.report(result_normal);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// 处理函数导出
|
|
326
|
+
if (node.left &&
|
|
327
|
+
node.left.type === 'MemberExpression' &&
|
|
328
|
+
node.left.object &&
|
|
329
|
+
node.left.object.type === 'Identifier' &&
|
|
330
|
+
node.left.object.name === 'exports' &&
|
|
331
|
+
node.left.property &&
|
|
332
|
+
node.left.property.type === 'Identifier' &&
|
|
333
|
+
node.right &&
|
|
334
|
+
(node.right.type === 'FunctionExpression' || node.right.type === 'ArrowFunctionExpression')) {
|
|
335
|
+
|
|
336
|
+
// 先检测节点类型
|
|
337
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
338
|
+
|
|
339
|
+
// 根据规则类型进行过滤
|
|
340
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
var result = this.detector.detect(node, node.left.property.name);
|
|
345
|
+
if (result) {
|
|
346
|
+
result.node = full_node;
|
|
347
|
+
result.fix = this.fix.createFunctionFixFunction(context, full_node, result);
|
|
348
|
+
context.report(result);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// 处理 module.exports = class user {} 形式的类导出
|
|
353
|
+
if (node.left &&
|
|
354
|
+
node.left.type === 'MemberExpression' &&
|
|
355
|
+
node.left.object &&
|
|
356
|
+
node.left.object.type === 'Identifier' &&
|
|
357
|
+
node.left.object.name === 'module' &&
|
|
358
|
+
node.left.property &&
|
|
359
|
+
node.left.property.type === 'Identifier' &&
|
|
360
|
+
node.left.property.name === 'exports' &&
|
|
361
|
+
node.right &&
|
|
362
|
+
node.right.type === 'ClassExpression') {
|
|
363
|
+
|
|
364
|
+
// 检测类表达式中的类名
|
|
365
|
+
if (node.right.id && node.right.id.type === 'Identifier') {
|
|
366
|
+
// 先检测节点类型
|
|
367
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
368
|
+
|
|
369
|
+
// 根据规则类型进行过滤
|
|
370
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
var result = this.detector.detect(node, node.right.id.name);
|
|
375
|
+
if (result) {
|
|
376
|
+
result.node = node.right; // 传递ClassExpression节点而不是AssignmentExpression节点
|
|
377
|
+
result.fix = this.fix.createClassFixFunction(context, node.right, result);
|
|
378
|
+
context.report(result);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* 处理方法定义节点
|
|
386
|
+
* @param {object} context ESLint上下文
|
|
387
|
+
* @param {object} full_node 完整AST节点
|
|
388
|
+
* @param {object} node AST节点
|
|
389
|
+
* @param {string} rule_type 规则类型
|
|
390
|
+
*/
|
|
391
|
+
handleMethodDefinition(context, full_node, node, rule_type) {
|
|
392
|
+
// 先检测节点类型
|
|
393
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
394
|
+
|
|
395
|
+
// 根据规则类型进行过滤
|
|
396
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
if (node.key && (node.key.type === 'Identifier' || node.key.type === 'PrivateIdentifier')) {
|
|
401
|
+
var result = this.detector.detect(node, node.key.name);
|
|
402
|
+
if (result) {
|
|
403
|
+
// 再次检查过滤条件,确保检测到的类型和规则匹配
|
|
404
|
+
if (this._shouldSkipDetection(rule_type, result.original_type)) {
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
result.node = full_node;
|
|
408
|
+
result.fix = this.fix.createMethodFixFunction(context, full_node, result);
|
|
409
|
+
context.report(result);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* 处理属性定义节点
|
|
416
|
+
* @param {object} context ESLint上下文
|
|
417
|
+
* @param {object} full_node 完整AST节点
|
|
418
|
+
* @param {object} node AST节点
|
|
419
|
+
* @param {string} rule_type 规则类型
|
|
420
|
+
*/
|
|
421
|
+
handlePropertyDefinition(context, full_node, node, rule_type) {
|
|
422
|
+
if (node.key && (node.key.type === 'Identifier' || node.key.type === 'PrivateIdentifier')) {
|
|
423
|
+
// 先检测节点类型
|
|
424
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
425
|
+
|
|
426
|
+
// 根据规则类型进行过滤
|
|
427
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
// 使用detect方法,它会自动检测类型
|
|
431
|
+
var result = this.detector.detect(node, node.key.name);
|
|
432
|
+
if (result) {
|
|
433
|
+
// 再次检查过滤条件,确保检测到的类型和规则匹配
|
|
434
|
+
if (this._shouldSkipDetection(rule_type, result.original_type)) {
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
result.node = full_node;
|
|
438
|
+
result.fix = this.fix.createPropertyFixFunction(context, full_node, result);
|
|
439
|
+
context.report(result);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* 处理对象属性节点
|
|
446
|
+
* @param {object} context ESLint上下文
|
|
447
|
+
* @param {object} full_node 完整AST节点
|
|
448
|
+
* @param {object} node AST节点
|
|
449
|
+
* @param {string} rule_type 规则类型
|
|
450
|
+
*/
|
|
451
|
+
handleObjectProperty(context, full_node, node, rule_type) {
|
|
452
|
+
if (node.key && node.key.type === 'Identifier') {
|
|
453
|
+
// 跳过解构赋值
|
|
454
|
+
if (this._isDestructuringProperty(node)) {
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// 跳过函数参数引用
|
|
459
|
+
if (this._isFunctionParamReference(node)) {
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// 先检测节点类型
|
|
464
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
465
|
+
|
|
466
|
+
// 根据规则类型进行过滤
|
|
467
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// 使用detect方法,它会自动检测类型
|
|
472
|
+
var result = this.detector.detect(node, node.key.name);
|
|
473
|
+
if (result) {
|
|
474
|
+
// 再次检查过滤条件,确保检测到的类型和规则匹配
|
|
475
|
+
if (this._shouldSkipDetection(rule_type, result.original_type)) {
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
result.node = full_node;
|
|
479
|
+
result.fix = this.fix.createPropertyFixFunction(context, full_node, result);
|
|
480
|
+
context.report(result);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* 处理函数声明节点
|
|
487
|
+
* @param {object} context ESLint上下文
|
|
488
|
+
* @param {object} full_node 完整AST节点
|
|
489
|
+
* @param {object} node AST节点
|
|
490
|
+
* @param {string} rule_type 规则类型
|
|
491
|
+
*/
|
|
492
|
+
handleFunctionDeclaration(context, full_node, node, rule_type) {
|
|
493
|
+
// 先检测节点类型
|
|
494
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
495
|
+
|
|
496
|
+
// 根据规则类型进行过滤
|
|
497
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
if (node.id && node.id.type === 'Identifier') {
|
|
502
|
+
var result = this.detector.detect(node, node.id.name);
|
|
503
|
+
if (result) {
|
|
504
|
+
// 再次检查过滤条件,确保检测到的类型和规则匹配
|
|
505
|
+
if (this._shouldSkipDetection(rule_type, result.original_type)) {
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
result.node = full_node;
|
|
509
|
+
result.fix = this.fix.createFunctionFixFunction(context, full_node, result);
|
|
510
|
+
context.report(result);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* 处理函数表达式节点
|
|
517
|
+
* @param {object} context ESLint上下文
|
|
518
|
+
* @param {object} full_node 完整AST节点
|
|
519
|
+
* @param {object} node AST节点
|
|
520
|
+
* @param {string} rule_type 规则类型
|
|
521
|
+
*/
|
|
522
|
+
handleFunctionExpression(context, full_node, node, rule_type) {
|
|
523
|
+
// 先检测节点类型
|
|
524
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
525
|
+
|
|
526
|
+
// 根据规则类型进行过滤
|
|
527
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// 检测函数表达式本身的名称
|
|
532
|
+
if (node.id && node.id.type === 'Identifier') {
|
|
533
|
+
var result = this.detector.detect(node, node.id.name);
|
|
534
|
+
if (result) {
|
|
535
|
+
// 再次检查过滤条件,确保检测到的类型和规则匹配
|
|
536
|
+
if (this._shouldSkipDetection(rule_type, result.original_type)) {
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
result.node = full_node;
|
|
540
|
+
result.fix = this.fix.createFunctionFixFunction(context, full_node, result);
|
|
541
|
+
context.report(result);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// 检测赋值给变量的函数表达式
|
|
546
|
+
if (node.parent && node.parent.type === 'VariableDeclarator' && node.parent.id && node.parent.id.type === 'Identifier') {
|
|
547
|
+
var result = this.detector.detect(node.parent, node.parent.id.name);
|
|
548
|
+
if (result) {
|
|
549
|
+
// 再次检查过滤条件,确保检测到的类型和规则匹配
|
|
550
|
+
if (this._shouldSkipDetection(rule_type, result.original_type)) {
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
result.node = full_node;
|
|
554
|
+
result.fix = this.fix.createFunctionFixFunction(context, full_node, result);
|
|
555
|
+
context.report(result);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* 处理箭头函数节点
|
|
562
|
+
* @param {object} context ESLint上下文
|
|
563
|
+
* @param {object} full_node 完整AST节点
|
|
564
|
+
* @param {object} node AST节点
|
|
565
|
+
* @param {string} rule_type 规则类型
|
|
566
|
+
*/
|
|
567
|
+
handleArrowFunctionExpression(context, full_node, node, rule_type) {
|
|
568
|
+
// 先检测节点类型
|
|
569
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
570
|
+
|
|
571
|
+
// 根据规则类型进行过滤
|
|
572
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// 箭头函数通常没有名称,但可能有变量名
|
|
577
|
+
if (node.parent && node.parent.type === 'VariableDeclarator' && node.parent.id && node.parent.id.type === 'Identifier') {
|
|
578
|
+
var result = this.detector.detect(node.parent, node.parent.id.name);
|
|
579
|
+
if (result) {
|
|
580
|
+
// 再次检查过滤条件,确保检测到的类型和规则匹配
|
|
581
|
+
if (this._shouldSkipDetection(rule_type, result.original_type)) {
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
result.node = full_node;
|
|
585
|
+
result.fix = this.fix.createFunctionFixFunction(context, full_node, result);
|
|
586
|
+
context.report(result);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* 处理函数调用节点
|
|
593
|
+
* @param {object} context ESLint上下文
|
|
594
|
+
* @param {object} full_node 完整AST节点
|
|
595
|
+
* @param {object} node AST节点
|
|
596
|
+
* @param {string} rule_type 规则类型
|
|
597
|
+
*/
|
|
598
|
+
handleCallExpression(context, full_node, node, rule_type) {
|
|
599
|
+
// 先检测节点类型
|
|
600
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
601
|
+
|
|
602
|
+
// 根据规则类型进行过滤
|
|
603
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
if (node.callee && node.callee.type === 'Identifier') {
|
|
608
|
+
var function_name = node.callee.name;
|
|
609
|
+
|
|
610
|
+
// 跳过混入函数调用
|
|
611
|
+
if (function_name === 'Loggable' || function_name === 'Serializable') {
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// 跳过JavaScript内置函数
|
|
616
|
+
var builtin_functions = [
|
|
617
|
+
'Symbol', 'Object', 'Array', 'String', 'Number', 'Boolean', 'Date',
|
|
618
|
+
'RegExp', 'Function', 'Error', 'Math', 'JSON', 'Promise', 'Map',
|
|
619
|
+
'Set', 'WeakMap', 'WeakSet', 'Proxy', 'Reflect', 'Intl', 'console',
|
|
620
|
+
'parseInt', 'parseFloat', 'isNaN', 'isFinite', 'eval', 'encodeURI',
|
|
621
|
+
'decodeURI', 'encodeURIComponent', 'decodeURIComponent', 'setTimeout',
|
|
622
|
+
'setInterval', 'clearTimeout', 'clearInterval', 'requestAnimationFrame',
|
|
623
|
+
'cancelAnimationFrame', 'alert', 'confirm', 'prompt', 'fetch',
|
|
624
|
+
'XMLHttpRequest', 'FormData', 'URL', 'URLSearchParams', 'Blob',
|
|
625
|
+
'File', 'FileReader', 'atob', 'btoa', 'crypto', 'performance'
|
|
626
|
+
];
|
|
627
|
+
|
|
628
|
+
if (builtin_functions.includes(function_name)) {
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
var result = this.detector.detect(node, function_name);
|
|
633
|
+
if (result) {
|
|
634
|
+
// 再次检查过滤条件,确保检测到的类型和规则匹配
|
|
635
|
+
if (this._shouldSkipDetection(rule_type, result.original_type)) {
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
result.node = full_node;
|
|
639
|
+
result.fix = this.fix.createFunctionFixFunction(context, full_node, result);
|
|
640
|
+
context.report(result);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* 判断是否为解构赋值中的属性
|
|
647
|
+
* @param {object} node AST节点
|
|
648
|
+
* @returns {boolean} 是否为解构赋值属性
|
|
649
|
+
*/
|
|
650
|
+
_isDestructuringProperty(node) {
|
|
651
|
+
var current_node = node;
|
|
652
|
+
while (current_node.parent) {
|
|
653
|
+
// 检查是否为解构赋值模式(变量声明)
|
|
654
|
+
if (current_node.parent.type === 'ObjectPattern' &&
|
|
655
|
+
current_node.parent.parent &&
|
|
656
|
+
current_node.parent.parent.type === 'VariableDeclarator') {
|
|
657
|
+
return true;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// 检查是否为函数参数中的解构参数
|
|
661
|
+
if (current_node.parent.type === 'ObjectPattern' &&
|
|
662
|
+
current_node.parent.parent &&
|
|
663
|
+
(current_node.parent.parent.type === 'FunctionDeclaration' ||
|
|
664
|
+
current_node.parent.parent.type === 'FunctionExpression' ||
|
|
665
|
+
current_node.parent.parent.type === 'ArrowFunctionExpression')) {
|
|
666
|
+
return true;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
current_node = current_node.parent;
|
|
670
|
+
}
|
|
671
|
+
return false;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
/**
|
|
675
|
+
* 判断是否为函数参数引用
|
|
676
|
+
* @param {object} node AST节点
|
|
677
|
+
* @returns {boolean} 是否为参数引用
|
|
678
|
+
*/
|
|
679
|
+
_isParameterReference(node) {
|
|
680
|
+
var current_node = node;
|
|
681
|
+
while (current_node.parent) {
|
|
682
|
+
// 检查是否为函数体中的参数引用(在对象字面量中使用参数)
|
|
683
|
+
if (current_node.parent.type === 'ObjectExpression') {
|
|
684
|
+
var function_node = current_node.parent;
|
|
685
|
+
while (function_node.parent) {
|
|
686
|
+
if (function_node.parent.type === 'FunctionDeclaration' ||
|
|
687
|
+
function_node.parent.type === 'FunctionExpression' ||
|
|
688
|
+
function_node.parent.type === 'ArrowFunctionExpression') {
|
|
689
|
+
return true;
|
|
690
|
+
}
|
|
691
|
+
function_node = function_node.parent;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
current_node = current_node.parent;
|
|
695
|
+
}
|
|
696
|
+
return false;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* 判断是否为module.exports属性
|
|
701
|
+
* @param {object} node AST节点
|
|
702
|
+
* @returns {boolean} 是否为module.exports属性
|
|
703
|
+
*/
|
|
704
|
+
_isModuleExportsProperty(node) {
|
|
705
|
+
var current_node = node;
|
|
706
|
+
while (current_node.parent) {
|
|
707
|
+
// 检查是否为 module.exports 对象字面量中的属性
|
|
708
|
+
if (current_node.parent.type === 'ObjectExpression') {
|
|
709
|
+
var obj_expr_node = current_node.parent;
|
|
710
|
+
while (obj_expr_node.parent) {
|
|
711
|
+
// 检查是否为 module.exports = { ... } 的情况
|
|
712
|
+
if (obj_expr_node.parent.type === 'AssignmentExpression' &&
|
|
713
|
+
obj_expr_node.parent.left &&
|
|
714
|
+
obj_expr_node.parent.left.type === 'MemberExpression' &&
|
|
715
|
+
obj_expr_node.parent.left.object &&
|
|
716
|
+
obj_expr_node.parent.left.object.type === 'Identifier' &&
|
|
717
|
+
obj_expr_node.parent.left.object.name === 'module' &&
|
|
718
|
+
obj_expr_node.parent.left.property &&
|
|
719
|
+
obj_expr_node.parent.left.property.type === 'Identifier' &&
|
|
720
|
+
obj_expr_node.parent.left.property.name === 'exports') {
|
|
721
|
+
return true;
|
|
722
|
+
}
|
|
723
|
+
obj_expr_node = obj_expr_node.parent;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
current_node = current_node.parent;
|
|
727
|
+
}
|
|
728
|
+
return false;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* 根据检测到的类型获取正确的规则类型
|
|
733
|
+
* @param {string} detected_type 检测到的类型
|
|
734
|
+
* @returns {string} 正确的规则类型
|
|
735
|
+
*/
|
|
736
|
+
_getCorrectRuleType(detected_type) {
|
|
737
|
+
var type_mapping = {
|
|
738
|
+
'class': 'class',
|
|
739
|
+
'property-class': 'class',
|
|
740
|
+
'class-instance': 'class-instance',
|
|
741
|
+
'property-class-instance': 'class-instance',
|
|
742
|
+
'static-class-instance': 'class-instance',
|
|
743
|
+
'function': 'function',
|
|
744
|
+
'property-function': 'function',
|
|
745
|
+
'static-function': 'function',
|
|
746
|
+
'variable': 'variable',
|
|
747
|
+
'property-variable': 'variable',
|
|
748
|
+
'static-variable': 'variable',
|
|
749
|
+
'constant': 'constant',
|
|
750
|
+
'property-constant': 'constant',
|
|
751
|
+
'static-constant': 'constant',
|
|
752
|
+
'param': 'param'
|
|
753
|
+
};
|
|
754
|
+
|
|
755
|
+
return type_mapping[detected_type] || 'variable';
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
/**
|
|
759
|
+
* 判断是否应该跳过检测
|
|
760
|
+
* @param {string} rule_type 规则类型
|
|
761
|
+
* @param {string} detected_type 检测到的类型
|
|
762
|
+
* @returns {boolean} 是否跳过
|
|
763
|
+
*/
|
|
764
|
+
_shouldSkipDetection(rule_type, detected_type) {
|
|
765
|
+
// 规则类型映射
|
|
766
|
+
var rule_type_mapping = {
|
|
767
|
+
'class': ['class', 'property-class'],
|
|
768
|
+
'class-instance': ['class-instance', 'property-class-instance', 'static-class-instance', 'prototype-class-instance', 'internal-class-instance'],
|
|
769
|
+
'function': ['function', 'property-function', 'static-function', 'prototype-function', 'private-function', 'internal-function'],
|
|
770
|
+
'variable': ['variable', 'property-variable', 'static-variable', 'prototype-variable', 'private-variable', 'internal-variable'],
|
|
771
|
+
'constant': ['constant', 'property-constant', 'static-constant', 'prototype-constant'],
|
|
772
|
+
'param': ['param']
|
|
773
|
+
};
|
|
774
|
+
|
|
775
|
+
// 如果规则类型不在映射中,不跳过
|
|
776
|
+
if (!rule_type_mapping[rule_type]) {
|
|
777
|
+
return false;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
// 特殊处理:类实例类型只能被class-instance规则检测
|
|
781
|
+
if (detected_type && detected_type.includes('class-instance')) {
|
|
782
|
+
return rule_type !== 'class-instance';
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
// 特殊处理:函数类型只能被function规则检测
|
|
786
|
+
if (detected_type && detected_type.includes('function')) {
|
|
787
|
+
return rule_type !== 'function';
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
// 特殊处理:类类型只能被class规则检测
|
|
791
|
+
if (detected_type && detected_type.includes('class') && !detected_type.includes('class-instance')) {
|
|
792
|
+
return rule_type !== 'class';
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
// 特殊处理:常量类型只能被constant规则检测
|
|
796
|
+
if (detected_type && detected_type.includes('constant')) {
|
|
797
|
+
return rule_type !== 'constant';
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
// 特殊处理:变量类型只能被variable规则检测
|
|
801
|
+
if (detected_type && detected_type.includes('variable')) {
|
|
802
|
+
return rule_type !== 'variable';
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
// 如果检测到的类型不属于该规则应该检测的类型,则跳过
|
|
806
|
+
return !rule_type_mapping[rule_type].includes(detected_type);
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* 处理导出默认声明节点
|
|
811
|
+
* @param {object} context ESLint上下文
|
|
812
|
+
* @param {object} full_node 完整AST节点
|
|
813
|
+
* @param {object} node AST节点
|
|
814
|
+
* @param {string} rule_type 规则类型
|
|
815
|
+
*/
|
|
816
|
+
handleExportDefaultDeclaration(context, full_node, node, rule_type) {
|
|
817
|
+
if (node.declaration && node.declaration.type === 'ClassDeclaration') {
|
|
818
|
+
// 检测导出的类名
|
|
819
|
+
if (node.declaration.id && node.declaration.id.type === 'Identifier') {
|
|
820
|
+
// 先检测节点类型
|
|
821
|
+
var detected_type = this.detector.detectTypeOnly(node.declaration);
|
|
822
|
+
|
|
823
|
+
// 根据规则类型进行过滤
|
|
824
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
825
|
+
return;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
var result = this.detector.detect(node.declaration, node.declaration.id.name);
|
|
829
|
+
if (result) {
|
|
830
|
+
result.node = full_node;
|
|
831
|
+
result.fix = this.fix.createVariableFixFunction(context, full_node, result);
|
|
832
|
+
context.report(result);
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
/**
|
|
839
|
+
* 处理导出命名声明节点
|
|
840
|
+
* @param {object} context ESLint上下文
|
|
841
|
+
* @param {object} full_node 完整AST节点
|
|
842
|
+
* @param {object} node AST节点
|
|
843
|
+
* @param {string} rule_type 规则类型
|
|
844
|
+
*/
|
|
845
|
+
handleExportNamedDeclaration(context, full_node, node, rule_type) {
|
|
846
|
+
if (node.declaration && node.declaration.type === 'ClassDeclaration') {
|
|
847
|
+
// 检测导出的类名
|
|
848
|
+
if (node.declaration.id && node.declaration.id.type === 'Identifier') {
|
|
849
|
+
// 先检测节点类型
|
|
850
|
+
var detected_type = this.detector.detectTypeOnly(node.declaration);
|
|
851
|
+
|
|
852
|
+
// 根据规则类型进行过滤
|
|
853
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
854
|
+
return;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
var result = this.detector.detect(node.declaration, node.declaration.id.name);
|
|
858
|
+
if (result) {
|
|
859
|
+
result.node = full_node;
|
|
860
|
+
result.fix = this.fix.createClassFixFunction(context, full_node, result);
|
|
861
|
+
context.report(result);
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
/**
|
|
868
|
+
* 处理类表达式节点
|
|
869
|
+
* @param {object} context ESLint上下文
|
|
870
|
+
* @param {object} node AST节点
|
|
871
|
+
* @param {string} rule_type 规则类型
|
|
872
|
+
*/
|
|
873
|
+
handleClassExpression(context, full_node, node, rule_type) {
|
|
874
|
+
// 检测类表达式本身的名称
|
|
875
|
+
if (node.id && node.id.type === 'Identifier') {
|
|
876
|
+
// 先检测节点类型
|
|
877
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
878
|
+
|
|
879
|
+
// 根据规则类型进行过滤
|
|
880
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
var result = this.detector.detect(node, node.id.name);
|
|
885
|
+
if (result) {
|
|
886
|
+
result.node = full_node;
|
|
887
|
+
result.fix = this.fix.createClassFixFunction(context, full_node, result);
|
|
888
|
+
context.report(result);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
/**
|
|
894
|
+
* 处理导入声明节点
|
|
895
|
+
* @param {object} context ESLint上下文
|
|
896
|
+
* @param {object} full_node 完整AST节点
|
|
897
|
+
* @param {object} node AST节点
|
|
898
|
+
* @param {string} rule_type 规则类型
|
|
899
|
+
*/
|
|
900
|
+
handleImportDeclaration(context, full_node, node, rule_type) {
|
|
901
|
+
// 检测导入的类名
|
|
902
|
+
if (node.specifiers && node.specifiers.length > 0) {
|
|
903
|
+
for (var i = 0; i < node.specifiers.length; i++) {
|
|
904
|
+
var specifier = node.specifiers[i];
|
|
905
|
+
|
|
906
|
+
// 检测导入的类名
|
|
907
|
+
if (specifier.imported && specifier.imported.type === 'Identifier') {
|
|
908
|
+
// 先检测节点类型
|
|
909
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
910
|
+
|
|
911
|
+
// 根据规则类型进行过滤
|
|
912
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
913
|
+
continue;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
var result = this.detector.detect(node, specifier.imported.name);
|
|
917
|
+
if (result) {
|
|
918
|
+
result.node = full_node;
|
|
919
|
+
result.fix = this.fix.createVariableFixFunction(context, full_node, result);
|
|
920
|
+
context.report(result);
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
// 检测默认导入的类名
|
|
925
|
+
if (specifier.type === 'ImportDefaultSpecifier' && specifier.local) {
|
|
926
|
+
// 先检测节点类型
|
|
927
|
+
var detected_type_default = this.detector.detectTypeOnly(node);
|
|
928
|
+
|
|
929
|
+
// 根据规则类型进行过滤
|
|
930
|
+
if (this._shouldSkipDetection(rule_type, detected_type_default)) {
|
|
931
|
+
continue;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
var result_default = this.detector.detect(node, specifier.local.name);
|
|
935
|
+
if (result_default) {
|
|
936
|
+
this.report(context, full_node, result_default);
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/**
|
|
944
|
+
* 处理标识符节点
|
|
945
|
+
* @param {object} context ESLint上下文
|
|
946
|
+
* @param {object} full_node 完整AST节点
|
|
947
|
+
* @param {object} node AST节点
|
|
948
|
+
* @param {string} rule_type 规则类型
|
|
949
|
+
*/
|
|
950
|
+
handleIdentifier(context, full_node, node, rule_type) {
|
|
951
|
+
// 检测类引用中的标识符
|
|
952
|
+
if (node.parent && node.parent.type === 'ClassDeclaration') {
|
|
953
|
+
// 先检测节点类型
|
|
954
|
+
var detected_type = this.detector.detectTypeOnly(node);
|
|
955
|
+
|
|
956
|
+
// 根据规则类型进行过滤
|
|
957
|
+
if (this._shouldSkipDetection(rule_type, detected_type)) {
|
|
958
|
+
return;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
var result = this.detector.detect(node, node.name);
|
|
962
|
+
if (result) {
|
|
963
|
+
result.node = full_node;
|
|
964
|
+
result.fix = this.fix.createMethodFixFunction(context, full_node, result);
|
|
965
|
+
context.report(result);
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
/**
|
|
971
|
+
* 处理对象表达式节点
|
|
972
|
+
* @param {object} context ESLint上下文
|
|
973
|
+
* @param {object} full_node 完整AST节点
|
|
974
|
+
* @param {object} node AST节点
|
|
975
|
+
* @param {string} rule_type 规则类型
|
|
976
|
+
*/
|
|
977
|
+
handleObjectExpression(context, full_node, node, rule_type) {
|
|
978
|
+
// 遍历对象的所有属性
|
|
979
|
+
if (node.properties && node.properties.length > 0) {
|
|
980
|
+
for (var i = 0; i < node.properties.length; i++) {
|
|
981
|
+
var property = node.properties[i];
|
|
982
|
+
|
|
983
|
+
// 只处理普通属性,跳过解构赋值等
|
|
984
|
+
if (property.type === 'Property' && property.key && property.key.type === 'Identifier') {
|
|
985
|
+
// 调用handleProperty方法处理每个属性
|
|
986
|
+
this.handleProperty(context, full_node, property, rule_type);
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
module.exports = { Handler };
|