.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / function-call-argument-newline.js
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",
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          * Check all arguments for line breaks in the CallExpression
57          * @param {CallExpression} node node to evaluate
58          * @param {{ messageId: string, check: Function }} checker selected checker
59          * @returns {void}
60          * @private
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          * Check if open space is present in a function name
90          * @param {CallExpression} node node to evaluate
91          * @returns {void}
92          * @private
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 };