]>
Commit | Line | Data |
---|---|---|
eb39fafa DC |
1 | /** |
2 | * @fileoverview Rule to enforce spacing around colons of switch statements. | |
3 | * @author Toru Nagashima | |
4 | */ | |
5 | ||
6 | "use strict"; | |
7 | ||
8 | //------------------------------------------------------------------------------ | |
9 | // Requirements | |
10 | //------------------------------------------------------------------------------ | |
11 | ||
12 | const astUtils = require("./utils/ast-utils"); | |
13 | ||
14 | //------------------------------------------------------------------------------ | |
15 | // Rule Definition | |
16 | //------------------------------------------------------------------------------ | |
17 | ||
34eeec05 | 18 | /** @type {import('../shared/types').Rule} */ |
eb39fafa DC |
19 | module.exports = { |
20 | meta: { | |
21 | type: "layout", | |
22 | ||
23 | docs: { | |
8f9d1d4d | 24 | description: "Enforce spacing around colons of switch statements", |
eb39fafa | 25 | recommended: false, |
f2a92ac6 | 26 | url: "https://eslint.org/docs/latest/rules/switch-colon-spacing" |
eb39fafa DC |
27 | }, |
28 | ||
29 | schema: [ | |
30 | { | |
31 | type: "object", | |
32 | properties: { | |
33 | before: { type: "boolean", default: false }, | |
34 | after: { type: "boolean", default: true } | |
35 | }, | |
36 | additionalProperties: false | |
37 | } | |
38 | ], | |
39 | fixable: "whitespace", | |
40 | messages: { | |
41 | expectedBefore: "Expected space(s) before this colon.", | |
42 | expectedAfter: "Expected space(s) after this colon.", | |
43 | unexpectedBefore: "Unexpected space(s) before this colon.", | |
44 | unexpectedAfter: "Unexpected space(s) after this colon." | |
45 | } | |
46 | }, | |
47 | ||
48 | create(context) { | |
f2a92ac6 | 49 | const sourceCode = context.sourceCode; |
eb39fafa DC |
50 | const options = context.options[0] || {}; |
51 | const beforeSpacing = options.before === true; // false by default | |
52 | const afterSpacing = options.after !== false; // true by default | |
53 | ||
eb39fafa DC |
54 | /** |
55 | * Check whether the spacing between the given 2 tokens is valid or not. | |
56 | * @param {Token} left The left token to check. | |
57 | * @param {Token} right The right token to check. | |
58 | * @param {boolean} expected The expected spacing to check. `true` if there should be a space. | |
59 | * @returns {boolean} `true` if the spacing between the tokens is valid. | |
60 | */ | |
61 | function isValidSpacing(left, right, expected) { | |
62 | return ( | |
63 | astUtils.isClosingBraceToken(right) || | |
64 | !astUtils.isTokenOnSameLine(left, right) || | |
65 | sourceCode.isSpaceBetweenTokens(left, right) === expected | |
66 | ); | |
67 | } | |
68 | ||
69 | /** | |
70 | * Check whether comments exist between the given 2 tokens. | |
71 | * @param {Token} left The left token to check. | |
72 | * @param {Token} right The right token to check. | |
73 | * @returns {boolean} `true` if comments exist between the given 2 tokens. | |
74 | */ | |
75 | function commentsExistBetween(left, right) { | |
76 | return sourceCode.getFirstTokenBetween( | |
77 | left, | |
78 | right, | |
79 | { | |
80 | includeComments: true, | |
81 | filter: astUtils.isCommentToken | |
82 | } | |
83 | ) !== null; | |
84 | } | |
85 | ||
86 | /** | |
87 | * Fix the spacing between the given 2 tokens. | |
88 | * @param {RuleFixer} fixer The fixer to fix. | |
89 | * @param {Token} left The left token of fix range. | |
90 | * @param {Token} right The right token of fix range. | |
91 | * @param {boolean} spacing The spacing style. `true` if there should be a space. | |
92 | * @returns {Fix|null} The fix object. | |
93 | */ | |
94 | function fix(fixer, left, right, spacing) { | |
95 | if (commentsExistBetween(left, right)) { | |
96 | return null; | |
97 | } | |
98 | if (spacing) { | |
99 | return fixer.insertTextAfter(left, " "); | |
100 | } | |
101 | return fixer.removeRange([left.range[1], right.range[0]]); | |
102 | } | |
103 | ||
104 | return { | |
105 | SwitchCase(node) { | |
609c276f | 106 | const colonToken = astUtils.getSwitchCaseColonToken(node, sourceCode); |
eb39fafa DC |
107 | const beforeToken = sourceCode.getTokenBefore(colonToken); |
108 | const afterToken = sourceCode.getTokenAfter(colonToken); | |
109 | ||
110 | if (!isValidSpacing(beforeToken, colonToken, beforeSpacing)) { | |
111 | context.report({ | |
112 | node, | |
113 | loc: colonToken.loc, | |
114 | messageId: beforeSpacing ? "expectedBefore" : "unexpectedBefore", | |
115 | fix: fixer => fix(fixer, beforeToken, colonToken, beforeSpacing) | |
116 | }); | |
117 | } | |
118 | if (!isValidSpacing(colonToken, afterToken, afterSpacing)) { | |
119 | context.report({ | |
120 | node, | |
121 | loc: colonToken.loc, | |
122 | messageId: afterSpacing ? "expectedAfter" : "unexpectedAfter", | |
123 | fix: fixer => fix(fixer, colonToken, afterToken, afterSpacing) | |
124 | }); | |
125 | } | |
126 | } | |
127 | }; | |
128 | } | |
129 | }; |