mm_eslint 1.4.0 → 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 +302 -39
  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,
@@ -711,25 +726,57 @@ Detector.prototype._splitNameIntoWords = function (name) {
711
726
  */
712
727
  Detector.prototype._isThirdPartyConfigProperty = function (node, parent_node) {
713
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
+
714
735
  // 检查当前节点是否为对象字面量的属性
715
- if (!parent_node || parent_node.type !== 'ObjectExpression') {
736
+ if (!actual_parent_node || actual_parent_node.type !== 'ObjectExpression') {
716
737
  return false;
717
738
  }
718
739
 
719
- // 检查对象字面量是否作为方法调用的参数
720
- var grandparent = parent_node.parent;
721
- 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) {
722
762
  return false;
723
763
  }
724
764
 
725
765
  // 检查方法调用是否来自外部模块(非当前文件定义的函数)
726
- var callee = grandparent.callee;
766
+ var callee = call_expression.callee;
727
767
  if (!callee) {
728
768
  return false;
729
769
  }
730
770
 
731
771
  // 如果是成员表达式(如 chokidar.watch),则认为是第三方库调用
732
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
+ // 对于其他成员表达式,也认为是第三方库调用(保守策略)
733
780
  return true;
734
781
  }
735
782
 
@@ -746,6 +793,12 @@ Detector.prototype._isThirdPartyConfigProperty = function (node, parent_node) {
746
793
  return true;
747
794
  }
748
795
 
796
+ // 检查标识符是否为模块导入变量
797
+ var is_module_import = this._isModuleImportVariable(callee);
798
+ if (is_module_import) {
799
+ return true;
800
+ }
801
+
749
802
  // 对于其他标识符,暂时不认为是第三方库调用(避免误判)
750
803
  return false;
751
804
  }
@@ -1056,6 +1109,12 @@ Detector.prototype._shouldUseLetInsteadOfConst = function (node, val_node) {
1056
1109
  return false;
1057
1110
  }
1058
1111
 
1112
+ // 检查是否为模块导入(需要排除的情况)
1113
+ var is_module_import = this._isModuleImport(node, val_node);
1114
+ if (is_module_import) {
1115
+ return false;
1116
+ }
1117
+
1059
1118
  // 检查是否为解构赋值
1060
1119
  var is_destructuring = false;
1061
1120
  if (node.parent && node.parent.type === 'VariableDeclarator') {
@@ -1065,11 +1124,30 @@ Detector.prototype._shouldUseLetInsteadOfConst = function (node, val_node) {
1065
1124
  }
1066
1125
  }
1067
1126
 
1068
- // 检查右侧是否为复杂类型(类实例、函数、对象等)
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
+ // 检查是否为解构赋值且右侧是复杂类型
1069
1145
  var is_complex_type = this._isComplexType(val_node);
1070
-
1071
- // 如果是解构赋值且右侧是复杂类型,建议使用let
1072
- 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;
1073
1151
  } catch (error) {
1074
1152
  console.error('检查是否应该使用let时出错:', error);
1075
1153
  return false;
@@ -1113,6 +1191,91 @@ Detector.prototype._isComplexType = function (val_node) {
1113
1191
  }
1114
1192
  };
1115
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
+
1116
1279
  /**
1117
1280
  * 检查是否为解构导入
1118
1281
  * @param {object} node AST节点
@@ -1199,15 +1362,25 @@ Detector.prototype._isDestructuredImport = function (node) {
1199
1362
  */
1200
1363
  Detector.prototype._isDestructuredImportProperty = function (node, parent_node) {
1201
1364
  try {
1202
- 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) {
1203
1372
  return false;
1204
1373
  }
1205
1374
 
1206
1375
  // 检查父节点是否为ObjectPattern(解构模式)
1207
- if (parent_node.type === 'ObjectPattern') {
1376
+ if (actual_parent_node.type === 'ObjectPattern') {
1208
1377
  // 检查父节点的父节点是否为VariableDeclarator
1209
- if (parent_node.parent && parent_node.parent.type === 'VariableDeclarator') {
1210
- 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;
1211
1384
 
1212
1385
  // 检查右侧是否为require调用或其他模块导入
1213
1386
  if (declarator.init) {
@@ -1235,6 +1408,83 @@ Detector.prototype._isDestructuredImportProperty = function (node, parent_node)
1235
1408
  }
1236
1409
  };
1237
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
+
1238
1488
  /**
1239
1489
  * 检查常量名是否符合规范
1240
1490
  * @param {string} constant_name 常量名
@@ -1350,12 +1600,25 @@ Detector.prototype._checkConstantNameForDestructuring = function (constant_name,
1350
1600
  return null;
1351
1601
  }
1352
1602
 
1353
- // 对于解构赋值,直接提示使用let而不是const
1354
- // 因为解构赋值通常不是真正的常量
1355
- return {
1356
- node: node,
1357
- message: `变量'${constant_name}'应该使用let而不是const声明,因为它不是真正的常量`
1358
- };
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
+ }
1359
1622
 
1360
1623
  // 检查并推荐更合适的词汇
1361
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.4.0",
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": [