]> git.proxmox.com Git - pve-eslint.git/blame - eslint/lib/rules/func-call-spacing.js
ship an example config and extend-rules sample files
[pve-eslint.git] / eslint / lib / rules / func-call-spacing.js
CommitLineData
eb39fafa
DC
1/**
2 * @fileoverview Rule to control spacing within function calls
3 * @author Matt DuVall <http://www.mattduvall.com>
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Requirements
10//------------------------------------------------------------------------------
11
12const astUtils = require("./utils/ast-utils");
13
14//------------------------------------------------------------------------------
15// Rule Definition
16//------------------------------------------------------------------------------
17
18module.exports = {
19 meta: {
20 type: "layout",
21
22 docs: {
23 description: "require or disallow spacing between function identifiers and their invocations",
24 category: "Stylistic Issues",
25 recommended: false,
26 url: "https://eslint.org/docs/rules/func-call-spacing"
27 },
28
29 fixable: "whitespace",
30
31 schema: {
32 anyOf: [
33 {
34 type: "array",
35 items: [
36 {
37 enum: ["never"]
38 }
39 ],
40 minItems: 0,
41 maxItems: 1
42 },
43 {
44 type: "array",
45 items: [
46 {
47 enum: ["always"]
48 },
49 {
50 type: "object",
51 properties: {
52 allowNewlines: {
53 type: "boolean"
54 }
55 },
56 additionalProperties: false
57 }
58 ],
59 minItems: 0,
60 maxItems: 2
61 }
62 ]
63 },
64
65 messages: {
56c4a2cb
DC
66 unexpectedWhitespace: "Unexpected whitespace between function name and paren.",
67 unexpectedNewline: "Unexpected newline between function name and paren.",
eb39fafa
DC
68 missing: "Missing space between function name and paren."
69 }
70 },
71
72 create(context) {
73
74 const never = context.options[0] !== "always";
75 const allowNewlines = !never && context.options[1] && context.options[1].allowNewlines;
76 const sourceCode = context.getSourceCode();
77 const text = sourceCode.getText();
78
79 /**
80 * Check if open space is present in a function name
81 * @param {ASTNode} node node to evaluate
82 * @param {Token} leftToken The last token of the callee. This may be the closing parenthesis that encloses the callee.
83 * @param {Token} rightToken Tha first token of the arguments. this is the opening parenthesis that encloses the arguments.
84 * @returns {void}
85 * @private
86 */
87 function checkSpacing(node, leftToken, rightToken) {
88 const textBetweenTokens = text.slice(leftToken.range[1], rightToken.range[0]).replace(/\/\*.*?\*\//gu, "");
89 const hasWhitespace = /\s/u.test(textBetweenTokens);
90 const hasNewline = hasWhitespace && astUtils.LINEBREAK_MATCHER.test(textBetweenTokens);
91
92 /*
93 * never allowNewlines hasWhitespace hasNewline message
94 * F F F F Missing space between function name and paren.
95 * F F F T (Invalid `!hasWhitespace && hasNewline`)
96 * F F T T Unexpected newline between function name and paren.
97 * F F T F (OK)
98 * F T T F (OK)
99 * F T T T (OK)
100 * F T F T (Invalid `!hasWhitespace && hasNewline`)
101 * F T F F Missing space between function name and paren.
102 * T T F F (Invalid `never && allowNewlines`)
103 * T T F T (Invalid `!hasWhitespace && hasNewline`)
104 * T T T T (Invalid `never && allowNewlines`)
105 * T T T F (Invalid `never && allowNewlines`)
106 * T F T F Unexpected space between function name and paren.
107 * T F T T Unexpected space between function name and paren.
108 * T F F T (Invalid `!hasWhitespace && hasNewline`)
109 * T F F F (OK)
110 *
111 * T T Unexpected space between function name and paren.
112 * F F Missing space between function name and paren.
113 * F F T Unexpected newline between function name and paren.
114 */
115
116 if (never && hasWhitespace) {
117 context.report({
118 node,
119 loc: leftToken.loc.start,
56c4a2cb 120 messageId: "unexpectedWhitespace",
eb39fafa
DC
121 fix(fixer) {
122
123 /*
124 * Only autofix if there is no newline
125 * https://github.com/eslint/eslint/issues/7787
126 */
127 if (!hasNewline) {
128 return fixer.removeRange([leftToken.range[1], rightToken.range[0]]);
129 }
130
131 return null;
132 }
133 });
134 } else if (!never && !hasWhitespace) {
135 context.report({
136 node,
137 loc: leftToken.loc.start,
138 messageId: "missing",
139 fix(fixer) {
140 return fixer.insertTextBefore(rightToken, " ");
141 }
142 });
143 } else if (!never && !allowNewlines && hasNewline) {
144 context.report({
145 node,
146 loc: leftToken.loc.start,
56c4a2cb 147 messageId: "unexpectedNewline",
eb39fafa
DC
148 fix(fixer) {
149 return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], " ");
150 }
151 });
152 }
153 }
154
155 return {
156 "CallExpression, NewExpression"(node) {
157 const lastToken = sourceCode.getLastToken(node);
158 const lastCalleeToken = sourceCode.getLastToken(node.callee);
159 const parenToken = sourceCode.getFirstTokenBetween(lastCalleeToken, lastToken, astUtils.isOpeningParenToken);
160 const prevToken = parenToken && sourceCode.getTokenBefore(parenToken);
161
162 // Parens in NewExpression are optional
163 if (!(parenToken && parenToken.range[1] < node.range[1])) {
164 return;
165 }
166
167 checkSpacing(node, prevToken, parenToken);
168 },
169
170 ImportExpression(node) {
171 const leftToken = sourceCode.getFirstToken(node);
172 const rightToken = sourceCode.getTokenAfter(leftToken);
173
174 checkSpacing(node, leftToken, rightToken);
175 }
176 };
177
178 }
179};