UNPKG

3.28 kBJavaScriptView Raw
1/**
2 * @fileoverview Rule to enforce placing object properties on separate lines.
3 * @author Vitor Balocco
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Rule Definition
10//------------------------------------------------------------------------------
11
12module.exports = {
13 meta: {
14 docs: {
15 description: "enforce placing object properties on separate lines",
16 category: "Stylistic Issues",
17 recommended: false
18 },
19
20 schema: [
21 {
22 type: "object",
23 properties: {
24 allowMultiplePropertiesPerLine: {
25 type: "boolean"
26 }
27 },
28 additionalProperties: false
29 }
30 ],
31
32 fixable: "whitespace"
33 },
34
35 create(context) {
36 const allowSameLine = context.options[0] && Boolean(context.options[0].allowMultiplePropertiesPerLine);
37 const errorMessage = allowSameLine
38 ? "Object properties must go on a new line if they aren't all on the same line."
39 : "Object properties must go on a new line.";
40
41 const sourceCode = context.getSourceCode();
42
43 return {
44 ObjectExpression(node) {
45 if (allowSameLine) {
46 if (node.properties.length > 1) {
47 const firstTokenOfFirstProperty = sourceCode.getFirstToken(node.properties[0]);
48 const lastTokenOfLastProperty = sourceCode.getLastToken(node.properties[node.properties.length - 1]);
49
50 if (firstTokenOfFirstProperty.loc.end.line === lastTokenOfLastProperty.loc.start.line) {
51
52 // All keys and values are on the same line
53 return;
54 }
55 }
56 }
57
58 for (let i = 1; i < node.properties.length; i++) {
59 const lastTokenOfPreviousProperty = sourceCode.getLastToken(node.properties[i - 1]);
60 const firstTokenOfCurrentProperty = sourceCode.getFirstToken(node.properties[i]);
61
62 if (lastTokenOfPreviousProperty.loc.end.line === firstTokenOfCurrentProperty.loc.start.line) {
63 context.report({
64 node,
65 loc: firstTokenOfCurrentProperty.loc.start,
66 message: errorMessage,
67 fix(fixer) {
68 const comma = sourceCode.getTokenBefore(firstTokenOfCurrentProperty);
69 const rangeAfterComma = [comma.range[1], firstTokenOfCurrentProperty.range[0]];
70
71 // Don't perform a fix if there are any comments between the comma and the next property.
72 if (sourceCode.text.slice(rangeAfterComma[0], rangeAfterComma[1]).trim()) {
73 return null;
74 }
75
76 return fixer.replaceTextRange(rangeAfterComma, "\n");
77 }
78 });
79 }
80 }
81 }
82 };
83 }
84};