no-confusing-arrow.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /**
  2. * @fileoverview A rule to warn against using arrow functions when they could be
  3. * confused with comparisons
  4. * @author Jxck <https://github.com/Jxck>
  5. * @deprecated in ESLint v8.53.0
  6. */
  7. "use strict";
  8. const astUtils = require("./utils/ast-utils.js");
  9. //------------------------------------------------------------------------------
  10. // Helpers
  11. //------------------------------------------------------------------------------
  12. /**
  13. * Checks whether or not a node is a conditional expression.
  14. * @param {ASTNode} node node to test
  15. * @returns {boolean} `true` if the node is a conditional expression.
  16. */
  17. function isConditional(node) {
  18. return node && node.type === "ConditionalExpression";
  19. }
  20. //------------------------------------------------------------------------------
  21. // Rule Definition
  22. //------------------------------------------------------------------------------
  23. /** @type {import('../types').Rule.RuleModule} */
  24. module.exports = {
  25. meta: {
  26. deprecated: {
  27. message: "Formatting rules are being moved out of ESLint core.",
  28. url: "https://eslint.org/blog/2023/10/deprecating-formatting-rules/",
  29. deprecatedSince: "8.53.0",
  30. availableUntil: "11.0.0",
  31. replacedBy: [
  32. {
  33. message:
  34. "ESLint Stylistic now maintains deprecated stylistic core rules.",
  35. url: "https://eslint.style/guide/migration",
  36. plugin: {
  37. name: "@stylistic/eslint-plugin",
  38. url: "https://eslint.style",
  39. },
  40. rule: {
  41. name: "no-confusing-arrow",
  42. url: "https://eslint.style/rules/no-confusing-arrow",
  43. },
  44. },
  45. ],
  46. },
  47. type: "suggestion",
  48. docs: {
  49. description:
  50. "Disallow arrow functions where they could be confused with comparisons",
  51. recommended: false,
  52. url: "https://eslint.org/docs/latest/rules/no-confusing-arrow",
  53. },
  54. fixable: "code",
  55. schema: [
  56. {
  57. type: "object",
  58. properties: {
  59. allowParens: { type: "boolean", default: true },
  60. onlyOneSimpleParam: { type: "boolean", default: false },
  61. },
  62. additionalProperties: false,
  63. },
  64. ],
  65. messages: {
  66. confusing:
  67. "Arrow function used ambiguously with a conditional expression.",
  68. },
  69. },
  70. create(context) {
  71. const config = context.options[0] || {};
  72. const allowParens = config.allowParens || config.allowParens === void 0;
  73. const onlyOneSimpleParam = config.onlyOneSimpleParam;
  74. const sourceCode = context.sourceCode;
  75. /**
  76. * Reports if an arrow function contains an ambiguous conditional.
  77. * @param {ASTNode} node A node to check and report.
  78. * @returns {void}
  79. */
  80. function checkArrowFunc(node) {
  81. const body = node.body;
  82. if (
  83. isConditional(body) &&
  84. !(allowParens && astUtils.isParenthesised(sourceCode, body)) &&
  85. !(
  86. onlyOneSimpleParam &&
  87. !(
  88. node.params.length === 1 &&
  89. node.params[0].type === "Identifier"
  90. )
  91. )
  92. ) {
  93. context.report({
  94. node,
  95. messageId: "confusing",
  96. fix(fixer) {
  97. // if `allowParens` is not set to true don't bother wrapping in parens
  98. return (
  99. allowParens &&
  100. fixer.replaceText(
  101. node.body,
  102. `(${sourceCode.getText(node.body)})`,
  103. )
  104. );
  105. },
  106. });
  107. }
  108. }
  109. return {
  110. ArrowFunctionExpression: checkArrowFunc,
  111. };
  112. },
  113. };