mm_eslint 1.6.0 → 1.6.2

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/lib/config.js CHANGED
@@ -118,7 +118,6 @@ Config.prototype.getForbiddenWords = function (name_type) {
118
118
  'parameters',
119
119
  'item',
120
120
  'items',
121
- 'process',
122
121
  'processor',
123
122
  'provider',
124
123
  'builder',
@@ -262,6 +262,11 @@ FunctionName.prototype.CallExpression = function (node) {
262
262
  return undefined;
263
263
  }
264
264
 
265
+ // 检查是否为导入的函数或第三方库函数
266
+ if (this._isExternalFunction(node, name)) {
267
+ return undefined;
268
+ }
269
+
265
270
  let original_type = 'use-function';
266
271
  let error = this.check(node, name, original_type);
267
272
  this.report(node, error, original_type);
@@ -281,6 +286,19 @@ FunctionName.prototype.CallExpression = function (node) {
281
286
  return undefined;
282
287
  }
283
288
 
289
+ // 检查是否为 this. 开头的函数调用,如果是则直接检测(通常是自定义函数)
290
+ if (callee.object && callee.object.type === 'ThisExpression') {
291
+ let original_type = 'use-function';
292
+ let error = this.check(callee.property, name, original_type);
293
+ this.report(callee.property, error, original_type);
294
+ return error;
295
+ }
296
+
297
+ // 检查是否为导入的函数或第三方库函数
298
+ if (this._isExternalFunction(node, name)) {
299
+ return undefined;
300
+ }
301
+
284
302
  let original_type = 'use-function';
285
303
  let error = this.check(callee.property, name, original_type);
286
304
  this.report(callee.property, error, original_type);
@@ -366,4 +384,125 @@ FunctionName.prototype.ExportNamedDeclaration = function (node) {
366
384
  }
367
385
  }
368
386
 
