implicit-arrow-linebreak.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /**
  2. * @fileoverview enforce the location of arrow function bodies
  3. * @author Sharmila Jesupaul
  4. */
  5. "use strict";
  6. const { isCommentToken, isNotOpeningParenToken } = require("./utils/ast-utils");
  7. //------------------------------------------------------------------------------
  8. // Rule Definition
  9. //------------------------------------------------------------------------------
  10. /** @type {import('../shared/types').Rule} */
  11. module.exports = {
  12. meta: {
  13. type: "layout",
  14. docs: {
  15. description: "Enforce the location of arrow function bodies",
  16. recommended: false,
  17. url: "https://eslint.org/docs/rules/implicit-arrow-linebreak"
  18. },
  19. fixable: "whitespace",
  20. schema: [
  21. {
  22. enum: ["beside", "below"]
  23. }
  24. ],
  25. messages: {
  26. expected: "Expected a linebreak before this expression.",
  27. unexpected: "Expected no linebreak before this expression."
  28. }
  29. },
  30. create(context) {
  31. const sourceCode = context.getSourceCode();
  32. const option = context.options[0] || "beside";
  33. /**
  34. * Validates the location of an arrow function body
  35. * @param {ASTNode} node The arrow function body
  36. * @returns {void}
  37. */
  38. function validateExpression(node) {
  39. if (node.body.type === "BlockStatement") {
  40. return;
  41. }
  42. const arrowToken = sourceCode.getTokenBefore(node.body, isNotOpeningParenToken);
  43. const firstTokenOfBody = sourceCode.getTokenAfter(arrowToken);
  44. if (arrowToken.loc.end.line === firstTokenOfBody.loc.start.line && option === "below") {
  45. context.report({
  46. node: firstTokenOfBody,
  47. messageId: "expected",
  48. fix: fixer => fixer.insertTextBefore(firstTokenOfBody, "\n")
  49. });
  50. } else if (arrowToken.loc.end.line !== firstTokenOfBody.loc.start.line && option === "beside") {
  51. context.report({
  52. node: firstTokenOfBody,
  53. messageId: "unexpected",
  54. fix(fixer) {
  55. if (sourceCode.getFirstTokenBetween(arrowToken, firstTokenOfBody, { includeComments: true, filter: isCommentToken })) {
  56. return null;
  57. }
  58. return fixer.replaceTextRange([arrowToken.range[1], firstTokenOfBody.range[0]], " ");
  59. }
  60. });
  61. }
  62. }
  63. //----------------------------------------------------------------------
  64. // Public
  65. //----------------------------------------------------------------------
  66. return {
  67. ArrowFunctionExpression: node => validateExpression(node)
  68. };
  69. }
  70. };