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
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { get_fixes } from "./fix_recorder.js"
|
|
2
|
+
/**
|
|
3
|
+
* @param {import("eslint").Rule.RuleModule} rule
|
|
4
|
+
* @returns {import("eslint").Rule.RuleModule}
|
|
5
|
+
*/
|
|
6
|
+
function keep_body_comments(rule) {
|
|
7
|
+
return {
|
|
8
|
+
...rule,
|
|
9
|
+
create(context) {
|
|
10
|
+
const source_code = context.sourceCode
|
|
11
|
+
const text = source_code.text
|
|
12
|
+
return rule.create(
|
|
13
|
+
Object.create(
|
|
14
|
+
context,
|
|
15
|
+
{
|
|
16
|
+
report: {
|
|
17
|
+
value: (
|
|
18
|
+
/** @type {import("eslint").Rule.ReportDescriptor} */ descriptor
|
|
19
|
+
) => {
|
|
20
|
+
const [ fix, extra ] = get_fixes(descriptor)
|
|
21
|
+
const body = fix && !extra && fix.text == `{${text.slice(fix.range[0], fix.range[1])}}`
|
|
22
|
+
? source_code.getTokenByRangeStart(fix.range[0])
|
|
23
|
+
: null
|
|
24
|
+
const comment = body && source_code.getCommentsBefore(body)[0]
|
|
25
|
+
if (!fix || !comment) {
|
|
26
|
+
context.report(descriptor)
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
/** @type {import("eslint").AST.Range} */
|
|
30
|
+
const range = [
|
|
31
|
+
/** @type {import("eslint").AST.Range} */(comment.range)/**/[0],
|
|
32
|
+
fix.range[1]
|
|
33
|
+
]
|
|
34
|
+
context.report(
|
|
35
|
+
{
|
|
36
|
+
...descriptor,
|
|
37
|
+
fix(fixer) {
|
|
38
|
+
return fixer.replaceTextRange(
|
|
39
|
+
range,
|
|
40
|
+
`{${text.slice(range[0], range[1])}}`
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export { keep_body_comments }
|
|
@@ -37,7 +37,9 @@ function keep_comment_order(rule) {
|
|
|
37
37
|
)]
|
|
38
38
|
return !!comment && comment.range[1] <= item.range[1]
|
|
39
39
|
}
|
|
40
|
-
))
|
|
40
|
+
)) {
|
|
41
|
+
return
|
|
42
|
+
}
|
|
41
43
|
context.report(descriptor)
|
|
42
44
|
}
|
|
43
45
|
}
|
|
@@ -83,7 +85,9 @@ function keep_comments(rule) {
|
|
|
83
85
|
text.slice(item.range[0], item.range[1])
|
|
84
86
|
)
|
|
85
87
|
|| ends.has(item.range[0]) && !line_break_regex.test(item.text)
|
|
86
|
-
))
|
|
88
|
+
)) {
|
|
89
|
+
return
|
|
90
|
+
}
|
|
87
91
|
context.report(descriptor)
|
|
88
92
|
}
|
|
89
93
|
}
|
|
@@ -9,7 +9,9 @@ function keep_line_breaks(rule) {
|
|
|
9
9
|
...rule,
|
|
10
10
|
create(context) {
|
|
11
11
|
const eol = create_source_text(context.sourceCode).eol
|
|
12
|
-
if (eol == "\n")
|
|
12
|
+
if (eol == "\n") {
|
|
13
|
+
return rule.create(context)
|
|
14
|
+
}
|
|
13
15
|
return rule.create(
|
|
14
16
|
Object.create(
|
|
15
17
|
context,
|
|
@@ -18,7 +18,9 @@ function skip_hole_commas(rule) {
|
|
|
18
18
|
const token = descriptor.node
|
|
19
19
|
if (token?.type == "Punctuator" && token.value == ",") {
|
|
20
20
|
const before = source_code.getTokenBefore(token)
|
|
21
|
-
if (before?.value == "," && before.loc.end.line < token.loc.start.line)
|
|
21
|
+
if (before?.value == "," && before.loc.end.line < token.loc.start.line) {
|
|
22
|
+
return
|
|
23
|
+
}
|
|
22
24
|
}
|
|
23
25
|
context.report(descriptor)
|
|
24
26
|
}
|
|
@@ -14,7 +14,9 @@ function skip_optional_patterns(rule) {
|
|
|
14
14
|
value: (
|
|
15
15
|
/** @type {import("eslint").Rule.ReportDescriptor & { node?: import("estree").Node & { optional?: boolean } }} */ descriptor
|
|
16
16
|
) => {
|
|
17
|
-
if (descriptor.node?.type == "ObjectPattern" && descriptor.node.optional)
|
|
17
|
+
if (descriptor.node?.type == "ObjectPattern" && descriptor.node.optional) {
|
|
18
|
+
return
|
|
19
|
+
}
|
|
18
20
|
context.report(descriptor)
|
|
19
21
|
}
|
|
20
22
|
}
|
package/src/utils/source_text.js
CHANGED
|
@@ -38,11 +38,14 @@ function create_source_text(source_code) {
|
|
|
38
38
|
const enclosers = []
|
|
39
39
|
/** @type {number[]} */
|
|
40
40
|
const line_starts = [ 0 ]
|
|
41
|
-
for (const match of text.matchAll(line_terminator_regex))
|
|
41
|
+
for (const match of text.matchAll(line_terminator_regex)) {
|
|
42
|
+
line_starts.push(match.index + match[0].length)
|
|
43
|
+
}
|
|
42
44
|
/** @type {[number, number][]} */
|
|
43
45
|
const multiline_literals = []
|
|
44
46
|
for (const token of source_code.ast.tokens) {
|
|
45
|
-
|
|
47
|
+
/** @type {string} */
|
|
48
|
+
const type = token.type
|
|
46
49
|
if ((type == "String" || type == "Template" || type == "JSXText" && quote_regex.test(token.value)) && line_break_regex.test(token.value)) {
|
|
47
50
|
multiline_literals.push(
|
|
48
51
|
/** @type {[number, number]} */(token.range)/**/
|
|
@@ -53,7 +56,9 @@ function create_source_text(source_code) {
|
|
|
53
56
|
* @returns {number[]}
|
|
54
57
|
*/
|
|
55
58
|
function build_anchors() {
|
|
56
|
-
if (anchors)
|
|
59
|
+
if (anchors) {
|
|
60
|
+
return anchors
|
|
61
|
+
}
|
|
57
62
|
const tokens = source_code.ast.tokens
|
|
58
63
|
anchors = []
|
|
59
64
|
/** @type {number[]} */
|
|
@@ -65,10 +70,13 @@ function create_source_text(source_code) {
|
|
|
65
70
|
: index
|
|
66
71
|
let encloser = openers[openers.length - 1]
|
|
67
72
|
if (token.type == "Punctuator") {
|
|
68
|
-
if (openers_set.has(token.value))
|
|
69
|
-
|
|
73
|
+
if (openers_set.has(token.value)) {
|
|
74
|
+
openers.push(index)
|
|
75
|
+
} else if (closers_set.has(token.value)) {
|
|
70
76
|
const opener = openers.pop()
|
|
71
|
-
if (opener != null && anchor != index)
|
|
77
|
+
if (opener != null && anchor != index) {
|
|
78
|
+
anchor = /** @type {number} */(anchors[opener])/**/
|
|
79
|
+
}/**/
|
|
72
80
|
encloser = openers[openers.length - 1]
|
|
73
81
|
}
|
|
74
82
|
}
|
|
@@ -150,7 +158,9 @@ function create_source_text(source_code) {
|
|
|
150
158
|
edit(start, end, value) {
|
|
151
159
|
const index = lower_bound(edits, get_edit_key, 1 - start)
|
|
152
160
|
let first = index
|
|
153
|
-
while (first > 0 && (/** @type {{ end: number }} */(edits[first - 1])/**/).end <= end)
|
|
161
|
+
while (first > 0 && (/** @type {{ end: number }} */(edits[first - 1])/**/).end <= end) {
|
|
162
|
+
first--
|
|
163
|
+
}
|
|
154
164
|
edits.splice(
|
|
155
165
|
first,
|
|
156
166
|
index - first,
|
|
@@ -179,7 +189,9 @@ function create_source_text(source_code) {
|
|
|
179
189
|
const tokens = source_code.ast.tokens
|
|
180
190
|
build_anchors()
|
|
181
191
|
const index = lower_bound(tokens, get_token_start, position)
|
|
182
|
-
if (tokens[index]?.range[0] != position)
|
|
192
|
+
if (tokens[index]?.range[0] != position) {
|
|
193
|
+
return -1
|
|
194
|
+
}
|
|
183
195
|
const encloser = /** @type {number} */(enclosers[index])/**/
|
|
184
196
|
return encloser < 0
|
|
185
197
|
? -1
|
|
@@ -192,7 +204,9 @@ function create_source_text(source_code) {
|
|
|
192
204
|
get_indent(index) {
|
|
193
205
|
const line_start = get_line_start(index)
|
|
194
206
|
let position = line_start
|
|
195
|
-
while (position < index && (text[position] == " " || text[position] == "\t"))
|
|
207
|
+
while (position < index && (text[position] == " " || text[position] == "\t")) {
|
|
208
|
+
position++
|
|
209
|
+
}
|
|
196
210
|
return text.slice(line_start, position)
|
|
197
211
|
},
|
|
198
212
|
/**
|
|
@@ -210,7 +224,9 @@ function create_source_text(source_code) {
|
|
|
210
224
|
line_start
|
|
211
225
|
) - 1]
|
|
212
226
|
let statement = node
|
|
213
|
-
while (statement.parent && !statement_lists.has(statement.parent.type))
|
|
227
|
+
while (statement.parent && !statement_lists.has(statement.parent.type)) {
|
|
228
|
+
statement = statement.parent
|
|
229
|
+
}
|
|
214
230
|
const before = source_code.getTokenBefore(
|
|
215
231
|
/** @type {import("estree").Node} */(statement)/**/
|
|
216
232
|
)
|
|
@@ -232,7 +248,9 @@ function create_source_text(source_code) {
|
|
|
232
248
|
}
|
|
233
249
|
if (comment && comment.range[1] > line_start && comment.range[1] <= position) {
|
|
234
250
|
let opener = this.get_encloser(position)
|
|
235
|
-
while (opener >= line_start)
|
|
251
|
+
while (opener >= line_start) {
|
|
252
|
+
opener = this.get_encloser(opener)
|
|
253
|
+
}
|
|
236
254
|
const statement_start = statement.range[0]
|
|
237
255
|
if (opener > statement_start) {
|
|
238
256
|
return this.get_line_indent(
|
|
@@ -257,7 +275,9 @@ function create_source_text(source_code) {
|
|
|
257
275
|
|| !!line_comment && line_comment.range[1] <= statement.range[0] && get_line_start(statement.range[0]) == line_start
|
|
258
276
|
) {
|
|
259
277
|
const container = /** @type {import("../../private.js").AstNode & { body: import("../../private.js").AstNode[] } | undefined} */(/** @type {unknown} */(statement.parent))/**/
|
|
260
|
-
if (!container || container.type == "Program")
|
|
278
|
+
if (!container || container.type == "Program") {
|
|
279
|
+
return ""
|
|
280
|
+
}
|
|
261
281
|
let opener = container.range[0]
|
|
262
282
|
/** @type {import("../../private.js").AstNode} */
|
|
263
283
|
let owner = container
|
|
@@ -281,7 +301,9 @@ function create_source_text(source_code) {
|
|
|
281
301
|
indent
|
|
282
302
|
)
|
|
283
303
|
}
|
|
284
|
-
if (container.type == "BlockStatement" && !statement_lists.has(container.parent.type))
|
|
304
|
+
if (container.type == "BlockStatement" && !statement_lists.has(container.parent.type)) {
|
|
305
|
+
owner = container.parent
|
|
306
|
+
}
|
|
285
307
|
}
|
|
286
308
|
const container_indent = this.get_line_indent(owner, owner.range[0], indent)
|
|
287
309
|
return get_line_start(opener) == line_start
|
|
@@ -303,7 +325,8 @@ function create_source_text(source_code) {
|
|
|
303
325
|
&& child == parent.right
|
|
304
326
|
&& parent.range[0] < line_start
|
|
305
327
|
) {
|
|
306
|
-
|
|
328
|
+
/** @type {string} */
|
|
329
|
+
const operator = parent.operator
|
|
307
330
|
const operator_start = /** @type {import("eslint").AST.Token} */(source_code.getTokenBefore(
|
|
308
331
|
/** @type {import("estree").Node} */(parent.right)/**/,
|
|
309
332
|
{
|
|
@@ -352,7 +375,9 @@ function create_source_text(source_code) {
|
|
|
352
375
|
let result = ""
|
|
353
376
|
for (let index = lower_bound(edits, get_edit_key, 1 - start) - 1; index >= 0; index--) {
|
|
354
377
|
const edit = /** @type {{ end: number, start: number, text: string }} */(edits[index])/**/
|
|
355
|
-
if (edit.end > end)
|
|
378
|
+
if (edit.end > end) {
|
|
379
|
+
break
|
|
380
|
+
}
|
|
356
381
|
result += text.slice(position, edit.start) + edit.text
|
|
357
382
|
position = edit.end
|
|
358
383
|
}
|
|
@@ -365,10 +390,13 @@ function create_source_text(source_code) {
|
|
|
365
390
|
*/
|
|
366
391
|
skip_left(position, limit) {
|
|
367
392
|
while (position > limit) {
|
|
368
|
-
if (is_space(text.charCodeAt(position - 1)))
|
|
369
|
-
|
|
393
|
+
if (is_space(text.charCodeAt(position - 1))) {
|
|
394
|
+
position--
|
|
395
|
+
} else {
|
|
370
396
|
const comment = comment_by_end.get(position)
|
|
371
|
-
if (!comment || comment.range[0] < limit)
|
|
397
|
+
if (!comment || comment.range[0] < limit) {
|
|
398
|
+
break
|
|
399
|
+
}
|
|
372
400
|
position = comment.range[0]
|
|
373
401
|
}
|
|
374
402
|
}
|
|
@@ -381,10 +409,13 @@ function create_source_text(source_code) {
|
|
|
381
409
|
*/
|
|
382
410
|
skip_right(position, limit) {
|
|
383
411
|
while (position < limit) {
|
|
384
|
-
if (is_space(text.charCodeAt(position)))
|
|
385
|
-
|
|
412
|
+
if (is_space(text.charCodeAt(position))) {
|
|
413
|
+
position++
|
|
414
|
+
} else {
|
|
386
415
|
const comment = comment_by_start.get(position)
|
|
387
|
-
if (!comment || comment.range[1] > limit)
|
|
416
|
+
if (!comment || comment.range[1] > limit) {
|
|
417
|
+
break
|
|
418
|
+
}
|
|
388
419
|
position = comment.range[1]
|
|
389
420
|
}
|
|
390
421
|
}
|
|
@@ -430,8 +461,11 @@ function lower_bound(array, get, value) {
|
|
|
430
461
|
const middle = (low + high) >> 1
|
|
431
462
|
if (get(
|
|
432
463
|
/** @type {T} */(array[middle])/**/
|
|
433
|
-
) < value)
|
|
434
|
-
|
|
464
|
+
) < value) {
|
|
465
|
+
low = middle + 1
|
|
466
|
+
} else {
|
|
467
|
+
high = middle
|
|
468
|
+
}
|
|
435
469
|
}
|
|
436
470
|
return low
|
|
437
471
|
}
|
package/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"AAyNA;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,MAAM,EAbF,OAAO,QAAQ,EAAE,MAAM,CAAC,MAAM,GAAG;IACtC,OAAO,EAAE;QACP,WAAW,EAAE,OAAO,QAAQ,EAAE,MAAM,CAAC,MAAM,GAAG;YAC5C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YACvD,KAAK,EAAE,OAAO,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAA;SAC3C,CAAA;QACD,MAAM,EAAE,OAAO,QAAQ,EAAE,MAAM,CAAC,MAAM,GAAG;YACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;YACvD,KAAK,EAAE,OAAO,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAA;SAC3C,CAAA;KACF,CAAA;CA2BL,CAAA;eAmDc,MAAM;AACrB,OAAO,EAAE,MAAM,IAAI,gBAAgB,EAAE,CAAA"}
|