eslint-plugin-lube 0.6.0 → 0.8.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 +39 -0
- package/README.md +6 -1
- package/docs/prefer-param-tag.md +25 -0
- package/docs/prefer-type-tag.md +45 -0
- package/package.json +3 -3
- package/src/index.js +14 -2
- package/src/rules/ascii-order.js +165 -78
- package/src/rules/prefer-param-tag.js +252 -0
- package/src/rules/prefer-type-tag.js +165 -0
- package/src/rules/pretty-imports.js +21 -12
- package/src/rules/pretty-jsdoc-casting.js +76 -37
- package/src/rules/pretty-sequence.js +110 -42
- package/src/rules/pretty-ternary.js +43 -23
- package/src/rules/svelte-naming-convention.js +287 -134
- 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 +4 -4
- 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
package/src/rules/ascii-order.js
CHANGED
|
@@ -66,7 +66,9 @@ const shebang_types = new Set([ "Hashbang", "Shebang" ])
|
|
|
66
66
|
*/
|
|
67
67
|
function compare(a, b) {
|
|
68
68
|
const rank = (a.rank ?? 1) - (b.rank ?? 1)
|
|
69
|
-
if (rank)
|
|
69
|
+
if (rank) {
|
|
70
|
+
return rank
|
|
71
|
+
}
|
|
70
72
|
return a.name < b.name
|
|
71
73
|
? -1
|
|
72
74
|
: a.name > b.name
|
|
@@ -81,7 +83,9 @@ function compare(a, b) {
|
|
|
81
83
|
function count_same_line(comments, line) {
|
|
82
84
|
let count = 0
|
|
83
85
|
for (const comment of comments) {
|
|
84
|
-
if (comment.loc.start.line != line)
|
|
86
|
+
if (comment.loc.start.line != line) {
|
|
87
|
+
break
|
|
88
|
+
}
|
|
85
89
|
line = comment.loc.end.line
|
|
86
90
|
count++
|
|
87
91
|
}
|
|
@@ -120,7 +124,9 @@ function create_reorder(context) {
|
|
|
120
124
|
last_token = /** @type {import("eslint").AST.Token} */(source_code.getTokenBefore(last_token))/**/
|
|
121
125
|
} else if (layout == "sequence") {
|
|
122
126
|
const next = source_code.getTokenAfter(last_token)
|
|
123
|
-
if (next?.value == ",")
|
|
127
|
+
if (next?.value == ",") {
|
|
128
|
+
separator = next
|
|
129
|
+
}
|
|
124
130
|
}
|
|
125
131
|
const inner = /** @type {import("../../private.js").Comment[]} */(source_code.getCommentsAfter(last_token))/**/
|
|
126
132
|
let code_end = last_token.range[1]
|
|
@@ -130,7 +136,9 @@ function create_reorder(context) {
|
|
|
130
136
|
if (separator) {
|
|
131
137
|
if (inner.some(
|
|
132
138
|
comment => comment.type == "Line"
|
|
133
|
-
))
|
|
139
|
+
)) {
|
|
140
|
+
return undefined
|
|
141
|
+
}
|
|
134
142
|
code_end = inner[inner.length - 1]?.range[1] ?? code_end
|
|
135
143
|
line = separator.loc.end.line
|
|
136
144
|
tail = /** @type {import("../../private.js").Comment[]} */(source_code.getCommentsAfter(separator))/**/
|
|
@@ -147,9 +155,13 @@ function create_reorder(context) {
|
|
|
147
155
|
const last_comment = tail[tail_count - 1]
|
|
148
156
|
const after = last_comment ? last_comment.range[1] : sep_end
|
|
149
157
|
let next = after
|
|
150
|
-
while (text[next] == " " || text[next] == "\t")
|
|
158
|
+
while (text[next] == " " || text[next] == "\t") {
|
|
159
|
+
next++
|
|
160
|
+
}
|
|
151
161
|
let previous = start
|
|
152
|
-
while (text[previous - 1] == " " || text[previous - 1] == "\t")
|
|
162
|
+
while (text[previous - 1] == " " || text[previous - 1] == "\t") {
|
|
163
|
+
previous--
|
|
164
|
+
}
|
|
153
165
|
const declaration = entry.last.type == "ExportNamedDeclaration"
|
|
154
166
|
? entry.last.declaration
|
|
155
167
|
: entry.last
|
|
@@ -184,14 +196,18 @@ function create_reorder(context) {
|
|
|
184
196
|
const items = []
|
|
185
197
|
for (const entry of entries) {
|
|
186
198
|
const item = get_item(entry, layout, get_level)
|
|
187
|
-
if (!item)
|
|
199
|
+
if (!item) {
|
|
200
|
+
return null
|
|
201
|
+
}
|
|
188
202
|
items.push(item)
|
|
189
203
|
}
|
|
190
204
|
const sorted = items.slice().sort(
|
|
191
205
|
(a, b) => compare(a.entry, b.entry)
|
|
192
206
|
)
|
|
193
207
|
const blocker = find_blocker(items, sorted, reported)
|
|
194
|
-
if (blocker)
|
|
208
|
+
if (blocker) {
|
|
209
|
+
return blocker
|
|
210
|
+
}
|
|
195
211
|
const last_index = items.length - 1
|
|
196
212
|
let result = ""
|
|
197
213
|
for (let i = 0; i <= last_index; i++) {
|
|
@@ -205,9 +221,13 @@ function create_reorder(context) {
|
|
|
205
221
|
|| slot.tail_start < slot.after && !slot.break_after && (i < last_index || !slot.closes)
|
|
206
222
|
|| has_tail && !slot.break_after && (i < last_index || item.tail_line)
|
|
207
223
|
|| layout == "statement" && i < last_index && !item.terminated && !slot.break_after
|
|
208
|
-
)
|
|
224
|
+
) {
|
|
225
|
+
return null
|
|
226
|
+
}
|
|
209
227
|
result += source.render(item.start, item.code_end) + source.render(slot.code_end, slot.sep_end)
|
|
210
|
-
if (has_tail)
|
|
228
|
+
if (has_tail) {
|
|
229
|
+
result += " " + source.render(item.tail_start, item.after)
|
|
230
|
+
}
|
|
211
231
|
if (i < last_index) {
|
|
212
232
|
result += source.render(
|
|
213
233
|
slot.after,
|
|
@@ -217,7 +237,9 @@ function create_reorder(context) {
|
|
|
217
237
|
}
|
|
218
238
|
const first = /** @type {import("../../private.js").OrderItem} */(items[0])/**/
|
|
219
239
|
const last = /** @type {import("../../private.js").OrderItem} */(items[last_index])/**/
|
|
220
|
-
if (last.semicolon && !(/** @type {import("../../private.js").OrderItem} */(sorted[last_index])/**/).semicolon)
|
|
240
|
+
if (last.semicolon && !(/** @type {import("../../private.js").OrderItem} */(sorted[last_index])/**/).semicolon) {
|
|
241
|
+
return null
|
|
242
|
+
}
|
|
221
243
|
source.edit(first.start, last.after, result)
|
|
222
244
|
return {
|
|
223
245
|
range: [ first.start, last.after ],
|
|
@@ -229,13 +251,8 @@ function create_reorder(context) {
|
|
|
229
251
|
* @returns {string}
|
|
230
252
|
*/
|
|
231
253
|
function get_snippet(node) {
|
|
232
|
-
const value = node.type == "Property"
|
|
233
|
-
? node.computed && node.key.type != "Literal"
|
|
234
|
-
? node.key
|
|
235
|
-
: node.value
|
|
236
|
-
: node
|
|
237
254
|
const snippet = source_code.getText(
|
|
238
|
-
/** @type {import("estree").
|
|
255
|
+
/** @type {import("estree").Property} */(node)/**/.value
|
|
239
256
|
).replace(/\s+/g, " ")
|
|
240
257
|
return snippet.length > 30 ? snippet.slice(0, 29) + "…" : snippet
|
|
241
258
|
}
|
|
@@ -260,7 +277,9 @@ function create_reorder(context) {
|
|
|
260
277
|
)
|
|
261
278
|
const entry = entries[index]
|
|
262
279
|
const previous = entries[index - 1]
|
|
263
|
-
if (!entry || !previous)
|
|
280
|
+
if (!entry || !previous) {
|
|
281
|
+
return
|
|
282
|
+
}
|
|
264
283
|
const replacement = get_replacement(entries, layout, entry, get_level)
|
|
265
284
|
const fix = replacement && "range" in replacement ? replacement : null
|
|
266
285
|
const blocker = replacement && "entry" in replacement ? replacement : null
|
|
@@ -317,7 +336,7 @@ function get_name(node) {
|
|
|
317
336
|
case "TemplateLiteral":
|
|
318
337
|
return node.expressions.length
|
|
319
338
|
? undefined
|
|
320
|
-
: /** @type {import("estree").TemplateElement} */(node.quasis[0])/**/.value.cooked
|
|
339
|
+
: /** @type {string} */(/** @type {import("estree").TemplateElement} */(node.quasis[0])/**/.value.cooked)/**/
|
|
321
340
|
}
|
|
322
341
|
return undefined
|
|
323
342
|
}
|
|
@@ -341,13 +360,19 @@ function is_portable_regexp(args) {
|
|
|
341
360
|
const [ pattern, flags ] = args
|
|
342
361
|
const source = pattern instanceof RegExp ? pattern.source : pattern
|
|
343
362
|
const flag_text = flags === undefined && pattern instanceof RegExp ? pattern.flags : flags
|
|
344
|
-
if (typeof source != "string" && source !== undefined || typeof flag_text != "string" && flag_text !== undefined)
|
|
345
|
-
|
|
363
|
+
if (typeof source != "string" && source !== undefined || typeof flag_text != "string" && flag_text !== undefined) {
|
|
364
|
+
return false
|
|
365
|
+
}
|
|
366
|
+
if (flag_text && !portable_flags_regex.test(flag_text) || source && regexp_modifier_regex.test(source)) {
|
|
367
|
+
return false
|
|
368
|
+
}
|
|
346
369
|
/** @type {Set<string>} */
|
|
347
370
|
const names = new Set()
|
|
348
371
|
for (const match of source?.matchAll(regexp_group_name_regex) ?? []) {
|
|
349
372
|
const name = /** @type {string} */(match[1])/**/
|
|
350
|
-
if (names.has(name))
|
|
373
|
+
if (names.has(name)) {
|
|
374
|
+
return false
|
|
375
|
+
}
|
|
351
376
|
names.add(name)
|
|
352
377
|
}
|
|
353
378
|
return true
|
|
@@ -421,7 +446,9 @@ export default {
|
|
|
421
446
|
case "TSTypeAssertion":
|
|
422
447
|
return classify(node.expression)
|
|
423
448
|
case "UnaryExpression":
|
|
424
|
-
if (node.operator == "delete")
|
|
449
|
+
if (node.operator == "delete") {
|
|
450
|
+
return 2
|
|
451
|
+
}
|
|
425
452
|
break
|
|
426
453
|
}
|
|
427
454
|
let level = 0
|
|
@@ -456,7 +483,9 @@ export default {
|
|
|
456
483
|
default_exports.add(statement.declaration.name)
|
|
457
484
|
} else if (statement.type == "ExportNamedDeclaration" && !statement.source) {
|
|
458
485
|
for (const specifier of statement.specifiers) {
|
|
459
|
-
if (get_name(specifier.exported) == "default")
|
|
486
|
+
if (get_name(specifier.exported) == "default") {
|
|
487
|
+
default_exports.add(get_name(specifier.local))
|
|
488
|
+
}
|
|
460
489
|
}
|
|
461
490
|
}
|
|
462
491
|
}
|
|
@@ -469,7 +498,9 @@ export default {
|
|
|
469
498
|
function collect_targets(node, names) {
|
|
470
499
|
switch (node?.type) {
|
|
471
500
|
case "ArrayPattern":
|
|
472
|
-
for (const element of node.elements)
|
|
501
|
+
for (const element of node.elements) {
|
|
502
|
+
collect_targets(element, names)
|
|
503
|
+
}
|
|
473
504
|
break
|
|
474
505
|
case "AssignmentPattern":
|
|
475
506
|
collect_targets(node.left, names)
|
|
@@ -478,7 +509,9 @@ export default {
|
|
|
478
509
|
names.push(node.name)
|
|
479
510
|
break
|
|
480
511
|
case "ObjectPattern":
|
|
481
|
-
for (const property of node.properties)
|
|
512
|
+
for (const property of node.properties) {
|
|
513
|
+
collect_targets(property, names)
|
|
514
|
+
}
|
|
482
515
|
break
|
|
483
516
|
case "Property":
|
|
484
517
|
collect_targets(node.value, names)
|
|
@@ -495,13 +528,17 @@ export default {
|
|
|
495
528
|
*/
|
|
496
529
|
function construct(node) {
|
|
497
530
|
const callee = node.callee
|
|
498
|
-
if (callee.type != "Identifier" || !safe_constructors.has(callee.name) || !is_global(callee))
|
|
531
|
+
if (callee.type != "Identifier" || !safe_constructors.has(callee.name) || !is_global(callee)) {
|
|
532
|
+
return not_static
|
|
533
|
+
}
|
|
499
534
|
const args = node.arguments.map(static_value)
|
|
500
535
|
if (
|
|
501
536
|
args.includes(not_static)
|
|
502
537
|
|| (callee.name.includes("Array") || callee.name == "DataView") && args.some(is_large)
|
|
503
538
|
|| callee.name == "RegExp" && !is_portable_regexp(args)
|
|
504
|
-
)
|
|
539
|
+
) {
|
|
540
|
+
return not_static
|
|
541
|
+
}
|
|
505
542
|
try {
|
|
506
543
|
return new (/** @type {new (...values: unknown[]) => unknown} */(/** @type {Record<string, unknown>} */(/** @type {unknown} */(globalThis))/**/[callee.name])/**/)(...args)
|
|
507
544
|
} catch {
|
|
@@ -552,7 +589,9 @@ export default {
|
|
|
552
589
|
*/
|
|
553
590
|
function get_key_name(node) {
|
|
554
591
|
const type = node.type
|
|
555
|
-
if (type != "Property" && type != "TSMethodSignature" && type != "TSPropertySignature")
|
|
592
|
+
if (type != "Property" && type != "TSMethodSignature" && type != "TSPropertySignature") {
|
|
593
|
+
return undefined
|
|
594
|
+
}
|
|
556
595
|
return node.computed && node.key.type != "Literal" ? undefined : get_name(node.key)
|
|
557
596
|
}
|
|
558
597
|
/**
|
|
@@ -560,7 +599,9 @@ export default {
|
|
|
560
599
|
* @returns {string | undefined}
|
|
561
600
|
*/
|
|
562
601
|
function get_specifier_name(node) {
|
|
563
|
-
if (node.type == "ImportSpecifier")
|
|
602
|
+
if (node.type == "ImportSpecifier") {
|
|
603
|
+
return get_name(node.imported)
|
|
604
|
+
}
|
|
564
605
|
return node.type == "ExportSpecifier" ? get_name(node.local) : undefined
|
|
565
606
|
}
|
|
566
607
|
/**
|
|
@@ -569,11 +610,17 @@ export default {
|
|
|
569
610
|
*/
|
|
570
611
|
function get_test_title(statement) {
|
|
571
612
|
const call = statement.type == "ExpressionStatement" ? statement.expression : undefined
|
|
572
|
-
if (call?.type != "CallExpression")
|
|
613
|
+
if (call?.type != "CallExpression") {
|
|
614
|
+
return undefined
|
|
615
|
+
}
|
|
573
616
|
let callee = call.callee
|
|
574
|
-
while (callee.type == "MemberExpression" && !callee.computed)
|
|
617
|
+
while (callee.type == "MemberExpression" && !callee.computed) {
|
|
618
|
+
callee = callee.object
|
|
619
|
+
}
|
|
575
620
|
const title = call.arguments[0]
|
|
576
|
-
if (callee.type != "Identifier" || !test_functions.has(callee.name))
|
|
621
|
+
if (callee.type != "Identifier" || !test_functions.has(callee.name)) {
|
|
622
|
+
return undefined
|
|
623
|
+
}
|
|
577
624
|
return title?.type == "Literal" && typeof title.value == "string" || title?.type == "TemplateLiteral"
|
|
578
625
|
? title
|
|
579
626
|
: undefined
|
|
@@ -587,8 +634,12 @@ export default {
|
|
|
587
634
|
const variable = scope.references.find(
|
|
588
635
|
reference => reference.identifier == node
|
|
589
636
|
)?.resolved
|
|
590
|
-
if (!variable?.defs.length)
|
|
591
|
-
|
|
637
|
+
if (!variable?.defs.length) {
|
|
638
|
+
return constant_globals.has(node.name) && is_global(node)
|
|
639
|
+
}
|
|
640
|
+
if (variable.defs.length > 1) {
|
|
641
|
+
return false
|
|
642
|
+
}
|
|
592
643
|
const def = /** @type {import("eslint").Scope.Definition} */(variable.defs[0])/**/
|
|
593
644
|
switch (def.type) {
|
|
594
645
|
case "ClassName":
|
|
@@ -627,7 +678,9 @@ export default {
|
|
|
627
678
|
*/
|
|
628
679
|
function is_global(node) {
|
|
629
680
|
let scope = context.sourceCode.getScope(node)
|
|
630
|
-
while (scope.upper && !scope.set.has(node.name))
|
|
681
|
+
while (scope.upper && !scope.set.has(node.name)) {
|
|
682
|
+
scope = scope.upper
|
|
683
|
+
}
|
|
631
684
|
return !scope.set.get(node.name)?.defs.length
|
|
632
685
|
}
|
|
633
686
|
/**
|
|
@@ -643,9 +696,13 @@ export default {
|
|
|
643
696
|
parent?.type == "SwitchCase"
|
|
644
697
|
|| parent?.parent?.type == "SwitchCase"
|
|
645
698
|
|| /** @type {[number, number]} */(node.range)/**/[0] < /** @type {[number, number]} */(declaration.range)/**/[1]
|
|
646
|
-
)
|
|
699
|
+
) {
|
|
700
|
+
return false
|
|
701
|
+
}
|
|
647
702
|
for (let current = /** @type {import("eslint").Scope.Scope | null} */(scope)/**/; current && current != variable.scope; current = current.upper) {
|
|
648
|
-
if (current.block.type == "FunctionDeclaration")
|
|
703
|
+
if (current.block.type == "FunctionDeclaration") {
|
|
704
|
+
return false
|
|
705
|
+
}
|
|
649
706
|
}
|
|
650
707
|
return true
|
|
651
708
|
}
|
|
@@ -654,11 +711,15 @@ export default {
|
|
|
654
711
|
* @returns {boolean}
|
|
655
712
|
*/
|
|
656
713
|
function is_package_condition(node) {
|
|
657
|
-
if (!/(?:^|[/\\])package\.json$/.test(context.filename))
|
|
714
|
+
if (!/(?:^|[/\\])package\.json$/.test(context.filename)) {
|
|
715
|
+
return false
|
|
716
|
+
}
|
|
658
717
|
let parent = /** @type {import("eslint").Rule.Node} */(node)/**/.parent
|
|
659
718
|
while (parent && parent.type != "Program") {
|
|
660
719
|
const name = get_key_name(parent)
|
|
661
|
-
if (name == "exports" || name == "imports")
|
|
720
|
+
if (name == "exports" || name == "imports") {
|
|
721
|
+
return true
|
|
722
|
+
}
|
|
662
723
|
parent = parent.parent
|
|
663
724
|
}
|
|
664
725
|
return false
|
|
@@ -679,7 +740,9 @@ export default {
|
|
|
679
740
|
for (const key of visitor_keys[node.type] ?? []) {
|
|
680
741
|
const value = /** @type {Record<string, import("../../private.js").OrderNode | import("../../private.js").OrderNode[] | null | undefined>} */(/** @type {unknown} */(node))/**/[key]
|
|
681
742
|
for (const child of Array.isArray(value) ? value : [ value ]) {
|
|
682
|
-
if (child?.type && predicate(child))
|
|
743
|
+
if (child?.type && predicate(child)) {
|
|
744
|
+
return true
|
|
745
|
+
}
|
|
683
746
|
}
|
|
684
747
|
}
|
|
685
748
|
return false
|
|
@@ -708,9 +771,13 @@ export default {
|
|
|
708
771
|
/** @type {Record<string, unknown>} */
|
|
709
772
|
const object = {}
|
|
710
773
|
for (const property of node.properties) {
|
|
711
|
-
if (property.type != "Property" || property.kind != "init" || property.computed || property.shorthand)
|
|
774
|
+
if (property.type != "Property" || property.kind != "init" || property.computed || property.shorthand) {
|
|
775
|
+
return not_static
|
|
776
|
+
}
|
|
712
777
|
const value = static_value(property.value)
|
|
713
|
-
if (value === not_static)
|
|
778
|
+
if (value === not_static) {
|
|
779
|
+
return not_static
|
|
780
|
+
}
|
|
714
781
|
object[String(get_name(property.key))] = value
|
|
715
782
|
}
|
|
716
783
|
return object
|
|
@@ -761,12 +828,14 @@ export default {
|
|
|
761
828
|
}
|
|
762
829
|
)
|
|
763
830
|
} else {
|
|
764
|
-
if (entries.length > 1)
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
831
|
+
if (entries.length > 1) {
|
|
832
|
+
defer(
|
|
833
|
+
entries,
|
|
834
|
+
message_id,
|
|
835
|
+
layout,
|
|
836
|
+
get_level
|
|
837
|
+
)
|
|
838
|
+
}
|
|
770
839
|
entries = []
|
|
771
840
|
}
|
|
772
841
|
}
|
|
@@ -776,14 +845,18 @@ export default {
|
|
|
776
845
|
* @returns {void}
|
|
777
846
|
*/
|
|
778
847
|
function verify_statements(node) {
|
|
779
|
-
if (!check_declarations && !check_imports && !check_tests)
|
|
848
|
+
if (!check_declarations && !check_imports && !check_tests) {
|
|
849
|
+
return
|
|
850
|
+
}
|
|
780
851
|
/** @type {import("../../private.js").OrderEntry[]} */
|
|
781
852
|
let entries = []
|
|
782
853
|
/** @type {"declarations" | "imports" | "tests" | undefined} */
|
|
783
854
|
let kind
|
|
784
855
|
for (const statement of [ ...node.body, null ]) {
|
|
785
856
|
let id = statement && check_declarations ? get_function_id(statement) : undefined
|
|
786
|
-
if (node.type == "Program" && default_exports.has(id?.name))
|
|
857
|
+
if (node.type == "Program" && default_exports.has(id?.name)) {
|
|
858
|
+
id = undefined
|
|
859
|
+
}
|
|
787
860
|
const source = statement && check_imports ? get_import_source(statement) : undefined
|
|
788
861
|
const title = statement && check_tests && !id ? get_test_title(statement) : undefined
|
|
789
862
|
const report = id ?? source ?? title
|
|
@@ -801,7 +874,9 @@ export default {
|
|
|
801
874
|
continue
|
|
802
875
|
}
|
|
803
876
|
if (kind != next_kind) {
|
|
804
|
-
if (kind && entries.length > 1)
|
|
877
|
+
if (kind && entries.length > 1) {
|
|
878
|
+
defer(entries, kind, "statement")
|
|
879
|
+
}
|
|
805
880
|
entries = []
|
|
806
881
|
kind = next_kind
|
|
807
882
|
}
|
|
@@ -821,23 +896,29 @@ export default {
|
|
|
821
896
|
const listener = {
|
|
822
897
|
BlockStatement: verify_statements,
|
|
823
898
|
ExportNamedDeclaration: node => {
|
|
824
|
-
if (check_names)
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
899
|
+
if (check_names) {
|
|
900
|
+
verify_nodes(
|
|
901
|
+
node.specifiers,
|
|
902
|
+
get_specifier_name,
|
|
903
|
+
"names",
|
|
904
|
+
"sequence"
|
|
905
|
+
)
|
|
906
|
+
}
|
|
830
907
|
},
|
|
831
908
|
ImportDeclaration: node => {
|
|
832
|
-
if (check_names)
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
909
|
+
if (check_names) {
|
|
910
|
+
verify_nodes(
|
|
911
|
+
node.specifiers,
|
|
912
|
+
get_specifier_name,
|
|
913
|
+
"names",
|
|
914
|
+
"sequence"
|
|
915
|
+
)
|
|
916
|
+
}
|
|
838
917
|
},
|
|
839
918
|
ObjectExpression: node => {
|
|
840
|
-
if (!check_keys)
|
|
919
|
+
if (!check_keys) {
|
|
920
|
+
return
|
|
921
|
+
}
|
|
841
922
|
const condition = is_package_condition(node)
|
|
842
923
|
verify_nodes(
|
|
843
924
|
node.properties,
|
|
@@ -859,7 +940,9 @@ export default {
|
|
|
859
940
|
for (const property of node.properties) {
|
|
860
941
|
const names = collect_targets(property, [])
|
|
861
942
|
for (const name of new Set(names)) {
|
|
862
|
-
if (seen.has(name))
|
|
943
|
+
if (seen.has(name)) {
|
|
944
|
+
repeated.add(name)
|
|
945
|
+
}
|
|
863
946
|
seen.add(name)
|
|
864
947
|
}
|
|
865
948
|
targets.set(property, names)
|
|
@@ -888,21 +971,25 @@ export default {
|
|
|
888
971
|
},
|
|
889
972
|
StaticBlock: verify_statements,
|
|
890
973
|
TSInterfaceBody: node => {
|
|
891
|
-
if (check_keys)
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
974
|
+
if (check_keys) {
|
|
975
|
+
verify_nodes(
|
|
976
|
+
node.body,
|
|
977
|
+
get_key_name,
|
|
978
|
+
"keys",
|
|
979
|
+
"member"
|
|
980
|
+
)
|
|
981
|
+
}
|
|
897
982
|
},
|
|
898
983
|
TSModuleBlock: verify_statements,
|
|
899
984
|
TSTypeLiteral: node => {
|
|
900
|
-
if (check_keys)
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
985
|
+
if (check_keys) {
|
|
986
|
+
verify_nodes(
|
|
987
|
+
node.members,
|
|
988
|
+
get_key_name,
|
|
989
|
+
"keys",
|
|
990
|
+
"member"
|
|
991
|
+
)
|
|
992
|
+
}
|
|
906
993
|
}
|
|
907
994
|
}
|
|
908
995
|
return /** @type {import("eslint").Rule.RuleListener} */(/** @type {unknown} */(listener))/**/
|