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.
- package/detector.js +302 -39
- package/index.js +7 -1
- 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
|
|
403
|
+
// 根据值类型确定应该应用的命名规则
|
|
404
|
+
var rule_type = 'constant-name'; // 默认使用常量命名规则
|
|
405
|
+
var allowed_styles = [];
|
|
415
406
|
|
|
416
|
-
//
|
|
417
|
-
if (
|
|
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
|
|
433
|
+
// 获取对应的命名规则
|
|
434
|
+
var rule = this.config.getRule(rule_type);
|
|
435
|
+
if (!rule) {
|
|
436
|
+
return null;
|
|
437
|
+
}
|
|
423
438
|
|
|
424
|
-
//
|
|
425
|
-
if (
|
|
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,
|
|
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 (!
|
|
736
|
+
if (!actual_parent_node || actual_parent_node.type !== 'ObjectExpression') {
|
|
716
737
|
return false;
|
|
717
738
|
}
|
|
718
739
|
|
|
719
|
-
//
|
|
720
|
-
var
|
|
721
|
-
|
|
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 =
|
|
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
|
-
|
|
1072
|
-
|
|
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
|
-
|
|
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 (
|
|
1376
|
+
if (actual_parent_node.type === 'ObjectPattern') {
|
|
1208
1377
|
// 检查父节点的父节点是否为VariableDeclarator
|
|
1209
|
-
|
|
1210
|
-
|
|
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
|
-
//
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
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
|
-
|
|
344
|
+
parent_info,
|
|
339
345
|
);
|
|
340
346
|
|
|
341
347
|
if (err) {
|