387
+ /**
388
+ * 检查函数是否为外部函数(不在当前作用域内定义的函数)
389
+ * @param {Object} node - 调用表达式节点
390
+ * @param {string} name - 函数名
391
+ * @returns {boolean} - 是否为外部函数
392
+ */
393
+ FunctionName.prototype._isExternalFunction = function (node, name) {
394
+ if (!name || !node) {
395
+ return false;
396
+ }
397
+
398
+ // 如果函数在当前作用域内有定义,则不是外部函数
399
+ if (this._isFunctionInScope(name, node)) {
400
+ return false;
401
+ }
402
+
403
+ // 检查是否为导入的函数(通过 import 或 require)
404
+ if (this._isImportedFunction(name, node)) {
405
+ return true;
406
+ }
407
+
408
+ // 检查是否为全局对象上的函数(如 console.log, Math.max 等)
409
+ if (this._isGlobalObjectFunction(name, node)) {
410
+ return true;
411
+ }
412
+
413
+ // 默认情况下,如果函数不在当前作用域内定义,则认为是外部函数
414
+ return true;
415
+ }
416
+
417
+ /**
418
+ * 检查函数是否为导入的函数
419
+ * @param {string} name - 函数名
420
+ * @param {Object} node - 当前节点
421
+ * @returns {boolean} - 是否为导入的函数
422
+ */
423
+ FunctionName.prototype._isImportedFunction = function (name, node) {
424
+ if (!name || !node) {
425
+ return false;
426
+ }
427
+
428
+ // 获取AST根节点
429
+ let program_node = this._getProgramNode(node);
430
+ if (!program_node || !program_node.body) {
431
+ return false;
432
+ }
433
+
434
+ // 遍历同级节点查找导入声明
435
+ for (let i = 0; i < program_node.body.length; i++) {
436
+ let sibling_node = program_node.body[i];
437
+
438
+ // 检查ES6导入声明
439
+ if (sibling_node.type === 'ImportDeclaration') {
440
+ if (sibling_node.specifiers && sibling_node.specifiers.length > 0) {
441
+ for (let j = 0; j < sibling_node.specifiers.length; j++) {
442
+ let specifier = sibling_node.specifiers[j];
443
+
444
+ // 检查导入的标识符名称
445
+ if (specifier.local && specifier.local.type === 'Identifier' && specifier.local.name === name) {
446
+ return true;
447
+ }
448
+ }
449
+ }
450
+ }
451
+
452
+ // 检查CommonJS require导入
453
+ if (sibling_node.type === 'VariableDeclaration') {
454
+ for (let j = 0; j < sibling_node.declarations.length; j++) {
455
+ let decl = sibling_node.declarations[j];
456
+ if (decl.id && decl.id.type === 'Identifier' && decl.id.name === name) {
457
+ // 检查是否为require调用
458
+ if (decl.init && decl.init.type === 'CallExpression' &&
459
+ decl.init.callee && decl.init.callee.type === 'Identifier' &&
460
+ decl.init.callee.name === 'require') {
461
+ return true;
462
+ }
463
+ }
464
+ }
465
+ }
466
+ }
467
+
468
+ return false;
469
+ }
470
+
471
+ /**
472
+ * 检查函数是否为全局对象上的函数
473
+ * @param {string} name - 函数名
474
+ * @param {Object} node - 当前节点
475
+ * @returns {boolean} - 是否为全局对象函数
476
+ */
477
+ FunctionName.prototype._isGlobalObjectFunction = function (name, node) {
478
+ if (!name) {
479
+ return false;
480
+ }
481
+
482
+ // 常见的全局对象函数列表
483
+ const global_object_functions = [
484
+ // console 对象
485
+ 'log', 'info', 'warn', 'error', 'debug', 'table', 'time', 'timeEnd',
486
+ // Math 对象
487
+ 'abs', 'ceil', 'floor', 'round', 'max', 'min', 'pow', 'sqrt', 'random',
488
+ // JSON 对象
489
+ 'parse', 'stringify',
490
+ // Object 对象
491
+ 'keys', 'values', 'entries', 'assign', 'create', 'freeze', 'seal',
492
+ // Array 对象
493
+ 'isArray', 'from', 'of',
494
+ // String 对象
495
+ 'fromCharCode', 'fromCodePoint',
496
+ // Number 对象
497
+ 'isFinite', 'isInteger', 'isNaN', 'isSafeInteger', 'parseFloat', 'parseInt',
498
+ // Date 对象
499
+ 'now', 'parse', 'UTC',
500
+ // RegExp 对象
501
+ 'test', 'exec'
502
+ ];
503
+
504
+ // 检查是否为全局对象函数
505
+ return global_object_functions.includes(name);
506
+ }
507
+
369
508
  module.exports = { FunctionName }
@@ -197,6 +197,69 @@ Name.prototype._isClassInScope = function (name, node) {
197
197
  return false;
198
198
  }
199
199
 
