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.

class-methods-use-this.js 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /**
  2. * @fileoverview Rule to enforce that all class methods use 'this'.
  3. * @author Patrick Williams
  4. */
  5. "use strict";
  6. //------------------------------------------------------------------------------
  7. // Rule Definition
  8. //------------------------------------------------------------------------------
  9. module.exports = {
  10. meta: {
  11. type: "suggestion",
  12. docs: {
  13. description: "enforce that class methods utilize `this`",
  14. category: "Best Practices",
  15. recommended: false,
  16. url: "https://eslint.org/docs/rules/class-methods-use-this"
  17. },
  18. schema: [{
  19. type: "object",
  20. properties: {
  21. exceptMethods: {
  22. type: "array",
  23. items: {
  24. type: "string"
  25. }
  26. }
  27. },
  28. additionalProperties: false
  29. }],
  30. messages: {
  31. missingThis: "Expected 'this' to be used by class method '{{name}}'."
  32. }
  33. },
  34. create(context) {
  35. const config = context.options[0] ? Object.assign({}, context.options[0]) : {};
  36. const exceptMethods = new Set(config.exceptMethods || []);
  37. const stack = [];
  38. /**
  39. * Initializes the current context to false and pushes it onto the stack.
  40. * These booleans represent whether 'this' has been used in the context.
  41. * @returns {void}
  42. * @private
  43. */
  44. function enterFunction() {
  45. stack.push(false);
  46. }
  47. /**
  48. * Check if the node is an instance method
  49. * @param {ASTNode} node - node to check
  50. * @returns {boolean} True if its an instance method
  51. * @private
  52. */
  53. function isInstanceMethod(node) {
  54. return !node.static && node.kind !== "constructor" && node.type === "MethodDefinition";
  55. }
  56. /**
  57. * Check if the node is an instance method not excluded by config
  58. * @param {ASTNode} node - node to check
  59. * @returns {boolean} True if it is an instance method, and not excluded by config
  60. * @private
  61. */
  62. function isIncludedInstanceMethod(node) {
  63. return isInstanceMethod(node) && !exceptMethods.has(node.key.name);
  64. }
  65. /**
  66. * Checks if we are leaving a function that is a method, and reports if 'this' has not been used.
  67. * Static methods and the constructor are exempt.
  68. * Then pops the context off the stack.
  69. * @param {ASTNode} node - A function node that was entered.
  70. * @returns {void}
  71. * @private
  72. */
  73. function exitFunction(node) {
  74. const methodUsesThis = stack.pop();
  75. if (isIncludedInstanceMethod(node.parent) && !methodUsesThis) {
  76. context.report({
  77. node,
  78. messageId: "missingThis",
  79. data: {
  80. name: node.parent.key.name
  81. }
  82. });
  83. }
  84. }
  85. /**
  86. * Mark the current context as having used 'this'.
  87. * @returns {void}
  88. * @private
  89. */
  90. function markThisUsed() {
  91. if (stack.length) {
  92. stack[stack.length - 1] = true;
  93. }
  94. }
  95. return {
  96. FunctionDeclaration: enterFunction,
  97. "FunctionDeclaration:exit": exitFunction,
  98. FunctionExpression: enterFunction,
  99. "FunctionExpression:exit": exitFunction,
  100. ThisExpression: markThisUsed,
  101. Super: markThisUsed
  102. };
  103. }
  104. };