mm_eslint 1.4.3 → 1.4.4

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/corrector.js ADDED
@@ -0,0 +1,323 @@
1
+ const { Config } = require('./config');
2
+ const { splitWords } = require('./util.js');
3
+ /**
4
+ * 命名规范修正器类
5
+ * 负责修正命名问题
6
+ */
7
+ class Corrector {
8
+ /**
9
+ * 构造函数
10
+ * @param {object} config 配置对象
11
+ */
12
+ constructor(config) {
13
+ this.config = config || new Config();
14
+ }
15
+ }
16
+
17
+ /**
18
+ * 获取修正建议
19
+ * @param {string} name 名称
20
+ * @param {object} error 错误信息
21
+ * @returns {string} 建议名称
22
+ */
23
+ Corrector.prototype.getSuggestion = function (error) {
24
+ var word = '';
25
+ try {
26
+ var { words, rule } = error;
27
+ switch (error.type) {
28
+ case 'style':
29
+ word = this.fixStyle(words, rule);
30
+ break;
31
+ case 'length':
32
+ word = this.fixLength(words, rule);
33
+ break;
34
+ case 'word_length':
35
+ word = this.fixWordLength(words, rule);
36
+ break;
37
+ case 'forbidden_word':
38
+ word = this.fixForbiddenWord(words, rule);
39
+ break;
40
+ default:
41
+ return error.name;
42
+ }
43
+ } catch {
44
+ return error.name;
45
+ }
46
+ return error.prefix + word;
47
+ };
48
+
49
+ /**
50
+ * 缩写名称
51
+ * @param {string} name 名称
52
+ * @param {number} max_length 最大长度
53
+ * @returns {string} 缩写后的名称
54
+ */
55
+ Corrector.prototype._abbreviateName = function (name, max_length) {
56
+ if (name.length <= max_length) {
57
+ return name;
58
+ }
59
+ // 先尝试推荐单词缩写,若失败则使用简单缩写策略
60
+ return this._abbreviateWord(name) || name.substring(0, max_length);
61
+ };
62
+
63
+ /**
64
+ * 推荐缩写单词
65
+ * @param {string} word 单词
66
+ * @returns {string} 缩写后的单词
67
+ */
68
+ Corrector.prototype._abbreviateWord = function (word) {
69
+ // 智能缩写策略:优先使用常见缩写,其次使用截断
70
+ var common_abbreviations = {
71
+ 'constants': 'const',
72
+ 'configuration': 'config',
73
+ 'application': 'app',
74
+ 'information': 'info',
75
+ 'temporary': 'temp',
76
+ 'parameter': 'param',
77
+ 'manager': 'mgr',
78
+ 'processor': 'proc',
79
+ 'controller': 'ctrl',
80
+ 'handler': 'hdlr',
81
+ 'service': 'svc',
82
+ 'provider': 'prov',
83
+ 'factory': 'fact',
84
+ 'builder': 'bldr',
85
+ 'adapter': 'adpt',
86
+ 'decorator': 'deco',
87
+ 'mediator': 'medi',
88
+ 'observer': 'obs',
89
+ 'strategy': 'strat',
90
+ 'command': 'cmd',
91
+ 'visitor': 'vis',
92
+ 'iterator': 'iter',
93
+ 'template': 'tmpl',
94
+ 'interpreter': 'interp',
95
+ 'component': 'comp',
96
+ 'property': 'prop',
97
+ 'entity': 'ent'
98
+ };
99
+
100
+ return common_abbreviations[word.toLowerCase()];
101
+ };
102
+
103
+ /**
104
+ * 转换命名风格
105
+ * @param {string} name 名称
106
+ * @param {string} target_style 目标风格
107
+ * @returns {string} 转换后的名称
108
+ */
109
+ Corrector.prototype.convertStyle = function (name, target_style) {
110
+ var words = splitWords(name);
111
+ return this.fixName(words, target_style);
112
+ };
113
+
114
+ /**
115
+ * 修正名称风格
116
+ * @param {array} words 单词数组
117
+ * @param {string} style 命名风格
118
+ * @returns {string} 修正后的名称
119
+ */
120
+ Corrector.prototype.fixName = function (words, style) {
121
+ let name = '';
122
+ switch (style) {
123
+ // 小写蛇形命名 (变量命名)
124
+ case 'snake_case':
125
+ for (let i = 0; i < words.length; i++) {
126
+ words[i] = words[i].toLowerCase();
127
+ }
128
+ name = words.join('_');
129
+ break;
130
+ // 小驼峰命名 (函数命名)
131
+ case 'camelCase':
132
+ for (let i = 0; i < words.length; i++) {
133
+ words[i] = words[i].toLowerCase();
134
+ if (i > 0) {
135
+ words[i] = words[i].charAt(0).toUpperCase() + words[i].substring(1);
136
+ }
137
+ }
138
+ name = words.join('');
139
+ break;
140
+ // 大驼峰命名 (类命名)
141
+ case 'PascalCase':
142
+ for (let i = 0; i < words.length; i++) {
143
+ words[i] = words[i].toLowerCase();
144
+ words[i] = words[i].charAt(0).toUpperCase() + words[i].substring(1);
145
+ }
146
+ name = words.join('');
147
+ break;
148
+ // 大写蛇形命名 (常量命名)
149
+ case 'UPPER_SNAKE_CASE':
150
+ for (let i = 0; i < words.length; i++) {
151
+ words[i] = words[i].toUpperCase();
152
+ }
153
+ name = words.join('_');
154
+ break;
155
+ // 小写命名 (变量命名)
156
+ case 'lowercase':
157
+ for (let i = 0; i < words.length; i++) {
158
+ words[i] = words[i].toLowerCase();
159
+ }
160
+ name = words.join('');
161
+ break;
162
+ // 大写命名 (常量命名)
163
+ case 'UPPERCASE':
164
+ for (let i = 0; i < words.length; i++) {
165
+ words[i] = words[i].toUpperCase();
166
+ }
167
+ name = words.join('');
168
+ break;
169
+ // 短横线命名 (拨号命名)
170
+ case 'kebab-case':
171
+ for (let i = 0; i < words.length; i++) {
172
+ words[i] = words[i].toLowerCase();
173
+ }
174
+ name = words.join('-');
175
+ break;
176
+ // 大写短横线命名 (密钥命名)
177
+ case 'UPPER-KEBAB-CASE':
178
+ for (let i = 0; i < words.length; i++) {
179
+ words[i] = words[i].toUpperCase();
180
+ }
181
+ name = words.join('-');
182
+ break;
183
+ }
184
+
185
+ return name;
186
+ }
187
+
188
+ /**
189
+ * 修正命名风格
190
+ * @param {string[]} words 单词数组
191
+ * @param {object} rule 规则配置
192
+ * @returns {string} 修正后的命名风格
193
+ */
194
+ Corrector.prototype.fixStyle = function (words, rule) {
195
+ var new_words = this._getNewWords(words, rule);
196
+ return this.fixName(new_words, rule.styles[0]);
197
+ }
198
+
199
+ /**
200
+ * 修正名称长度
201
+ * @param {string[]} words 单词数组
202
+ * @param {object} rule 规则配置
203
+ * @returns {string} 修正后的名称长度
204
+ */
205
+ Corrector.prototype.fixLength = function (words, rule) {
206
+ var new_words = this._getNewWords(words, rule);
207
+ new_words[0] = this._abbreviateName(new_words[0], rule.max);
208
+ return this.fixName(new_words, rule.styles[0]);
209
+ }
210
+
211
+ /**
212
+ * 修正单词长度
213
+ * @param {string[]} words 单词数组
214
+ * @param {object} rule 规则配置
215
+ * @returns {string} 修正后的单词长度
216
+ */
217
+ Corrector.prototype.fixWordLength = function (words, rule) {
218
+ var new_words = this._getNewWords(words, rule);
219
+ for (let i = 0; i < new_words.length; i++) {
220
+ if (new_words[i].length > rule.single_word_len) {
221
+ new_words[i] = new_words[i].substring(0, 4);
222
+ }
223
+ }
224
+ return this.fixName(new_words, rule.styles[0]);
225
+ }
226
+
227
+ /**
228
+ * 获取新的单词数组
229
+ * @param {string[]} words 单词数组
230
+ * @param {object} rule 规则配置
231
+ * @returns {string[]} 新的单词数组
232
+ */
233
+ Corrector.prototype._getNewWords = function (words, rule) {
234
+ var new_words = this._filterForbiddenWord(words, rule.forbidden_words);
235
+ return this._toRecommendWords(new_words, rule.recommend_words, rule.single_word_len);
236
+ }
237
+
238
+ /**
239
+ * 修正禁止词汇
240
+ * @param {string[]} words 单词数组
241
+ * @param {object} rule 规则配置
242
+ * @returns {string} 修正后的禁止词汇
243
+ */
244
+ Corrector.prototype.fixForbiddenWord = function (words, rule) {
245
+ var new_words = this._filterForbiddenWord(words, rule.forbidden_words);
246
+ return this.fixName(new_words, rule.styles[0]);
247
+ }
248
+
249
+ /**
250
+ * 是否禁止拼接词
251
+ * @param {string} word 单词
252
+ * @param {object} rule 规则配置
253
+ * @returns {boolean} 是否禁止拼接词
254
+ */
255
+ Corrector.prototype._isForbiddenWord = function (word, forbidden_words) {
256
+ for (let i = 0; i < forbidden_words.length; i++) {
257
+ let forbidden_word = forbidden_words[i];
258
+ if (word.toLowerCase() === forbidden_word.toLowerCase()) {
259
+ return true;
260
+ }
261
+ }
262
+ return false;
263
+ }
264
+
265
+ /**
266
+ * 过滤禁止拼接词
267
+ */
268
+ Corrector.prototype._filterForbiddenWord = function (words, forbidden_words) {
269
+ var new_word = [];
270
+ for (let i = 0; i < words.length; i++) {
271
+ let word = words[i];
272
+ if (!this._isForbiddenWord(word, forbidden_words)) {
273
+ new_word.push(word);
274
+ }
275
+ }
276
+ return new_word;
277
+ }
278
+
279
+ /**
280
+ * 获取推荐的单词
281
+ * @param {string[]} words 单词数组
282
+ * @param {object} recommend 推荐配置
283
+ * @param {number} single_word_len 单个单词长度
284
+ * @returns {string[]} 推荐的单词数组
285
+ */
286
+ Corrector.prototype._toRecommendWords = function (words, recommend, single_word_len) {
287
+ // console.log('推荐单词', words, recommend, single_word_len);
288
+ let recommend_words = [];
289
+ for (let i = 0; i < words.length; i++) {
290
+ let word = words[i];
291
+ if (word.length > single_word_len) {
292
+ var recommend_word = this._getRecommendWord(word, recommend);
293
+ if (recommend_word) {
294
+ word = recommend_word;
295
+ }
296
+ }
297
+ recommend_words.push(word);
298
+ }
299
+ return recommend_words;
300
+ }
301
+
302
+ /**
303
+ * 获取推荐的单词
304
+ * @param {string} word 单词
305
+ * @param {object} recommend 推荐配置
306
+ * @returns {string} 推荐的单词
307
+ */
308
+ Corrector.prototype._getRecommendWord = function (word, recommend) {
309
+ var recommend_word = null;
310
+ for (var k in recommend) {
311
+ let arr = recommend[k];
312
+ for (let i = 0; i < arr.length; i++) {
313
+ let recommended = arr[i];
314
+ if (word.toLowerCase() === recommended.toLowerCase()) {
315
+ recommend_word = k;
316
+ continue;
317
+ }
318
+ }
319
+ }
320
+ return recommend_word;
321
+ }
322
+
323
+ module.exports = { Corrector };