UNPKG

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