| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 | /** * @fileoverview Rule to flag wrapping non-iife in parens * @author Gyandeep Singh */"use strict";//------------------------------------------------------------------------------// Helpers//------------------------------------------------------------------------------/** * Checks whether or not a given node is an `Identifier` node which was named a given name. * @param {ASTNode} node - A node to check. * @param {string} name - An expected name of the node. * @returns {boolean} `true` if the node is an `Identifier` node which was named as expected. */function isIdentifier(node, name) {    return node.type === "Identifier" && node.name === name;}/** * Checks whether or not a given node is an argument of a specified method call. * @param {ASTNode} node - A node to check. * @param {number} index - An expected index of the node in arguments. * @param {string} object - An expected name of the object of the method. * @param {string} property - An expected name of the method. * @returns {boolean} `true` if the node is an argument of the specified method call. */function isArgumentOfMethodCall(node, index, object, property) {    const parent = node.parent;    return (        parent.type === "CallExpression" &&        parent.callee.type === "MemberExpression" &&        parent.callee.computed === false &&        isIdentifier(parent.callee.object, object) &&        isIdentifier(parent.callee.property, property) &&        parent.arguments[index] === node    );}/** * Checks whether or not a given node is a property descriptor. * @param {ASTNode} node - A node to check. * @returns {boolean} `true` if the node is a property descriptor. */function isPropertyDescriptor(node) {    // Object.defineProperty(obj, "foo", {set: ...})    if (isArgumentOfMethodCall(node, 2, "Object", "defineProperty") ||        isArgumentOfMethodCall(node, 2, "Reflect", "defineProperty")    ) {        return true;    }    /*     * Object.defineProperties(obj, {foo: {set: ...}})     * Object.create(proto, {foo: {set: ...}})     */    const grandparent = node.parent.parent;    return grandparent.type === "ObjectExpression" && (        isArgumentOfMethodCall(grandparent, 1, "Object", "create") ||        isArgumentOfMethodCall(grandparent, 1, "Object", "defineProperties")    );}//------------------------------------------------------------------------------// Rule Definition//------------------------------------------------------------------------------module.exports = {    meta: {        docs: {            description: "enforce getter and setter pairs in objects",            category: "Best Practices",            recommended: false,            url: "https://eslint.org/docs/rules/accessor-pairs"        },        schema: [{            type: "object",            properties: {                getWithoutSet: {                    type: "boolean"                },                setWithoutGet: {                    type: "boolean"                }            },            additionalProperties: false        }],        messages: {            getter: "Getter is not present.",            setter: "Setter is not present."        }    },    create(context) {        const config = context.options[0] || {};        const checkGetWithoutSet = config.getWithoutSet === true;        const checkSetWithoutGet = config.setWithoutGet !== false;        /**         * Checks a object expression to see if it has setter and getter both present or none.         * @param {ASTNode} node The node to check.         * @returns {void}         * @private         */        function checkLonelySetGet(node) {            let isSetPresent = false;            let isGetPresent = false;            const isDescriptor = isPropertyDescriptor(node);            for (let i = 0, end = node.properties.length; i < end; i++) {                const property = node.properties[i];                let propToCheck = "";                if (property.kind === "init") {                    if (isDescriptor && !property.computed) {                        propToCheck = property.key.name;                    }                } else {                    propToCheck = property.kind;                }                switch (propToCheck) {                    case "set":                        isSetPresent = true;                        break;                    case "get":                        isGetPresent = true;                        break;                    default:                        // Do nothing                }                if (isSetPresent && isGetPresent) {                    break;                }            }            if (checkSetWithoutGet && isSetPresent && !isGetPresent) {                context.report({ node, messageId: "getter" });            } else if (checkGetWithoutSet && isGetPresent && !isSetPresent) {                context.report({ node, messageId: "setter" });            }        }        return {            ObjectExpression(node) {                if (checkSetWithoutGet || checkGetWithoutSet) {                    checkLonelySetGet(node);                }            }        };    }};
 |