/** * @author Toru Nagashima * 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 }, } }, }