eslint-plugin-power-esrules 0.1.8 → 0.1.10
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.
|
@@ -20,298 +20,309 @@
|
|
|
20
20
|
* Проверяет, содержит ли имя переменной "id" (в любом регистре)
|
|
21
21
|
*/
|
|
22
22
|
function containsId(name) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
if (!name || typeof name !== "string") {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
return /id/i.test(name);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Проверяет, правильно ли написано "ID" в имени переменной
|
|
31
31
|
*/
|
|
32
32
|
function hasCorrectIdFormat(name) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
33
|
+
if (!name || typeof name !== "string") {
|
|
34
|
+
return true; // Если имени нет, пропускаем
|
|
35
|
+
}
|
|
36
|
+
const lowerName = name.toLowerCase();
|
|
37
|
+
const excludedWords = [
|
|
38
|
+
"identifier",
|
|
39
|
+
"valid",
|
|
40
|
+
"invalid",
|
|
41
|
+
"provide",
|
|
42
|
+
"divide",
|
|
43
|
+
"decide",
|
|
44
|
+
"hide",
|
|
45
|
+
"slide",
|
|
46
|
+
"guide",
|
|
47
|
+
"wide",
|
|
48
|
+
"side",
|
|
49
|
+
"messageid",
|
|
50
|
+
"grid",
|
|
51
|
+
];
|
|
52
|
+
if (
|
|
53
|
+
excludedWords.some((word) => lowerName.includes(word)) ||
|
|
54
|
+
lowerName === "id"
|
|
55
|
+
) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
const idMatches = name.matchAll(/([a-zA-Z]*?)([Ii]d|ID)([a-zA-Z]*)/g);
|
|
59
|
+
const matchesArray = Array.from(idMatches);
|
|
60
|
+
for (const match of matchesArray) {
|
|
61
|
+
const idPart = match[2];
|
|
62
|
+
const afterID = match[3];
|
|
63
|
+
if (afterID && afterID.length > 0) {
|
|
64
|
+
continue;
|
|
53
65
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
for (const match of matchesArray) {
|
|
57
|
-
const idPart = match[2];
|
|
58
|
-
const afterID = match[3];
|
|
59
|
-
if (afterID && afterID.length > 0) {
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
if (idPart !== 'ID') {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
66
|
+
if (idPart !== "ID") {
|
|
67
|
+
return false;
|
|
65
68
|
}
|
|
66
|
-
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
67
71
|
}
|
|
68
72
|
|
|
69
73
|
/**
|
|
70
74
|
* Получает имя из узла объявления переменной
|
|
71
75
|
*/
|
|
72
76
|
function getVariableName(node) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
if (!node) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
if (node.type === "Identifier") {
|
|
81
|
+
return node.name;
|
|
82
|
+
}
|
|
83
|
+
if (node.type === "VariableDeclarator" && node.id) {
|
|
84
|
+
if (node.id.type === "Identifier") {
|
|
85
|
+
return node.id.name;
|
|
78
86
|
}
|
|
79
|
-
if (node.type ===
|
|
80
|
-
|
|
81
|
-
return node.id.name;
|
|
82
|
-
}
|
|
83
|
-
if (node.id.type === 'ObjectPattern') {
|
|
84
|
-
return null;
|
|
85
|
-
}
|
|
87
|
+
if (node.id.type === "ObjectPattern") {
|
|
88
|
+
return null;
|
|
86
89
|
}
|
|
87
|
-
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
88
92
|
}
|
|
89
93
|
|
|
90
94
|
/**
|
|
91
95
|
* Генерирует правильное имя с ID в капсе
|
|
92
96
|
*/
|
|
93
97
|
function fixIdName(name) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
return
|
|
102
|
-
|
|
98
|
+
if (!name || typeof name !== "string") {
|
|
99
|
+
return name;
|
|
100
|
+
}
|
|
101
|
+
return name.replace(
|
|
102
|
+
/([a-zA-Z]*?)([Ii]d)([^a-zA-Z]*|$)/g,
|
|
103
|
+
(match, before, idPart, after) => {
|
|
104
|
+
if (after && /[a-zA-Z]/.test(after)) {
|
|
105
|
+
return match;
|
|
106
|
+
}
|
|
107
|
+
return `${before}ID${after}`;
|
|
108
|
+
},
|
|
109
|
+
);
|
|
103
110
|
}
|
|
104
111
|
|
|
105
112
|
/**
|
|
106
113
|
* Проверяет все идентификаторы в деструктуризации
|
|
107
114
|
*/
|
|
108
115
|
function checkDestructuredProperties(node, context) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
}
|
|
116
|
+
if (!node || node.type !== "ObjectPattern") {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const { properties } = node;
|
|
120
|
+
if (!properties || !Array.isArray(properties)) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
for (const prop of properties) {
|
|
124
|
+
if (prop.type === "Property") {
|
|
125
|
+
const { key } = prop;
|
|
126
|
+
if (key && key.type === "Identifier") {
|
|
127
|
+
const { name } = key;
|
|
128
|
+
if (containsId(name) && !hasCorrectIdFormat(name)) {
|
|
129
|
+
const suggestedName = fixIdName(name);
|
|
130
|
+
context.report({
|
|
131
|
+
node: key,
|
|
132
|
+
messageId: "idMustBeUppercase",
|
|
133
|
+
data: {
|
|
134
|
+
variableName: name,
|
|
135
|
+
suggestedName,
|
|
136
|
+
},
|
|
137
|
+
/*
|
|
138
|
+
* OLD auto-fix:
|
|
139
|
+
* fix(fixer) {
|
|
140
|
+
* return fixer.replaceText(key, suggestedName);
|
|
141
|
+
* },
|
|
142
|
+
*/
|
|
143
|
+
suggest: [
|
|
144
|
+
{
|
|
145
|
+
messageId: "suggestRenameTo",
|
|
146
|
+
data: { suggestedName },
|
|
147
|
+
fix(fixer) {
|
|
148
|
+
return fixer.replaceText(key, suggestedName);
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
});
|
|
148
153
|
}
|
|
154
|
+
}
|
|
149
155
|
}
|
|
156
|
+
}
|
|
150
157
|
}
|
|
151
158
|
|
|
152
159
|
module.exports = {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
},
|
|
160
|
-
// fixable: 'code', // OLD: auto-fixable (eslint --fix)
|
|
161
|
-
hasSuggestions: true, // NEW: quick-fix suggestions (not applied by eslint --fix)
|
|
162
|
-
schema: [],
|
|
163
|
-
messages: {
|
|
164
|
-
idMustBeUppercase:
|
|
165
|
-
'Идентификаторы должны использовать "ID" в капсе. ' +
|
|
166
|
-
'Вместо "{{variableName}}" используйте "{{suggestedName}}"',
|
|
167
|
-
suggestRenameTo: 'Переименовать в "{{suggestedName}}"',
|
|
168
|
-
},
|
|
160
|
+
meta: {
|
|
161
|
+
type: "suggestion",
|
|
162
|
+
docs: {
|
|
163
|
+
description: "Проверяет, что идентификаторы используют ID в капсе",
|
|
164
|
+
category: "Stylistic Issues",
|
|
165
|
+
recommended: false,
|
|
169
166
|
},
|
|
167
|
+
// fixable: 'code', // OLD: auto-fixable (eslint --fix)
|
|
168
|
+
hasSuggestions: true, // NEW: quick-fix suggestions (not applied by eslint --fix)
|
|
169
|
+
schema: [],
|
|
170
|
+
messages: {
|
|
171
|
+
idMustBeUppercase:
|
|
172
|
+
'Идентификаторы должны использовать "ID" в капсе. ' +
|
|
173
|
+
'Вместо "{{variableName}}" используйте "{{suggestedName}}"',
|
|
174
|
+
suggestRenameTo: 'Переименовать в "{{suggestedName}}"',
|
|
175
|
+
},
|
|
176
|
+
},
|
|
170
177
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
* return fixer.replaceText(node.id, suggestedName);
|
|
188
|
-
* },
|
|
189
|
-
*/
|
|
190
|
-
suggest: [
|
|
191
|
-
{
|
|
192
|
-
messageId: 'suggestRenameTo',
|
|
193
|
-
data: { suggestedName },
|
|
194
|
-
fix(fixer) {
|
|
195
|
-
return fixer.replaceText(node.id, suggestedName);
|
|
196
|
-
},
|
|
197
|
-
},
|
|
198
|
-
],
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
if (node.id && node.id.type === 'ObjectPattern') {
|
|
202
|
-
checkDestructuredProperties(node.id, context);
|
|
203
|
-
}
|
|
178
|
+
create(context) {
|
|
179
|
+
return {
|
|
180
|
+
VariableDeclarator(node) {
|
|
181
|
+
const variableName = getVariableName(node);
|
|
182
|
+
if (
|
|
183
|
+
variableName &&
|
|
184
|
+
containsId(variableName) &&
|
|
185
|
+
!hasCorrectIdFormat(variableName)
|
|
186
|
+
) {
|
|
187
|
+
const suggestedName = fixIdName(variableName);
|
|
188
|
+
context.report({
|
|
189
|
+
node: node.id,
|
|
190
|
+
messageId: "idMustBeUppercase",
|
|
191
|
+
data: {
|
|
192
|
+
variableName,
|
|
193
|
+
suggestedName,
|
|
204
194
|
},
|
|
195
|
+
/*
|
|
196
|
+
* OLD auto-fix:
|
|
197
|
+
* fix(fixer) {
|
|
198
|
+
* return fixer.replaceText(node.id, suggestedName);
|
|
199
|
+
* },
|
|
200
|
+
*/
|
|
201
|
+
suggest: [
|
|
202
|
+
{
|
|
203
|
+
messageId: "suggestRenameTo",
|
|
204
|
+
data: { suggestedName },
|
|
205
|
+
fix(fixer) {
|
|
206
|
+
return fixer.replaceText(node.id, suggestedName);
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
],
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
if (node.id && node.id.type === "ObjectPattern") {
|
|
213
|
+
checkDestructuredProperties(node.id, context);
|
|
214
|
+
}
|
|
215
|
+
},
|
|
205
216
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
217
|
+
FunctionDeclaration(node) {
|
|
218
|
+
if (!node.params || !Array.isArray(node.params)) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
for (const param of node.params) {
|
|
222
|
+
if (param.type === "Identifier") {
|
|
223
|
+
const { name } = param;
|
|
224
|
+
if (containsId(name) && !hasCorrectIdFormat(name)) {
|
|
225
|
+
const suggestedName = fixIdName(name);
|
|
226
|
+
context.report({
|
|
227
|
+
node: param,
|
|
228
|
+
messageId: "idMustBeUppercase",
|
|
229
|
+
data: {
|
|
230
|
+
variableName: name,
|
|
231
|
+
suggestedName,
|
|
232
|
+
},
|
|
233
|
+
/*
|
|
234
|
+
* OLD auto-fix:
|
|
235
|
+
* fix(fixer) {
|
|
236
|
+
* return fixer.replaceText(param, suggestedName);
|
|
237
|
+
* },
|
|
238
|
+
*/
|
|
239
|
+
suggest: [
|
|
240
|
+
{
|
|
241
|
+
messageId: "suggestRenameTo",
|
|
242
|
+
data: { suggestedName },
|
|
243
|
+
fix(fixer) {
|
|
244
|
+
return fixer.replaceText(param, suggestedName);
|
|
245
|
+
},
|
|
246
|
+
},
|
|
247
|
+
],
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
} else if (param.type === "ObjectPattern") {
|
|
251
|
+
checkDestructuredProperties(param, context);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
},
|
|
244
255
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
256
|
+
ArrowFunctionExpression(node) {
|
|
257
|
+
if (!node.params || !Array.isArray(node.params)) {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
for (const param of node.params) {
|
|
261
|
+
if (param.type === "Identifier") {
|
|
262
|
+
const { name } = param;
|
|
263
|
+
if (containsId(name) && !hasCorrectIdFormat(name)) {
|
|
264
|
+
const suggestedName = fixIdName(name);
|
|
265
|
+
context.report({
|
|
266
|
+
node: param,
|
|
267
|
+
messageId: "idMustBeUppercase",
|
|
268
|
+
data: {
|
|
269
|
+
variableName: name,
|
|
270
|
+
suggestedName,
|
|
271
|
+
},
|
|
272
|
+
/*
|
|
273
|
+
* OLD auto-fix:
|
|
274
|
+
* fix(fixer) {
|
|
275
|
+
* return fixer.replaceText(param, suggestedName);
|
|
276
|
+
* },
|
|
277
|
+
*/
|
|
278
|
+
suggest: [
|
|
279
|
+
{
|
|
280
|
+
messageId: "suggestRenameTo",
|
|
281
|
+
data: { suggestedName },
|
|
282
|
+
fix(fixer) {
|
|
283
|
+
return fixer.replaceText(param, suggestedName);
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
],
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
} else if (param.type === "ObjectPattern") {
|
|
290
|
+
checkDestructuredProperties(param, context);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
},
|
|
283
294
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
295
|
+
Property(node) {
|
|
296
|
+
if (node.key && node.key.type === "Identifier") {
|
|
297
|
+
const { name } = node.key;
|
|
298
|
+
if (containsId(name) && !hasCorrectIdFormat(name)) {
|
|
299
|
+
const suggestedName = fixIdName(name);
|
|
300
|
+
context.report({
|
|
301
|
+
node: node.key,
|
|
302
|
+
messageId: "idMustBeUppercase",
|
|
303
|
+
data: {
|
|
304
|
+
variableName: name,
|
|
305
|
+
suggestedName,
|
|
306
|
+
},
|
|
307
|
+
/*
|
|
308
|
+
* OLD auto-fix:
|
|
309
|
+
* fix(fixer) {
|
|
310
|
+
* return fixer.replaceText(node.key, suggestedName);
|
|
311
|
+
* },
|
|
312
|
+
*/
|
|
313
|
+
suggest: [
|
|
314
|
+
{
|
|
315
|
+
messageId: "suggestRenameTo",
|
|
316
|
+
data: { suggestedName },
|
|
317
|
+
fix(fixer) {
|
|
318
|
+
return fixer.replaceText(node.key, suggestedName);
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
],
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
},
|
|
317
328
|
};
|
|
@@ -6,149 +6,156 @@
|
|
|
6
6
|
* Названия переменных созданных через useState по возможности должны иметь окончание State
|
|
7
7
|
* (например innerModalState, setInnerModalState).
|
|
8
8
|
*/
|
|
9
|
+
String.prototype.firstLetterToUppercase = function () {
|
|
10
|
+
return this[0].toUpperCase() + this.slice(1);
|
|
11
|
+
};
|
|
9
12
|
|
|
10
13
|
/**
|
|
11
14
|
* Проверяет, является ли узел вызовом useState
|
|
12
15
|
*/
|
|
13
16
|
function isUseStateCall(node) {
|
|
14
|
-
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
const { callee } = node;
|
|
18
|
-
if (callee.type === 'Identifier' && callee.name === 'useState') {
|
|
19
|
-
return true;
|
|
20
|
-
}
|
|
21
|
-
if (
|
|
22
|
-
callee.type === 'MemberExpression' &&
|
|
23
|
-
callee.property &&
|
|
24
|
-
callee.property.type === 'Identifier' &&
|
|
25
|
-
callee.property.name === 'useState'
|
|
26
|
-
) {
|
|
27
|
-
return true;
|
|
28
|
-
}
|
|
17
|
+
if (!node || node.type !== "CallExpression") {
|
|
29
18
|
return false;
|
|
19
|
+
}
|
|
20
|
+
const { callee } = node;
|
|
21
|
+
if (callee.type === "Identifier" && callee.name === "useState") {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
if (
|
|
25
|
+
callee.type === "MemberExpression" &&
|
|
26
|
+
callee.property &&
|
|
27
|
+
callee.property.type === "Identifier" &&
|
|
28
|
+
callee.property.name === "useState"
|
|
29
|
+
) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
/**
|
|
33
36
|
* Проверяет, заканчивается ли имя на "State"
|
|
34
37
|
*/
|
|
35
38
|
function endsWithState(name) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
if (!name || typeof name !== "string") {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return name.endsWith("State");
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
/**
|
|
43
46
|
* Генерирует правильное имя с окончанием State
|
|
44
47
|
*/
|
|
45
48
|
function fixStateName(name) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
if (!name || typeof name !== "string") {
|
|
50
|
+
return name;
|
|
51
|
+
}
|
|
52
|
+
if (endsWithState(name)) {
|
|
53
|
+
return name;
|
|
54
|
+
}
|
|
55
|
+
return `${name}State`;
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
module.exports = {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
},
|
|
63
|
-
// fixable: 'code', // OLD: auto-fixable (eslint --fix)
|
|
64
|
-
hasSuggestions: true, // NEW: quick-fix suggestions (not applied by eslint --fix)
|
|
65
|
-
schema: [],
|
|
66
|
-
messages: {
|
|
67
|
-
useStateShouldEndWithState:
|
|
68
|
-
'Переменные useState должны иметь окончание "State". ' +
|
|
69
|
-
'Вместо "{{variableName}}" используйте "{{suggestedName}}"',
|
|
70
|
-
suggestRenameTo: 'Переименовать в "{{suggestedName}}"',
|
|
71
|
-
},
|
|
59
|
+
meta: {
|
|
60
|
+
type: "suggestion",
|
|
61
|
+
docs: {
|
|
62
|
+
description: "Проверяет, что переменные useState имеют окончание State",
|
|
63
|
+
category: "Stylistic Issues",
|
|
64
|
+
recommended: false,
|
|
72
65
|
},
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (!init || !isUseStateCall(init)) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
const { elements } = node.id;
|
|
85
|
-
if (!elements || elements.length < 1) {
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
const stateElement = elements[0];
|
|
89
|
-
let stateName = null;
|
|
90
|
-
if (stateElement && stateElement.type === 'Identifier') {
|
|
91
|
-
stateName = stateElement.name;
|
|
92
|
-
if (!endsWithState(stateName)) {
|
|
93
|
-
const suggestedName = fixStateName(stateName);
|
|
94
|
-
context.report({
|
|
95
|
-
node: stateElement,
|
|
96
|
-
messageId: 'useStateShouldEndWithState',
|
|
97
|
-
data: {
|
|
98
|
-
variableName: stateName,
|
|
99
|
-
suggestedName,
|
|
100
|
-
},
|
|
101
|
-
/*
|
|
102
|
-
* OLD auto-fix:
|
|
103
|
-
* fix(fixer) {
|
|
104
|
-
* return fixer.replaceText(stateElement, suggestedName);
|
|
105
|
-
* },
|
|
106
|
-
*/
|
|
107
|
-
suggest: [
|
|
108
|
-
{
|
|
109
|
-
messageId: 'suggestRenameTo',
|
|
110
|
-
data: { suggestedName },
|
|
111
|
-
fix(fixer) {
|
|
112
|
-
return fixer.replaceText(stateElement, suggestedName);
|
|
113
|
-
},
|
|
114
|
-
},
|
|
115
|
-
],
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
const setterElement = elements[1];
|
|
120
|
-
if (setterElement && setterElement.type === 'Identifier' && stateName) {
|
|
121
|
-
const setterName = setterElement.name;
|
|
122
|
-
const correctedStateName = endsWithState(stateName) ? stateName : fixStateName(stateName);
|
|
123
|
-
const stateNameWithoutState = correctedStateName.replace(/State$/, '');
|
|
124
|
-
const expectedSetterName = `set${stateNameWithoutState}State`;
|
|
125
|
-
if (setterName !== expectedSetterName) {
|
|
126
|
-
context.report({
|
|
127
|
-
node: setterElement,
|
|
128
|
-
messageId: 'useStateShouldEndWithState',
|
|
129
|
-
data: {
|
|
130
|
-
variableName: setterName,
|
|
131
|
-
suggestedName: expectedSetterName,
|
|
132
|
-
},
|
|
133
|
-
/*
|
|
134
|
-
* OLD auto-fix:
|
|
135
|
-
* fix(fixer) {
|
|
136
|
-
* return fixer.replaceText(setterElement, expectedSetterName);
|
|
137
|
-
* },
|
|
138
|
-
*/
|
|
139
|
-
suggest: [
|
|
140
|
-
{
|
|
141
|
-
messageId: 'suggestRenameTo',
|
|
142
|
-
data: { suggestedName: expectedSetterName },
|
|
143
|
-
fix(fixer) {
|
|
144
|
-
return fixer.replaceText(setterElement, expectedSetterName);
|
|
145
|
-
},
|
|
146
|
-
},
|
|
147
|
-
],
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
},
|
|
152
|
-
};
|
|
66
|
+
// fixable: 'code', // OLD: auto-fixable (eslint --fix)
|
|
67
|
+
hasSuggestions: true, // NEW: quick-fix suggestions (not applied by eslint --fix)
|
|
68
|
+
schema: [],
|
|
69
|
+
messages: {
|
|
70
|
+
useStateShouldEndWithState:
|
|
71
|
+
'Переменные useState должны иметь окончание "State". ' +
|
|
72
|
+
'Вместо "{{variableName}}" используйте "{{suggestedName}}"',
|
|
73
|
+
suggestRenameTo: 'Переименовать в "{{suggestedName}}"',
|
|
153
74
|
},
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
create(context) {
|
|
78
|
+
return {
|
|
79
|
+
VariableDeclarator(node) {
|
|
80
|
+
if (!node.id || node.id.type !== "ArrayPattern") {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const { init } = node;
|
|
84
|
+
if (!init || !isUseStateCall(init)) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const { elements } = node.id;
|
|
88
|
+
if (!elements || elements.length < 1) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const stateElement = elements[0];
|
|
92
|
+
let stateName = null;
|
|
93
|
+
if (stateElement && stateElement.type === "Identifier") {
|
|
94
|
+
stateName = stateElement.name;
|
|
95
|
+
if (!endsWithState(stateName)) {
|
|
96
|
+
const suggestedName = fixStateName(stateName);
|
|
97
|
+
context.report({
|
|
98
|
+
node: stateElement,
|
|
99
|
+
messageId: "useStateShouldEndWithState",
|
|
100
|
+
data: {
|
|
101
|
+
variableName: stateName,
|
|
102
|
+
suggestedName,
|
|
103
|
+
},
|
|
104
|
+
/*
|
|
105
|
+
* OLD auto-fix:
|
|
106
|
+
* fix(fixer) {
|
|
107
|
+
* return fixer.replaceText(stateElement, suggestedName);
|
|
108
|
+
* },
|
|
109
|
+
*/
|
|
110
|
+
suggest: [
|
|
111
|
+
{
|
|
112
|
+
messageId: "suggestRenameTo",
|
|
113
|
+
data: { suggestedName },
|
|
114
|
+
fix(fixer) {
|
|
115
|
+
return fixer.replaceText(stateElement, suggestedName);
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const setterElement = elements[1];
|
|
123
|
+
if (setterElement && setterElement.type === "Identifier" && stateName) {
|
|
124
|
+
const setterName = setterElement.name;
|
|
125
|
+
const correctedStateName = endsWithState(stateName)
|
|
126
|
+
? stateName
|
|
127
|
+
: fixStateName(stateName);
|
|
128
|
+
const stateNameWithoutState = correctedStateName
|
|
129
|
+
.replace(/State$/, "")
|
|
130
|
+
.firstLetterToUppercase();
|
|
131
|
+
const expectedSetterName = `set${stateNameWithoutState}State`;
|
|
132
|
+
if (setterName !== expectedSetterName) {
|
|
133
|
+
context.report({
|
|
134
|
+
node: setterElement,
|
|
135
|
+
messageId: "useStateShouldEndWithState",
|
|
136
|
+
data: {
|
|
137
|
+
variableName: setterName,
|
|
138
|
+
suggestedName: expectedSetterName,
|
|
139
|
+
},
|
|
140
|
+
/*
|
|
141
|
+
* OLD auto-fix:
|
|
142
|
+
* fix(fixer) {
|
|
143
|
+
* return fixer.replaceText(setterElement, expectedSetterName);
|
|
144
|
+
* },
|
|
145
|
+
*/
|
|
146
|
+
suggest: [
|
|
147
|
+
{
|
|
148
|
+
messageId: "suggestRenameTo",
|
|
149
|
+
data: { suggestedName: expectedSetterName },
|
|
150
|
+
fix(fixer) {
|
|
151
|
+
return fixer.replaceText(setterElement, expectedSetterName);
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
},
|
|
154
161
|
};
|