| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 | /** * @author Toru Nagashima <https://github.com/mysticatea> * See LICENSE file in root directory for full license. */"use strict"const { isArrowToken } = require("eslint-utils")module.exports = {    meta: {        docs: {            description: "disallow arrow function expressions.",            category: "ES2015",            recommended: false,            url:                "http://mysticatea.github.io/eslint-plugin-es/rules/no-arrow-functions.html",        },        fixable: "code",        schema: [],        messages: {            forbidden: "ES2015 arrow function expressions are forbidden.",        },    },    create(context) {        const sourceCode = context.getSourceCode()        /**         * ArrowFunctionExpression to FunctionExpression         * @param  {Node} node ArrowFunctionExpression Node         * @returns {string} function expression text         */        function toFunctionExpression(node) {            const params = node.params            const paramText = params.length                ? sourceCode.text.slice(                      params[0].range[0],                      params[params.length - 1].range[1]                  )                : ""            const arrowToken = sourceCode.getTokenBefore(                node.body,                isArrowToken            )            const preText = sourceCode.text.slice(                arrowToken.range[1],                node.body.range[0]            )            const bodyText = sourceCode.text.slice(                arrowToken.range[1],                node.range[1]            )            if (node.body.type === "BlockStatement") {                return `function(${paramText})${bodyText}`            }            if (preText.includes("\n")) {                return `function(${paramText}){return(${bodyText})}`            }            return `function(${paramText}){return ${bodyText}}`        }        /**         * Report that ArrowFunctionExpression is being used         * @param {Node} node ArrowFunctionExpression Node         * @param {boolean} hasThis Whether `this` is referenced in` function` scope         * @param {boolean} hasSuper Whether `super` is referenced in` function` scope         * @returns {void}         */        function report(node, hasThis, hasSuper) {            context.report({                node,                messageId: "forbidden",                fix(fixer) {                    if (hasSuper) {                        return undefined                    }                    const functionText = toFunctionExpression(node)                    return fixer.replaceText(                        node,                        hasThis ? `${functionText}.bind(this)` : functionText                    )                },            })        }        let stack = { upper: null, hasThis: false, hasSuper: false }        return {            ":function"() {                stack = { upper: stack, hasThis: false, hasSuper: false }            },            ":function:exit"(node) {                const { hasThis, hasSuper } = stack                stack = stack.upper                if (node.type === "ArrowFunctionExpression") {                    report(node, hasThis, hasSuper)                    stack.hasThis = stack.hasThis || hasThis                    stack.hasSuper = stack.hasSuper || hasSuper                }            },            ThisExpression() {                stack.hasThis = true            },            Super() {                stack.hasSuper = true            },        }    },}
 |