text: /**
   * @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: {
          type: "suggestion",
  
          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);
                  }
              }
          };
      }
  };
  