-
-
Notifications
You must be signed in to change notification settings - Fork 48
/
Copy pathfirst-attribute-linebreak.ts
80 lines (74 loc) · 2.08 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
import type { AST } from 'svelte-eslint-parser';
import { createRule } from '../utils';
import { getSourceCode } from '../utils/compat';
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 = getSourceCode(context);
/**
* 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);
}
};
}
});