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