prefer-boolean-length-check.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /**
  2. * @fileoverview Prefer boolean length check
  3. *
  4. * This Source Code Form is subject to the terms of the Mozilla Public
  5. * License, v. 2.0. If a copy of the MPL was not distributed with this
  6. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  7. */
  8. "use strict";
  9. function funcForBooleanLength(context, node, conditionCheck) {
  10. let newText = "";
  11. const sourceCode = context.getSourceCode();
  12. switch (node.operator) {
  13. case ">":
  14. if (node.right.value == 0) {
  15. if (conditionCheck) {
  16. newText = sourceCode.getText(node.left);
  17. } else {
  18. newText = "!!" + sourceCode.getText(node.left);
  19. }
  20. } else {
  21. newText = "!" + sourceCode.getText(node.right);
  22. }
  23. break;
  24. case "<":
  25. if (node.right.value == 0) {
  26. newText = "!" + sourceCode.getText(node.left);
  27. } else if (conditionCheck) {
  28. newText = sourceCode.getText(node.right);
  29. } else {
  30. newText = "!!" + sourceCode.getText(node.right);
  31. }
  32. break;
  33. case "==":
  34. if (node.right.value == 0) {
  35. newText = "!" + sourceCode.getText(node.left);
  36. } else {
  37. newText = "!" + sourceCode.getText(node.right);
  38. }
  39. break;
  40. case "!=":
  41. if (node.right.value == 0) {
  42. if (conditionCheck) {
  43. newText = sourceCode.getText(node.left);
  44. } else {
  45. newText = "!!" + sourceCode.getText(node.left);
  46. }
  47. } else if (conditionCheck) {
  48. newText = sourceCode.getText(node.right);
  49. } else {
  50. newText = "!!" + sourceCode.getText(node.right);
  51. }
  52. break;
  53. }
  54. return newText;
  55. }
  56. module.exports = {
  57. meta: {
  58. docs: {
  59. url:
  60. "https://firefox-source-docs.mozilla.org/code-quality/lint/linters/eslint-plugin-mozilla/prefer-boolean-length-check.html",
  61. },
  62. fixable: "code",
  63. type: "suggestion",
  64. },
  65. create(context) {
  66. const conditionStatement = [
  67. "IfStatement",
  68. "WhileStatement",
  69. "DoWhileStatement",
  70. "ForStatement",
  71. "ForInStatement",
  72. "ConditionalExpression",
  73. ];
  74. return {
  75. BinaryExpression(node) {
  76. if (
  77. ["==", "!=", ">", "<"].includes(node.operator) &&
  78. ((node.right.type == "Literal" &&
  79. node.right.value == 0 &&
  80. node.left.property?.name == "length") ||
  81. (node.left.type == "Literal" &&
  82. node.left.value == 0 &&
  83. node.right.property?.name == "length"))
  84. ) {
  85. if (
  86. conditionStatement.includes(node.parent.type) ||
  87. (node.parent.type == "LogicalExpression" &&
  88. conditionStatement.includes(node.parent.parent.type))
  89. ) {
  90. context.report({
  91. node,
  92. fix: fixer => {
  93. let generateExpression = funcForBooleanLength(
  94. context,
  95. node,
  96. true
  97. );
  98. return fixer.replaceText(node, generateExpression);
  99. },
  100. message: "Prefer boolean length check",
  101. });
  102. } else {
  103. context.report({
  104. node,
  105. fix: fixer => {
  106. let generateExpression = funcForBooleanLength(
  107. context,
  108. node,
  109. false
  110. );
  111. return fixer.replaceText(node, generateExpression);
  112. },
  113. message: "Prefer boolean length check",
  114. });
  115. }
  116. }
  117. },
  118. };
  119. },
  120. };