mm_eslint 1.3.9 → 1.4.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 (3) hide show
  1. package/detector.js +316 -42
  2. package/index.js +7 -1
  3. package/package.json +1 -1
package/detector.js CHANGED
@@ -381,20 +381,10 @@ Detector.prototype._checkParamName = function (param_name, node) {
381
381
  */
382
382
  Detector.prototype._checkConstantName = function (constant_name, node, val_node) {
383
383
  try {
384
- var rule = this.config.getRule('constant-name');
385
- if (!rule) {
386
- return null;
387
- }
388
-
389
- // 检查是否为忽略词
390
- if (this._isIgnoredWord(constant_name, 'constant-name')) {
391
- return null;
392
- }
393
-
394
384
  // 检查是否为解构导入(从模块导入的变量)
395
385
  var is_destructured_import = this._isDestructuredImport(node);
396
386
 
397
- // 如果是解构导入,则不进行常量检测
387
+ // 如果是解构导入,则不进行命名检测
398
388
  if (is_destructured_import) {
399
389
  return null;
400
390
  }
@@ -410,24 +400,49 @@ Detector.prototype._checkConstantName = function (constant_name, node, val_node)
410
400
  };
411
401
  }
412
402
 
413
- // 检查是否为复杂类型(方法、函数、实例等)
414
- var is_complex_type = this._isComplexType(val_node);
403
+ // 根据值类型确定应该应用的命名规则
404
+ var rule_type = 'constant-name'; // 默认使用常量命名规则
405
+ var allowed_styles = [];
415
406
 
416
- // 如果是复杂类型,则不进行常量检测
417
- if (is_complex_type) {
407
+ // 检查是否为函数表达式或箭头函数
408
+ if (val_node && (val_node.type === 'FunctionExpression' || val_node.type === 'ArrowFunctionExpression')) {
409
+ rule_type = 'function-name';
410
+ }
411
+ // 检查是否为类表达式
412
+ else if (val_node && val_node.type === 'ClassExpression') {
413
+ rule_type = 'class-name';
414
+ }
415
+ // 检查是否为类实例(new表达式)
416
+ else if (val_node && val_node.type === 'NewExpression') {
417
+ rule_type = 'function-name'; // 类实例使用函数命名规则(camelCase)
418
+ }
419
+ // 检查是否为基础值类型
420
+ else if (val_node && this._isBaseValue(val_node)) {
421
+ rule_type = 'constant-name';
422
+ }
423
+ // 检查是否为其他复杂类型(函数调用、变量引用等)
424
+ else if (val_node && this._isComplexType(val_node)) {
425
+ // 其他复杂类型不进行命名检测
426
+ return null;
427
+ }
428
+ // 其他情况不进行命名检测
429
+ else {
418
430
  return null;
419
431
  }
420
432
 
421
- // 检查是否为基础值类型
422
- var is_base_value = this._isBaseValue(val_node);
433
+ // 获取对应的命名规则
434
+ var rule = this.config.getRule(rule_type);
435
+ if (!rule) {
436
+ return null;
437
+ }
423
438
 
424
- // 如果不是基础值也不是复杂类型(可能是其他类型),则不进行常量检测
425
- if (!is_base_value) {
439
+ // 检查是否为忽略词
440
+ if (this._isIgnoredWord(constant_name, rule_type)) {
426
441
  return null;
427
442
  }
428
443
 
429
444
  // 检查命名风格
430
- var style_err = this._validate_naming_style(constant_name, rule.styles, 'constant-name');
445
+ var style_err = this._validate_naming_style(constant_name, rule.styles, rule_type);
431
446
  if (style_err) {
432
447
  return {
433
448
  node: node,
@@ -542,9 +557,7 @@ Detector.prototype._checkWordLength = function (name, max_word_len, name_type) {
542
557
  }
543
558
 
544
559
  var name_type_desc = this.config.name_type_map[name_type] || '名称';
545
- // 分割单词(根据命名风格)
546
- var words = [];
547
-
560
+
548
561
  // 处理私有标识符(开头的下划线)
549
562
  var processed_name = name;
550
563
  var has_private_prefix = false;
@@ -554,6 +567,9 @@ Detector.prototype._checkWordLength = function (name, max_word_len, name_type) {
554
567
  processed_name = name.substring(1); // 去掉开头的下划线
555
568
  }
556
569
 
570
+ // 分割单词(根据命名风格)
571
+ var words = [];
572
+
557
573
  if (processed_name.includes('_')) {
558
574
  words = processed_name.split('_');
559
575
  } else if (processed_name.includes('-')) {
@@ -568,6 +584,16 @@ Detector.prototype._checkWordLength = function (name, max_word_len, name_type) {
568
584
  words.unshift('_');
569
585
  }
570
586
 
587
+ // 过滤空字符串
588
+ words = words.filter(function(word) {
589
+ return word && word.length > 0;
590
+ });
591
+
592
+ // 如果是单个单词,则不检测单词长度
593
+ if (words.length <= 1) {
594
+ return null;
595
+ }
596
+
571
597
  for (var i = 0; i < words.length; i++) {
572
598
  var word = words[i];
573
599
  // 跳过空字符串和私有标识符(单个下划线)
@@ -700,25 +726,57 @@ Detector.prototype._splitNameIntoWords = function (name) {
700
726
  */
701
727
  Detector.prototype._isThirdPartyConfigProperty = function (node, parent_node) {
702
728
  try {
729
+ // 处理新的父节点信息结构(包含node和parent属性)
730
+ var actual_parent_node = parent_node;
731
+ if (parent_node && typeof parent_node === 'object' && parent_node.node) {
732
+ actual_parent_node = parent_node.node;
733
+ }
734
+
703
735
  // 检查当前节点是否为对象字面量的属性
704
- if (!parent_node || parent_node.type !== 'ObjectExpression') {
736
+ if (!actual_parent_node || actual_parent_node.type !== 'ObjectExpression') {
705
737
  return false;
706
738
  }
707
739
 
708
- // 检查对象字面量是否作为方法调用的参数
709
- var grandparent = parent_node.parent;
710
- if (!grandparent || grandparent.type !== 'CallExpression') {
740
+ // 递归查找调用表达式(处理嵌套对象的情况)
741
+ var findCallExpression = function(current_node) {
742
+ if (!current_node) {
743
+ return null;
744
+ }
745
+
746
+ if (current_node.type === 'CallExpression') {
747
+ return current_node;
748
+ }
749
+
750
+ // 继续向上查找
751
+ return findCallExpression(current_node.parent);
752
+ };
753
+
754
+ // 优先使用新的父节点信息结构中的parent属性
755
+ var grandparent = parent_node && typeof parent_node === 'object' && parent_node.parent
756
+ ? parent_node.parent
757
+ : actual_parent_node.parent;
758
+
759
+ // 查找调用表达式
760
+ var call_expression = findCallExpression(grandparent);
761
+ if (!call_expression) {
711
762
  return false;
712
763
  }
713
764
 
714
765
  // 检查方法调用是否来自外部模块(非当前文件定义的函数)
715
- var callee = grandparent.callee;
766
+ var callee = call_expression.callee;
716
767
  if (!callee) {
717
768
  return false;
718
769
  }
719
770
 
720
771
  // 如果是成员表达式(如 chokidar.watch),则认为是第三方库调用
721
772
  if (callee.type === 'MemberExpression') {
773
+ // 检查成员表达式的对象是否为模块导入变量
774
+ var is_module_import = this._isModuleImportVariable(callee.object);
775
+ if (is_module_import) {
776
+ return true;
777
+ }
778
+
779
+ // 对于其他成员表达式,也认为是第三方库调用(保守策略)
722
780
  return true;
723
781
  }
724
782
 
@@ -735,6 +793,12 @@ Detector.prototype._isThirdPartyConfigProperty = function (node, parent_node) {
735
793
  return true;
736
794
  }
737
795
 
796
+ // 检查标识符是否为模块导入变量
797
+ var is_module_import = this._isModuleImportVariable(callee);
798
+ if (is_module_import) {
799
+ return true;
800
+ }
801
+
738
802
  // 对于其他标识符,暂时不认为是第三方库调用(避免误判)
739
803
  return false;
740
804
  }
@@ -1045,6 +1109,12 @@ Detector.prototype._shouldUseLetInsteadOfConst = function (node, val_node) {
1045
1109
  return false;
1046
1110
  }
1047
1111
 
1112
+ // 检查是否为模块导入(需要排除的情况)
1113
+ var is_module_import = this._isModuleImport(node, val_node);
1114
+ if (is_module_import) {
1115
+ return false;
1116
+ }
1117
+
1048
1118
  // 检查是否为解构赋值
1049
1119
  var is_destructuring = false;
1050
1120
  if (node.parent && node.parent.type === 'VariableDeclarator') {
@@ -1054,11 +1124,30 @@ Detector.prototype._shouldUseLetInsteadOfConst = function (node, val_node) {
1054
1124
  }
1055
1125
  }
1056
1126
 
1057
- // 检查右侧是否为复杂类型(类实例、函数、对象等)
1127
+ // 应该使用let的情况:
1128
+ // 1. 函数调用(CallExpression)- 返回值可能变化
1129
+ // 2. 变量引用(Identifier)- 可能被重新赋值
1130
+ // 3. 条件表达式等可能产生不同结果的情况
1131
+
1132
+ var should_use_let = false;
1133
+
1134
+ // 检查是否为函数调用
1135
+ if (val_node.type === 'CallExpression') {
1136
+ should_use_let = true;
1137
+ }
1138
+
1139
+ // 检查是否为变量引用
1140
+ if (val_node.type === 'Identifier') {
1141
+ should_use_let = true;
1142
+ }
1143
+
1144
+ // 检查是否为解构赋值且右侧是复杂类型
1058
1145
  var is_complex_type = this._isComplexType(val_node);
1059
-
1060
- // 如果是解构赋值且右侧是复杂类型,建议使用let
1061
- return is_destructuring && is_complex_type;
1146
+ if (is_destructuring && is_complex_type) {
1147
+ should_use_let = true;
1148
+ }
1149
+
1150
+ return should_use_let;
1062
1151
  } catch (error) {
1063
1152
  console.error('检查是否应该使用let时出错:', error);
1064
1153
  return false;
@@ -1102,6 +1191,91 @@ Detector.prototype._isComplexType = function (val_node) {
1102
1191
  }
1103
1192
  };
1104
1193
 
1194
+ /**
1195
+ * 检查是否为模块导入(需要排除const检测的情况)
1196
+ * @param {object} node 变量声明节点
1197
+ * @param {object} val_node 值节点
1198
+ * @returns {boolean} 是否为模块导入
1199
+ */
1200
+ Detector.prototype._isModuleImport = function (node, val_node) {
1201
+ try {
1202
+ if (!node || !val_node) {
1203
+ return false;
1204
+ }
1205
+
1206
+ // 情况1:const xxx = require('module') - 直接模块导入
1207
+ if (val_node.type === 'CallExpression' && val_node.callee) {
1208
+ // 检查是否为require调用
1209
+ if (val_node.callee.type === 'Identifier' && val_node.callee.name === 'require') {
1210
+ return true;
1211
+ }
1212
+
1213
+ // 检查是否为import()动态导入
1214
+ if (val_node.callee.type === 'Import') {
1215
+ return true;
1216
+ }
1217
+ }
1218
+
1219
+ // 情况2:const {xxx} = require('module') - 解构模块导入
1220
+ if (node.parent && node.parent.type === 'VariableDeclarator') {
1221
+ var declarator = node.parent;
1222
+
1223
+ // 检查是否为解构赋值
1224
+ if (declarator.id && declarator.id.type === 'ObjectPattern') {
1225
+ // 检查右侧是否为require调用
1226
+ if (val_node.type === 'CallExpression' && val_node.callee) {
1227
+ if (val_node.callee.type === 'Identifier' && val_node.callee.name === 'require') {
1228
+ return true;
1229
+ }
1230
+ }
1231
+ }
1232
+ }
1233
+
1234
+ return false;
1235
+ } catch (error) {
1236
+ console.error('检查是否为模块导入时出错:', error);
1237
+ return false;
1238
+ }
1239
+ };
1240
+
1241
+ /**
1242
+ * 检查标识符是否为模块导入变量
1243
+ * @param {object} node AST节点(Identifier类型)
1244
+ * @returns {boolean} 是否为模块导入变量
1245
+ */
1246
+ Detector.prototype._isModuleImportVariable = function (node) {
1247
+ try {
1248
+ if (!node || node.type !== 'Identifier') {
1249
+ return false;
1250
+ }
1251
+
1252
+ // 检查变量声明是否为模块导入
1253
+ if (node.parent && node.parent.parent) {
1254
+ var variable_declaration = node.parent.parent;
1255
+
1256
+ // 检查是否为const声明
1257
+ if (variable_declaration.type === 'VariableDeclaration' && variable_declaration.kind === 'const') {
1258
+ // 检查声明中是否有require调用
1259
+ var declarators = variable_declaration.declarations;
1260
+ for (var i = 0; i < declarators.length; i++) {
1261
+ var declarator = declarators[i];
1262
+ if (declarator.init && declarator.init.type === 'CallExpression') {
1263
+ var init_call = declarator.init;
1264
+ if (init_call.callee && init_call.callee.type === 'Identifier' && init_call.callee.name === 'require') {
1265
+ return true;
1266
+ }
1267
+ }
1268
+ }
1269
+ }
1270
+ }
1271
+
1272
+ return false;
1273
+ } catch (error) {
1274
+ console.error('检查是否为模块导入变量时出错:', error);
1275
+ return false;
1276
+ }
1277
+ };
1278
+
1105
1279
  /**
1106
1280
  * 检查是否为解构导入
1107
1281
  * @param {object} node AST节点
@@ -1188,15 +1362,25 @@ Detector.prototype._isDestructuredImport = function (node) {
1188
1362
  */
1189
1363
  Detector.prototype._isDestructuredImportProperty = function (node, parent_node) {
1190
1364
  try {
1191
- if (!node || !parent_node) {
1365
+ // 处理新的父节点信息结构(包含node和parent属性)
1366
+ var actual_parent_node = parent_node;
1367
+ if (parent_node && typeof parent_node === 'object' && parent_node.node) {
1368
+ actual_parent_node = parent_node.node;
1369
+ }
1370
+
1371
+ if (!node || !actual_parent_node) {
1192
1372
  return false;
1193
1373
  }
1194
1374
 
1195
1375
  // 检查父节点是否为ObjectPattern(解构模式)
1196
- if (parent_node.type === 'ObjectPattern') {
1376
+ if (actual_parent_node.type === 'ObjectPattern') {
1197
1377
  // 检查父节点的父节点是否为VariableDeclarator
1198
- if (parent_node.parent && parent_node.parent.type === 'VariableDeclarator') {
1199
- var declarator = parent_node.parent;
1378
+ var actual_parent_parent = parent_node && typeof parent_node === 'object' && parent_node.parent
1379
+ ? parent_node.parent
1380
+ : actual_parent_node.parent;
1381
+
1382
+ if (actual_parent_parent && actual_parent_parent.type === 'VariableDeclarator') {
1383
+ var declarator = actual_parent_parent;
1200
1384
 
1201
1385
  // 检查右侧是否为require调用或其他模块导入
1202
1386
  if (declarator.init) {
@@ -1224,6 +1408,83 @@ Detector.prototype._isDestructuredImportProperty = function (node, parent_node)
1224
1408
  }
1225
1409
  };
1226
1410
 
1411
+ /**
1412
+ * 检查是否为函数赋值(函数表达式或箭头函数)
1413
+ * @param {object} node AST节点
1414
+ * @returns {boolean} 是否为函数赋值
1415
+ */
1416
+ Detector.prototype._isFunctionAssignment = function (node) {
1417
+ try {
1418
+ if (!node) {
1419
+ return false;
1420
+ }
1421
+
1422
+ // 检查节点是否为解构赋值中的属性
1423
+ if (node.type === 'Property' && node.key === node) {
1424
+ // 检查父节点是否为ObjectPattern
1425
+ if (node.parent && node.parent.type === 'ObjectPattern') {
1426
+ // 检查父节点的父节点是否为VariableDeclarator
1427
+ if (node.parent.parent && node.parent.parent.type === 'VariableDeclarator') {
1428
+ var declarator = node.parent.parent;
1429
+
1430
+ // 检查右侧是否为函数表达式或箭头函数
1431
+ if (declarator.init) {
1432
+ var init_type = declarator.init.type;
1433
+
1434
+ // 函数表达式
1435
+ if (init_type === 'FunctionExpression') {
1436
+ return true;
1437
+ }
1438
+
1439
+ // 箭头函数
1440
+ if (init_type === 'ArrowFunctionExpression') {
1441
+ return true;
1442
+ }
1443
+
1444
+ // 函数调用(可能返回函数)
1445
+ if (init_type === 'CallExpression') {
1446
+ return true;
1447
+ }
1448
+ }
1449
+ }
1450
+ }
1451
+ }
1452
+
1453
+ // 检查节点是否为解构赋值中的数组元素
1454
+ if (node.type === 'Identifier' && node.parent && node.parent.type === 'ArrayPattern') {
1455
+ // 检查父节点的父节点是否为VariableDeclarator
1456
+ if (node.parent.parent && node.parent.parent.type === 'VariableDeclarator') {
1457
+ var declarator = node.parent.parent;
1458
+
1459
+ // 检查右侧是否为函数表达式或箭头函数
1460
+ if (declarator.init) {
1461
+ var init_type = declarator.init.type;
1462
+
1463
+ // 函数表达式
1464
+ if (init_type === 'FunctionExpression') {
1465
+ return true;
1466
+ }
1467
+
1468
+ // 箭头函数
1469
+ if (init_type === 'ArrowFunctionExpression') {
1470
+ return true;
1471
+ }
1472
+
1473
+ // 函数调用(可能返回函数)
1474
+ if (init_type === 'CallExpression') {
1475
+ return true;
1476
+ }
1477
+ }
1478
+ }
1479
+ }
1480
+
1481
+ return false;
1482
+ } catch (error) {
1483
+ console.error('检查是否为函数赋值时出错:', error);
1484
+ return false;
1485
+ }
1486
+ };
1487
+
1227
1488
  /**
1228
1489
  * 检查常量名是否符合规范
1229
1490
  * @param {string} constant_name 常量名
@@ -1339,12 +1600,25 @@ Detector.prototype._checkConstantNameForDestructuring = function (constant_name,
1339
1600
  return null;
1340
1601
  }
1341
1602
 
1342
- // 对于解构赋值,直接提示使用let而不是const
1343
- // 因为解构赋值通常不是真正的常量
1344
- return {
1345
- node: node,
1346
- message: `变量'${constant_name}'应该使用let而不是const声明,因为它不是真正的常量`
1347
- };
1603
+ // 检查是否为函数赋值(函数表达式或箭头函数)
1604
+ var is_function_assignment = this._isFunctionAssignment(node);
1605
+
1606
+ // 如果是函数赋值,允许camelCase命名风格
1607
+ var allowed_styles = [];
1608
+ if (is_function_assignment) {
1609
+ allowed_styles = ['camelCase', 'UPPER_SNAKE_CASE'];
1610
+ } else {
1611
+ allowed_styles = rule.styles;
1612
+ }
1613
+
1614
+ // 检查命名风格
1615
+ var style_err = this._validate_naming_style(constant_name, allowed_styles, 'constant-name');
1616
+ if (style_err) {
1617
+ return {
1618
+ node: node,
1619
+ message: style_err,
1620
+ };
1621
+ }
1348
1622
 
1349
1623
  // 检查并推荐更合适的词汇
1350
1624
  var rec_err = this._checkAndRecommend(constant_name, 'constant-name');
package/index.js CHANGED
@@ -331,11 +331,17 @@ function createNamingRules() {
331
331
  return;
332
332
  }
333
333
 
334
+ // 传递祖父节点信息,用于第三方库排除检测
335
+ var parent_info = {
336
+ node: node.parent,
337
+ parent: node.parent ? node.parent.parent : null
338
+ };
339
+
334
340
  var err = detector._checkPropertyName(
335
341
  prop_name,
336
342
  node,
337
343
  node.value,
338
- node.parent,
344
+ parent_info,
339
345
  );
340
346
 
341
347
  if (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mm_eslint",
3
- "version": "1.3.9",
3
+ "version": "1.4.1",
4
4
  "description": "ESLint plugin for naming conventions - PascalCase, camelCase, snake_case, and UPPER_SNAKE_CASE naming rules",
5
5
  "main": "index.js",
6
6
  "keywords": [