]>
git.proxmox.com Git - pve-eslint.git/blob - eslint/lib/rules/arrow-parens.js
2 * @fileoverview Rule to require parens in arrow function arguments.
7 //------------------------------------------------------------------------------
9 //------------------------------------------------------------------------------
11 const astUtils
= require("./utils/ast-utils");
13 //------------------------------------------------------------------------------
15 //------------------------------------------------------------------------------
18 * Determines if the given arrow function has block body.
19 * @param {ASTNode} node `ArrowFunctionExpression` node.
20 * @returns {boolean} `true` if the function has block body.
22 function hasBlockBody(node
) {
23 return node
.body
.type
=== "BlockStatement";
26 //------------------------------------------------------------------------------
28 //------------------------------------------------------------------------------
30 /** @type {import('../shared/types').Rule} */
36 description
: "Require parentheses around arrow function arguments",
38 url
: "https://eslint.org/docs/rules/arrow-parens"
45 enum: ["always", "as-needed"]
50 requireForBlockBody
: {
55 additionalProperties
: false
60 unexpectedParens
: "Unexpected parentheses around single function argument.",
61 expectedParens
: "Expected parentheses around arrow function argument.",
63 unexpectedParensInline
: "Unexpected parentheses around single function argument having a body with no curly braces.",
64 expectedParensBlock
: "Expected parentheses around arrow function argument having a body with curly braces."
69 const asNeeded
= context
.options
[0] === "as-needed";
70 const requireForBlockBody
= asNeeded
&& context
.options
[1] && context
.options
[1].requireForBlockBody
=== true;
72 const sourceCode
= context
.getSourceCode();
75 * Finds opening paren of parameters for the given arrow function, if it exists.
76 * It is assumed that the given arrow function has exactly one parameter.
77 * @param {ASTNode} node `ArrowFunctionExpression` node.
78 * @returns {Token|null} the opening paren, or `null` if the given arrow function doesn't have parens of parameters.
80 function findOpeningParenOfParams(node
) {
81 const tokenBeforeParams
= sourceCode
.getTokenBefore(node
.params
[0]);
85 astUtils
.isOpeningParenToken(tokenBeforeParams
) &&
86 node
.range
[0] <= tokenBeforeParams
.range
[0]
88 return tokenBeforeParams
;
95 * Finds closing paren of parameters for the given arrow function.
96 * It is assumed that the given arrow function has parens of parameters and that it has exactly one parameter.
97 * @param {ASTNode} node `ArrowFunctionExpression` node.
98 * @returns {Token} the closing paren of parameters.
100 function getClosingParenOfParams(node
) {
101 return sourceCode
.getTokenAfter(node
.params
[0], astUtils
.isClosingParenToken
);
105 * Determines whether the given arrow function has comments inside parens of parameters.
106 * It is assumed that the given arrow function has parens of parameters.
107 * @param {ASTNode} node `ArrowFunctionExpression` node.
108 * @param {Token} openingParen Opening paren of parameters.
109 * @returns {boolean} `true` if the function has at least one comment inside of parens of parameters.
111 function hasCommentsInParensOfParams(node
, openingParen
) {
112 return sourceCode
.commentsExistBetween(openingParen
, getClosingParenOfParams(node
));
116 * Determines whether the given arrow function has unexpected tokens before opening paren of parameters,
117 * in which case it will be assumed that the existing parens of parameters are necessary.
118 * Only tokens within the range of the arrow function (tokens that are part of the arrow function) are taken into account.
119 * Example: <T>(a) => b
120 * @param {ASTNode} node `ArrowFunctionExpression` node.
121 * @param {Token} openingParen Opening paren of parameters.
122 * @returns {boolean} `true` if the function has at least one unexpected token.
124 function hasUnexpectedTokensBeforeOpeningParen(node
, openingParen
) {
125 const expectedCount
= node
.async
? 1 : 0;
127 return sourceCode
.getFirstToken(node
, { skip
: expectedCount
}) !== openingParen
;
131 "ArrowFunctionExpression[params.length=1]"(node
) {
132 const shouldHaveParens
= !asNeeded
|| requireForBlockBody
&& hasBlockBody(node
);
133 const openingParen
= findOpeningParenOfParams(node
);
134 const hasParens
= openingParen
!== null;
135 const [param
] = node
.params
;
137 if (shouldHaveParens
&& !hasParens
) {
140 messageId
: requireForBlockBody
? "expectedParensBlock" : "expectedParens",
143 yield fixer
.insertTextBefore(param
, "(");
144 yield fixer
.insertTextAfter(param
, ")");
152 param
.type
=== "Identifier" &&
153 !param
.typeAnnotation
&&
155 !hasCommentsInParensOfParams(node
, openingParen
) &&
156 !hasUnexpectedTokensBeforeOpeningParen(node
, openingParen
)
160 messageId
: requireForBlockBody
? "unexpectedParensInline" : "unexpectedParens",
163 const tokenBeforeOpeningParen
= sourceCode
.getTokenBefore(openingParen
);
164 const closingParen
= getClosingParenOfParams(node
);
167 tokenBeforeOpeningParen
&&
168 tokenBeforeOpeningParen
.range
[1] === openingParen
.range
[0] &&
169 !astUtils
.canTokensBeAdjacent(tokenBeforeOpeningParen
, sourceCode
.getFirstToken(param
))
171 yield fixer
.insertTextBefore(openingParen
, " ");
174 // remove parens, whitespace inside parens, and possible trailing comma
175 yield fixer
.removeRange([openingParen
.range
[0], param
.range
[0]]);
176 yield fixer
.removeRange([param
.range
[1], closingParen
.range
[1]]);