Ohm-Management - Projektarbeit B-ME
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

accessor-pairs.js 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /**
  2. * @fileoverview Rule to flag wrapping non-iife in parens
  3. * @author Gyandeep Singh
  4. */
  5. "use strict";
  6. //------------------------------------------------------------------------------
  7. // Helpers
  8. //------------------------------------------------------------------------------
  9. /**
  10. * Checks whether or not a given node is an `Identifier` node which was named a given name.
  11. * @param {ASTNode} node - A node to check.
  12. * @param {string} name - An expected name of the node.
  13. * @returns {boolean} `true` if the node is an `Identifier` node which was named as expected.
  14. */
  15. function isIdentifier(node, name) {
  16. return node.type === "Identifier" && node.name === name;
  17. }
  18. /**
  19. * Checks whether or not a given node is an argument of a specified method call.
  20. * @param {ASTNode} node - A node to check.
  21. * @param {number} index - An expected index of the node in arguments.
  22. * @param {string} object - An expected name of the object of the method.
  23. * @param {string} property - An expected name of the method.
  24. * @returns {boolean} `true` if the node is an argument of the specified method call.
  25. */
  26. function isArgumentOfMethodCall(node, index, object, property) {
  27. const parent = node.parent;
  28. return (
  29. parent.type === "CallExpression" &&
  30. parent.callee.type === "MemberExpression" &&
  31. parent.callee.computed === false &&
  32. isIdentifier(parent.callee.object, object) &&
  33. isIdentifier(parent.callee.property, property) &&
  34. parent.arguments[index] === node
  35. );
  36. }
  37. /**
  38. * Checks whether or not a given node is a property descriptor.
  39. * @param {ASTNode} node - A node to check.
  40. * @returns {boolean} `true` if the node is a property descriptor.
  41. */
  42. function isPropertyDescriptor(node) {
  43. // Object.defineProperty(obj, "foo", {set: ...})
  44. if (isArgumentOfMethodCall(node, 2, "Object", "defineProperty") ||
  45. isArgumentOfMethodCall(node, 2, "Reflect", "defineProperty")
  46. ) {
  47. return true;
  48. }
  49. /*
  50. * Object.defineProperties(obj, {foo: {set: ...}})
  51. * Object.create(proto, {foo: {set: ...}})
  52. */
  53. const grandparent = node.parent.parent;
  54. return grandparent.type === "ObjectExpression" && (
  55. isArgumentOfMethodCall(grandparent, 1, "Object", "create") ||
  56. isArgumentOfMethodCall(grandparent, 1, "Object", "defineProperties")
  57. );
  58. }
  59. //------------------------------------------------------------------------------
  60. // Rule Definition
  61. //------------------------------------------------------------------------------
  62. module.exports = {
  63. meta: {
  64. type: "suggestion",
  65. docs: {
  66. description: "enforce getter and setter pairs in objects",
  67. category: "Best Practices",
  68. recommended: false,
  69. url: "https://eslint.org/docs/rules/accessor-pairs"
  70. },
  71. schema: [{
  72. type: "object",
  73. properties: {
  74. getWithoutSet: {
  75. type: "boolean"
  76. },
  77. setWithoutGet: {
  78. type: "boolean"
  79. }
  80. },
  81. additionalProperties: false
  82. }],
  83. messages: {
  84. getter: "Getter is not present.",
  85. setter: "Setter is not present."
  86. }
  87. },
  88. create(context) {
  89. const config = context.options[0] || {};
  90. const checkGetWithoutSet = config.getWithoutSet === true;
  91. const checkSetWithoutGet = config.setWithoutGet !== false;
  92. /**
  93. * Checks a object expression to see if it has setter and getter both present or none.
  94. * @param {ASTNode} node The node to check.
  95. * @returns {void}
  96. * @private
  97. */
  98. function checkLonelySetGet(node) {
  99. let isSetPresent = false;
  100. let isGetPresent = false;
  101. const isDescriptor = isPropertyDescriptor(node);
  102. for (let i = 0, end = node.properties.length; i < end; i++) {
  103. const property = node.properties[i];
  104. let propToCheck = "";
  105. if (property.kind === "init") {
  106. if (isDescriptor && !property.computed) {
  107. propToCheck = property.key.name;
  108. }
  109. } else {
  110. propToCheck = property.kind;
  111. }
  112. switch (propToCheck) {
  113. case "set":
  114. isSetPresent = true;
  115. break;
  116. case "get":
  117. isGetPresent = true;
  118. break;
  119. default:
  120. // Do nothing
  121. }
  122. if (isSetPresent && isGetPresent) {
  123. break;
  124. }
  125. }
  126. if (checkSetWithoutGet && isSetPresent && !isGetPresent) {
  127. context.report({ node, messageId: "getter" });
  128. } else if (checkGetWithoutSet && isGetPresent && !isSetPresent) {
  129. context.report({ node, messageId: "setter" });
  130. }
  131. }
  132. return {
  133. ObjectExpression(node) {
  134. if (checkSetWithoutGet || checkGetWithoutSet) {
  135. checkLonelySetGet(node);
  136. }
  137. }
  138. };
  139. }
  140. };