implicit-arrow-linebreak.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /**
  2. * @fileoverview enforce the location of arrow function bodies
  3. * @author Sharmila Jesupaul
  4. */
  5. "use strict";
  6. //------------------------------------------------------------------------------
  7. // Rule Definition
  8. //------------------------------------------------------------------------------
  9. module.exports = {
  10. meta: {
  11. docs: {
  12. description: "enforce the location of arrow function bodies",
  13. category: "Stylistic Issues",
  14. recommended: false,
  15. url: "https://eslint.org/docs/rules/implicit-arrow-linebreak"
  16. },
  17. fixable: "whitespace",
  18. schema: [
  19. {
  20. enum: ["beside", "below"]
  21. }
  22. ]
  23. },
  24. create(context) {
  25. const sourceCode = context.getSourceCode();
  26. //----------------------------------------------------------------------
  27. // Helpers
  28. //----------------------------------------------------------------------
  29. /**
  30. * Gets the applicable preference for a particular keyword
  31. * @returns {string} The applicable option for the keyword, e.g. 'beside'
  32. */
  33. function getOption() {
  34. return context.options[0] || "beside";
  35. }
  36. /**
  37. * Validates the location of an arrow function body
  38. * @param {ASTNode} node The arrow function body
  39. * @param {string} keywordName The applicable keyword name for the arrow function body
  40. * @returns {void}
  41. */
  42. function validateExpression(node) {
  43. const option = getOption();
  44. let tokenBefore = sourceCode.getTokenBefore(node.body);
  45. const hasParens = tokenBefore.value === "(";
  46. if (node.type === "BlockStatement") {
  47. return;
  48. }
  49. let fixerTarget = node.body;
  50. if (hasParens) {
  51. // Gets the first token before the function body that is not an open paren
  52. tokenBefore = sourceCode.getTokenBefore(node.body, token => token.value !== "(");
  53. fixerTarget = sourceCode.getTokenAfter(tokenBefore);
  54. }
  55. if (tokenBefore.loc.end.line === fixerTarget.loc.start.line && option === "below") {
  56. context.report({
  57. node: fixerTarget,
  58. message: "Expected a linebreak before this expression.",
  59. fix: fixer => fixer.insertTextBefore(fixerTarget, "\n")
  60. });
  61. } else if (tokenBefore.loc.end.line !== fixerTarget.loc.start.line && option === "beside") {
  62. context.report({
  63. node: fixerTarget,
  64. message: "Expected no linebreak before this expression.",
  65. fix: fixer => fixer.replaceTextRange([tokenBefore.range[1], fixerTarget.range[0]], " ")
  66. });
  67. }
  68. }
  69. //----------------------------------------------------------------------
  70. // Public
  71. //----------------------------------------------------------------------
  72. return {
  73. ArrowFunctionExpression: node => validateExpression(node)
  74. };
  75. }
  76. };