no-inverted-boolean-check.js 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. "use strict";
  2. /*
  3. * eslint-plugin-sonarjs
  4. * Copyright (C) 2018-2021 SonarSource SA
  5. * mailto:info AT sonarsource DOT com
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 3 of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public License
  18. * along with this program; if not, write to the Free Software Foundation,
  19. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  20. */
  21. // https://sonarsource.github.io/rspec/#/rspec/S1940
  22. const nodes_1 = require("../utils/nodes");
  23. const docs_url_1 = require("../utils/docs-url");
  24. const invertedOperators = {
  25. '==': '!=',
  26. '!=': '==',
  27. '===': '!==',
  28. '!==': '===',
  29. '>': '<=',
  30. '<': '>=',
  31. '>=': '<',
  32. '<=': '>',
  33. };
  34. const rule = {
  35. meta: {
  36. messages: {
  37. useOppositeOperator: 'Use the opposite operator ({{invertedOperator}}) instead.',
  38. suggestOperationInversion: 'Invert inner operation (apply if NaN is not expected)',
  39. },
  40. schema: [],
  41. type: 'suggestion',
  42. docs: {
  43. description: 'Boolean checks should not be inverted',
  44. recommended: false,
  45. url: (0, docs_url_1.default)(__filename),
  46. },
  47. hasSuggestions: true,
  48. fixable: 'code',
  49. },
  50. create(context) {
  51. return {
  52. UnaryExpression: (node) => visitUnaryExpression(node, context),
  53. };
  54. },
  55. };
  56. function visitUnaryExpression(unaryExpression, context) {
  57. var _a;
  58. if (unaryExpression.operator === '!' && (0, nodes_1.isBinaryExpression)(unaryExpression.argument)) {
  59. const condition = unaryExpression.argument;
  60. const invertedOperator = invertedOperators[condition.operator];
  61. if (invertedOperator) {
  62. const left = context.getSourceCode().getText(condition.left);
  63. const right = context.getSourceCode().getText(condition.right);
  64. const [start, end] = ((_a = unaryExpression.parent) === null || _a === void 0 ? void 0 : _a.type) === 'UnaryExpression' ? ['(', ')'] : ['', ''];
  65. context.report({
  66. messageId: 'useOppositeOperator',
  67. suggest: [
  68. {
  69. messageId: 'suggestOperationInversion',
  70. fix: fixer => fixer.replaceText(unaryExpression, `${start}${left} ${invertedOperator} ${right}${end}`),
  71. },
  72. ],
  73. data: { invertedOperator },
  74. node: unaryExpression,
  75. });
  76. }
  77. }
  78. }
  79. module.exports = rule;
  80. //# sourceMappingURL=no-inverted-boolean-check.js.map