mm_eslint 1.0.1 → 1.0.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/README.md +125 -18
- package/README_EN.md +121 -14
- package/index.js +573 -96
- package/package.json +5 -2
package/index.js
CHANGED
|
@@ -3,91 +3,120 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* 命名规范检测器类
|
|
5
5
|
*/
|
|
6
|
-
class
|
|
6
|
+
class Detector {
|
|
7
7
|
static config = {
|
|
8
8
|
forbidden_words: [
|
|
9
9
|
'manager', 'handler', 'processor', 'controller',
|
|
10
10
|
'Management', 'Handler', 'Processor', 'Controller',
|
|
11
11
|
'LoggerManager', 'AppState', 'UserHandler'
|
|
12
12
|
],
|
|
13
|
+
regex: {
|
|
14
|
+
'PascalCase': /^[A-Z][a-zA-Z]*$/, // 大驼峰:大写字母开头,只包含字母。主要用于类名
|
|
15
|
+
'camelCase': /^[a-z][a-zA-Z]*$/, // 小驼峰:小写字母开头,只包含字母。主要用于方法名、函数名
|
|
16
|
+
'snake_case': /^[a-z][a-z0-9_]*(_[a-z0-9]+)*$/, // 小写蛇形:小写字母开头,可包含下划线。主要用于变量名、入参名
|
|
17
|
+
'UPPER_SNAKE_CASE': /^[A-Z][A-Z0-9_]*(_[A-Z0-9]+)*$/, // 大写蛇形:大写字母开头,可包含下划线。主要用于常量名
|
|
18
|
+
'kebab-case': /^[a-z][a-z0-9-]*(-[a-z0-9]+)*$/, // 小写横杠:小写字母开头,可包含短横线,小写短横线。主要用于资源名、路由路径
|
|
19
|
+
'UPPER-KEBAB-CASE': /^[A-Z][A-Z0-9-]*(-[A-Z0-9]+)*$/, // 大写横杠:大写字母开头,可包含短横线,大写短横线。主要用于资源名、路由路径
|
|
20
|
+
'lowercase': /^[a-z][a-z0-9]*$/, // 小写单词:小写字母开头,只包含小写字母和数字。主要用于对象、属性名
|
|
21
|
+
'UPPERCASE': /^[A-Z][A-Z0-9]*$/, // 大写单词:大写字母开头,只包含大写字母和数字。主要用于枚举值、常量名
|
|
22
|
+
'camelCase-kebab': /^[a-z][a-z0-9-]*(-[a-z0-9]+)*$/, // 支持横杠小驼峰:小写字母开头,可包含短横线,小写短横线。主要用于资源名、路由路径
|
|
23
|
+
'PascalCase-kebab': /^[A-Z][a-zA-Z]*$/, // 支持横杠大驼峰:大写字母开头,只包含字母。主要用于资源名、路由路径
|
|
24
|
+
'_camelCase': /^_[a-z][a-zA-Z]*$/, // 下划线小驼峰:下划线加小写字母开头,只包含字母。主要用于私有方法名
|
|
25
|
+
'_snake_case': /^_[a-z][a-z0-9_]*(_[a-z0-9]+)*$/, // 下划线小写蛇形:下划线加小写字母开头,可包含下划线。主要用于私有变量名
|
|
26
|
+
'_lowercase': /^_[a-z][a-z0-9]*$/, // 下划线小写单词:下划线加小写字母开头,只包含小写字母和数字。主要用于对象、属性名
|
|
27
|
+
},
|
|
28
|
+
|
|
13
29
|
// 类名大驼峰规则
|
|
14
30
|
'class-name': {
|
|
15
31
|
name: '类名',
|
|
16
|
-
message: '
|
|
17
|
-
regex:
|
|
32
|
+
message: '必须使用大驼峰命名法(PascalCase),长度{min}-{max}字符,且优先使用单个单词,每个单词不超过{word_len}字符',
|
|
33
|
+
regex: null, // 使用styles属性进行验证
|
|
18
34
|
min: 1,
|
|
19
|
-
max: 20
|
|
35
|
+
max: 20,
|
|
36
|
+
styles: ['PascalCase'],
|
|
37
|
+
single_word: true,
|
|
38
|
+
single_word_len: 8
|
|
20
39
|
},
|
|
21
40
|
|
|
22
41
|
// 函数名小驼峰规则
|
|
23
42
|
'function-name': {
|
|
24
43
|
name: '函数名',
|
|
25
|
-
message: '必须使用小驼峰命名法(camelCase),长度{min}-{max}
|
|
26
|
-
regex:
|
|
44
|
+
message: '必须使用小驼峰命名法(camelCase),长度{min}-{max}字符,且优先使用单个单词,每个单词不超过{word_len}字符',
|
|
45
|
+
regex: null, // 使用styles属性进行验证
|
|
27
46
|
min: 1,
|
|
28
47
|
max: 20,
|
|
29
|
-
|
|
48
|
+
styles: ['camelCase'],
|
|
49
|
+
single_word: true,
|
|
50
|
+
single_word_len: 8
|
|
30
51
|
},
|
|
31
52
|
|
|
32
53
|
// 方法名小驼峰规则
|
|
33
54
|
'method-name': {
|
|
34
55
|
name: '方法名',
|
|
35
|
-
message: '必须使用小驼峰命名法(camelCase),长度{min}-{max}
|
|
36
|
-
regex:
|
|
56
|
+
message: '必须使用小驼峰命名法(camelCase),长度{min}-{max}字符,且优先使用单个单词,每个单词不超过{word_len}字符',
|
|
57
|
+
regex: null, // 使用styles属性进行验证
|
|
37
58
|
min: 1,
|
|
38
59
|
max: 20,
|
|
39
|
-
|
|
60
|
+
styles: ['camelCase'],
|
|
61
|
+
single_word: true,
|
|
62
|
+
single_word_len: 8
|
|
40
63
|
},
|
|
41
64
|
|
|
42
65
|
// 入参名小写蛇形规则
|
|
43
66
|
'param-name': {
|
|
44
67
|
name: '入参名',
|
|
45
68
|
message: '必须使用小写蛇形命名法(snake_case),长度{min}-{max}字符',
|
|
46
|
-
regex:
|
|
69
|
+
regex: null, // 使用styles属性进行验证
|
|
47
70
|
min: 1,
|
|
48
|
-
max: 20
|
|
71
|
+
max: 20,
|
|
72
|
+
styles: ['lowercase', 'snake_case']
|
|
49
73
|
},
|
|
50
74
|
|
|
51
75
|
// 变量名小写蛇形规则
|
|
52
76
|
'variable-name': {
|
|
53
77
|
name: '变量名',
|
|
54
78
|
message: '必须使用小写蛇形命名法(snake_case),长度{min}-{max}字符',
|
|
55
|
-
regex:
|
|
79
|
+
regex: null, // 使用styles属性进行验证
|
|
56
80
|
min: 1,
|
|
57
|
-
max: 20
|
|
81
|
+
max: 20,
|
|
82
|
+
styles: ['lowercase', 'snake_case']
|
|
58
83
|
},
|
|
59
84
|
|
|
60
85
|
// 常量名大写蛇形规则
|
|
61
86
|
'constant-name': {
|
|
62
87
|
name: '常量名',
|
|
63
88
|
message: '必须使用大写蛇形命名法(UPPER_SNAKE_CASE),长度{min}-{max}字符',
|
|
64
|
-
regex:
|
|
89
|
+
regex: null, // 使用styles属性进行验证
|
|
65
90
|
min: 1,
|
|
66
|
-
max: 20
|
|
91
|
+
max: 20,
|
|
92
|
+
styles: ['UPPERCASE', 'UPPER_SNAKE_CASE']
|
|
67
93
|
},
|
|
68
94
|
|
|
69
|
-
//
|
|
95
|
+
// 属性名多风格规则(根据值类型应用不同规则)
|
|
70
96
|
'property-name': {
|
|
71
97
|
name: '属性名',
|
|
72
|
-
message: '
|
|
73
|
-
regex: /^[a-z][a-z0-9_]*(_[a-z0-9]+)*$/, // 小写字母开头,可包含下划线
|
|
98
|
+
message: '根据属性值类型应用不同命名规则',
|
|
74
99
|
min: 1,
|
|
75
|
-
max: 20
|
|
100
|
+
max: 20,
|
|
101
|
+
single_word: true,
|
|
102
|
+
single_word_len: 8,
|
|
103
|
+
styles: ['lowercase', '_lowercase', 'UPPERCASE', 'snake_case', '_snake_case']
|
|
76
104
|
},
|
|
77
105
|
|
|
78
106
|
// 私有方法/属性规则
|
|
79
107
|
'private-naming': {
|
|
80
108
|
name: '私有成员',
|
|
81
109
|
message: '必须以单下划线开头,后跟小写蛇形命名,长度{min}-{max}字符',
|
|
82
|
-
regex:
|
|
110
|
+
regex: null, // 使用styles属性进行验证
|
|
83
111
|
min: 2,
|
|
84
|
-
max: 20
|
|
112
|
+
max: 20,
|
|
113
|
+
styles: ['_lowercase', '_snake_case', '_camelCase']
|
|
85
114
|
}
|
|
86
115
|
}
|
|
87
116
|
|
|
88
117
|
constructor(config) {
|
|
89
118
|
// 合并默认配置和传入配置
|
|
90
|
-
const merged_config = { ...
|
|
119
|
+
const merged_config = { ...Detector.config };
|
|
91
120
|
if (config && typeof config === 'object') {
|
|
92
121
|
Object.keys(config).forEach(key => {
|
|
93
122
|
if (merged_config[key]) {
|
|
@@ -116,29 +145,40 @@ class NamingDetector {
|
|
|
116
145
|
this._init_rules();
|
|
117
146
|
}
|
|
118
147
|
|
|
119
|
-
_new_model() {
|
|
120
|
-
return {
|
|
121
|
-
name: '',
|
|
122
|
-
message: '',
|
|
123
|
-
regex: null,
|
|
124
|
-
min: 1,
|
|
125
|
-
max: 20
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
148
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* 创建新的规则模型
|
|
153
|
+
* @returns {Object} 规则模型
|
|
154
|
+
* @private
|
|
155
|
+
*/
|
|
156
|
+
Detector.prototype._new_model = function () {
|
|
157
|
+
return {
|
|
158
|
+
name: '',
|
|
159
|
+
message: '',
|
|
160
|
+
regex: null,
|
|
161
|
+
min: 1,
|
|
162
|
+
max: 20
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* 初始化规则检查方法
|
|
168
|
+
* @private
|
|
169
|
+
*/
|
|
170
|
+
Detector.prototype._init_rules = function () {
|
|
171
|
+
// 绑定规则检查方法
|
|
172
|
+
this._rules = {
|
|
173
|
+
'class-name': this._checkName.bind(this, 'class-name'),
|
|
174
|
+
'function-name': this._checkName.bind(this, 'function-name'),
|
|
175
|
+
'method-name': this._checkName.bind(this, 'method-name'),
|
|
176
|
+
'param-name': this._checkName.bind(this, 'param-name'),
|
|
177
|
+
'variable-name': this._checkName.bind(this, 'variable-name'),
|
|
178
|
+
'constant-name': this._checkName.bind(this, 'constant-name'),
|
|
179
|
+
'property-name': this._checkPropertyName.bind(this),
|
|
180
|
+
'private-naming': this._checkName.bind(this, 'private-naming')
|
|
181
|
+
};
|
|
142
182
|
}
|
|
143
183
|
|
|
144
184
|
/**
|
|
@@ -148,7 +188,7 @@ class NamingDetector {
|
|
|
148
188
|
* @returns {Object} 检查结果
|
|
149
189
|
* @private
|
|
150
190
|
*/
|
|
151
|
-
|
|
191
|
+
Detector.prototype._checkName = function (rule_type, name) {
|
|
152
192
|
if (!name) {
|
|
153
193
|
throw new TypeError('名称不能为空');
|
|
154
194
|
}
|
|
@@ -159,6 +199,7 @@ NamingDetector.prototype._checkName = function (rule_type, name) {
|
|
|
159
199
|
}
|
|
160
200
|
|
|
161
201
|
const errors = [];
|
|
202
|
+
const warnings = [];
|
|
162
203
|
|
|
163
204
|
// 检查长度
|
|
164
205
|
if (name.length < config.min) {
|
|
@@ -168,15 +209,32 @@ NamingDetector.prototype._checkName = function (rule_type, name) {
|
|
|
168
209
|
errors.push(`${config.name}长度不能超过${config.max}个字符`);
|
|
169
210
|
}
|
|
170
211
|
|
|
171
|
-
//
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
212
|
+
// 检查命名规则(优先使用regex,如果regex为空则使用styles)
|
|
213
|
+
let name_valid = false;
|
|
214
|
+
|
|
215
|
+
if (config.regex && config.regex.toString() !== '/(?:)/') {
|
|
216
|
+
// 使用regex进行验证
|
|
217
|
+
name_valid = config.regex.test(name);
|
|
218
|
+
if (!name_valid) {
|
|
219
|
+
const error_message = config.message
|
|
220
|
+
.replace('{name}', `"${name}"`)
|
|
221
|
+
.replace('{type}', config.name)
|
|
222
|
+
.replace('{min}', config.min)
|
|
223
|
+
.replace('{max}', config.max)
|
|
224
|
+
.replace('{word_len}', config.single_word_len || 8)
|
|
225
|
+
.replace('{regex}', config.regex.toString());
|
|
226
|
+
errors.push(error_message);
|
|
227
|
+
}
|
|
228
|
+
} else if (config.styles && config.styles.length > 0) {
|
|
229
|
+
// 使用styles进行验证
|
|
230
|
+
name_valid = this._checkNameByStyles(name, config.styles);
|
|
231
|
+
if (!name_valid) {
|
|
232
|
+
const allowed_styles = config.styles.join('、');
|
|
233
|
+
errors.push(`${config.name}必须符合以下命名风格之一:${allowed_styles}`);
|
|
234
|
+
}
|
|
235
|
+
} else {
|
|
236
|
+
// 既没有regex也没有styles,跳过命名格式检查
|
|
237
|
+
name_valid = true;
|
|
180
238
|
}
|
|
181
239
|
|
|
182
240
|
// 检查禁止词汇
|
|
@@ -184,26 +242,253 @@ NamingDetector.prototype._checkName = function (rule_type, name) {
|
|
|
184
242
|
errors.push(`${config.name}包含禁止的废话词`);
|
|
185
243
|
}
|
|
186
244
|
|
|
187
|
-
//
|
|
188
|
-
if (config.
|
|
189
|
-
|
|
190
|
-
|
|
245
|
+
// 检查是否优先使用单个单词(警告级别)
|
|
246
|
+
if (config.single_word) {
|
|
247
|
+
// 检测驼峰命名中的大写字母(表示多单词组合)
|
|
248
|
+
// 排除第一个字母后,检查是否包含大写字母(表示多单词)
|
|
249
|
+
const has_uppercase = /[A-Z]/.test(name.slice(1));
|
|
250
|
+
// 检测下划线或连字符
|
|
251
|
+
const has_separators = name.includes('_') || name.includes('-');
|
|
252
|
+
|
|
253
|
+
// 对于函数名和方法名,需要更精确地检测多单词
|
|
254
|
+
// getName(get前缀+单个单词)不算多单词,getUserName(get前缀+多单词)才算多单词
|
|
255
|
+
const is_function_or_method = rule_type === 'function-name' || rule_type === 'method-name';
|
|
256
|
+
let is_multi_word = has_uppercase || has_separators;
|
|
257
|
+
|
|
258
|
+
if (is_function_or_method && is_multi_word) {
|
|
259
|
+
// 检查是否是add/del/set/get/is/has等前缀后跟单个单词
|
|
260
|
+
const prefix_match = name.match(/^(add|del|set|get|is|has|can|not)([A-Z][a-z]*)$/);
|
|
261
|
+
if (prefix_match && prefix_match[2]) {
|
|
262
|
+
// 如果前缀后只有一个单词,不算多单词
|
|
263
|
+
is_multi_word = false;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (is_multi_word) {
|
|
268
|
+
warnings.push(`${config.name}应优先使用单个单词`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// 检查单个单词长度限制
|
|
273
|
+
if (config.single_word_len && config.single_word_len > 0) {
|
|
274
|
+
const words = this._splitWords(name, rule_type);
|
|
275
|
+
const long_words = words.filter(word => word.length > config.single_word_len);
|
|
276
|
+
|
|
277
|
+
if (long_words.length > 0) {
|
|
278
|
+
errors.push(`${config.name}中的单词"${long_words.join('、')}"超过${config.single_word_len}个字符限制`);
|
|
191
279
|
}
|
|
192
280
|
}
|
|
193
281
|
|
|
194
282
|
return {
|
|
195
283
|
valid: errors.length === 0,
|
|
196
|
-
errors: errors
|
|
284
|
+
errors: errors,
|
|
285
|
+
warnings: warnings
|
|
197
286
|
};
|
|
198
287
|
}
|
|
199
288
|
|
|
289
|
+
/**
|
|
290
|
+
* 根据styles列表检查名称是否符合命名风格
|
|
291
|
+
* @param {string} name - 名称
|
|
292
|
+
* @param {Array} styles - 命名风格列表
|
|
293
|
+
* @returns {boolean} 是否符合任一风格
|
|
294
|
+
* @private
|
|
295
|
+
*/
|
|
296
|
+
Detector.prototype._checkNameByStyles = function (name, styles) {
|
|
297
|
+
if (!name || !styles || styles.length === 0) {
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// 检查名称是否符合任一指定的命名风格
|
|
302
|
+
for (const style of styles) {
|
|
303
|
+
const regex = this.config.regex[style];
|
|
304
|
+
if (regex && regex.test(name)) {
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return false;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* 拆分名称中的单词
|
|
314
|
+
* @param {string} name - 名称
|
|
315
|
+
* @param {string} rule_type - 规则类型
|
|
316
|
+
* @returns {Array} 拆分后的单词数组
|
|
317
|
+
* @private
|
|
318
|
+
*/
|
|
319
|
+
Detector.prototype._splitWords = function (name, rule_type) {
|
|
320
|
+
if (!name) {
|
|
321
|
+
return [];
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const words = [];
|
|
325
|
+
|
|
326
|
+
// 根据命名风格拆分单词
|
|
327
|
+
if (name.includes('_')) {
|
|
328
|
+
// 蛇形命名:user_name → ["user", "name"]
|
|
329
|
+
words.push(...name.split('_').filter(word => word.length > 0));
|
|
330
|
+
} else if (name.includes('-')) {
|
|
331
|
+
// 横杠命名:user-name → ["user", "name"]
|
|
332
|
+
words.push(...name.split('-').filter(word => word.length > 0));
|
|
333
|
+
} else {
|
|
334
|
+
// 驼峰命名:userName → ["user", "Name"]
|
|
335
|
+
// 使用正则表达式拆分驼峰命名
|
|
336
|
+
const camel_case_words = name.split(/(?=[A-Z])/);
|
|
337
|
+
|
|
338
|
+
// 对于函数名和方法名,处理常见前缀
|
|
339
|
+
if (rule_type === 'function-name' || rule_type === 'method-name') {
|
|
340
|
+
const prefix_match = name.match(/^(add|del|set|get|is|has|can|not)([A-Z].*)$/);
|
|
341
|
+
if (prefix_match) {
|
|
342
|
+
// 如果是前缀+单词的组合,将前缀作为单独单词
|
|
343
|
+
words.push(prefix_match[1]);
|
|
344
|
+
// 拆分剩余部分
|
|
345
|
+
const remaining_words = prefix_match[2].split(/(?=[A-Z])/);
|
|
346
|
+
words.push(...remaining_words);
|
|
347
|
+
} else {
|
|
348
|
+
words.push(...camel_case_words);
|
|
349
|
+
}
|
|
350
|
+
} else {
|
|
351
|
+
words.push(...camel_case_words);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// 过滤空字符串并转换为小写进行比较
|
|
356
|
+
return words.filter(word => word.length > 0).map(word => word.toLowerCase());
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* 属性名检查方法(根据属性值类型应用不同规则)
|
|
361
|
+
* @param {string} name - 属性名
|
|
362
|
+
* @param {Object} value_node - 属性值AST节点
|
|
363
|
+
* @returns {Object} 检查结果
|
|
364
|
+
* @private
|
|
365
|
+
*/
|
|
366
|
+
Detector.prototype._checkPropertyName = function (name, value_node) {
|
|
367
|
+
if (!name) {
|
|
368
|
+
throw new TypeError('属性名不能为空');
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
const config = this.config['property-name'];
|
|
372
|
+
if (!config) {
|
|
373
|
+
throw new Error('属性名规则配置不存在');
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const errors = [];
|
|
377
|
+
const warnings = [];
|
|
378
|
+
|
|
379
|
+
// 检查长度
|
|
380
|
+
if (name.length < config.min) {
|
|
381
|
+
errors.push(`${config.name}长度不能少于${config.min}个字符`);
|
|
382
|
+
}
|
|
383
|
+
if (name.length > config.max) {
|
|
384
|
+
errors.push(`${config.name}长度不能超过${config.max}个字符`);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// 检查禁止词汇
|
|
388
|
+
if (this._hasForbiddenWords(name)) {
|
|
389
|
+
errors.push(`${config.name}包含禁止的废话词`);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// 根据属性值类型应用不同的命名规则
|
|
393
|
+
const value_type = this._getPropertyValueType(value_node);
|
|
394
|
+
|
|
395
|
+
switch (value_type) {
|
|
396
|
+
case 'function':
|
|
397
|
+
// 函数属性:使用函数名检测规则
|
|
398
|
+
const function_result = this._checkName('function-name', name);
|
|
399
|
+
if (!function_result.valid) {
|
|
400
|
+
errors.push(`${config.name}(函数属性)${function_result.errors.join(', ')}`);
|
|
401
|
+
}
|
|
402
|
+
break;
|
|
403
|
+
|
|
404
|
+
case 'class':
|
|
405
|
+
// 类属性:使用类名检测规则
|
|
406
|
+
const class_result = this._checkName('class-name', name);
|
|
407
|
+
if (!class_result.valid) {
|
|
408
|
+
errors.push(`${config.name}(类属性)${class_result.errors.join(', ')}`);
|
|
409
|
+
}
|
|
410
|
+
break;
|
|
411
|
+
|
|
412
|
+
case 'value':
|
|
413
|
+
default:
|
|
414
|
+
// 值属性:使用styles配置检查命名风格
|
|
415
|
+
const is_uppercase_snake = /^[A-Z][A-Z0-9_]*(_[A-Z0-9]+)+$/.test(name); // 包含下划线的大写蛇形
|
|
416
|
+
const is_uppercase_multi = /^[A-Z][A-Z0-9]*[A-Z][A-Z0-9]*$/.test(name); // 多单词大写组合(没有下划线)
|
|
417
|
+
|
|
418
|
+
// 检查是否为大写蛇形(禁止)
|
|
419
|
+
if (is_uppercase_snake || is_uppercase_multi) {
|
|
420
|
+
errors.push(`${config.name}(值属性)禁止使用大写蛇形命名(如PRODUCT_ID或PRODUCTID)`);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// 使用styles配置检查命名风格
|
|
424
|
+
if (config.styles && config.styles.length > 0) {
|
|
425
|
+
const is_valid_style = this._checkNameByStyles(name, config.styles);
|
|
426
|
+
if (!is_valid_style && !is_uppercase_snake && !is_uppercase_multi) {
|
|
427
|
+
const allowed_styles = config.styles.join('、');
|
|
428
|
+
errors.push(`${config.name}(值属性)必须符合以下命名风格之一:${allowed_styles}`);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
break;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// 检查是否优先使用单个单词(警告级别)
|
|
435
|
+
if (config.single_word) {
|
|
436
|
+
// 检测驼峰命名中的大写字母(表示多单词组合)
|
|
437
|
+
const has_uppercase = /[A-Z]/.test(name.slice(1));
|
|
438
|
+
// 检测下划线或连字符
|
|
439
|
+
const has_separators = name.includes('_') || name.includes('-');
|
|
440
|
+
|
|
441
|
+
if (has_uppercase || has_separators) {
|
|
442
|
+
warnings.push(`${config.name}应优先使用单个单词`);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
return {
|
|
447
|
+
valid: errors.length === 0,
|
|
448
|
+
errors: errors,
|
|
449
|
+
warnings: warnings,
|
|
450
|
+
value_type: value_type
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* 获取属性值类型
|
|
456
|
+
* @param {Object} value_node - 属性值AST节点
|
|
457
|
+
* @returns {string} 属性值类型('function', 'class', 'value')
|
|
458
|
+
* @private
|
|
459
|
+
*/
|
|
460
|
+
Detector.prototype._getPropertyValueType = function (value_node) {
|
|
461
|
+
if (!value_node) {
|
|
462
|
+
return 'value'; // 默认值类型
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// 检查是否为函数
|
|
466
|
+
if (value_node.type === 'FunctionExpression' ||
|
|
467
|
+
value_node.type === 'ArrowFunctionExpression' ||
|
|
468
|
+
(value_node.type === 'Identifier' && value_node.name &&
|
|
469
|
+
(value_node.name.endsWith('Function') || value_node.name.endsWith('Func') ||
|
|
470
|
+
value_node.name.startsWith('on') || value_node.name.startsWith('handle')))) {
|
|
471
|
+
return 'function';
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// 检查是否为类
|
|
475
|
+
if (value_node.type === 'ClassExpression' ||
|
|
476
|
+
(value_node.type === 'Identifier' && value_node.name &&
|
|
477
|
+
/^[A-Z][a-zA-Z]*$/.test(value_node.name))) {
|
|
478
|
+
return 'class';
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// 默认为值类型
|
|
482
|
+
return 'value';
|
|
483
|
+
}
|
|
484
|
+
|
|
200
485
|
/**
|
|
201
486
|
* 检查是否包含禁止的废话词
|
|
202
487
|
* @param {string} name - 名称
|
|
203
488
|
* @returns {boolean} 是否包含禁止词
|
|
204
489
|
* @private
|
|
205
490
|
*/
|
|
206
|
-
|
|
491
|
+
Detector.prototype._hasForbiddenWords = function (name) {
|
|
207
492
|
if (!name) {
|
|
208
493
|
return false;
|
|
209
494
|
}
|
|
@@ -221,7 +506,7 @@ NamingDetector.prototype._hasForbiddenWords = function (name) {
|
|
|
221
506
|
* @param {string} type - 类型(class/function/variable/constant/private)
|
|
222
507
|
* @returns {Object} 检测结果
|
|
223
508
|
*/
|
|
224
|
-
|
|
509
|
+
Detector.prototype.checkName = function (name, type) {
|
|
225
510
|
if (typeof name !== 'string' || !name.trim()) {
|
|
226
511
|
return {
|
|
227
512
|
valid: false,
|
|
@@ -260,7 +545,7 @@ NamingDetector.prototype.checkName = function (name, type) {
|
|
|
260
545
|
* @param {string} type - 类型
|
|
261
546
|
* @returns {Array} 检测结果数组
|
|
262
547
|
*/
|
|
263
|
-
|
|
548
|
+
Detector.prototype.checkNames = function (names, type) {
|
|
264
549
|
if (!Array.isArray(names)) {
|
|
265
550
|
throw new TypeError('名称必须是数组');
|
|
266
551
|
}
|
|
@@ -275,7 +560,7 @@ NamingDetector.prototype.checkNames = function (names, type) {
|
|
|
275
560
|
/**
|
|
276
561
|
* 类名大驼峰规则
|
|
277
562
|
*/
|
|
278
|
-
const
|
|
563
|
+
const class_name_rule = {
|
|
279
564
|
meta: {
|
|
280
565
|
type: 'suggestion',
|
|
281
566
|
docs: {
|
|
@@ -291,7 +576,9 @@ const classNameRule = {
|
|
|
291
576
|
min: { type: 'number' },
|
|
292
577
|
max: { type: 'number' },
|
|
293
578
|
message: { type: 'string' },
|
|
294
|
-
|
|
579
|
+
single_word: { type: 'boolean' },
|
|
580
|
+
single_word_len: { type: 'number' },
|
|
581
|
+
styles: { type: 'array', items: { type: 'string' } }
|
|
295
582
|
},
|
|
296
583
|
additionalProperties: false
|
|
297
584
|
}
|
|
@@ -302,7 +589,7 @@ const classNameRule = {
|
|
|
302
589
|
return {
|
|
303
590
|
ClassDeclaration(node) {
|
|
304
591
|
const class_name = node.id.name;
|
|
305
|
-
const detector = new
|
|
592
|
+
const detector = new Detector({ 'class-name': options });
|
|
306
593
|
const result = detector.checkName(class_name, 'class-name');
|
|
307
594
|
|
|
308
595
|
if (!result.valid) {
|
|
@@ -321,7 +608,7 @@ const classNameRule = {
|
|
|
321
608
|
/**
|
|
322
609
|
* 函数名小驼峰规则
|
|
323
610
|
*/
|
|
324
|
-
const
|
|
611
|
+
const function_name_rule = {
|
|
325
612
|
meta: {
|
|
326
613
|
type: 'suggestion',
|
|
327
614
|
docs: {
|
|
@@ -337,7 +624,9 @@ const functionNameRule = {
|
|
|
337
624
|
min: { type: 'number' },
|
|
338
625
|
max: { type: 'number' },
|
|
339
626
|
message: { type: 'string' },
|
|
340
|
-
|
|
627
|
+
single_word: { type: 'boolean' },
|
|
628
|
+
single_word_len: { type: 'number' },
|
|
629
|
+
styles: { type: 'array', items: { type: 'string' } }
|
|
341
630
|
},
|
|
342
631
|
additionalProperties: false
|
|
343
632
|
}
|
|
@@ -349,7 +638,7 @@ const functionNameRule = {
|
|
|
349
638
|
FunctionDeclaration(node) {
|
|
350
639
|
const function_name = node.id ? node.id.name : 'anonymous';
|
|
351
640
|
if (function_name !== 'anonymous') {
|
|
352
|
-
const detector = new
|
|
641
|
+
const detector = new Detector({ 'function-name': options });
|
|
353
642
|
const result = detector.checkName(function_name, 'function-name');
|
|
354
643
|
|
|
355
644
|
if (!result.valid) {
|
|
@@ -366,7 +655,7 @@ const functionNameRule = {
|
|
|
366
655
|
FunctionExpression(node) {
|
|
367
656
|
if (node.id) {
|
|
368
657
|
const function_name = node.id.name;
|
|
369
|
-
const detector = new
|
|
658
|
+
const detector = new Detector({ 'function-name': options });
|
|
370
659
|
const result = detector.checkName(function_name, 'function-name');
|
|
371
660
|
|
|
372
661
|
if (!result.valid) {
|
|
@@ -386,7 +675,7 @@ const functionNameRule = {
|
|
|
386
675
|
/**
|
|
387
676
|
* 方法名小驼峰规则
|
|
388
677
|
*/
|
|
389
|
-
const
|
|
678
|
+
const method_name_rule = {
|
|
390
679
|
meta: {
|
|
391
680
|
type: 'suggestion',
|
|
392
681
|
docs: {
|
|
@@ -402,7 +691,9 @@ const methodNameRule = {
|
|
|
402
691
|
min: { type: 'number' },
|
|
403
692
|
max: { type: 'number' },
|
|
404
693
|
message: { type: 'string' },
|
|
405
|
-
|
|
694
|
+
single_word: { type: 'boolean' },
|
|
695
|
+
single_word_len: { type: 'number' },
|
|
696
|
+
styles: { type: 'array', items: { type: 'string' } }
|
|
406
697
|
},
|
|
407
698
|
additionalProperties: false
|
|
408
699
|
}
|
|
@@ -413,7 +704,13 @@ const methodNameRule = {
|
|
|
413
704
|
return {
|
|
414
705
|
MethodDefinition(node) {
|
|
415
706
|
const method_name = node.key.name;
|
|
416
|
-
|
|
707
|
+
|
|
708
|
+
// 跳过私有方法的检测(私有方法由private-naming规则处理)
|
|
709
|
+
if (method_name.startsWith('_')) {
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
const detector = new Detector({ 'method-name': options });
|
|
417
714
|
const result = detector.checkName(method_name, 'method-name');
|
|
418
715
|
|
|
419
716
|
if (!result.valid) {
|
|
@@ -432,7 +729,7 @@ const methodNameRule = {
|
|
|
432
729
|
/**
|
|
433
730
|
* 变量名小写蛇形规则
|
|
434
731
|
*/
|
|
435
|
-
const
|
|
732
|
+
const variable_name_rule = {
|
|
436
733
|
meta: {
|
|
437
734
|
type: 'suggestion',
|
|
438
735
|
docs: {
|
|
@@ -448,7 +745,9 @@ const variableNameRule = {
|
|
|
448
745
|
min: { type: 'number' },
|
|
449
746
|
max: { type: 'number' },
|
|
450
747
|
message: { type: 'string' },
|
|
451
|
-
|
|
748
|
+
single_word: { type: 'boolean' },
|
|
749
|
+
single_word_len: { type: 'number' },
|
|
750
|
+
styles: { type: 'array', items: { type: 'string' } }
|
|
452
751
|
},
|
|
453
752
|
additionalProperties: false
|
|
454
753
|
}
|
|
@@ -456,11 +755,39 @@ const variableNameRule = {
|
|
|
456
755
|
},
|
|
457
756
|
create(context) {
|
|
458
757
|
const options = context.options[0] || {};
|
|
758
|
+
|
|
759
|
+
function isRealConstant(node) {
|
|
760
|
+
// 真正的常量特征:
|
|
761
|
+
// 1. 在模块顶层作用域(不在函数或块内)
|
|
762
|
+
// 2. 名称包含大写字母(表示意图作为常量)
|
|
763
|
+
|
|
764
|
+
// 检查是否在模块顶层
|
|
765
|
+
let scope_node = node;
|
|
766
|
+
while (scope_node.parent) {
|
|
767
|
+
scope_node = scope_node.parent;
|
|
768
|
+
if (scope_node.type === 'FunctionDeclaration' ||
|
|
769
|
+
scope_node.type === 'FunctionExpression' ||
|
|
770
|
+
scope_node.type === 'ArrowFunctionExpression' ||
|
|
771
|
+
scope_node.type === 'BlockStatement') {
|
|
772
|
+
return false; // 在函数或块内,不是真正的常量
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// 检查名称是否包含大写字母(表示意图作为常量)
|
|
777
|
+
const name = node.id.name;
|
|
778
|
+
return /[A-Z]/.test(name);
|
|
779
|
+
}
|
|
780
|
+
|
|
459
781
|
return {
|
|
460
782
|
VariableDeclarator(node) {
|
|
461
783
|
if (node.id.type === 'Identifier') {
|
|
784
|
+
// 对于const声明,只对不是真正常量的应用变量命名规则
|
|
785
|
+
if (node.parent.kind === 'const' && isRealConstant(node)) {
|
|
786
|
+
return; // 这是真正的常量,由常量规则处理
|
|
787
|
+
}
|
|
788
|
+
|
|
462
789
|
const variable_name = node.id.name;
|
|
463
|
-
const detector = new
|
|
790
|
+
const detector = new Detector({ 'variable-name': options });
|
|
464
791
|
const result = detector.checkName(variable_name, 'variable-name');
|
|
465
792
|
|
|
466
793
|
if (!result.valid) {
|
|
@@ -480,7 +807,7 @@ const variableNameRule = {
|
|
|
480
807
|
/**
|
|
481
808
|
* 常量名大写蛇形规则
|
|
482
809
|
*/
|
|
483
|
-
const
|
|
810
|
+
const constant_name_rule = {
|
|
484
811
|
meta: {
|
|
485
812
|
type: 'suggestion',
|
|
486
813
|
docs: {
|
|
@@ -496,7 +823,9 @@ const constantNameRule = {
|
|
|
496
823
|
min: { type: 'number' },
|
|
497
824
|
max: { type: 'number' },
|
|
498
825
|
message: { type: 'string' },
|
|
499
|
-
|
|
826
|
+
single_word: { type: 'boolean' },
|
|
827
|
+
single_word_len: { type: 'number' },
|
|
828
|
+
styles: { type: 'array', items: { type: 'string' } }
|
|
500
829
|
},
|
|
501
830
|
additionalProperties: false
|
|
502
831
|
}
|
|
@@ -504,18 +833,162 @@ const constantNameRule = {
|
|
|
504
833
|
},
|
|
505
834
|
create(context) {
|
|
506
835
|
const options = context.options[0] || {};
|
|
836
|
+
|
|
837
|
+
function isRealConstant(node) {
|
|
838
|
+
// 真正的常量特征:
|
|
839
|
+
// 1. 在模块顶层作用域(不在函数或块内)
|
|
840
|
+
// 2. 名称包含大写字母(表示意图作为常量)
|
|
841
|
+
// 3. 或者名称是常见的常量模式(如全大写)
|
|
842
|
+
|
|
843
|
+
// 检查是否在模块顶层
|
|
844
|
+
let scope_node = node;
|
|
845
|
+
while (scope_node.parent) {
|
|
846
|
+
scope_node = scope_node.parent;
|
|
847
|
+
if (scope_node.type === 'FunctionDeclaration' ||
|
|
848
|
+
scope_node.type === 'FunctionExpression' ||
|
|
849
|
+
scope_node.type === 'ArrowFunctionExpression' ||
|
|
850
|
+
scope_node.type === 'BlockStatement') {
|
|
851
|
+
return false; // 在函数或块内,不是真正的常量
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
// 检查名称是否包含大写字母(表示意图作为常量)
|
|
856
|
+
const name = node.id.name;
|
|
857
|
+
return /[A-Z]/.test(name);
|
|
858
|
+
}
|
|
859
|
+
|
|
507
860
|
return {
|
|
508
861
|
VariableDeclarator(node) {
|
|
509
862
|
if (node.id.type === 'Identifier' && node.parent.kind === 'const') {
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
863
|
+
// 只对真正的常量应用常量命名规则
|
|
864
|
+
if (isRealConstant(node)) {
|
|
865
|
+
const constant_name = node.id.name;
|
|
866
|
+
const detector = new Detector({ 'constant-name': options });
|
|
867
|
+
const result = detector.checkName(constant_name, 'constant-name');
|
|
868
|
+
|
|
869
|
+
if (!result.valid) {
|
|
870
|
+
result.errors.forEach(error => {
|
|
871
|
+
context.report({
|
|
872
|
+
node: node.id,
|
|
873
|
+
message: `常量名"${constant_name}"不符合规范: ${error}`
|
|
874
|
+
});
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
};
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* 入参名小写蛇形规则
|
|
886
|
+
*/
|
|
887
|
+
const param_name_rule = {
|
|
888
|
+
meta: {
|
|
889
|
+
type: 'suggestion',
|
|
890
|
+
docs: {
|
|
891
|
+
description: '入参名必须使用小写蛇形命名法(snake_case)',
|
|
892
|
+
category: 'Stylistic Issues',
|
|
893
|
+
recommended: true
|
|
894
|
+
},
|
|
895
|
+
schema: [
|
|
896
|
+
{
|
|
897
|
+
type: 'object',
|
|
898
|
+
properties: {
|
|
899
|
+
regex: { type: 'string' },
|
|
900
|
+
min: { type: 'number' },
|
|
901
|
+
max: { type: 'number' },
|
|
902
|
+
message: { type: 'string' },
|
|
903
|
+
single_word: { type: 'boolean' },
|
|
904
|
+
single_word_len: { type: 'number' },
|
|
905
|
+
styles: { type: 'array', items: { type: 'string' } }
|
|
906
|
+
},
|
|
907
|
+
additionalProperties: false
|
|
908
|
+
}
|
|
909
|
+
]
|
|
910
|
+
},
|
|
911
|
+
create(context) {
|
|
912
|
+
const options = context.options[0] || {};
|
|
913
|
+
|
|
914
|
+
function checkParam(node) {
|
|
915
|
+
node.params.forEach(param => {
|
|
916
|
+
if (param.type === 'Identifier') {
|
|
917
|
+
const param_name = param.name;
|
|
918
|
+
const detector = new Detector({ 'param-name': options });
|
|
919
|
+
const result = detector.checkName(param_name, 'param-name');
|
|
513
920
|
|
|
514
921
|
if (!result.valid) {
|
|
515
922
|
result.errors.forEach(error => {
|
|
516
923
|
context.report({
|
|
517
|
-
node:
|
|
518
|
-
message:
|
|
924
|
+
node: param,
|
|
925
|
+
message: `入参名"${param_name}"不符合规范: ${error}`
|
|
926
|
+
});
|
|
927
|
+
});
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
return {
|
|
934
|
+
FunctionDeclaration: checkParam,
|
|
935
|
+
FunctionExpression: checkParam,
|
|
936
|
+
ArrowFunctionExpression: checkParam
|
|
937
|
+
};
|
|
938
|
+
}
|
|
939
|
+
};
|
|
940
|
+
|
|
941
|
+
/**
|
|
942
|
+
* 属性名小写蛇形规则
|
|
943
|
+
*/
|
|
944
|
+
const property_name_rule = {
|
|
945
|
+
meta: {
|
|
946
|
+
type: 'suggestion',
|
|
947
|
+
docs: {
|
|
948
|
+
description: '属性名必须使用小写蛇形命名法(snake_case)',
|
|
949
|
+
category: 'Stylistic Issues',
|
|
950
|
+
recommended: true
|
|
951
|
+
},
|
|
952
|
+
schema: [
|
|
953
|
+
{
|
|
954
|
+
type: 'object',
|
|
955
|
+
properties: {
|
|
956
|
+
regex: { type: 'string' },
|
|
957
|
+
min: { type: 'number' },
|
|
958
|
+
max: { type: 'number' },
|
|
959
|
+
message: { type: 'string' },
|
|
960
|
+
single_word: { type: 'boolean' },
|
|
961
|
+
single_word_len: { type: 'number' },
|
|
962
|
+
styles: { type: 'array', items: { type: 'string' } }
|
|
963
|
+
},
|
|
964
|
+
additionalProperties: false
|
|
965
|
+
}
|
|
966
|
+
]
|
|
967
|
+
},
|
|
968
|
+
create(context) {
|
|
969
|
+
const options = context.options[0] || {};
|
|
970
|
+
return {
|
|
971
|
+
Property(node) {
|
|
972
|
+
// 检测类属性、对象字面量属性、模块导出属性
|
|
973
|
+
const is_class_property = node.parent &&
|
|
974
|
+
(node.parent.type === 'ClassBody' ||
|
|
975
|
+
(node.parent.type === 'ObjectExpression' &&
|
|
976
|
+
node.parent.parent &&
|
|
977
|
+
node.parent.parent.type === 'ClassDeclaration'));
|
|
978
|
+
|
|
979
|
+
const is_object_property = node.parent && node.parent.type === 'ObjectExpression';
|
|
980
|
+
|
|
981
|
+
// 检测所有非私有属性(不以_开头)
|
|
982
|
+
if (node.key.type === 'Identifier' && !node.key.name.startsWith('_')) {
|
|
983
|
+
const property_name = node.key.name;
|
|
984
|
+
const detector = new Detector({ 'property-name': options });
|
|
985
|
+
const result = detector._checkPropertyName(property_name, node.value);
|
|
986
|
+
|
|
987
|
+
if (!result.valid) {
|
|
988
|
+
result.errors.forEach(error => {
|
|
989
|
+
context.report({
|
|
990
|
+
node: node.key,
|
|
991
|
+
message: `属性名"${property_name}"不符合规范: ${error}`
|
|
519
992
|
});
|
|
520
993
|
});
|
|
521
994
|
}
|
|
@@ -528,7 +1001,7 @@ const constantNameRule = {
|
|
|
528
1001
|
/**
|
|
529
1002
|
* 私有成员命名规则
|
|
530
1003
|
*/
|
|
531
|
-
const
|
|
1004
|
+
const private_naming_rule = {
|
|
532
1005
|
meta: {
|
|
533
1006
|
type: 'suggestion',
|
|
534
1007
|
docs: {
|
|
@@ -544,7 +1017,9 @@ const privateNamingRule = {
|
|
|
544
1017
|
min: { type: 'number' },
|
|
545
1018
|
max: { type: 'number' },
|
|
546
1019
|
message: { type: 'string' },
|
|
547
|
-
|
|
1020
|
+
single_word: { type: 'boolean' },
|
|
1021
|
+
single_word_len: { type: 'number' },
|
|
1022
|
+
styles: { type: 'array', items: { type: 'string' } }
|
|
548
1023
|
},
|
|
549
1024
|
additionalProperties: false
|
|
550
1025
|
}
|
|
@@ -556,7 +1031,7 @@ const privateNamingRule = {
|
|
|
556
1031
|
MethodDefinition(node) {
|
|
557
1032
|
const method_name = node.key.name;
|
|
558
1033
|
if (method_name.startsWith('_')) {
|
|
559
|
-
const detector = new
|
|
1034
|
+
const detector = new Detector({ 'private-naming': options });
|
|
560
1035
|
const result = detector.checkName(method_name, 'private-naming');
|
|
561
1036
|
|
|
562
1037
|
if (!result.valid) {
|
|
@@ -573,7 +1048,7 @@ const privateNamingRule = {
|
|
|
573
1048
|
Property(node) {
|
|
574
1049
|
if (node.key.type === 'Identifier' && node.key.name.startsWith('_')) {
|
|
575
1050
|
const private_name = node.key.name;
|
|
576
|
-
const detector = new
|
|
1051
|
+
const detector = new Detector({ 'private-naming': options });
|
|
577
1052
|
const result = detector.checkName(private_name, 'private-naming');
|
|
578
1053
|
|
|
579
1054
|
if (!result.valid) {
|
|
@@ -593,16 +1068,18 @@ const privateNamingRule = {
|
|
|
593
1068
|
/**
|
|
594
1069
|
* 命名规范ESLint插件
|
|
595
1070
|
*/
|
|
596
|
-
const
|
|
597
|
-
'class-name':
|
|
598
|
-
'function-name':
|
|
599
|
-
'method-name':
|
|
600
|
-
'variable-name':
|
|
601
|
-
'constant-name':
|
|
602
|
-
'private-naming':
|
|
1071
|
+
const naming_rules = {
|
|
1072
|
+
'class-name': class_name_rule,
|
|
1073
|
+
'function-name': function_name_rule,
|
|
1074
|
+
'method-name': method_name_rule,
|
|
1075
|
+
'variable-name': variable_name_rule,
|
|
1076
|
+
'constant-name': constant_name_rule,
|
|
1077
|
+
'private-naming': private_naming_rule,
|
|
1078
|
+
'param-name': param_name_rule,
|
|
1079
|
+
'property-name': property_name_rule
|
|
603
1080
|
};
|
|
604
1081
|
|
|
605
1082
|
module.exports = {
|
|
606
|
-
|
|
607
|
-
rules:
|
|
1083
|
+
Detector,
|
|
1084
|
+
rules: naming_rules
|
|
608
1085
|
};
|