200
+ /**
201
+ * 检查类声明中是否包含指定名称的方法
202
+ * @param {Object} class_node - 类声明节点
203
+ * @param {string} name - 方法名
204
+ * @returns {boolean} - 是否包含该方法
205
+ */
206
+ Name.prototype._isFunctionInClass = function (class_node, name) {
207
+ if (!class_node || !class_node.body || !class_node.body.body) {
208
+ return false;
209
+ }
210
+
211
+ // 遍历类体中的方法定义
212
+ for (let i = 0; i < class_node.body.body.length; i++) {
213
+ let method_node = class_node.body.body[i];
214
+
215
+ // 检查方法定义(MethodDefinition)
216
+ if (method_node.type === 'MethodDefinition') {
217
+ if (method_node.key && method_node.key.type === 'Identifier' && method_node.key.name === name) {
218
+ return true;
219
+ }
220
+ }
221
+
222
+ // 检查类属性中的函数赋值(PropertyDefinition)
223
+ if (method_node.type === 'PropertyDefinition') {
224
+ if (method_node.key && method_node.key.type === 'Identifier' && method_node.key.name === name) {
225
+ // 检查属性值是否为函数表达式
226
+ if (method_node.value && (method_node.value.type === 'FunctionExpression' || method_node.value.type === 'ArrowFunctionExpression')) {
227
+ return true;
228
+ }
229
+ }
230
+ }
231
+
232
+ // 检查构造函数中的方法赋值
233
+ if (method_node.type === 'MethodDefinition' && method_node.kind === 'constructor') {
234
+ if (method_node.value && method_node.value.body && method_node.value.body.body) {
235
+ // 遍历构造函数体中的语句
236
+ for (let j = 0; j < method_node.value.body.body.length; j++) {
237
+ let statement = method_node.value.body.body[j];
238
+
239
+ // 检查 this.property = function() {} 形式的赋值
240
+ if (statement.type === 'ExpressionStatement' && statement.expression && statement.expression.type === 'AssignmentExpression') {
241
+ let expr = statement.expression;
242
+
243
+ // 检查左边是否为 this.propertyName 形式
244
+ if (expr.left && expr.left.type === 'MemberExpression' &&
245
+ expr.left.object && expr.left.object.type === 'ThisExpression' &&
246
+ expr.left.property && expr.left.property.type === 'Identifier' &&
247
+ expr.left.property.name === name) {
248
+
249
+ // 检查右边是否为函数表达式
250
+ if (expr.right && (expr.right.type === 'FunctionExpression' || expr.right.type === 'ArrowFunctionExpression')) {
251
+ return true;
252
+ }
253
+ }
254
+ }
255
+ }
256
+ }
257
+ }
258
+ }
259
+
260
+ return false;
261
+ }
262
+
200
263
  /**
201
264
  * 检查标识符是否在作用域内定义为函数
202
265
  * @param {string} name - 标识符名称
@@ -242,6 +305,13 @@ Name.prototype._isFunctionInScope = function (name, node) {
242
305
  }
243
306
  }
244
307
  }
308
+
309
+ // 查找类声明中的方法定义
310
+ if (sibling_node.type === 'ClassDeclaration') {
311
+ if (this._isFunctionInClass(sibling_node, name)) {
312
+ return true;
313
+ }
314
+ }
245
315
  }
246
316
 
247
317
  return false;
package/lib/validator.js CHANGED
@@ -84,7 +84,9 @@ Validator.prototype.check = function (name, words, rule) {
84
84
  }
85
85
 
86
86
  // 检查每个单词的长度, 警告级。
87
- var word_error = this._validateWordLength(words, rule.single_word_len);
87
+ // 长度检测前过滤掉忽略词
88
+ var ws = this._filterIgnoreWords(words, rule.ignore_words);
89
+ var word_error = this._validateWordLength(ws, rule.single_word_len);
88
90
  if (word_error) {
89
91
  return word_error;
90
92
  }
@@ -96,6 +98,29 @@ Validator.prototype.check = function (name, words, rule) {
96
98
  }
97
99
  }
98
100
 
101
+ /**
102
+ * 过滤掉忽略词
103
+ * @param {array} words 单词数组
104
+ * @param {array} ignore_words 忽略词数组
105
+ * @returns {array} 过滤后的单词数组
106
+ */
107
+ Validator.prototype._filterIgnoreWords = function (words, ignore_words) {
108
+ if (!words || words.length === 0) {
109
+ return [];
110
+ }
111
+
112
+ if (!ignore_words || ignore_words.length === 0) {
113
+ return words;
114
+ }
115
+
116
+ // 过滤掉忽略词
117
+ var ws = words.filter((word) => {
118
+ return !this._isIgnoreWord(word, ignore_words);
119
+ });
120
+
121
+ return ws;
122
+ }
123
+
99
124
  /**
100
125
  * 判断名称是否为忽略词
101
126
  * @param {string} name 名称
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mm_eslint",
3
- "version": "1.6.0",
3
+ "version": "1.6.2",
4
4
  "description": "ESLint plugin for personal naming conventions - supports PascalCase, camelCase, snake_case, and UPPER_SNAKE_CASE naming rules with intelligent recommendations",
5
5
  "main": "index.js",
6
6
  "keywords": [