mm_eslint 1.1.3 → 1.1.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/index.js +205 -76
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -184,6 +184,11 @@ class Detector {
|
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
},
|
|
187
|
+
// 私有方法前缀列表:以这些前缀开头的方法名应该被检测为私有方法
|
|
188
|
+
private_method_prefixes: [
|
|
189
|
+
'setup', 'init', 'internal', 'private', 'helper', 'util'
|
|
190
|
+
],
|
|
191
|
+
|
|
187
192
|
// 废话词
|
|
188
193
|
forbidden_words: {
|
|
189
194
|
// 类废话词:禁止在类名中使用的冗余拼接词汇(统一小写)
|
|
@@ -1777,36 +1782,55 @@ const method_name_rule = {
|
|
|
1777
1782
|
},
|
|
1778
1783
|
create(context) {
|
|
1779
1784
|
const options = context.options[0] || {};
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
return;
|
|
1787
|
-
}
|
|
1785
|
+
|
|
1786
|
+
function checkMethodName(node, method_name) {
|
|
1787
|
+
// 跳过私有方法的检测(私有方法由private-naming规则处理)
|
|
1788
|
+
if (method_name.startsWith("_")) {
|
|
1789
|
+
return;
|
|
1790
|
+
}
|
|
1788
1791
|
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1792
|
+
// 跳过JavaScript内置特殊方法名
|
|
1793
|
+
const builtin_methods = [
|
|
1794
|
+
"constructor",
|
|
1795
|
+
"toString",
|
|
1796
|
+
"valueOf",
|
|
1797
|
+
"toJSON",
|
|
1798
|
+
];
|
|
1799
|
+
if (builtin_methods.includes(method_name)) {
|
|
1800
|
+
return;
|
|
1801
|
+
}
|
|
1799
1802
|
|
|
1800
|
-
|
|
1801
|
-
|
|
1803
|
+
const detector = new Detector({ "method-name": options });
|
|
1804
|
+
const result = detector.checkName(method_name, "method-name");
|
|
1802
1805
|
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
});
|
|
1806
|
+
if (!result.valid) {
|
|
1807
|
+
result.errors.forEach((error) => {
|
|
1808
|
+
context.report({
|
|
1809
|
+
node: node.key || node,
|
|
1810
|
+
message: `方法名"${method_name}"不符合规范: ${error}`,
|
|
1809
1811
|
});
|
|
1812
|
+
});
|
|
1813
|
+
}
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
return {
|
|
1817
|
+
// 处理类中的方法
|
|
1818
|
+
MethodDefinition(node) {
|
|
1819
|
+
checkMethodName(node, node.key.name);
|
|
1820
|
+
},
|
|
1821
|
+
|
|
1822
|
+
// 处理对象字面量中的方法
|
|
1823
|
+
Property(node) {
|
|
1824
|
+
// 检查是否是方法(函数表达式或箭头函数或方法简写)
|
|
1825
|
+
if (node.key.type === "Identifier" && !node.key.name.startsWith("_")) {
|
|
1826
|
+
const is_method = node.value &&
|
|
1827
|
+
(node.value.type === "FunctionExpression" ||
|
|
1828
|
+
node.value.type === "ArrowFunctionExpression" ||
|
|
1829
|
+
(node.method === true)); // 方法简写语法
|
|
1830
|
+
|
|
1831
|
+
if (is_method) {
|
|
1832
|
+
checkMethodName(node, node.key.name);
|
|
1833
|
+
}
|
|
1810
1834
|
}
|
|
1811
1835
|
},
|
|
1812
1836
|
};
|
|
@@ -2063,20 +2087,18 @@ const constant_name_rule = {
|
|
|
2063
2087
|
return {
|
|
2064
2088
|
VariableDeclarator(node) {
|
|
2065
2089
|
if (node.id.type === "Identifier" && node.parent.kind === "const") {
|
|
2066
|
-
//
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
const result = detector.checkName(constant_name, "constant-name");
|
|
2090
|
+
// 对所有const声明应用常量命名规则
|
|
2091
|
+
const constant_name = node.id.name;
|
|
2092
|
+
const detector = new Detector({ "constant-name": options });
|
|
2093
|
+
const result = detector.checkName(constant_name, "constant-name");
|
|
2071
2094
|
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
});
|
|
2095
|
+
if (!result.valid) {
|
|
2096
|
+
result.errors.forEach((error) => {
|
|
2097
|
+
context.report({
|
|
2098
|
+
node: node.id,
|
|
2099
|
+
message: `常量名"${constant_name}"不符合规范: ${error}`,
|
|
2078
2100
|
});
|
|
2079
|
-
}
|
|
2101
|
+
});
|
|
2080
2102
|
}
|
|
2081
2103
|
}
|
|
2082
2104
|
},
|
|
@@ -2184,19 +2206,20 @@ const prop_name_rule = {
|
|
|
2184
2206
|
const options = context.options[0] || {};
|
|
2185
2207
|
return {
|
|
2186
2208
|
Property(node) {
|
|
2187
|
-
// 检测类属性、对象字面量属性、模块导出属性
|
|
2188
|
-
const is_class_property =
|
|
2189
|
-
node.parent &&
|
|
2190
|
-
(node.parent.type === "ClassBody" ||
|
|
2191
|
-
(node.parent.type === "ObjectExpression" &&
|
|
2192
|
-
node.parent.parent &&
|
|
2193
|
-
node.parent.parent.type === "ClassDeclaration"));
|
|
2194
|
-
|
|
2195
|
-
const is_object_property =
|
|
2196
|
-
node.parent && node.parent.type === "ObjectExpression";
|
|
2197
|
-
|
|
2198
2209
|
// 检测所有非私有属性(不以_开头)
|
|
2199
2210
|
if (node.key.type === "Identifier" && !node.key.name.startsWith("_")) {
|
|
2211
|
+
// 检查是否是方法(函数表达式或箭头函数或方法简写)
|
|
2212
|
+
const is_method = node.value &&
|
|
2213
|
+
(node.value.type === "FunctionExpression" ||
|
|
2214
|
+
node.value.type === "ArrowFunctionExpression" ||
|
|
2215
|
+
(node.method === true)); // 方法简写语法
|
|
2216
|
+
|
|
2217
|
+
// 如果是方法,跳过属性检测(方法由method-name规则处理)
|
|
2218
|
+
if (is_method) {
|
|
2219
|
+
return;
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2222
|
+
// 如果是真正的属性,使用属性规则检测
|
|
2200
2223
|
const prop_name = node.key.name;
|
|
2201
2224
|
const detector = new Detector({ "property-name": options });
|
|
2202
2225
|
const result = detector._checkPropName(prop_name, node.value);
|
|
@@ -2206,6 +2229,7 @@ const prop_name_rule = {
|
|
|
2206
2229
|
context.report({
|
|
2207
2230
|
node: node.key,
|
|
2208
2231
|
message: `属性名"${prop_name}"不符合规范: ${error}`,
|
|
2232
|
+
ruleId: "naming-convention/property-name",
|
|
2209
2233
|
});
|
|
2210
2234
|
});
|
|
2211
2235
|
}
|
|
@@ -2244,23 +2268,81 @@ const private_method_rule = {
|
|
|
2244
2268
|
},
|
|
2245
2269
|
create(context) {
|
|
2246
2270
|
const options = context.options[0] || {};
|
|
2271
|
+
|
|
2272
|
+
function checkPrivateMethodName(node, method_name) {
|
|
2273
|
+
const detector = new Detector({ "private-method-naming": options });
|
|
2274
|
+
const result = detector.checkName(
|
|
2275
|
+
method_name,
|
|
2276
|
+
"private-method-naming",
|
|
2277
|
+
);
|
|
2278
|
+
|
|
2279
|
+
if (!result.valid) {
|
|
2280
|
+
result.errors.forEach((error) => {
|
|
2281
|
+
context.report({
|
|
2282
|
+
node: node.key || node,
|
|
2283
|
+
message: `私有方法名"${method_name}"不符合规范: ${error}`,
|
|
2284
|
+
});
|
|
2285
|
+
});
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
|
|
2289
|
+
// 检测应该是私有方法但没有_前缀的情况
|
|
2290
|
+
function checkMissingPrivatePrefix(node, method_name) {
|
|
2291
|
+
// 使用配置中的私有方法前缀列表
|
|
2292
|
+
const detector = new Detector({ "private-method-naming": options });
|
|
2293
|
+
const private_prefixes = detector.config.private_method_prefixes || [];
|
|
2294
|
+
|
|
2295
|
+
// 判断是否应该是私有方法(基于前缀判断)
|
|
2296
|
+
const should_be_private = private_prefixes.some(prefix => {
|
|
2297
|
+
if (!method_name.toLowerCase().startsWith(prefix.toLowerCase())) {
|
|
2298
|
+
return false;
|
|
2299
|
+
}
|
|
2300
|
+
|
|
2301
|
+
// 额外检查:只有多单词的方法名才需要是私有方法
|
|
2302
|
+
// 例如:init() 可以非私有,但initService() 必须私有
|
|
2303
|
+
const remaining_part = method_name.substring(prefix.length);
|
|
2304
|
+
const is_multi_word = remaining_part.length > 0 &&
|
|
2305
|
+
remaining_part[0].toUpperCase() === remaining_part[0];
|
|
2306
|
+
|
|
2307
|
+
return is_multi_word;
|
|
2308
|
+
});
|
|
2309
|
+
|
|
2310
|
+
if (should_be_private && !method_name.startsWith("_")) {
|
|
2311
|
+
context.report({
|
|
2312
|
+
node: node.key || node,
|
|
2313
|
+
message: `方法名"${method_name}"应该是私有方法,但缺少_前缀`,
|
|
2314
|
+
});
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
|
|
2247
2318
|
return {
|
|
2319
|
+
// 处理类中的私有方法
|
|
2248
2320
|
MethodDefinition(node) {
|
|
2249
2321
|
const method_name = node.key.name;
|
|
2250
2322
|
if (method_name.startsWith("_")) {
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2323
|
+
checkPrivateMethodName(node, method_name);
|
|
2324
|
+
} else {
|
|
2325
|
+
// 检测应该是私有方法但没有_前缀的情况
|
|
2326
|
+
checkMissingPrivatePrefix(node, method_name);
|
|
2327
|
+
}
|
|
2328
|
+
},
|
|
2329
|
+
|
|
2330
|
+
// 处理对象字面量中的私有方法
|
|
2331
|
+
Property(node) {
|
|
2332
|
+
if (node.key.type === "Identifier") {
|
|
2333
|
+
// 检查是否是方法(函数表达式或箭头函数或方法简写)
|
|
2334
|
+
const is_method = node.value &&
|
|
2335
|
+
(node.value.type === "FunctionExpression" ||
|
|
2336
|
+
node.value.type === "ArrowFunctionExpression" ||
|
|
2337
|
+
(node.method === true)); // 方法简写语法
|
|
2338
|
+
|
|
2339
|
+
if (is_method) {
|
|
2340
|
+
if (node.key.name.startsWith("_")) {
|
|
2341
|
+
checkPrivateMethodName(node, node.key.name);
|
|
2342
|
+
} else {
|
|
2343
|
+
// 检测应该是私有方法但没有_前缀的情况
|
|
2344
|
+
checkMissingPrivatePrefix(node, node.key.name);
|
|
2345
|
+
}
|
|
2264
2346
|
}
|
|
2265
2347
|
}
|
|
2266
2348
|
},
|
|
@@ -2300,20 +2382,43 @@ const private_variable_rule = {
|
|
|
2300
2382
|
return {
|
|
2301
2383
|
Property(node) {
|
|
2302
2384
|
if (node.key.type === "Identifier" && node.key.name.startsWith("_")) {
|
|
2303
|
-
|
|
2304
|
-
const
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2385
|
+
// 检查是否是方法(函数表达式或箭头函数)
|
|
2386
|
+
const is_method = node.value &&
|
|
2387
|
+
(node.value.type === "FunctionExpression" ||
|
|
2388
|
+
node.value.type === "ArrowFunctionExpression");
|
|
2389
|
+
|
|
2390
|
+
// 如果是方法,应该使用私有方法规则检测,而不是私有变量规则
|
|
2391
|
+
if (is_method) {
|
|
2392
|
+
const detector = new Detector({ "private-method-naming": options });
|
|
2393
|
+
const result = detector.checkName(
|
|
2394
|
+
node.key.name,
|
|
2395
|
+
"private-method-naming",
|
|
2396
|
+
);
|
|
2309
2397
|
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2398
|
+
if (!result.valid) {
|
|
2399
|
+
result.errors.forEach((error) => {
|
|
2400
|
+
context.report({
|
|
2401
|
+
node: node.key,
|
|
2402
|
+
message: `私有方法名"${node.key.name}"不符合规范: ${error}`,
|
|
2403
|
+
});
|
|
2315
2404
|
});
|
|
2316
|
-
}
|
|
2405
|
+
}
|
|
2406
|
+
} else {
|
|
2407
|
+
// 如果是真正的属性,使用私有变量规则检测
|
|
2408
|
+
const detector = new Detector({ "private-variable-naming": options });
|
|
2409
|
+
const result = detector.checkName(
|
|
2410
|
+
node.key.name,
|
|
2411
|
+
"private-variable-naming",
|
|
2412
|
+
);
|
|
2413
|
+
|
|
2414
|
+
if (!result.valid) {
|
|
2415
|
+
result.errors.forEach((error) => {
|
|
2416
|
+
context.report({
|
|
2417
|
+
node: node.key,
|
|
2418
|
+
message: `私有属性名"${node.key.name}"不符合规范: ${error}`,
|
|
2419
|
+
});
|
|
2420
|
+
});
|
|
2421
|
+
}
|
|
2317
2422
|
}
|
|
2318
2423
|
}
|
|
2319
2424
|
},
|
|
@@ -2360,8 +2465,9 @@ const instance_property_rule = {
|
|
|
2360
2465
|
!node.left.property.name.startsWith("_")
|
|
2361
2466
|
) {
|
|
2362
2467
|
const prop_name = node.left.property.name;
|
|
2363
|
-
|
|
2364
|
-
const
|
|
2468
|
+
// 实例属性应该符合方法命名规范(小驼峰)
|
|
2469
|
+
const detector = new Detector({ "method-name": options });
|
|
2470
|
+
const result = detector.checkName(prop_name, "method-name");
|
|
2365
2471
|
|
|
2366
2472
|
if (!result.valid) {
|
|
2367
2473
|
result.errors.forEach((error) => {
|
|
@@ -2373,6 +2479,29 @@ const instance_property_rule = {
|
|
|
2373
2479
|
}
|
|
2374
2480
|
}
|
|
2375
2481
|
},
|
|
2482
|
+
// 检测构造函数内的属性声明
|
|
2483
|
+
PropertyDefinition(node) {
|
|
2484
|
+
if (
|
|
2485
|
+
node.parent &&
|
|
2486
|
+
node.parent.type === "ClassBody" &&
|
|
2487
|
+
node.key.type === "Identifier" &&
|
|
2488
|
+
!node.key.name.startsWith("_")
|
|
2489
|
+
) {
|
|
2490
|
+
const prop_name = node.key.name;
|
|
2491
|
+
// 实例属性应该符合方法命名规范(小驼峰)
|
|
2492
|
+
const detector = new Detector({ "method-name": options });
|
|
2493
|
+
const result = detector.checkName(prop_name, "method-name");
|
|
2494
|
+
|
|
2495
|
+
if (!result.valid) {
|
|
2496
|
+
result.errors.forEach((error) => {
|
|
2497
|
+
context.report({
|
|
2498
|
+
node: node.key,
|
|
2499
|
+
message: `实例属性名"${prop_name}"不符合规范: ${error}`,
|
|
2500
|
+
});
|
|
2501
|
+
});
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
},
|
|
2376
2505
|
};
|
|
2377
2506
|
},
|
|
2378
2507
|
};
|