| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 | /** * @fileoverview Rule to require parens in arrow function arguments. * @author Jxck */"use strict";//------------------------------------------------------------------------------// Requirements//------------------------------------------------------------------------------const astUtils = require("../ast-utils");//------------------------------------------------------------------------------// Rule Definition//------------------------------------------------------------------------------module.exports = {    meta: {        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"                    }                },                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();        /**         * Determines whether a arrow function argument end with `)`         * @param {ASTNode} node The arrow function node.         * @returns {void}         */        function parens(node) {            const isAsync = node.async;            const firstTokenOfParam = sourceCode.getFirstToken(node, isAsync ? 1 : 0);            /**             * Remove the parenthesis around a parameter             * @param {Fixer} fixer Fixer             * @returns {string} fixed parameter             */            function fixParamsWithParenthesis(fixer) {                const paramToken = sourceCode.getTokenAfter(firstTokenOfParam);                /*                 * ES8 allows Trailing commas in function parameter lists and calls                 * https://github.com/eslint/eslint/issues/8834                 */                const closingParenToken = sourceCode.getTokenAfter(paramToken, astUtils.isClosingParenToken);                const asyncToken = isAsync ? sourceCode.getTokenBefore(firstTokenOfParam) : null;                const shouldAddSpaceForAsync = asyncToken && (asyncToken.range[1] === firstTokenOfParam.range[0]);                return fixer.replaceTextRange([                    firstTokenOfParam.range[0],                    closingParenToken.range[1]                ], `${shouldAddSpaceForAsync ? " " : ""}${paramToken.value}`);            }            // "as-needed", { "requireForBlockBody": true }: x => x            if (                requireForBlockBody &&                node.params.length === 1 &&                node.params[0].type === "Identifier" &&                !node.params[0].typeAnnotation &&                node.body.type !== "BlockStatement" &&                !node.returnType            ) {                if (astUtils.isOpeningParenToken(firstTokenOfParam)) {                    context.report({                        node,                        messageId: "unexpectedParensInline",                        fix: fixParamsWithParenthesis                    });                }                return;            }            if (                requireForBlockBody &&                node.body.type === "BlockStatement"            ) {                if (!astUtils.isOpeningParenToken(firstTokenOfParam)) {                    context.report({                        node,                        messageId: "expectedParensBlock",                        fix(fixer) {                            return fixer.replaceText(firstTokenOfParam, `(${firstTokenOfParam.value})`);                        }                    });                }                return;            }            // "as-needed": x => x            if (asNeeded &&                node.params.length === 1 &&                node.params[0].type === "Identifier" &&                !node.params[0].typeAnnotation &&                !node.returnType            ) {                if (astUtils.isOpeningParenToken(firstTokenOfParam)) {                    context.report({                        node,                        messageId: "unexpectedParens",                        fix: fixParamsWithParenthesis                    });                }                return;            }            if (firstTokenOfParam.type === "Identifier") {                const after = sourceCode.getTokenAfter(firstTokenOfParam);                // (x) => x                if (after.value !== ")") {                    context.report({                        node,                        messageId: "expectedParens",                        fix(fixer) {                            return fixer.replaceText(firstTokenOfParam, `(${firstTokenOfParam.value})`);                        }                    });                }            }        }        return {            ArrowFunctionExpression: parens        };    }};
 |