-
-
Notifications
You must be signed in to change notification settings - Fork 48
/
Copy pathfirst-attribute-linebreak.ts
83 lines (77 loc) · 2.29 KB
/
first-attribute-linebreak.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import type { AST } from "svelte-eslint-parser"
import { createRule } from "../utils"
export default createRule("first-attribute-linebreak", {
meta: {
docs: {
description: "enforce the location of first attribute",
category: "Stylistic Issues",
recommended: false,
conflictWithPrettier: true,
},
fixable: "whitespace",
schema: [
{
type: "object",
properties: {
multiline: { enum: ["below", "beside"] },
singleline: { enum: ["below", "beside"] },
},
additionalProperties: false,
},
],
messages: {
expected: "Expected a linebreak before this attribute.",
unexpected: "Expected no linebreak before this attribute.",
},
type: "layout",
},
create(context) {
const multiline: "below" | "beside" =
context.options[0]?.multiline || "below"
const singleline: "below" | "beside" =
context.options[0]?.singleline || "beside"
const sourceCode = context.getSourceCode()
/**
* Report attribute
*/
function report(
firstAttribute: AST.SvelteStartTag["attributes"][number],
location: "below" | "beside",
) {
context.report({
node: firstAttribute,
messageId: location === "beside" ? "unexpected" : "expected",
fix(fixer) {
const prevToken = sourceCode.getTokenBefore(firstAttribute, {
includeComments: true,
})!
return fixer.replaceTextRange(
[prevToken.range[1], firstAttribute.range[0]],
location === "beside" ? " " : "\n",
)
},
})
}
return {
SvelteStartTag(node) {
const firstAttribute = node.attributes[0]
if (!firstAttribute) return
const lastAttribute = node.attributes[node.attributes.length - 1]
const location =
firstAttribute.loc.start.line === lastAttribute.loc.end.line
? singleline
: multiline
if (location === "beside") {
if (node.parent.name.loc.end.line === firstAttribute.loc.start.line) {
return
}
} else {
if (node.parent.name.loc.end.line < firstAttribute.loc.start.line) {
return
}
}
report(firstAttribute, location)
},
}
},
})