123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- "use strict";
- const astUtils = require("./utils/ast-utils");
- module.exports = {
- meta: {
- type: "layout",
- docs: {
- description: "require or disallow spacing between function identifiers and their invocations",
- category: "Stylistic Issues",
- recommended: false,
- url: "https://eslint.org/docs/rules/func-call-spacing"
- },
- fixable: "whitespace",
- schema: {
- anyOf: [
- {
- type: "array",
- items: [
- {
- enum: ["never"]
- }
- ],
- minItems: 0,
- maxItems: 1
- },
- {
- type: "array",
- items: [
- {
- enum: ["always"]
- },
- {
- type: "object",
- properties: {
- allowNewlines: {
- type: "boolean"
- }
- },
- additionalProperties: false
- }
- ],
- minItems: 0,
- maxItems: 2
- }
- ]
- },
- messages: {
- unexpectedWhitespace: "Unexpected whitespace between function name and paren.",
- unexpectedNewline: "Unexpected newline between function name and paren.",
- missing: "Missing space between function name and paren."
- }
- },
- create(context) {
- const never = context.options[0] !== "always";
- const allowNewlines = !never && context.options[1] && context.options[1].allowNewlines;
- const sourceCode = context.getSourceCode();
- const text = sourceCode.getText();
-
- function checkSpacing(node, leftToken, rightToken) {
- const textBetweenTokens = text.slice(leftToken.range[1], rightToken.range[0]).replace(/\/\*.*?\*\//gu, "");
- const hasWhitespace = /\s/u.test(textBetweenTokens);
- const hasNewline = hasWhitespace && astUtils.LINEBREAK_MATCHER.test(textBetweenTokens);
-
- if (never && hasWhitespace) {
- context.report({
- node,
- loc: {
- start: leftToken.loc.end,
- end: {
- line: rightToken.loc.start.line,
- column: rightToken.loc.start.column - 1
- }
- },
- messageId: "unexpectedWhitespace",
- fix(fixer) {
-
- if (sourceCode.commentsExistBetween(leftToken, rightToken)) {
- return null;
- }
-
- if (node.optional) {
- return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], "?.");
- }
-
- if (hasNewline) {
- return null;
- }
- return fixer.removeRange([leftToken.range[1], rightToken.range[0]]);
- }
- });
- } else if (!never && !hasWhitespace) {
- context.report({
- node,
- loc: {
- start: {
- line: leftToken.loc.end.line,
- column: leftToken.loc.end.column - 1
- },
- end: rightToken.loc.start
- },
- messageId: "missing",
- fix(fixer) {
- if (node.optional) {
- return null;
- }
- return fixer.insertTextBefore(rightToken, " ");
- }
- });
- } else if (!never && !allowNewlines && hasNewline) {
- context.report({
- node,
- loc: {
- start: leftToken.loc.end,
- end: rightToken.loc.start
- },
- messageId: "unexpectedNewline",
- fix(fixer) {
-
- if (!node.optional) {
- return null;
- }
-
- if (sourceCode.commentsExistBetween(leftToken, rightToken)) {
- return null;
- }
- const range = [leftToken.range[1], rightToken.range[0]];
- const qdToken = sourceCode.getTokenAfter(leftToken);
- if (qdToken.range[0] === leftToken.range[1]) {
- return fixer.replaceTextRange(range, "?. ");
- }
- if (qdToken.range[1] === rightToken.range[0]) {
- return fixer.replaceTextRange(range, " ?.");
- }
- return fixer.replaceTextRange(range, " ?. ");
- }
- });
- }
- }
- return {
- "CallExpression, NewExpression"(node) {
- const lastToken = sourceCode.getLastToken(node);
- const lastCalleeToken = sourceCode.getLastToken(node.callee);
- const parenToken = sourceCode.getFirstTokenBetween(lastCalleeToken, lastToken, astUtils.isOpeningParenToken);
- const prevToken = parenToken && sourceCode.getTokenBefore(parenToken, astUtils.isNotQuestionDotToken);
-
- if (!(parenToken && parenToken.range[1] < node.range[1])) {
- return;
- }
- checkSpacing(node, prevToken, parenToken);
- },
- ImportExpression(node) {
- const leftToken = sourceCode.getFirstToken(node);
- const rightToken = sourceCode.getTokenAfter(leftToken);
- checkSpacing(node, leftToken, rightToken);
- }
- };
- }
- };
|