minor adjustment to readme
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / arrow-parens.js
1 /**
2  * @fileoverview Rule to require parens in arrow function arguments.
3  * @author Jxck
4  */
5 "use strict";
6
7 //------------------------------------------------------------------------------
8 // Requirements
9 //------------------------------------------------------------------------------
10
11 const astUtils = require("./utils/ast-utils");
12
13 //------------------------------------------------------------------------------
14 // Helpers
15 //------------------------------------------------------------------------------
16
17 /**
18  * Get location should be reported by AST node.
19  * @param {ASTNode} node AST Node.
20  * @returns {Location} Location information.
21  */
22 function getLocation(node) {
23     return {
24         start: node.params[0].loc.start,
25         end: node.params[node.params.length - 1].loc.end
26     };
27 }
28
29 //------------------------------------------------------------------------------
30 // Rule Definition
31 //------------------------------------------------------------------------------
32
33 module.exports = {
34     meta: {
35         type: "layout",
36
37         docs: {
38             description: "require parentheses around arrow function arguments",
39             category: "ECMAScript 6",
40             recommended: false,
41             url: "https://eslint.org/docs/rules/arrow-parens"
42         },
43
44         fixable: "code",
45
46         schema: [
47             {
48                 enum: ["always", "as-needed"]
49             },
50             {
51                 type: "object",
52                 properties: {
53                     requireForBlockBody: {
54                         type: "boolean",
55                         default: false
56                     }
57                 },
58                 additionalProperties: false
59             }
60         ],
61
62         messages: {
63             unexpectedParens: "Unexpected parentheses around single function argument.",
64             expectedParens: "Expected parentheses around arrow function argument.",
65
66             unexpectedParensInline: "Unexpected parentheses around single function argument having a body with no curly braces.",
67             expectedParensBlock: "Expected parentheses around arrow function argument having a body with curly braces."
68         }
69     },
70
71     create(context) {
72         const asNeeded = context.options[0] === "as-needed";
73         const requireForBlockBody = asNeeded && context.options[1] && context.options[1].requireForBlockBody === true;
74
75         const sourceCode = context.getSourceCode();
76
77         /**
78          * Determines whether a arrow function argument end with `)`
79          * @param {ASTNode} node The arrow function node.
80          * @returns {void}
81          */
82         function parens(node) {
83             const isAsync = node.async;
84             const firstTokenOfParam = sourceCode.getFirstToken(node, isAsync ? 1 : 0);
85
86             /**
87              * Remove the parenthesis around a parameter
88              * @param {Fixer} fixer Fixer
89              * @returns {string} fixed parameter
90              */
91             function fixParamsWithParenthesis(fixer) {
92                 const paramToken = sourceCode.getTokenAfter(firstTokenOfParam);
93
94                 /*
95                  * ES8 allows Trailing commas in function parameter lists and calls
96                  * https://github.com/eslint/eslint/issues/8834
97                  */
98                 const closingParenToken = sourceCode.getTokenAfter(paramToken, astUtils.isClosingParenToken);
99                 const asyncToken = isAsync ? sourceCode.getTokenBefore(firstTokenOfParam) : null;
100                 const shouldAddSpaceForAsync = asyncToken && (asyncToken.range[1] === firstTokenOfParam.range[0]);
101
102                 return fixer.replaceTextRange([
103                     firstTokenOfParam.range[0],
104                     closingParenToken.range[1]
105                 ], `${shouldAddSpaceForAsync ? " " : ""}${paramToken.value}`);
106             }
107
108             // "as-needed", { "requireForBlockBody": true }: x => x
109             if (
110                 requireForBlockBody &&
111                 node.params.length === 1 &&
112                 node.params[0].type === "Identifier" &&
113                 !node.params[0].typeAnnotation &&
114                 node.body.type !== "BlockStatement" &&
115                 !node.returnType
116             ) {
117                 if (astUtils.isOpeningParenToken(firstTokenOfParam)) {
118                     context.report({
119                         node,
120                         messageId: "unexpectedParensInline",
121                         loc: getLocation(node),
122                         fix: fixParamsWithParenthesis
123                     });
124                 }
125                 return;
126             }
127
128             if (
129                 requireForBlockBody &&
130                 node.body.type === "BlockStatement"
131             ) {
132                 if (!astUtils.isOpeningParenToken(firstTokenOfParam)) {
133                     context.report({
134                         node,
135                         messageId: "expectedParensBlock",
136                         loc: getLocation(node),
137                         fix(fixer) {
138                             return fixer.replaceText(firstTokenOfParam, `(${firstTokenOfParam.value})`);
139                         }
140                     });
141                 }
142                 return;
143             }
144
145             // "as-needed": x => x
146             if (asNeeded &&
147                 node.params.length === 1 &&
148                 node.params[0].type === "Identifier" &&
149                 !node.params[0].typeAnnotation &&
150                 !node.returnType
151             ) {
152                 if (astUtils.isOpeningParenToken(firstTokenOfParam)) {
153                     context.report({
154                         node,
155                         messageId: "unexpectedParens",
156                         loc: getLocation(node),
157                         fix: fixParamsWithParenthesis
158                     });
159                 }
160                 return;
161             }
162
163             if (firstTokenOfParam.type === "Identifier") {
164                 const after = sourceCode.getTokenAfter(firstTokenOfParam);
165
166                 // (x) => x
167                 if (after.value !== ")") {
168                     context.report({
169                         node,
170                         messageId: "expectedParens",
171                         loc: getLocation(node),
172                         fix(fixer) {
173                             return fixer.replaceText(firstTokenOfParam, `(${firstTokenOfParam.value})`);
174                         }
175                     });
176                 }
177             }
178         }
179
180         return {
181             ArrowFunctionExpression: parens
182         };
183     }
184 };