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.

no-extra-boolean-cast.js 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /**
  2. * @fileoverview Rule to flag unnecessary double negation in Boolean contexts
  3. * @author Brandon Mills
  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: "disallow unnecessary boolean casts",
  18. category: "Possible Errors",
  19. recommended: true,
  20. url: "https://eslint.org/docs/rules/no-extra-boolean-cast"
  21. },
  22. schema: [],
  23. fixable: "code",
  24. messages: {
  25. unexpectedCall: "Redundant Boolean call.",
  26. unexpectedNegation: "Redundant double negation."
  27. }
  28. },
  29. create(context) {
  30. const sourceCode = context.getSourceCode();
  31. // Node types which have a test which will coerce values to booleans.
  32. const BOOLEAN_NODE_TYPES = [
  33. "IfStatement",
  34. "DoWhileStatement",
  35. "WhileStatement",
  36. "ConditionalExpression",
  37. "ForStatement"
  38. ];
  39. /**
  40. * Check if a node is in a context where its value would be coerced to a boolean at runtime.
  41. *
  42. * @param {Object} node The node
  43. * @param {Object} parent Its parent
  44. * @returns {boolean} If it is in a boolean context
  45. */
  46. function isInBooleanContext(node, parent) {
  47. return (
  48. (BOOLEAN_NODE_TYPES.indexOf(parent.type) !== -1 &&
  49. node === parent.test) ||
  50. // !<bool>
  51. (parent.type === "UnaryExpression" &&
  52. parent.operator === "!")
  53. );
  54. }
  55. return {
  56. UnaryExpression(node) {
  57. const ancestors = context.getAncestors(),
  58. parent = ancestors.pop(),
  59. grandparent = ancestors.pop();
  60. // Exit early if it's guaranteed not to match
  61. if (node.operator !== "!" ||
  62. parent.type !== "UnaryExpression" ||
  63. parent.operator !== "!") {
  64. return;
  65. }
  66. if (isInBooleanContext(parent, grandparent) ||
  67. // Boolean(<bool>) and new Boolean(<bool>)
  68. ((grandparent.type === "CallExpression" || grandparent.type === "NewExpression") &&
  69. grandparent.callee.type === "Identifier" &&
  70. grandparent.callee.name === "Boolean")
  71. ) {
  72. context.report({
  73. node,
  74. messageId: "unexpectedNegation",
  75. fix: fixer => fixer.replaceText(parent, sourceCode.getText(node.argument))
  76. });
  77. }
  78. },
  79. CallExpression(node) {
  80. const parent = node.parent;
  81. if (node.callee.type !== "Identifier" || node.callee.name !== "Boolean") {
  82. return;
  83. }
  84. if (isInBooleanContext(node, parent)) {
  85. context.report({
  86. node,
  87. messageId: "unexpectedCall",
  88. fix: fixer => {
  89. if (!node.arguments.length) {
  90. return fixer.replaceText(parent, "true");
  91. }
  92. if (node.arguments.length > 1 || node.arguments[0].type === "SpreadElement") {
  93. return null;
  94. }
  95. const argument = node.arguments[0];
  96. if (astUtils.getPrecedence(argument) < astUtils.getPrecedence(node.parent)) {
  97. return fixer.replaceText(node, `(${sourceCode.getText(argument)})`);
  98. }
  99. return fixer.replaceText(node, sourceCode.getText(argument));
  100. }
  101. });
  102. }
  103. }
  104. };
  105. }
  106. };