UNPKG

4.33 kBJavaScriptView Raw
1const { fixingNodes } = require('./es-beautifier-common.js');
2
3const create = (context) => {
4 const option = context.options[0] || {
5 allowSingleLine: true,
6 maxStatementsInSingleLine: 2,
7 maxlenInSingleLine: 80,
8 };
9 const allowSingleLine = option.allowSingleLine;
10 const maxStatements = option.maxStatementsInSingleLine;
11 const maxLen = option.maxLenInSingleLine;
12
13 const sourceCode = context.getSourceCode();
14
15 const enterSwitchStatement = (node) => {
16 let prev = null;
17 node.cases.forEach((curr) => {
18 if (prev && prev.loc.end.line === curr.loc.start.line) {
19 context.report({
20 node,
21 message: 'Switch case in a switch statement must be on a new line.',
22 loc: curr.loc.start,
23 fix: fixer => fixer.insertTextBefore(curr, '\n'),
24 });
25 }
26 prev = curr;
27 });
28
29 if (node.cases.length) {
30 const firstToken = sourceCode.getFirstToken(node);
31 const lastToken = sourceCode.getLastToken(node);
32 const firstChild = node.cases[0];
33 const lastChild = node.cases[node.cases.length - 1];
34 if (firstToken.loc.end.line === firstChild.loc.start.line) {
35 context.report({
36 node,
37 message: 'Switch case in a switch statement must be on a new line.',
38 loc: firstToken.loc.start,
39 fix: fixer => fixer.insertTextBefore(firstChild, '\n'),
40 });
41 }
42 if (lastToken.loc.start.line === lastChild.loc.end.line) {
43 context.report({
44 node,
45 message: 'Switch case in a switch statement must be on a new line.',
46 loc: lastToken.loc.end,
47 fix: fixer => fixer.insertTextAfter(lastChild, '\n'),
48 });
49 }
50 }
51 };
52
53 const enterSwitchCase = (node) => {
54 if (allowSingleLine &&
55 node.loc.start.line === node.loc.end.line &&
56 (!maxStatements || node.consequent.length <= maxStatements) &&
57 (!maxLen || sourceCode.lines[node.loc.end.line - 1].length < maxLen)) {
58 // we accept one line
59 // but require a space
60 if (node.consequent.length) {
61 const punctuator = sourceCode.getTokenBefore(node.consequent[0]);
62 if (punctuator.type === 'Punctuator' && punctuator.range[1] === node.consequent[0].range[0]) {
63 context.report({
64 node,
65 message: 'Test in a switch case shoule follow a space.',
66 loc: punctuator.loc.end,
67 fix: fixer => fixer.insertTextAfter(punctuator, ' '),
68 });
69 }
70 }
71 return;
72 }
73
74 if (allowSingleLine) {
75 let parent = node.parent;
76 while (parent && parent.loc.start.line === node.loc.start.line) {
77 if (fixingNodes.has(parent)) {
78 // we ignore this time as we are still in the process
79 return;
80 }
81 parent = parent.parent;
82 }
83 }
84
85 let fixed = false;
86 let prev = null;
87 node.consequent.forEach((curr) => {
88 if (prev && prev.loc.end.line === curr.loc.start.line) {
89 context.report({
90 node,
91 message: 'Statement in a switch case must be on a new line.',
92 loc: curr.loc.start,
93 fix: fixer => fixer.insertTextBefore(curr, '\n'),
94 });
95 fixed = true;
96 }
97 prev = curr;
98 });
99
100 if (node.consequent.length) {
101 const firstToken = sourceCode.getFirstToken(node);
102 const firstChild = node.consequent[0];
103 if (firstToken.loc.end.line === firstChild.loc.start.line) {
104 context.report({
105 node,
106 message: 'Statement in a switch case must be on a new line.',
107 loc: firstToken.loc.start,
108 fix: fixer => fixer.insertTextBefore(firstChild, '\n'),
109 });
110 fixed = true;
111 }
112 }
113
114 if (fixed) fixingNodes.add(node);
115 };
116
117 return {
118 SwitchStatement: enterSwitchStatement,
119 SwitchCase: enterSwitchCase,
120 };
121};
122
123module.exports = {
124 meta: {
125 docs: {
126 description: 'enforce multi-line switch cases in a switch statement',
127 category: 'Stylistic Issues',
128 },
129 fixable: 'whitespace',
130 schema: [{
131 type: 'object',
132 properties: {
133 allowSingleLine: { type: 'boolean' },
134 maxStatementsInSingleLine: { type: 'integer' },
135 maxLenInSingleLine: { type: 'integer' },
136 },
137 additionalProperties: false,
138 }],
139 },
140 create,
141};