no-self-compare.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. /**
  2. * @fileoverview Rule to flag comparison where left part is the same as the right
  3. * part.
  4. * @author Ilya Volodin
  5. */
  6. "use strict";
  7. //------------------------------------------------------------------------------
  8. // Rule Definition
  9. //------------------------------------------------------------------------------
  10. /** @type {import('../shared/types').Rule} */
  11. module.exports = {
  12. meta: {
  13. type: "problem",
  14. docs: {
  15. description: "Disallow comparisons where both sides are exactly the same",
  16. recommended: false,
  17. url: "https://eslint.org/docs/rules/no-self-compare"
  18. },
  19. schema: [],
  20. messages: {
  21. comparingToSelf: "Comparing to itself is potentially pointless."
  22. }
  23. },
  24. create(context) {
  25. const sourceCode = context.getSourceCode();
  26. /**
  27. * Determines whether two nodes are composed of the same tokens.
  28. * @param {ASTNode} nodeA The first node
  29. * @param {ASTNode} nodeB The second node
  30. * @returns {boolean} true if the nodes have identical token representations
  31. */
  32. function hasSameTokens(nodeA, nodeB) {
  33. const tokensA = sourceCode.getTokens(nodeA);
  34. const tokensB = sourceCode.getTokens(nodeB);
  35. return tokensA.length === tokensB.length &&
  36. tokensA.every((token, index) => token.type === tokensB[index].type && token.value === tokensB[index].value);
  37. }
  38. return {
  39. BinaryExpression(node) {
  40. const operators = new Set(["===", "==", "!==", "!=", ">", "<", ">=", "<="]);
  41. if (operators.has(node.operator) && hasSameTokens(node.left, node.right)) {
  42. context.report({ node, messageId: "comparingToSelf" });
  43. }
  44. }
  45. };
  46. }
  47. };