| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 | 
							- /**
 
-  * @fileoverview Rule to require parens in arrow function arguments.
 
-  * @author Jxck
 
-  */
 
- "use strict";
 
- //------------------------------------------------------------------------------
 
- // Requirements
 
- //------------------------------------------------------------------------------
 
- const astUtils = require("./utils/ast-utils");
 
- //------------------------------------------------------------------------------
 
- // Helpers
 
- //------------------------------------------------------------------------------
 
- /**
 
-  * Determines if the given arrow function has block body.
 
-  * @param {ASTNode} node `ArrowFunctionExpression` node.
 
-  * @returns {boolean} `true` if the function has block body.
 
-  */
 
- function hasBlockBody(node) {
 
-     return node.body.type === "BlockStatement";
 
- }
 
- //------------------------------------------------------------------------------
 
- // Rule Definition
 
- //------------------------------------------------------------------------------
 
- module.exports = {
 
-     meta: {
 
-         type: "layout",
 
-         docs: {
 
-             description: "require parentheses around arrow function arguments",
 
-             category: "ECMAScript 6",
 
-             recommended: false,
 
-             url: "https://eslint.org/docs/rules/arrow-parens"
 
-         },
 
-         fixable: "code",
 
-         schema: [
 
-             {
 
-                 enum: ["always", "as-needed"]
 
-             },
 
-             {
 
-                 type: "object",
 
-                 properties: {
 
-                     requireForBlockBody: {
 
-                         type: "boolean",
 
-                         default: false
 
-                     }
 
-                 },
 
-                 additionalProperties: false
 
-             }
 
-         ],
 
-         messages: {
 
-             unexpectedParens: "Unexpected parentheses around single function argument.",
 
-             expectedParens: "Expected parentheses around arrow function argument.",
 
-             unexpectedParensInline: "Unexpected parentheses around single function argument having a body with no curly braces.",
 
-             expectedParensBlock: "Expected parentheses around arrow function argument having a body with curly braces."
 
-         }
 
-     },
 
-     create(context) {
 
-         const asNeeded = context.options[0] === "as-needed";
 
-         const requireForBlockBody = asNeeded && context.options[1] && context.options[1].requireForBlockBody === true;
 
-         const sourceCode = context.getSourceCode();
 
-         /**
 
-          * Finds opening paren of parameters for the given arrow function, if it exists.
 
-          * It is assumed that the given arrow function has exactly one parameter.
 
-          * @param {ASTNode} node `ArrowFunctionExpression` node.
 
-          * @returns {Token|null} the opening paren, or `null` if the given arrow function doesn't have parens of parameters.
 
-          */
 
-         function findOpeningParenOfParams(node) {
 
-             const tokenBeforeParams = sourceCode.getTokenBefore(node.params[0]);
 
-             if (
 
-                 tokenBeforeParams &&
 
-                 astUtils.isOpeningParenToken(tokenBeforeParams) &&
 
-                 node.range[0] <= tokenBeforeParams.range[0]
 
-             ) {
 
-                 return tokenBeforeParams;
 
-             }
 
-             return null;
 
-         }
 
-         /**
 
-          * Finds closing paren of parameters for the given arrow function.
 
-          * It is assumed that the given arrow function has parens of parameters and that it has exactly one parameter.
 
-          * @param {ASTNode} node `ArrowFunctionExpression` node.
 
-          * @returns {Token} the closing paren of parameters.
 
-          */
 
-         function getClosingParenOfParams(node) {
 
-             return sourceCode.getTokenAfter(node.params[0], astUtils.isClosingParenToken);
 
-         }
 
-         /**
 
-          * Determines whether the given arrow function has comments inside parens of parameters.
 
-          * It is assumed that the given arrow function has parens of parameters.
 
-          * @param {ASTNode} node `ArrowFunctionExpression` node.
 
-          * @param {Token} openingParen Opening paren of parameters.
 
-          * @returns {boolean} `true` if the function has at least one comment inside of parens of parameters.
 
-          */
 
-         function hasCommentsInParensOfParams(node, openingParen) {
 
-             return sourceCode.commentsExistBetween(openingParen, getClosingParenOfParams(node));
 
-         }
 
-         /**
 
-          * Determines whether the given arrow function has unexpected tokens before opening paren of parameters,
 
-          * in which case it will be assumed that the existing parens of parameters are necessary.
 
-          * Only tokens within the range of the arrow function (tokens that are part of the arrow function) are taken into account.
 
-          * Example: <T>(a) => b
 
-          * @param {ASTNode} node `ArrowFunctionExpression` node.
 
-          * @param {Token} openingParen Opening paren of parameters.
 
-          * @returns {boolean} `true` if the function has at least one unexpected token.
 
-          */
 
-         function hasUnexpectedTokensBeforeOpeningParen(node, openingParen) {
 
-             const expectedCount = node.async ? 1 : 0;
 
-             return sourceCode.getFirstToken(node, { skip: expectedCount }) !== openingParen;
 
-         }
 
-         return {
 
-             "ArrowFunctionExpression[params.length=1]"(node) {
 
-                 const shouldHaveParens = !asNeeded || requireForBlockBody && hasBlockBody(node);
 
-                 const openingParen = findOpeningParenOfParams(node);
 
-                 const hasParens = openingParen !== null;
 
-                 const [param] = node.params;
 
-                 if (shouldHaveParens && !hasParens) {
 
-                     context.report({
 
-                         node,
 
-                         messageId: requireForBlockBody ? "expectedParensBlock" : "expectedParens",
 
-                         loc: param.loc,
 
-                         *fix(fixer) {
 
-                             yield fixer.insertTextBefore(param, "(");
 
-                             yield fixer.insertTextAfter(param, ")");
 
-                         }
 
-                     });
 
-                 }
 
-                 if (
 
-                     !shouldHaveParens &&
 
-                     hasParens &&
 
-                     param.type === "Identifier" &&
 
-                     !param.typeAnnotation &&
 
-                     !node.returnType &&
 
-                     !hasCommentsInParensOfParams(node, openingParen) &&
 
-                     !hasUnexpectedTokensBeforeOpeningParen(node, openingParen)
 
-                 ) {
 
-                     context.report({
 
-                         node,
 
-                         messageId: requireForBlockBody ? "unexpectedParensInline" : "unexpectedParens",
 
-                         loc: param.loc,
 
-                         *fix(fixer) {
 
-                             const tokenBeforeOpeningParen = sourceCode.getTokenBefore(openingParen);
 
-                             const closingParen = getClosingParenOfParams(node);
 
-                             if (
 
-                                 tokenBeforeOpeningParen &&
 
-                                 tokenBeforeOpeningParen.range[1] === openingParen.range[0] &&
 
-                                 !astUtils.canTokensBeAdjacent(tokenBeforeOpeningParen, sourceCode.getFirstToken(param))
 
-                             ) {
 
-                                 yield fixer.insertTextBefore(openingParen, " ");
 
-                             }
 
-                             // remove parens, whitespace inside parens, and possible trailing comma
 
-                             yield fixer.removeRange([openingParen.range[0], param.range[0]]);
 
-                             yield fixer.removeRange([param.range[1], closingParen.range[1]]);
 
-                         }
 
-                     });
 
-                 }
 
-             }
 
-         };
 
-     }
 
- };
 
 
  |