massive update, probably broken
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / comma-spacing.js
1 /**
2  * @fileoverview Comma spacing - validates spacing before and after comma
3  * @author Vignesh Anand aka vegetableman.
4  */
5 "use strict";
6
7 const astUtils = require("./utils/ast-utils");
8
9 //------------------------------------------------------------------------------
10 // Rule Definition
11 //------------------------------------------------------------------------------
12
13 module.exports = {
14     meta: {
15         type: "layout",
16
17         docs: {
18             description: "enforce consistent spacing before and after commas",
19             category: "Stylistic Issues",
20             recommended: false,
21             url: "https://eslint.org/docs/rules/comma-spacing"
22         },
23
24         fixable: "whitespace",
25
26         schema: [
27             {
28                 type: "object",
29                 properties: {
30                     before: {
31                         type: "boolean",
32                         default: false
33                     },
34                     after: {
35                         type: "boolean",
36                         default: true
37                     }
38                 },
39                 additionalProperties: false
40             }
41         ],
42
43         messages: {
44             missing: "A space is required {{loc}} ','.",
45             unexpected: "There should be no space {{loc}} ','."
46         }
47     },
48
49     create(context) {
50
51         const sourceCode = context.getSourceCode();
52         const tokensAndComments = sourceCode.tokensAndComments;
53
54         const options = {
55             before: context.options[0] ? context.options[0].before : false,
56             after: context.options[0] ? context.options[0].after : true
57         };
58
59         //--------------------------------------------------------------------------
60         // Helpers
61         //--------------------------------------------------------------------------
62
63         // list of comma tokens to ignore for the check of leading whitespace
64         const commaTokensToIgnore = [];
65
66         /**
67          * Reports a spacing error with an appropriate message.
68          * @param {ASTNode} node The binary expression node to report.
69          * @param {string} loc Is the error "before" or "after" the comma?
70          * @param {ASTNode} otherNode The node at the left or right of `node`
71          * @returns {void}
72          * @private
73          */
74         function report(node, loc, otherNode) {
75             context.report({
76                 node,
77                 fix(fixer) {
78                     if (options[loc]) {
79                         if (loc === "before") {
80                             return fixer.insertTextBefore(node, " ");
81                         }
82                         return fixer.insertTextAfter(node, " ");
83
84                     }
85                     let start, end;
86                     const newText = "";
87
88                     if (loc === "before") {
89                         start = otherNode.range[1];
90                         end = node.range[0];
91                     } else {
92                         start = node.range[1];
93                         end = otherNode.range[0];
94                     }
95
96                     return fixer.replaceTextRange([start, end], newText);
97
98                 },
99                 messageId: options[loc] ? "missing" : "unexpected",
100                 data: {
101                     loc
102                 }
103             });
104         }
105
106         /**
107          * Validates the spacing around a comma token.
108          * @param {Object} tokens The tokens to be validated.
109          * @param {Token} tokens.comma The token representing the comma.
110          * @param {Token} [tokens.left] The last token before the comma.
111          * @param {Token} [tokens.right] The first token after the comma.
112          * @param {Token|ASTNode} reportItem The item to use when reporting an error.
113          * @returns {void}
114          * @private
115          */
116         function validateCommaItemSpacing(tokens, reportItem) {
117             if (tokens.left && astUtils.isTokenOnSameLine(tokens.left, tokens.comma) &&
118                     (options.before !== sourceCode.isSpaceBetweenTokens(tokens.left, tokens.comma))
119             ) {
120                 report(reportItem, "before", tokens.left);
121             }
122
123             if (tokens.right && astUtils.isClosingParenToken(tokens.right)) {
124                 return;
125             }
126
127             if (tokens.right && !options.after && tokens.right.type === "Line") {
128                 return;
129             }
130
131             if (tokens.right && astUtils.isTokenOnSameLine(tokens.comma, tokens.right) &&
132                     (options.after !== sourceCode.isSpaceBetweenTokens(tokens.comma, tokens.right))
133             ) {
134                 report(reportItem, "after", tokens.right);
135             }
136         }
137
138         /**
139          * Adds null elements of the given ArrayExpression or ArrayPattern node to the ignore list.
140          * @param {ASTNode} node An ArrayExpression or ArrayPattern node.
141          * @returns {void}
142          */
143         function addNullElementsToIgnoreList(node) {
144             let previousToken = sourceCode.getFirstToken(node);
145
146             node.elements.forEach(element => {
147                 let token;
148
149                 if (element === null) {
150                     token = sourceCode.getTokenAfter(previousToken);
151
152                     if (astUtils.isCommaToken(token)) {
153                         commaTokensToIgnore.push(token);
154                     }
155                 } else {
156                     token = sourceCode.getTokenAfter(element);
157                 }
158
159                 previousToken = token;
160             });
161         }
162
163         //--------------------------------------------------------------------------
164         // Public
165         //--------------------------------------------------------------------------
166
167         return {
168             "Program:exit"() {
169                 tokensAndComments.forEach((token, i) => {
170
171                     if (!astUtils.isCommaToken(token)) {
172                         return;
173                     }
174
175                     if (token && token.type === "JSXText") {
176                         return;
177                     }
178
179                     const previousToken = tokensAndComments[i - 1];
180                     const nextToken = tokensAndComments[i + 1];
181
182                     validateCommaItemSpacing({
183                         comma: token,
184                         left: astUtils.isCommaToken(previousToken) || commaTokensToIgnore.includes(token) ? null : previousToken,
185                         right: astUtils.isCommaToken(nextToken) ? null : nextToken
186                     }, token);
187                 });
188             },
189             ArrayExpression: addNullElementsToIgnoreList,
190             ArrayPattern: addNullElementsToIgnoreList
191
192         };
193
194     }
195 };