no-negated-condition.js 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /**
  2. * @fileoverview Rule to disallow a negated condition
  3. * @author Alberto Rodríguez
  4. */
  5. "use strict";
  6. //------------------------------------------------------------------------------
  7. // Rule Definition
  8. //------------------------------------------------------------------------------
  9. /** @type {import('../shared/types').Rule} */
  10. module.exports = {
  11. meta: {
  12. type: "suggestion",
  13. docs: {
  14. description: "Disallow negated conditions",
  15. recommended: false,
  16. url: "https://eslint.org/docs/rules/no-negated-condition"
  17. },
  18. schema: [],
  19. messages: {
  20. unexpectedNegated: "Unexpected negated condition."
  21. }
  22. },
  23. create(context) {
  24. /**
  25. * Determines if a given node is an if-else without a condition on the else
  26. * @param {ASTNode} node The node to check.
  27. * @returns {boolean} True if the node has an else without an if.
  28. * @private
  29. */
  30. function hasElseWithoutCondition(node) {
  31. return node.alternate && node.alternate.type !== "IfStatement";
  32. }
  33. /**
  34. * Determines if a given node is a negated unary expression
  35. * @param {Object} test The test object to check.
  36. * @returns {boolean} True if the node is a negated unary expression.
  37. * @private
  38. */
  39. function isNegatedUnaryExpression(test) {
  40. return test.type === "UnaryExpression" && test.operator === "!";
  41. }
  42. /**
  43. * Determines if a given node is a negated binary expression
  44. * @param {Test} test The test to check.
  45. * @returns {boolean} True if the node is a negated binary expression.
  46. * @private
  47. */
  48. function isNegatedBinaryExpression(test) {
  49. return test.type === "BinaryExpression" &&
  50. (test.operator === "!=" || test.operator === "!==");
  51. }
  52. /**
  53. * Determines if a given node has a negated if expression
  54. * @param {ASTNode} node The node to check.
  55. * @returns {boolean} True if the node has a negated if expression.
  56. * @private
  57. */
  58. function isNegatedIf(node) {
  59. return isNegatedUnaryExpression(node.test) || isNegatedBinaryExpression(node.test);
  60. }
  61. return {
  62. IfStatement(node) {
  63. if (!hasElseWithoutCondition(node)) {
  64. return;
  65. }
  66. if (isNegatedIf(node)) {
  67. context.report({
  68. node,
  69. messageId: "unexpectedNegated"
  70. });
  71. }
  72. },
  73. ConditionalExpression(node) {
  74. if (isNegatedIf(node)) {
  75. context.report({
  76. node,
  77. messageId: "unexpectedNegated"
  78. });
  79. }
  80. }
  81. };
  82. }
  83. };