eslint-plugin-lube 0.6.0 → 0.7.0
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/CHANGELOG.md +23 -0
- package/README.md +4 -1
- package/docs/prefer-type-tag.md +45 -0
- package/package.json +1 -1
- package/src/index.js +11 -2
- package/src/rules/ascii-order.js +163 -71
- package/src/rules/prefer-type-tag.js +165 -0
- package/src/rules/pretty-imports.js +24 -12
- package/src/rules/pretty-jsdoc-casting.js +76 -29
- package/src/rules/pretty-sequence.js +110 -37
- package/src/rules/pretty-ternary.js +42 -14
- package/src/rules/svelte-naming-convention.js +281 -122
- package/src/utils/keep_body_comments.js +53 -0
- package/src/utils/keep_comments.js +6 -2
- package/src/utils/keep_line_breaks.js +3 -1
- package/src/utils/skip_hole_commas.js +3 -1
- package/src/utils/skip_optional_patterns.js +3 -1
- package/src/utils/skip_unchanged_fixes.js +3 -1
- package/src/utils/source_text.js +57 -23
- package/types/index.d.ts.map +1 -1
|
@@ -42,7 +42,7 @@ export default {
|
|
|
42
42
|
const fixable_name_regex = /^[_$]?[_$]?(?:[\dA-Za-z]+(?:_[\dA-Za-z]+)*\$?\$?)?$/
|
|
43
43
|
/** @type {Set<string>} */
|
|
44
44
|
const blocked = new Set()
|
|
45
|
-
const is_svelte = !!
|
|
45
|
+
const is_svelte = !!source.parserServices?.isSvelte
|
|
46
46
|
/** @type {Map<string, import("../../private.js").NamingIdentifier[]>} */
|
|
47
47
|
const store_usages = new Map()
|
|
48
48
|
/** @type {Set<import("../../private.js").NamingIdentifier>} */
|
|
@@ -74,8 +74,11 @@ export default {
|
|
|
74
74
|
*/
|
|
75
75
|
function add(map, node) {
|
|
76
76
|
const nodes = map.get(node.name)
|
|
77
|
-
if (nodes)
|
|
78
|
-
|
|
77
|
+
if (nodes) {
|
|
78
|
+
nodes.push(node)
|
|
79
|
+
} else {
|
|
80
|
+
map.set(node.name, [ node ])
|
|
81
|
+
}
|
|
79
82
|
}
|
|
80
83
|
/**
|
|
81
84
|
* @param {import("../../private.js").Comment} comment
|
|
@@ -84,7 +87,9 @@ export default {
|
|
|
84
87
|
* @returns {import("../../private.js").RenameEdit[]}
|
|
85
88
|
*/
|
|
86
89
|
function comment_edits(comment, name, names_params) {
|
|
87
|
-
if (comment.type != "Block" || !comment.value.startsWith("*"))
|
|
90
|
+
if (comment.type != "Block" || !comment.value.startsWith("*")) {
|
|
91
|
+
return []
|
|
92
|
+
}
|
|
88
93
|
const text = comment.value
|
|
89
94
|
const start = comment.range[0] + 2
|
|
90
95
|
const fixed_name = to_snake_case(name)
|
|
@@ -97,7 +102,9 @@ export default {
|
|
|
97
102
|
"g"
|
|
98
103
|
)
|
|
99
104
|
)) {
|
|
100
|
-
if (!in_braces(text, match.index))
|
|
105
|
+
if (!in_braces(text, match.index)) {
|
|
106
|
+
continue
|
|
107
|
+
}
|
|
101
108
|
edits.push(
|
|
102
109
|
{
|
|
103
110
|
range: [
|
|
@@ -108,7 +115,9 @@ export default {
|
|
|
108
115
|
}
|
|
109
116
|
)
|
|
110
117
|
}
|
|
111
|
-
if (!names_params)
|
|
118
|
+
if (!names_params) {
|
|
119
|
+
return edits
|
|
120
|
+
}
|
|
112
121
|
for (const match of text.matchAll(jsdoc_param_regex)) {
|
|
113
122
|
let index = skip_space(
|
|
114
123
|
text,
|
|
@@ -116,12 +125,17 @@ export default {
|
|
|
116
125
|
)
|
|
117
126
|
if (text[index] == "{") {
|
|
118
127
|
for (let depth = 0; index < text.length; index++) {
|
|
119
|
-
if (text[index] == "{")
|
|
120
|
-
|
|
128
|
+
if (text[index] == "{") {
|
|
129
|
+
depth++
|
|
130
|
+
} else if (text[index] == "}" && !--depth) {
|
|
131
|
+
break
|
|
132
|
+
}
|
|
121
133
|
}
|
|
122
134
|
index = skip_space(text, index + 1)
|
|
123
135
|
}
|
|
124
|
-
if (text[index] == "[")
|
|
136
|
+
if (text[index] == "[") {
|
|
137
|
+
index = skip_space(text, index + 1)
|
|
138
|
+
}
|
|
125
139
|
if (text.startsWith(name, index) && !word_character_regex.test(
|
|
126
140
|
text[index + name.length] ?? ""
|
|
127
141
|
)) {
|
|
@@ -157,14 +171,18 @@ export default {
|
|
|
157
171
|
)
|
|
158
172
|
: []
|
|
159
173
|
)
|
|
160
|
-
if (leading)
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
174
|
+
if (leading) {
|
|
175
|
+
comments.add(leading)
|
|
176
|
+
}
|
|
177
|
+
for (const comment of comments) {
|
|
178
|
+
edits.push(
|
|
179
|
+
...comment_edits(
|
|
180
|
+
comment,
|
|
181
|
+
node.name,
|
|
182
|
+
comment == leading
|
|
183
|
+
)
|
|
166
184
|
)
|
|
167
|
-
|
|
185
|
+
}
|
|
168
186
|
return edits
|
|
169
187
|
}
|
|
170
188
|
/**
|
|
@@ -198,7 +216,8 @@ export default {
|
|
|
198
216
|
const child = node.parent.type == "AssignmentPattern" && node.parent.left == node || node.parent.type == "RestElement"
|
|
199
217
|
? node.parent
|
|
200
218
|
: node
|
|
201
|
-
|
|
219
|
+
/** @type {import("../../private.js").AstNode & { params?: import("../../private.js").AstNode[] }} */
|
|
220
|
+
const func = child.parent
|
|
202
221
|
return function_types.has(func.type) && func.params?.includes(child) ? func : void 0
|
|
203
222
|
}
|
|
204
223
|
/**
|
|
@@ -209,8 +228,11 @@ export default {
|
|
|
209
228
|
function in_braces(text, index) {
|
|
210
229
|
let depth = 0
|
|
211
230
|
for (let i = 0; i < index; i++) {
|
|
212
|
-
if (text[i] == "{")
|
|
213
|
-
|
|
231
|
+
if (text[i] == "{") {
|
|
232
|
+
depth++
|
|
233
|
+
} else if (text[i] == "}" && depth) {
|
|
234
|
+
depth--
|
|
235
|
+
}
|
|
214
236
|
}
|
|
215
237
|
return depth > 0
|
|
216
238
|
}
|
|
@@ -248,7 +270,9 @@ export default {
|
|
|
248
270
|
for (const directive of disable_directives) {
|
|
249
271
|
const rule_ids = directive.value.split(",").map(rule_id => rule_id.trim())
|
|
250
272
|
.filter(Boolean)
|
|
251
|
-
if (rule_ids.length && !rule_ids.includes(context.id))
|
|
273
|
+
if (rule_ids.length && !rule_ids.includes(context.id)) {
|
|
274
|
+
continue
|
|
275
|
+
}
|
|
252
276
|
const comment_loc = directive.node.loc
|
|
253
277
|
switch (directive.type) {
|
|
254
278
|
case "disable":
|
|
@@ -258,10 +282,14 @@ export default {
|
|
|
258
282
|
}
|
|
259
283
|
break
|
|
260
284
|
case "disable-line":
|
|
261
|
-
if (comment_loc.start.line == line)
|
|
285
|
+
if (comment_loc.start.line == line) {
|
|
286
|
+
return true
|
|
287
|
+
}
|
|
262
288
|
break
|
|
263
289
|
case "disable-next-line":
|
|
264
|
-
if (comment_loc.end.line + 1 == line)
|
|
290
|
+
if (comment_loc.end.line + 1 == line) {
|
|
291
|
+
return true
|
|
292
|
+
}
|
|
265
293
|
}
|
|
266
294
|
}
|
|
267
295
|
return disabled
|
|
@@ -280,9 +308,13 @@ export default {
|
|
|
280
308
|
anchor = parent
|
|
281
309
|
break
|
|
282
310
|
case "VariableDeclarator":
|
|
283
|
-
if (parent.init == func)
|
|
311
|
+
if (parent.init == func) {
|
|
312
|
+
anchor = parent.parent
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (anchor.parent.type == "ExportDefaultDeclaration" || anchor.parent.type == "ExportNamedDeclaration") {
|
|
316
|
+
anchor = anchor.parent
|
|
284
317
|
}
|
|
285
|
-
if (anchor.parent.type == "ExportDefaultDeclaration" || anchor.parent.type == "ExportNamedDeclaration") anchor = anchor.parent
|
|
286
318
|
return /** @type {import("../../private.js").Comment[]} */(source.getCommentsBefore(
|
|
287
319
|
/** @type {import("estree").Node} */(anchor)/**/
|
|
288
320
|
))/**/.at(-1)
|
|
@@ -302,22 +334,31 @@ export default {
|
|
|
302
334
|
? /** @type {import("../../private.js").AstNode} */(decorators[decorators.length - 1])/**/.range[1]
|
|
303
335
|
: target.range[0]
|
|
304
336
|
)
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
337
|
+
/** @type {[number, number]} */
|
|
338
|
+
const range = [ start, start + name.length ]
|
|
339
|
+
if (svelte_shorthands.has(target)) {
|
|
340
|
+
return {
|
|
341
|
+
range: /** @type {[number, number]} */(parent.range)/**/,
|
|
342
|
+
text: name + "={" + fixed_name + "}"
|
|
343
|
+
}
|
|
309
344
|
}
|
|
310
|
-
if (shorthand_properties.has(target))
|
|
311
|
-
|
|
312
|
-
|
|
345
|
+
if (shorthand_properties.has(target)) {
|
|
346
|
+
return {
|
|
347
|
+
range,
|
|
348
|
+
text: name + ": " + fixed_name
|
|
349
|
+
}
|
|
313
350
|
}
|
|
314
|
-
if (import_shorthands.has(target))
|
|
315
|
-
|
|
316
|
-
|
|
351
|
+
if (import_shorthands.has(target)) {
|
|
352
|
+
return {
|
|
353
|
+
range,
|
|
354
|
+
text: name + " as " + fixed_name
|
|
355
|
+
}
|
|
317
356
|
}
|
|
318
|
-
if (export_shorthands.has(target))
|
|
319
|
-
|
|
320
|
-
|
|
357
|
+
if (export_shorthands.has(target)) {
|
|
358
|
+
return {
|
|
359
|
+
range,
|
|
360
|
+
text: fixed_name + " as " + name
|
|
361
|
+
}
|
|
321
362
|
}
|
|
322
363
|
if (parent.type == "ImportSpecifier" && parent.imported.type == "Identifier" && parent.imported.name == fixed_name) {
|
|
323
364
|
return {
|
|
@@ -352,7 +393,9 @@ export default {
|
|
|
352
393
|
name: node.name
|
|
353
394
|
},
|
|
354
395
|
fix(fixer) {
|
|
355
|
-
if (!edits)
|
|
396
|
+
if (!edits) {
|
|
397
|
+
return null
|
|
398
|
+
}
|
|
356
399
|
/** @type {Set<number>} */
|
|
357
400
|
const starts = new Set()
|
|
358
401
|
return edits.filter(
|
|
@@ -377,7 +420,9 @@ export default {
|
|
|
377
420
|
function skip_space(text, index) {
|
|
378
421
|
while (index < text.length && space_regex.test(
|
|
379
422
|
/** @type {string} */(text[index])/**/
|
|
380
|
-
))
|
|
423
|
+
)) {
|
|
424
|
+
index++
|
|
425
|
+
}
|
|
381
426
|
return index
|
|
382
427
|
}
|
|
383
428
|
/**
|
|
@@ -396,11 +441,18 @@ export default {
|
|
|
396
441
|
const store = name.slice(1)
|
|
397
442
|
if (is_svelte) {
|
|
398
443
|
const nodes = store_usages.get(store)
|
|
399
|
-
if (nodes)
|
|
400
|
-
|
|
401
|
-
|
|
444
|
+
if (nodes) {
|
|
445
|
+
nodes.push(node)
|
|
446
|
+
} else {
|
|
447
|
+
store_usages.set(store, [ node ])
|
|
448
|
+
}
|
|
449
|
+
} else {
|
|
450
|
+
blocked.add(store)
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
if (allow_regex.test(name) || visited.has(node)) {
|
|
454
|
+
return
|
|
402
455
|
}
|
|
403
|
-
if (allow_regex.test(name) || visited.has(node)) return
|
|
404
456
|
visited.add(node)
|
|
405
457
|
const parent = /** @type {import("../../private.js").NamingParent} */(node.parent)/**/
|
|
406
458
|
switch (parent.type) {
|
|
@@ -410,29 +462,41 @@ export default {
|
|
|
410
462
|
case "TSAbstractPropertyDefinition":
|
|
411
463
|
case "TSMethodSignature":
|
|
412
464
|
case "TSPropertySignature":
|
|
413
|
-
if (parent.computed || parent.value == node)
|
|
465
|
+
if (parent.computed || parent.value == node) {
|
|
466
|
+
defer(node)
|
|
467
|
+
}
|
|
414
468
|
break
|
|
415
469
|
case "ArrayExpression":
|
|
416
470
|
defer(node)
|
|
417
471
|
break
|
|
418
472
|
case "ArrayPattern":
|
|
419
|
-
if (is_declaration(node))
|
|
420
|
-
|
|
473
|
+
if (is_declaration(node)) {
|
|
474
|
+
declare(node)
|
|
475
|
+
} else {
|
|
476
|
+
defer(node)
|
|
477
|
+
}
|
|
421
478
|
break
|
|
422
479
|
case "ArrowFunctionExpression":
|
|
423
|
-
if (parent.body == node)
|
|
424
|
-
|
|
480
|
+
if (parent.body == node) {
|
|
481
|
+
defer(node)
|
|
482
|
+
} else {
|
|
483
|
+
declare(node)
|
|
484
|
+
}
|
|
425
485
|
break
|
|
426
486
|
case "AssignmentExpression":
|
|
427
487
|
defer(node)
|
|
428
488
|
break
|
|
429
489
|
case "AssignmentPattern":
|
|
430
|
-
if (parent.left != node)
|
|
431
|
-
|
|
490
|
+
if (parent.left != node) {
|
|
491
|
+
defer(node)
|
|
492
|
+
} else if (parent.parent?.type == "Property" && parent.parent.shorthand) {
|
|
432
493
|
shorthand_properties.add(node)
|
|
433
494
|
defer(node)
|
|
434
|
-
} else if (is_declaration(node))
|
|
435
|
-
|
|
495
|
+
} else if (is_declaration(node)) {
|
|
496
|
+
declare(node)
|
|
497
|
+
} else {
|
|
498
|
+
defer(node)
|
|
499
|
+
}
|
|
436
500
|
break
|
|
437
501
|
case "AwaitExpression":
|
|
438
502
|
defer(node)
|
|
@@ -480,8 +544,11 @@ export default {
|
|
|
480
544
|
break
|
|
481
545
|
case "ClassDeclaration":
|
|
482
546
|
case "ClassExpression":
|
|
483
|
-
if (parent.id == node)
|
|
484
|
-
|
|
547
|
+
if (parent.id == node) {
|
|
548
|
+
declare(node)
|
|
549
|
+
} else {
|
|
550
|
+
defer(node)
|
|
551
|
+
}
|
|
485
552
|
break
|
|
486
553
|
case "ConditionalExpression":
|
|
487
554
|
defer(node)
|
|
@@ -498,7 +565,9 @@ export default {
|
|
|
498
565
|
case "ExportSpecifier":
|
|
499
566
|
if (parent.local == node && !(/** @type {import("estree").ExportNamedDeclaration} */(parent.parent)/**/).source) {
|
|
500
567
|
const is_shorthand = parent.exported == node || parent.exported.range?.[0] == node.range[0]
|
|
501
|
-
if (is_shorthand)
|
|
568
|
+
if (is_shorthand) {
|
|
569
|
+
export_shorthands.add(node)
|
|
570
|
+
}
|
|
502
571
|
add(export_locals, node)
|
|
503
572
|
}
|
|
504
573
|
break
|
|
@@ -517,8 +586,12 @@ export default {
|
|
|
517
586
|
case "FunctionDeclaration":
|
|
518
587
|
case "TSDeclareFunction":
|
|
519
588
|
if (parent.id != node) {
|
|
520
|
-
if (parent.type == "FunctionDeclaration")
|
|
521
|
-
|
|
589
|
+
if (parent.type == "FunctionDeclaration") {
|
|
590
|
+
declare(node)
|
|
591
|
+
}
|
|
592
|
+
} else if (parent.parent?.type != "ExportNamedDeclaration" || !camel_case_regex.test(name)) {
|
|
593
|
+
declare(node)
|
|
594
|
+
}
|
|
522
595
|
break
|
|
523
596
|
case "FunctionExpression":
|
|
524
597
|
declare(node)
|
|
@@ -540,17 +613,23 @@ export default {
|
|
|
540
613
|
if (parent.imported.type == "Identifier" && parent.imported.name == name) {
|
|
541
614
|
import_shorthands.add(node)
|
|
542
615
|
defer(node)
|
|
543
|
-
} else
|
|
616
|
+
} else {
|
|
617
|
+
declare(node)
|
|
618
|
+
}
|
|
544
619
|
}
|
|
545
620
|
break
|
|
546
621
|
case "LogicalExpression":
|
|
547
622
|
defer(node)
|
|
548
623
|
break
|
|
549
624
|
case "MemberExpression":
|
|
550
|
-
if (parent.object == node || parent.computed)
|
|
625
|
+
if (parent.object == node || parent.computed) {
|
|
626
|
+
defer(node)
|
|
627
|
+
}
|
|
551
628
|
break
|
|
552
629
|
case "MethodDefinition":
|
|
553
|
-
if (parent.computed)
|
|
630
|
+
if (parent.computed) {
|
|
631
|
+
defer(node)
|
|
632
|
+
}
|
|
554
633
|
break
|
|
555
634
|
case "NewExpression":
|
|
556
635
|
defer(node)
|
|
@@ -558,18 +637,30 @@ export default {
|
|
|
558
637
|
case "Property":
|
|
559
638
|
if (parent.value == node) {
|
|
560
639
|
const is_shorthand = parent.shorthand
|
|
561
|
-
if (is_shorthand)
|
|
640
|
+
if (is_shorthand) {
|
|
641
|
+
shorthand_properties.add(node)
|
|
642
|
+
}
|
|
562
643
|
const declares = !is_shorthand && parent.parent?.type == "ObjectPattern" && is_declaration(node)
|
|
563
|
-
if (declares)
|
|
564
|
-
|
|
565
|
-
|
|
644
|
+
if (declares) {
|
|
645
|
+
declare(node)
|
|
646
|
+
} else {
|
|
647
|
+
defer(node)
|
|
648
|
+
}
|
|
649
|
+
} else if (parent.computed) {
|
|
650
|
+
defer(node)
|
|
651
|
+
}
|
|
566
652
|
break
|
|
567
653
|
case "PropertyDefinition":
|
|
568
|
-
if (parent.value == node || parent.computed)
|
|
654
|
+
if (parent.value == node || parent.computed) {
|
|
655
|
+
defer(node)
|
|
656
|
+
}
|
|
569
657
|
break
|
|
570
658
|
case "RestElement":
|
|
571
|
-
if (is_declaration(node))
|
|
572
|
-
|
|
659
|
+
if (is_declaration(node)) {
|
|
660
|
+
declare(node)
|
|
661
|
+
} else {
|
|
662
|
+
defer(node)
|
|
663
|
+
}
|
|
573
664
|
break
|
|
574
665
|
case "ReturnStatement":
|
|
575
666
|
defer(node)
|
|
@@ -587,14 +678,21 @@ export default {
|
|
|
587
678
|
defer(node)
|
|
588
679
|
break
|
|
589
680
|
case "TSEnumMember":
|
|
590
|
-
if (parent.initializer == node)
|
|
681
|
+
if (parent.initializer == node) {
|
|
682
|
+
defer(node)
|
|
683
|
+
}
|
|
591
684
|
break
|
|
592
685
|
case "TSImportEqualsDeclaration":
|
|
593
|
-
if (parent.id == node)
|
|
594
|
-
|
|
686
|
+
if (parent.id == node) {
|
|
687
|
+
declare(node)
|
|
688
|
+
} else {
|
|
689
|
+
defer(node)
|
|
690
|
+
}
|
|
595
691
|
break
|
|
596
692
|
case "TSQualifiedName":
|
|
597
|
-
if (parent.left == node)
|
|
693
|
+
if (parent.left == node) {
|
|
694
|
+
defer(node)
|
|
695
|
+
}
|
|
598
696
|
break
|
|
599
697
|
case "TaggedTemplateExpression":
|
|
600
698
|
defer(node)
|
|
@@ -619,7 +717,9 @@ export default {
|
|
|
619
717
|
) {
|
|
620
718
|
declare(node)
|
|
621
719
|
}
|
|
622
|
-
} else
|
|
720
|
+
} else {
|
|
721
|
+
defer(node)
|
|
722
|
+
}
|
|
623
723
|
break
|
|
624
724
|
case "WhileStatement":
|
|
625
725
|
defer(node)
|
|
@@ -628,7 +728,8 @@ export default {
|
|
|
628
728
|
defer(node)
|
|
629
729
|
break
|
|
630
730
|
default: {
|
|
631
|
-
|
|
731
|
+
/** @type {string} */
|
|
732
|
+
const type = parent.type
|
|
632
733
|
const svelte_parent = /** @type {{ expression?: unknown, kind?: string, value?: unknown }} */(/** @type {unknown} */(parent))/**/
|
|
633
734
|
if (type == "SvelteShorthandAttribute") {
|
|
634
735
|
if (svelte_parent.value == node) {
|
|
@@ -639,17 +740,23 @@ export default {
|
|
|
639
740
|
svelte_usage_parents.has(type)
|
|
640
741
|
|| type == "SvelteDirective" && svelte_parent.kind != "Let"
|
|
641
742
|
|| svelte_expression_parents.has(type) && svelte_parent.expression == node
|
|
642
|
-
)
|
|
643
|
-
|
|
743
|
+
) {
|
|
744
|
+
defer(node)
|
|
745
|
+
} else {
|
|
746
|
+
blocked.add(name)
|
|
747
|
+
}
|
|
644
748
|
}
|
|
645
749
|
}
|
|
646
750
|
},
|
|
647
751
|
/** @param {import("../../private.js").AstNode & import("estree").Identifier} node */
|
|
648
752
|
JSXIdentifier(node) {
|
|
649
753
|
const name = node.name
|
|
650
|
-
|
|
754
|
+
/** @type {{ object?: unknown, type: string }} */
|
|
755
|
+
const parent = node.parent
|
|
651
756
|
if (parent.type == "JSXMemberExpression" && parent.object == node) {
|
|
652
|
-
if (allow_regex.test(name))
|
|
757
|
+
if (allow_regex.test(name)) {
|
|
758
|
+
return
|
|
759
|
+
}
|
|
653
760
|
jsx_objects.add(node)
|
|
654
761
|
defer(node)
|
|
655
762
|
} else if ((parent.type == "JSXOpeningElement" || parent.type == "JSXClosingElement") && !lowercase_regex.test(name)) {
|
|
@@ -657,7 +764,9 @@ export default {
|
|
|
657
764
|
}
|
|
658
765
|
},
|
|
659
766
|
"Program:exit": () => {
|
|
660
|
-
if (!declarations.size)
|
|
767
|
+
if (!declarations.size) {
|
|
768
|
+
return
|
|
769
|
+
}
|
|
661
770
|
/** @type {Map<import("../../private.js").AstNode, import("eslint").Scope.Variable | null>} */
|
|
662
771
|
const resolution = new Map()
|
|
663
772
|
/** @type {Map<string, import("eslint").Scope.Variable[]>} */
|
|
@@ -666,22 +775,31 @@ export default {
|
|
|
666
775
|
for (const scope of scopes) {
|
|
667
776
|
for (const variable of scope.variables) {
|
|
668
777
|
const same_names = variables_by_name.get(variable.name)
|
|
669
|
-
if (same_names)
|
|
670
|
-
|
|
671
|
-
|
|
778
|
+
if (same_names) {
|
|
779
|
+
same_names.push(variable)
|
|
780
|
+
} else {
|
|
781
|
+
variables_by_name.set(variable.name, [ variable ])
|
|
782
|
+
}
|
|
783
|
+
for (const identifier of variable.identifiers) {
|
|
784
|
+
resolution.set(
|
|
672
785
|
/** @type {import("../../private.js").AstNode} */(/** @type {unknown} */(identifier))/**/,
|
|
673
|
-
|
|
674
|
-
|
|
786
|
+
variable
|
|
787
|
+
)
|
|
788
|
+
}
|
|
675
789
|
}
|
|
676
790
|
}
|
|
677
791
|
for (const scope of scopes) {
|
|
678
792
|
for (const reference of scope.references) {
|
|
679
793
|
const identifier = /** @type {import("../../private.js").AstNode} */(/** @type {unknown} */(reference.identifier))/**/
|
|
680
|
-
if (!resolution.has(identifier))
|
|
794
|
+
if (!resolution.has(identifier)) {
|
|
795
|
+
resolution.set(identifier, reference.resolved)
|
|
796
|
+
}
|
|
681
797
|
}
|
|
682
798
|
}
|
|
683
799
|
for (const node of jsx_objects) {
|
|
684
|
-
if (!resolution.has(node))
|
|
800
|
+
if (!resolution.has(node)) {
|
|
801
|
+
blocked.add(node.name)
|
|
802
|
+
}
|
|
685
803
|
}
|
|
686
804
|
/** @type {Set<import("eslint").Scope.Variable>} */
|
|
687
805
|
const renamable = new Set()
|
|
@@ -691,7 +809,9 @@ export default {
|
|
|
691
809
|
for (const node of nodes) {
|
|
692
810
|
declared.add(node)
|
|
693
811
|
const variable = resolution.get(node)
|
|
694
|
-
if (variable)
|
|
812
|
+
if (variable) {
|
|
813
|
+
renamable.add(variable)
|
|
814
|
+
}
|
|
695
815
|
}
|
|
696
816
|
}
|
|
697
817
|
/** @type {Map<string, Set<import("eslint").Scope.Scope>>} */
|
|
@@ -699,11 +819,14 @@ export default {
|
|
|
699
819
|
for (const variable of renamable) {
|
|
700
820
|
const target = to_snake_case(variable.name)
|
|
701
821
|
const target_scopes = scopes_by_target.get(target)
|
|
702
|
-
if (target_scopes)
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
822
|
+
if (target_scopes) {
|
|
823
|
+
target_scopes.add(variable.scope)
|
|
824
|
+
} else {
|
|
825
|
+
scopes_by_target.set(
|
|
826
|
+
target,
|
|
827
|
+
new Set([ variable.scope ])
|
|
828
|
+
)
|
|
829
|
+
}
|
|
707
830
|
}
|
|
708
831
|
/** @type {Set<string>} */
|
|
709
832
|
const nested_targets = new Set()
|
|
@@ -711,7 +834,9 @@ export default {
|
|
|
711
834
|
const target = to_snake_case(variable.name)
|
|
712
835
|
const target_scopes = /** @type {Set<import("eslint").Scope.Scope>} */(scopes_by_target.get(target))/**/
|
|
713
836
|
for (let scope = variable.scope.upper; scope; scope = scope.upper) {
|
|
714
|
-
if (target_scopes.has(scope))
|
|
837
|
+
if (target_scopes.has(scope)) {
|
|
838
|
+
nested_targets.add(target)
|
|
839
|
+
}
|
|
715
840
|
}
|
|
716
841
|
}
|
|
717
842
|
/**
|
|
@@ -719,7 +844,9 @@ export default {
|
|
|
719
844
|
* @returns {boolean}
|
|
720
845
|
*/
|
|
721
846
|
function belongs(node) {
|
|
722
|
-
if (!resolution.has(node))
|
|
847
|
+
if (!resolution.has(node)) {
|
|
848
|
+
return true
|
|
849
|
+
}
|
|
723
850
|
const variable = resolution.get(node)
|
|
724
851
|
return !!variable && renamable.has(variable)
|
|
725
852
|
}
|
|
@@ -729,9 +856,13 @@ export default {
|
|
|
729
856
|
*/
|
|
730
857
|
function collides(name) {
|
|
731
858
|
const others = variables_by_name.get(to_snake_case(name)) ?? []
|
|
732
|
-
if (!others.length)
|
|
859
|
+
if (!others.length) {
|
|
860
|
+
return false
|
|
861
|
+
}
|
|
733
862
|
for (const variable of variables_by_name.get(name) ?? []) {
|
|
734
|
-
if (!renamable.has(variable))
|
|
863
|
+
if (!renamable.has(variable)) {
|
|
864
|
+
continue
|
|
865
|
+
}
|
|
735
866
|
for (const scope of [
|
|
736
867
|
variable.scope,
|
|
737
868
|
...variable.references.map(reference => reference.from)
|
|
@@ -739,14 +870,20 @@ export default {
|
|
|
739
870
|
for (let current = /** @type {import("eslint").Scope.Scope | null} */(scope)/**/; current; current = current.upper) {
|
|
740
871
|
if (others.some(
|
|
741
872
|
other => other.scope == current
|
|
742
|
-
))
|
|
743
|
-
|
|
873
|
+
)) {
|
|
874
|
+
return true
|
|
875
|
+
}
|
|
876
|
+
if (current == variable.scope) {
|
|
877
|
+
break
|
|
878
|
+
}
|
|
744
879
|
}
|
|
745
880
|
}
|
|
746
881
|
for (const other of others) {
|
|
747
882
|
for (const reference of other.references) {
|
|
748
883
|
for (let current = /** @type {import("eslint").Scope.Scope | null} */(reference.from)/**/; current && current != other.scope; current = current.upper) {
|
|
749
|
-
if (current == variable.scope)
|
|
884
|
+
if (current == variable.scope) {
|
|
885
|
+
return true
|
|
886
|
+
}
|
|
750
887
|
}
|
|
751
888
|
}
|
|
752
889
|
}
|
|
@@ -770,9 +907,11 @@ export default {
|
|
|
770
907
|
const held = new Set(default_exports)
|
|
771
908
|
for (const variable of renamable) {
|
|
772
909
|
for (const reference of variable.references) {
|
|
773
|
-
if (reference.isWrite() && !reference.init)
|
|
910
|
+
if (reference.isWrite() && !reference.init) {
|
|
911
|
+
held.add(
|
|
774
912
|
/** @type {import("../../private.js").AstNode} */(/** @type {unknown} */(reference.identifier))/**/
|
|
775
|
-
|
|
913
|
+
)
|
|
914
|
+
}
|
|
776
915
|
}
|
|
777
916
|
}
|
|
778
917
|
/** @type {Map<string, import("../../private.js").RenamePlan>} */
|
|
@@ -820,17 +959,23 @@ export default {
|
|
|
820
959
|
let atomic_node
|
|
821
960
|
for (const [ name, nodes ] of declarations) {
|
|
822
961
|
const plan = /** @type {import("../../private.js").RenamePlan} */(plans.get(name))/**/
|
|
823
|
-
if (!plan.exported.length || !plan.fixable || !plan.atomic && plan.used.length)
|
|
962
|
+
if (!plan.exported.length || !plan.fixable || !plan.atomic && plan.used.length) {
|
|
963
|
+
continue
|
|
964
|
+
}
|
|
824
965
|
atomic_node ??= nodes[0]
|
|
825
|
-
for (const node of nodes)
|
|
826
|
-
|
|
827
|
-
|
|
966
|
+
for (const node of nodes) {
|
|
967
|
+
atomic.push(
|
|
968
|
+
...declaration_edits(node, resolution)
|
|
969
|
+
)
|
|
970
|
+
}
|
|
828
971
|
for (const node of [
|
|
829
972
|
...plan.exported,
|
|
830
973
|
...plan.used,
|
|
831
974
|
...plan.held,
|
|
832
975
|
...store_usages.get(name) ?? []
|
|
833
|
-
])
|
|
976
|
+
]) {
|
|
977
|
+
atomic.push(rename_edit(node))
|
|
978
|
+
}
|
|
834
979
|
}
|
|
835
980
|
for (const [ name, nodes ] of declarations) {
|
|
836
981
|
const {
|
|
@@ -841,15 +986,19 @@ export default {
|
|
|
841
986
|
used
|
|
842
987
|
} = /** @type {import("../../private.js").RenamePlan} */(plans.get(name))/**/
|
|
843
988
|
if (exported.length) {
|
|
844
|
-
for (const node of nodes)
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
989
|
+
for (const node of nodes) {
|
|
990
|
+
report(
|
|
991
|
+
node,
|
|
992
|
+
node == atomic_node ? atomic : null
|
|
993
|
+
)
|
|
994
|
+
}
|
|
848
995
|
} else if (!renames_at_once) {
|
|
849
|
-
for (const node of nodes)
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
996
|
+
for (const node of nodes) {
|
|
997
|
+
report(
|
|
998
|
+
node,
|
|
999
|
+
fixable && !used.length ? declaration_fix(node, nodes, usages_held) : null
|
|
1000
|
+
)
|
|
1001
|
+
}
|
|
853
1002
|
} else {
|
|
854
1003
|
report(
|
|
855
1004
|
/** @type {import("../../private.js").NamingIdentifier} */(nodes[0])/**/,
|
|
@@ -864,15 +1013,25 @@ export default {
|
|
|
864
1013
|
]
|
|
865
1014
|
: null
|
|
866
1015
|
)
|
|
867
|
-
for (const node of nodes.slice(1))
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
1016
|
+
for (const node of nodes.slice(1)) {
|
|
1017
|
+
report(node, null)
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
if (!fix_same_names) {
|
|
1021
|
+
continue
|
|
1022
|
+
}
|
|
1023
|
+
for (const node of exported) {
|
|
1024
|
+
report(node, null)
|
|
1025
|
+
}
|
|
1026
|
+
for (const node of usages_held) {
|
|
1027
|
+
report(node, null)
|
|
1028
|
+
}
|
|
1029
|
+
for (const node of used) {
|
|
1030
|
+
report(
|
|
1031
|
+
node,
|
|
1032
|
+
fixable && !renames_at_once ? [ rename_edit(node) ] : null
|
|
1033
|
+
)
|
|
1034
|
+
}
|
|
876
1035
|
}
|
|
877
1036
|
}
|
|
878
1037
|
}
|