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.

eqeqeq.js 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /**
  2. * @fileoverview Rule to flag statements that use != and == instead of !== and ===
  3. * @author Nicholas C. Zakas
  4. */
  5. "use strict";
  6. //------------------------------------------------------------------------------
  7. // Requirements
  8. //------------------------------------------------------------------------------
  9. const astUtils = require("../util/ast-utils");
  10. //------------------------------------------------------------------------------
  11. // Rule Definition
  12. //------------------------------------------------------------------------------
  13. module.exports = {
  14. meta: {
  15. type: "suggestion",
  16. docs: {
  17. description: "require the use of `===` and `!==`",
  18. category: "Best Practices",
  19. recommended: false,
  20. url: "https://eslint.org/docs/rules/eqeqeq"
  21. },
  22. schema: {
  23. anyOf: [
  24. {
  25. type: "array",
  26. items: [
  27. {
  28. enum: ["always"]
  29. },
  30. {
  31. type: "object",
  32. properties: {
  33. null: {
  34. enum: ["always", "never", "ignore"]
  35. }
  36. },
  37. additionalProperties: false
  38. }
  39. ],
  40. additionalItems: false
  41. },
  42. {
  43. type: "array",
  44. items: [
  45. {
  46. enum: ["smart", "allow-null"]
  47. }
  48. ],
  49. additionalItems: false
  50. }
  51. ]
  52. },
  53. fixable: "code",
  54. messages: {
  55. unexpected: "Expected '{{expectedOperator}}' and instead saw '{{actualOperator}}'."
  56. }
  57. },
  58. create(context) {
  59. const config = context.options[0] || "always";
  60. const options = context.options[1] || {};
  61. const sourceCode = context.getSourceCode();
  62. const nullOption = (config === "always")
  63. ? options.null || "always"
  64. : "ignore";
  65. const enforceRuleForNull = (nullOption === "always");
  66. const enforceInverseRuleForNull = (nullOption === "never");
  67. /**
  68. * Checks if an expression is a typeof expression
  69. * @param {ASTNode} node The node to check
  70. * @returns {boolean} if the node is a typeof expression
  71. */
  72. function isTypeOf(node) {
  73. return node.type === "UnaryExpression" && node.operator === "typeof";
  74. }
  75. /**
  76. * Checks if either operand of a binary expression is a typeof operation
  77. * @param {ASTNode} node The node to check
  78. * @returns {boolean} if one of the operands is typeof
  79. * @private
  80. */
  81. function isTypeOfBinary(node) {
  82. return isTypeOf(node.left) || isTypeOf(node.right);
  83. }
  84. /**
  85. * Checks if operands are literals of the same type (via typeof)
  86. * @param {ASTNode} node The node to check
  87. * @returns {boolean} if operands are of same type
  88. * @private
  89. */
  90. function areLiteralsAndSameType(node) {
  91. return node.left.type === "Literal" && node.right.type === "Literal" &&
  92. typeof node.left.value === typeof node.right.value;
  93. }
  94. /**
  95. * Checks if one of the operands is a literal null
  96. * @param {ASTNode} node The node to check
  97. * @returns {boolean} if operands are null
  98. * @private
  99. */
  100. function isNullCheck(node) {
  101. return astUtils.isNullLiteral(node.right) || astUtils.isNullLiteral(node.left);
  102. }
  103. /**
  104. * Gets the location (line and column) of the binary expression's operator
  105. * @param {ASTNode} node The binary expression node to check
  106. * @param {string} operator The operator to find
  107. * @returns {Object} { line, column } location of operator
  108. * @private
  109. */
  110. function getOperatorLocation(node) {
  111. const opToken = sourceCode.getTokenAfter(node.left);
  112. return { line: opToken.loc.start.line, column: opToken.loc.start.column };
  113. }
  114. /**
  115. * Reports a message for this rule.
  116. * @param {ASTNode} node The binary expression node that was checked
  117. * @param {string} expectedOperator The operator that was expected (either '==', '!=', '===', or '!==')
  118. * @returns {void}
  119. * @private
  120. */
  121. function report(node, expectedOperator) {
  122. context.report({
  123. node,
  124. loc: getOperatorLocation(node),
  125. messageId: "unexpected",
  126. data: { expectedOperator, actualOperator: node.operator },
  127. fix(fixer) {
  128. // If the comparison is a `typeof` comparison or both sides are literals with the same type, then it's safe to fix.
  129. if (isTypeOfBinary(node) || areLiteralsAndSameType(node)) {
  130. const operatorToken = sourceCode.getFirstTokenBetween(
  131. node.left,
  132. node.right,
  133. token => token.value === node.operator
  134. );
  135. return fixer.replaceText(operatorToken, expectedOperator);
  136. }
  137. return null;
  138. }
  139. });
  140. }
  141. return {
  142. BinaryExpression(node) {
  143. const isNull = isNullCheck(node);
  144. if (node.operator !== "==" && node.operator !== "!=") {
  145. if (enforceInverseRuleForNull && isNull) {
  146. report(node, node.operator.slice(0, -1));
  147. }
  148. return;
  149. }
  150. if (config === "smart" && (isTypeOfBinary(node) ||
  151. areLiteralsAndSameType(node) || isNull)) {
  152. return;
  153. }
  154. if (!enforceRuleForNull && isNull) {
  155. return;
  156. }
  157. report(node, `${node.operator}=`);
  158. }
  159. };
  160. }
  161. };