File size: 3,834 Bytes
bc20498
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("../utils");
const compat_1 = require("../utils/compat");
/**
 * Check whether the component is declared in a single line or not.
 */
function isSingleLine(node) {
    return node.loc.start.line === node.loc.end.line;
}
/**
 * Group attributes line by line.
 */
function groupAttributesByLine(attributes) {
    const group = [];
    for (const attr of attributes) {
        if (group[0]?.[0]?.loc.end.line === attr.loc.start.line) {
            group[0].push(attr);
        }
        else {
            group.unshift([attr]);
        }
    }
    return group.reverse();
}
exports.default = (0, utils_1.createRule)('max-attributes-per-line', {
    meta: {
        docs: {
            description: 'enforce the maximum number of attributes per line',
            category: 'Stylistic Issues',
            recommended: false,
            conflictWithPrettier: true
        },
        fixable: 'whitespace',
        schema: [
            {
                type: 'object',
                properties: {
                    multiline: {
                        type: 'number',
                        minimum: 1
                    },
                    singleline: {
                        type: 'number',
                        minimum: 1
                    }
                },
                additionalProperties: false
            }
        ],
        messages: {
            requireNewline: "'{{name}}' should be on a new line."
        },
        type: 'layout'
    },
    create(context) {
        const multilineMaximum = context.options[0]?.multiline ?? 1;
        const singlelineMaximum = context.options[0]?.singleline ?? 1;
        const sourceCode = (0, compat_1.getSourceCode)(context);
        /**
         * Report attributes
         */
        function report(attribute) {
            if (!attribute) {
                return;
            }
            let name;
            if (attribute.type === 'SvelteAttribute' ||
                attribute.type === 'SvelteShorthandAttribute' ||
                attribute.type === 'SvelteDirective' ||
                attribute.type === 'SvelteStyleDirective' ||
                attribute.type === 'SvelteSpecialDirective') {
                name = sourceCode.text.slice(...attribute.key.range);
            }
            else {
                // if (attribute.type === "SvelteSpreadAttribute")
                name = sourceCode.text.slice(...attribute.range);
            }
            context.report({
                node: attribute,
                loc: attribute.loc,
                messageId: 'requireNewline',
                data: { name },
                fix(fixer) {
                    // Find the closest token before the current attribute
                    // that is not a white space
                    const prevToken = sourceCode.getTokenBefore(attribute, {
                        includeComments: true
                    });
                    const range = [prevToken.range[1], attribute.range[0]];
                    return fixer.replaceTextRange(range, '\n');
                }
            });
        }
        return {
            SvelteStartTag(node) {
                const numberOfAttributes = node.attributes.length;
                if (!numberOfAttributes)
                    return;
                if (isSingleLine(node)) {
                    if (numberOfAttributes > singlelineMaximum) {
                        report(node.attributes[singlelineMaximum]);
                    }
                }
                else {
                    for (const attrs of groupAttributesByLine(node.attributes)) {
                        report(attrs[multilineMaximum]);
                    }
                }
            }
        };
    }
});