]>
Commit | Line | Data |
---|---|---|
eb39fafa DC |
1 | /** |
2 | * @fileoverview Rule to enforce line breaks between arguments of a function call | |
3 | * @author Alexey Gonchar <https://github.com/finico> | |
4 | */ | |
5 | ||
6 | "use strict"; | |
7 | ||
8 | //------------------------------------------------------------------------------ | |
9 | // Rule Definition | |
10 | //------------------------------------------------------------------------------ | |
11 | ||
12 | module.exports = { | |
13 | meta: { | |
14 | type: "layout", | |
15 | ||
16 | docs: { | |
17 | description: "enforce line breaks between arguments of a function call", | |
eb39fafa DC |
18 | recommended: false, |
19 | url: "https://eslint.org/docs/rules/function-call-argument-newline" | |
20 | }, | |
21 | ||
22 | fixable: "whitespace", | |
23 | ||
24 | schema: [ | |
25 | { | |
26 | enum: ["always", "never", "consistent"] | |
27 | } | |
28 | ], | |
29 | ||
30 | messages: { | |
31 | unexpectedLineBreak: "There should be no line break here.", | |
32 | missingLineBreak: "There should be a line break after this argument." | |
33 | } | |
34 | }, | |
35 | ||
36 | create(context) { | |
37 | const sourceCode = context.getSourceCode(); | |
38 | ||
39 | const checkers = { | |
40 | unexpected: { | |
41 | messageId: "unexpectedLineBreak", | |
42 | check: (prevToken, currentToken) => prevToken.loc.end.line !== currentToken.loc.start.line, | |
43 | createFix: (token, tokenBefore) => fixer => | |
44 | fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], " ") | |
45 | }, | |
46 | missing: { | |
47 | messageId: "missingLineBreak", | |
48 | check: (prevToken, currentToken) => prevToken.loc.end.line === currentToken.loc.start.line, | |
49 | createFix: (token, tokenBefore) => fixer => | |
50 | fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], "\n") | |
51 | } | |
52 | }; | |
53 | ||
54 | /** | |
55 | * Check all arguments for line breaks in the CallExpression | |
56 | * @param {CallExpression} node node to evaluate | |
57 | * @param {{ messageId: string, check: Function }} checker selected checker | |
58 | * @returns {void} | |
59 | * @private | |
60 | */ | |
61 | function checkArguments(node, checker) { | |
62 | for (let i = 1; i < node.arguments.length; i++) { | |
63 | const prevArgToken = sourceCode.getLastToken(node.arguments[i - 1]); | |
64 | const currentArgToken = sourceCode.getFirstToken(node.arguments[i]); | |
65 | ||
66 | if (checker.check(prevArgToken, currentArgToken)) { | |
67 | const tokenBefore = sourceCode.getTokenBefore( | |
68 | currentArgToken, | |
69 | { includeComments: true } | |
70 | ); | |
71 | ||
72 | const hasLineCommentBefore = tokenBefore.type === "Line"; | |
73 | ||
74 | context.report({ | |
75 | node, | |
76 | loc: { | |
77 | start: tokenBefore.loc.end, | |
78 | end: currentArgToken.loc.start | |
79 | }, | |
80 | messageId: checker.messageId, | |
81 | fix: hasLineCommentBefore ? null : checker.createFix(currentArgToken, tokenBefore) | |
82 | }); | |
83 | } | |
84 | } | |
85 | } | |
86 | ||
87 | /** | |
88 | * Check if open space is present in a function name | |
89 | * @param {CallExpression} node node to evaluate | |
90 | * @returns {void} | |
91 | * @private | |
92 | */ | |
93 | function check(node) { | |
94 | if (node.arguments.length < 2) { | |
95 | return; | |
96 | } | |
97 | ||
98 | const option = context.options[0] || "always"; | |
99 | ||
100 | if (option === "never") { | |
101 | checkArguments(node, checkers.unexpected); | |
102 | } else if (option === "always") { | |
103 | checkArguments(node, checkers.missing); | |
104 | } else if (option === "consistent") { | |
105 | const firstArgToken = sourceCode.getLastToken(node.arguments[0]); | |
106 | const secondArgToken = sourceCode.getFirstToken(node.arguments[1]); | |
107 | ||
108 | if (firstArgToken.loc.end.line === secondArgToken.loc.start.line) { | |
109 | checkArguments(node, checkers.unexpected); | |
110 | } else { | |
111 | checkArguments(node, checkers.missing); | |
112 | } | |
113 | } | |
114 | } | |
115 | ||
116 | return { | |
117 | CallExpression: check, | |
118 | NewExpression: check | |
119 | }; | |
120 | } | |
121 | }; |