| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 | /** * @fileoverview Rule to flag use of an object property of the global object (Math and JSON) as a function * @author James Allardice */"use strict";//------------------------------------------------------------------------------// Requirements//------------------------------------------------------------------------------const { CALL, CONSTRUCT, ReferenceTracker } = require("eslint-utils");const getPropertyName = require("./utils/ast-utils").getStaticPropertyName;//------------------------------------------------------------------------------// Helpers//------------------------------------------------------------------------------const nonCallableGlobals = ["Atomics", "JSON", "Math", "Reflect", "Intl"];/** * Returns the name of the node to report * @param {ASTNode} node A node to report * @returns {string} name to report */function getReportNodeName(node) {    if (node.type === "ChainExpression") {        return getReportNodeName(node.expression);    }    if (node.type === "MemberExpression") {        return getPropertyName(node);    }    return node.name;}//------------------------------------------------------------------------------// Rule Definition//------------------------------------------------------------------------------/** @type {import('../shared/types').Rule} */module.exports = {    meta: {        type: "problem",        docs: {            description: "Disallow calling global object properties as functions",            recommended: true,            url: "https://eslint.org/docs/rules/no-obj-calls"        },        schema: [],        messages: {            unexpectedCall: "'{{name}}' is not a function.",            unexpectedRefCall: "'{{name}}' is reference to '{{ref}}', which is not a function."        }    },    create(context) {        return {            Program() {                const scope = context.getScope();                const tracker = new ReferenceTracker(scope);                const traceMap = {};                for (const g of nonCallableGlobals) {                    traceMap[g] = {                        [CALL]: true,                        [CONSTRUCT]: true                    };                }                for (const { node, path } of tracker.iterateGlobalReferences(traceMap)) {                    const name = getReportNodeName(node.callee);                    const ref = path[0];                    const messageId = name === ref ? "unexpectedCall" : "unexpectedRefCall";                    context.report({ node, messageId, data: { name, ref } });                }            }        };    }};
 |