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
|
@@ -43,7 +43,9 @@ export default {
|
|
|
43
43
|
}
|
|
44
44
|
)?.range[0]
|
|
45
45
|
: node.range[1] - 1
|
|
46
|
-
if (end == null || text[node.range[0]] != opener || text[end] != closer)
|
|
46
|
+
if (end == null || text[node.range[0]] != opener || text[end] != closer) {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
47
49
|
return {
|
|
48
50
|
end,
|
|
49
51
|
items,
|
|
@@ -68,15 +70,21 @@ export default {
|
|
|
68
70
|
let left = code_start
|
|
69
71
|
for (;;) {
|
|
70
72
|
left = source.skip_left(code_start, start)
|
|
71
|
-
if (left <= start || text[left - 1] != "(")
|
|
73
|
+
if (left <= start || text[left - 1] != "(") {
|
|
74
|
+
break
|
|
75
|
+
}
|
|
72
76
|
const right = source.skip_right(code_end, end)
|
|
73
|
-
if (right >= end || text[right] != ")")
|
|
77
|
+
if (right >= end || text[right] != ")") {
|
|
78
|
+
break
|
|
79
|
+
}
|
|
74
80
|
code_start = left - 1
|
|
75
81
|
code_end = right + 1
|
|
76
82
|
}
|
|
77
83
|
const right = source.skip_right(code_end, end)
|
|
78
84
|
let last = right
|
|
79
|
-
while (last > code_end && source.is_space(text.charCodeAt(last - 1)))
|
|
85
|
+
while (last > code_end && source.is_space(text.charCodeAt(last - 1))) {
|
|
86
|
+
last--
|
|
87
|
+
}
|
|
80
88
|
return {
|
|
81
89
|
after_comma: "",
|
|
82
90
|
after_comma_comments: 0,
|
|
@@ -117,7 +125,9 @@ export default {
|
|
|
117
125
|
if (first && last) {
|
|
118
126
|
open = source_code.getTokenBefore(first)
|
|
119
127
|
close = source_code.getTokenAfter(last)
|
|
120
|
-
if (close?.value == ",")
|
|
128
|
+
if (close?.value == ",") {
|
|
129
|
+
close = source_code.getTokenAfter(close)
|
|
130
|
+
}
|
|
121
131
|
} else {
|
|
122
132
|
const before = node.typeParameters ?? (node.type == "ArrowFunctionExpression" ? void 0 : node.id)
|
|
123
133
|
open = before
|
|
@@ -135,7 +145,9 @@ export default {
|
|
|
135
145
|
|| close?.value != ")"
|
|
136
146
|
|| open.range[0] < node.range[0]
|
|
137
147
|
|| close.range[1] > node.range[1]
|
|
138
|
-
)
|
|
148
|
+
) {
|
|
149
|
+
return
|
|
150
|
+
}
|
|
139
151
|
return {
|
|
140
152
|
end: close.range[0],
|
|
141
153
|
items: params,
|
|
@@ -161,7 +173,9 @@ export default {
|
|
|
161
173
|
close?.value != ")"
|
|
162
174
|
|| open?.value != "("
|
|
163
175
|
|| open.range[0] >= close.range[0]
|
|
164
|
-
)
|
|
176
|
+
) {
|
|
177
|
+
return
|
|
178
|
+
}
|
|
165
179
|
return {
|
|
166
180
|
end: close.range[0],
|
|
167
181
|
items: node.arguments,
|
|
@@ -203,7 +217,9 @@ export default {
|
|
|
203
217
|
* @returns {void}
|
|
204
218
|
*/
|
|
205
219
|
function push(node) {
|
|
206
|
-
if (!ignore_template_literal || node.range[0] >= template_end)
|
|
220
|
+
if (!ignore_template_literal || node.range[0] >= template_end) {
|
|
221
|
+
nodes.push(node)
|
|
222
|
+
}
|
|
207
223
|
}
|
|
208
224
|
/**
|
|
209
225
|
* @param {number} start
|
|
@@ -224,7 +240,9 @@ export default {
|
|
|
224
240
|
const texts = []
|
|
225
241
|
for (let index = start; index < end; index++) {
|
|
226
242
|
const comment = source.comment_by_start.get(index)
|
|
227
|
-
if (!comment)
|
|
243
|
+
if (!comment) {
|
|
244
|
+
continue
|
|
245
|
+
}
|
|
228
246
|
texts.push(
|
|
229
247
|
render(
|
|
230
248
|
comment.range[0],
|
|
@@ -244,12 +262,16 @@ export default {
|
|
|
244
262
|
function take_same_line_comments(position, limit, holes) {
|
|
245
263
|
let index = position
|
|
246
264
|
for (;;) {
|
|
247
|
-
while (index < limit && (text[index] == " " || text[index] == "\t" || text[index] == "," && holes-- > 0))
|
|
265
|
+
while (index < limit && (text[index] == " " || text[index] == "\t" || text[index] == "," && holes-- > 0)) {
|
|
266
|
+
index++
|
|
267
|
+
}
|
|
248
268
|
const comment = source.comment_by_start.get(index)
|
|
249
269
|
if (!comment || comment.range[1] > limit || comment.loc?.start.line != comment.loc?.end.line) {
|
|
250
270
|
return position
|
|
251
271
|
}
|
|
252
|
-
if (comment.type == "Line")
|
|
272
|
+
if (comment.type == "Line") {
|
|
273
|
+
return comment.range[1]
|
|
274
|
+
}
|
|
253
275
|
index = comment.range[1]
|
|
254
276
|
}
|
|
255
277
|
}
|
|
@@ -266,7 +288,9 @@ export default {
|
|
|
266
288
|
*/
|
|
267
289
|
function verify(node) {
|
|
268
290
|
const sequence = get_sequence(node)
|
|
269
|
-
if (!sequence)
|
|
291
|
+
if (!sequence) {
|
|
292
|
+
return
|
|
293
|
+
}
|
|
270
294
|
const { end, line_indent, start } = sequence
|
|
271
295
|
const is_sequence_expression = node.type == "SequenceExpression"
|
|
272
296
|
const items = sequence.items.map(
|
|
@@ -275,9 +299,13 @@ export default {
|
|
|
275
299
|
const last_index = items.length - 1
|
|
276
300
|
items.forEach(
|
|
277
301
|
(before, i) => {
|
|
278
|
-
if (!before || i == last_index || before.trailing_line_comment || text[before.right] != ",")
|
|
302
|
+
if (!before || i == last_index || before.trailing_line_comment || text[before.right] != ",") {
|
|
303
|
+
return
|
|
304
|
+
}
|
|
279
305
|
let next = i + 1
|
|
280
|
-
while (next <= last_index && !items[next])
|
|
306
|
+
while (next <= last_index && !items[next]) {
|
|
307
|
+
next++
|
|
308
|
+
}
|
|
281
309
|
const item = items[i + 1]
|
|
282
310
|
const comma_end = before.right + 1
|
|
283
311
|
const taken = take_same_line_comments(
|
|
@@ -285,11 +313,15 @@ export default {
|
|
|
285
313
|
items[next]?.code_start ?? end,
|
|
286
314
|
next - i - 1
|
|
287
315
|
)
|
|
288
|
-
if (taken == comma_end)
|
|
316
|
+
if (taken == comma_end) {
|
|
317
|
+
return
|
|
318
|
+
}
|
|
289
319
|
before.after_comma = item ? render(comma_end, taken).trim() : render_comments(comma_end, taken)
|
|
290
320
|
before.after_comma_comments = source.count_comments(comma_end, taken)
|
|
291
321
|
before.after_comma_line_comment = true
|
|
292
|
-
if (!item)
|
|
322
|
+
if (!item) {
|
|
323
|
+
return
|
|
324
|
+
}
|
|
293
325
|
item.left = source.skip_left(item.code_start, taken)
|
|
294
326
|
item.text = render(item.left, item.right).trim()
|
|
295
327
|
}
|
|
@@ -303,7 +335,9 @@ export default {
|
|
|
303
335
|
let comment_end = end
|
|
304
336
|
while (source.is_space(
|
|
305
337
|
text.charCodeAt(comment_end - 1)
|
|
306
|
-
))
|
|
338
|
+
)) {
|
|
339
|
+
comment_end--
|
|
340
|
+
}
|
|
307
341
|
last.after_comma = after_comma.trimStart()
|
|
308
342
|
last.after_comma_comments = comments
|
|
309
343
|
last.after_comma_line_comment = source.comment_by_end.get(comment_end)?.type == "Line"
|
|
@@ -317,7 +351,9 @@ export default {
|
|
|
317
351
|
let length = 0
|
|
318
352
|
let multiline = false
|
|
319
353
|
for (const item of items) {
|
|
320
|
-
if (!item)
|
|
354
|
+
if (!item) {
|
|
355
|
+
continue
|
|
356
|
+
}
|
|
321
357
|
covered_comments += source.count_comments(item.left, item.right) + item.after_comma_comments
|
|
322
358
|
length += text_width(item.text) + item.after_comma.length
|
|
323
359
|
if (
|
|
@@ -326,11 +362,17 @@ export default {
|
|
|
326
362
|
|| item.after_comma.includes("\n")
|
|
327
363
|
|| item.text.includes("\n")
|
|
328
364
|
|| item.trailing_line_comment
|
|
329
|
-
)
|
|
365
|
+
) {
|
|
366
|
+
multiline = true
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
if (covered_comments != source.count_comments(start, end)) {
|
|
370
|
+
return
|
|
330
371
|
}
|
|
331
|
-
if (covered_comments != source.count_comments(start, end)) return
|
|
332
372
|
const too_long = length > max_length
|
|
333
|
-
if (too_long)
|
|
373
|
+
if (too_long) {
|
|
374
|
+
multiline = true
|
|
375
|
+
}
|
|
334
376
|
let corrected_text = ""
|
|
335
377
|
if (multiline) {
|
|
336
378
|
const item_indent = is_sequence_expression ? line_indent : line_indent + indent
|
|
@@ -341,7 +383,9 @@ export default {
|
|
|
341
383
|
continue
|
|
342
384
|
}
|
|
343
385
|
const add_indent = !is_sequence_expression && source.get_line_start(start) == source.get_line_start(item.node.range[0])
|
|
344
|
-
if (add_indent && source.has_multiline_literal(item.left, item.right))
|
|
386
|
+
if (add_indent && source.has_multiline_literal(item.left, item.right)) {
|
|
387
|
+
return
|
|
388
|
+
}
|
|
345
389
|
/**
|
|
346
390
|
* @param {string} value
|
|
347
391
|
* @returns {string}
|
|
@@ -364,12 +408,19 @@ export default {
|
|
|
364
408
|
corrected_text += indented(item.text) + "," + comment + "\n" + item_indent
|
|
365
409
|
}
|
|
366
410
|
}
|
|
367
|
-
if (!is_sequence_expression)
|
|
411
|
+
if (!is_sequence_expression) {
|
|
412
|
+
corrected_text = "\n" + item_indent + corrected_text + "\n" + line_indent
|
|
413
|
+
}
|
|
368
414
|
} else {
|
|
369
415
|
corrected_text = items.map(item => item ? item.text : "").join(", ")
|
|
370
|
-
if (last?.after_comma)
|
|
371
|
-
|
|
372
|
-
if (
|
|
416
|
+
if (last?.after_comma) {
|
|
417
|
+
corrected_text += " " + last.after_comma
|
|
418
|
+
} else if (items[last_index] === null) {
|
|
419
|
+
corrected_text += ","
|
|
420
|
+
}
|
|
421
|
+
if (length && sequence.spacing) {
|
|
422
|
+
corrected_text = " " + corrected_text + " "
|
|
423
|
+
}
|
|
373
424
|
}
|
|
374
425
|
const current = render(start, end)
|
|
375
426
|
const same_structure = to_structure(current) == to_structure(corrected_text)
|
|
@@ -411,31 +462,49 @@ export default {
|
|
|
411
462
|
/** @type {import("../../private.js").RuleListener} */
|
|
412
463
|
const listener = {
|
|
413
464
|
ArrayExpression: node => {
|
|
414
|
-
if (check_array)
|
|
465
|
+
if (check_array) {
|
|
466
|
+
push(node)
|
|
467
|
+
}
|
|
415
468
|
},
|
|
416
469
|
ArrayPattern: node => {
|
|
417
|
-
if (check_array)
|
|
470
|
+
if (check_array) {
|
|
471
|
+
push(node)
|
|
472
|
+
}
|
|
418
473
|
},
|
|
419
474
|
ArrowFunctionExpression: node => {
|
|
420
|
-
if (check_call)
|
|
475
|
+
if (check_call) {
|
|
476
|
+
push(node)
|
|
477
|
+
}
|
|
421
478
|
},
|
|
422
479
|
CallExpression: node => {
|
|
423
|
-
if (check_call)
|
|
480
|
+
if (check_call) {
|
|
481
|
+
push(node)
|
|
482
|
+
}
|
|
424
483
|
},
|
|
425
484
|
FunctionDeclaration: node => {
|
|
426
|
-
if (check_call)
|
|
485
|
+
if (check_call) {
|
|
486
|
+
push(node)
|
|
487
|
+
}
|
|
427
488
|
},
|
|
428
489
|
FunctionExpression: node => {
|
|
429
|
-
if (check_call)
|
|
490
|
+
if (check_call) {
|
|
491
|
+
push(node)
|
|
492
|
+
}
|
|
430
493
|
},
|
|
431
494
|
NewExpression: node => {
|
|
432
|
-
if (check_call)
|
|
495
|
+
if (check_call) {
|
|
496
|
+
push(node)
|
|
497
|
+
}
|
|
433
498
|
},
|
|
434
499
|
ObjectExpression: node => {
|
|
435
|
-
if (check_object)
|
|
500
|
+
if (check_object) {
|
|
501
|
+
push(node)
|
|
502
|
+
}
|
|
436
503
|
},
|
|
437
504
|
ObjectPattern: node => {
|
|
438
|
-
if (check_object)
|
|
505
|
+
if (check_object) {
|
|
506
|
+
push(node)
|
|
507
|
+
}
|
|
439
508
|
},
|
|
440
509
|
"Program:exit": () => {
|
|
441
510
|
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
@@ -445,10 +514,14 @@ export default {
|
|
|
445
514
|
}
|
|
446
515
|
},
|
|
447
516
|
SequenceExpression: node => {
|
|
448
|
-
if (check_sequence)
|
|
517
|
+
if (check_sequence) {
|
|
518
|
+
push(node)
|
|
519
|
+
}
|
|
449
520
|
},
|
|
450
521
|
TemplateLiteral: node => {
|
|
451
|
-
if (node.range[1] > template_end)
|
|
522
|
+
if (node.range[1] > template_end) {
|
|
523
|
+
template_end = node.range[1]
|
|
524
|
+
}
|
|
452
525
|
}
|
|
453
526
|
}
|
|
454
527
|
return /** @type {import("eslint").Rule.RuleListener} */(/** @type {unknown} */(listener))/**/
|
|
@@ -40,7 +40,9 @@ export default {
|
|
|
40
40
|
|| !colon
|
|
41
41
|
|| question.range[1] > parts.consequent.range[0]
|
|
42
42
|
|| colon.range[1] > parts.alternate.range[0]
|
|
43
|
-
)
|
|
43
|
+
) {
|
|
44
|
+
return false
|
|
45
|
+
}
|
|
44
46
|
for (const operator of [ question, colon ]) {
|
|
45
47
|
const before = /** @type {import("eslint").AST.Token | import("estree").Comment} */(source_code.getTokenBefore(
|
|
46
48
|
operator,
|
|
@@ -50,7 +52,9 @@ export default {
|
|
|
50
52
|
operator,
|
|
51
53
|
{ includeComments: true }
|
|
52
54
|
))/**/
|
|
53
|
-
if (after.type == "Line")
|
|
55
|
+
if (after.type == "Line") {
|
|
56
|
+
return false
|
|
57
|
+
}
|
|
54
58
|
gaps.push(
|
|
55
59
|
{
|
|
56
60
|
depth,
|
|
@@ -70,7 +74,9 @@ export default {
|
|
|
70
74
|
parts.consequent,
|
|
71
75
|
parts.alternate
|
|
72
76
|
]) {
|
|
73
|
-
if (is_chained(branch) && !collect(branch, depth + 1, gaps))
|
|
77
|
+
if (is_chained(branch) && !collect(branch, depth + 1, gaps)) {
|
|
78
|
+
return false
|
|
79
|
+
}
|
|
74
80
|
}
|
|
75
81
|
return true
|
|
76
82
|
}
|
|
@@ -97,9 +103,13 @@ export default {
|
|
|
97
103
|
*/
|
|
98
104
|
function is_chained(node) {
|
|
99
105
|
const parent = node.parent
|
|
100
|
-
if (!parent || !is_ternary(node) || parent.type != node.type)
|
|
106
|
+
if (!parent || !is_ternary(node) || parent.type != node.type) {
|
|
107
|
+
return false
|
|
108
|
+
}
|
|
101
109
|
const parts = get_parts(parent)
|
|
102
|
-
if (node != parts.consequent && node != parts.alternate)
|
|
110
|
+
if (node != parts.consequent && node != parts.alternate) {
|
|
111
|
+
return false
|
|
112
|
+
}
|
|
103
113
|
const before = source_code.getTokenBefore(
|
|
104
114
|
/** @type {import("estree").Node} */(/** @type {unknown} */(node))/**/
|
|
105
115
|
)
|
|
@@ -117,19 +127,27 @@ export default {
|
|
|
117
127
|
* @returns {void}
|
|
118
128
|
*/
|
|
119
129
|
function push(node) {
|
|
120
|
-
if (!ignore_template_literal || node.range[0] >= template_end)
|
|
130
|
+
if (!ignore_template_literal || node.range[0] >= template_end) {
|
|
131
|
+
nodes.push(node)
|
|
132
|
+
}
|
|
121
133
|
}
|
|
122
134
|
/**
|
|
123
135
|
* @param {import("../../private.js").TernaryNode} node
|
|
124
136
|
* @returns {void}
|
|
125
137
|
*/
|
|
126
138
|
function verify(node) {
|
|
127
|
-
if (is_chained(node))
|
|
139
|
+
if (is_chained(node)) {
|
|
140
|
+
return
|
|
141
|
+
}
|
|
128
142
|
/** @type {import("../../private.js").TernaryGap[]} */
|
|
129
143
|
const gaps = []
|
|
130
|
-
if (!collect(node, 0, gaps))
|
|
144
|
+
if (!collect(node, 0, gaps)) {
|
|
145
|
+
return
|
|
146
|
+
}
|
|
131
147
|
let length = node.range[1] - node.range[0]
|
|
132
|
-
for (const gap of gaps)
|
|
148
|
+
for (const gap of gaps) {
|
|
149
|
+
length -= gap.end - gap.start - 1
|
|
150
|
+
}
|
|
133
151
|
const reason = gaps.length > 4
|
|
134
152
|
? "a branch is another ternary"
|
|
135
153
|
: length > max_length
|
|
@@ -152,15 +170,21 @@ export default {
|
|
|
152
170
|
for (const gap of gaps) {
|
|
153
171
|
const current = text.slice(gap.start, gap.end)
|
|
154
172
|
const breaks = multiline && gap.line_break
|
|
155
|
-
if (breaks && line_break_regex.test(current))
|
|
173
|
+
if (breaks && line_break_regex.test(current)) {
|
|
174
|
+
continue
|
|
175
|
+
}
|
|
156
176
|
const value = breaks
|
|
157
177
|
? eol + line_indent + indent.repeat(gap.depth + 1)
|
|
158
178
|
: " "
|
|
159
|
-
if (current == value)
|
|
179
|
+
if (current == value) {
|
|
180
|
+
continue
|
|
181
|
+
}
|
|
160
182
|
ranges.push([ gap.start, gap.end ])
|
|
161
183
|
values.push(value)
|
|
162
184
|
}
|
|
163
|
-
if (!ranges.length)
|
|
185
|
+
if (!ranges.length) {
|
|
186
|
+
return
|
|
187
|
+
}
|
|
164
188
|
context.report(
|
|
165
189
|
{
|
|
166
190
|
data: { reason },
|
|
@@ -185,7 +209,9 @@ export default {
|
|
|
185
209
|
)
|
|
186
210
|
},
|
|
187
211
|
"Program:exit": () => {
|
|
188
|
-
for (const node of nodes)
|
|
212
|
+
for (const node of nodes) {
|
|
213
|
+
verify(node)
|
|
214
|
+
}
|
|
189
215
|
},
|
|
190
216
|
/** @param {import("estree").Node} node */
|
|
191
217
|
TSConditionalType(node) {
|
|
@@ -196,7 +222,9 @@ export default {
|
|
|
196
222
|
/** @param {import("estree").TemplateLiteral} node */
|
|
197
223
|
TemplateLiteral(node) {
|
|
198
224
|
const end = /** @type {[number, number]} */(node.range)/**/[1]
|
|
199
|
-
if (end > template_end)
|
|
225
|
+
if (end > template_end) {
|
|
226
|
+
template_end = end
|
|
227
|
+
}
|
|
200
228
|
}
|
|
201
229
|
}
|
|
202
230
|
},
|