• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * @fileoverview A rule to warn against using arrow functions when they could be
3 * confused with comparisons
4 * @author Jxck <https://github.com/Jxck>
5 */
6
7"use strict";
8
9const astUtils = require("./utils/ast-utils.js");
10
11//------------------------------------------------------------------------------
12// Helpers
13//------------------------------------------------------------------------------
14
15/**
16 * Checks whether or not a node is a conditional expression.
17 * @param {ASTNode} node node to test
18 * @returns {boolean} `true` if the node is a conditional expression.
19 */
20function isConditional(node) {
21    return node && node.type === "ConditionalExpression";
22}
23
24//------------------------------------------------------------------------------
25// Rule Definition
26//------------------------------------------------------------------------------
27
28module.exports = {
29    meta: {
30        type: "suggestion",
31
32        docs: {
33            description: "disallow arrow functions where they could be confused with comparisons",
34            category: "ECMAScript 6",
35            recommended: false,
36            url: "https://eslint.org/docs/rules/no-confusing-arrow"
37        },
38
39        fixable: "code",
40
41        schema: [{
42            type: "object",
43            properties: {
44                allowParens: { type: "boolean", default: true }
45            },
46            additionalProperties: false
47        }],
48
49        messages: {
50            confusing: "Arrow function used ambiguously with a conditional expression."
51        }
52    },
53
54    create(context) {
55        const config = context.options[0] || {};
56        const allowParens = config.allowParens || (config.allowParens === void 0);
57        const sourceCode = context.getSourceCode();
58
59
60        /**
61         * Reports if an arrow function contains an ambiguous conditional.
62         * @param {ASTNode} node A node to check and report.
63         * @returns {void}
64         */
65        function checkArrowFunc(node) {
66            const body = node.body;
67
68            if (isConditional(body) && !(allowParens && astUtils.isParenthesised(sourceCode, body))) {
69                context.report({
70                    node,
71                    messageId: "confusing",
72                    fix(fixer) {
73
74                        // if `allowParens` is not set to true don't bother wrapping in parens
75                        return allowParens && fixer.replaceText(node.body, `(${sourceCode.getText(node.body)})`);
76                    }
77                });
78            }
79        }
80
81        return {
82            ArrowFunctionExpression: checkArrowFunc
83        };
84    }
85};
86