Forbid AstPath.call without name (#10541)

This commit is contained in:
fisker Cheung authored and GitHub committed 2021-03-15 17:20:27 +08:00
1 parent 521b63bb27
commit 863eb079dc
14 files changed
+103 -19

No files matched your search

+1
View File
@@ -121,6 +121,7 @@ overrides:
prettier-internal-rules/flat-ast-path-call: error
prettier-internal-rules/no-doc-builder-concat: error
prettier-internal-rules/no-empty-flat-contents-for-if-break: error
prettier-internal-rules/no-unnecessary-ast-path-call: error
prettier-internal-rules/prefer-ast-path-each: error
prettier-internal-rules/prefer-indent-if-break: error
prettier-internal-rules/prefer-is-non-empty-array: error
@@ -10,6 +10,7 @@ module.exports = {
"no-empty-flat-contents-for-if-break": require("./no-empty-flat-contents-for-if-break"),
"no-identifier-n": require("./no-identifier-n"),
"no-node-comments": require("./no-node-comments"),
"no-unnecessary-ast-path-call": require("./no-unnecessary-ast-path-call"),
"prefer-ast-path-each": require("./prefer-ast-path-each"),
"prefer-indent-if-break": require("./prefer-indent-if-break"),
"prefer-is-non-empty-array": require("./prefer-is-non-empty-array"),
@@ -0,0 +1,57 @@
"use strict";
const selector = [
"CallExpression",
"[optional=false]",
'[callee.type="MemberExpression"]',
"[callee.computed=false]",
"[callee.optional=false]",
'[callee.property.type="Identifier"]',
'[callee.property.name="call"]',
"[arguments.length=1]",
'[arguments.0.type!="SpreadElement"]',
].join("");
const messageId = "no-unnecessary-ast-path-call";
module.exports = {
meta: {
type: "suggestion",
docs: {
url:
"https://github.com/prettier/prettier/blob/main/scripts/eslint-plugin-prettier-internal-rules/no-unnecessary-ast-path-call.js",
},
messages: {
[messageId]: "Do not use `AstPath.call()` with one argument.",
},
fixable: "code",
},
create(context) {
const sourceCode = context.getSourceCode();
return {
[selector](node) {
const problem = {
node,
messageId,
};
const [callback] = node.arguments;
// Don't fix to IIFE
if (
callback.type !== "ArrowFunctionExpression" &&
callback.type !== "FunctionExpression"
) {
problem.fix = function (fixer) {
const callbackText = sourceCode.getText(callback);
const astPathText = sourceCode.getText(node.callee.object);
return fixer.replaceText(node, `${callbackText}(${astPathText})`);
};
}
context.report(problem);
},
};
},
};
@@ -367,3 +367,28 @@ test("no-empty-flat-contents-for-if-break", {
},
],
});
test("no-unnecessary-ast-path-call", {
valid: [
"call(foo)",
'foo["call"](bar)',
"foo.call?.(bar)",
"foo?.call(bar)",
"foo.call(bar, name)",
"foo.notCall(bar)",
"foo.call(...bar)",
"foo.call()",
],
invalid: [
{
code: "foo.call(bar)",
output: "bar(foo)",
errors: 1,
},
{
code: "foo.call(() => bar)",
output: "foo.call(() => bar)",
errors: 1,
},
],
});
+2 -2
View File
@@ -311,7 +311,7 @@ function genericPrint(path, options, print) {
if (node.type === "media-query" && node.value === "") {
return;
}
parts.push(childPath.call(print));
parts.push(print(childPath));
}, "nodes");
return group(indent(join(line, parts)));
@@ -988,7 +988,7 @@ function printNodeSequence(path, options, print) {
options.originalText.slice(locStart(childNode), locEnd(childNode))
);
} else {
parts.push(pathChild.call(print));
parts.push(print(pathChild));
}
if (i !== nodes.length - 1) {
+1 -1
View File
@@ -21,7 +21,7 @@ function genericPrint(path, options, print) {
case "Document": {
const parts = [];
path.each((pathChild, index, definitions) => {
parts.push(pathChild.call(print));
parts.push(print(pathChild));
if (index !== definitions.length - 1) {
parts.push(hardline);
if (
+1 -1
View File
@@ -285,7 +285,7 @@ function printBinaryishExpressions(
}
} else {
// Our stopping case. Simply print the node normally.
parts.push(group(path.call(print)));
parts.push(group(print(path)));
}
return parts;
+2 -2
View File
@@ -150,7 +150,7 @@ function printCallArguments(path, options, print) {
if (shouldGroupFirst && i === 0) {
printedExpanded = [
[
argPath.call((p) => print(p, { expandFirstArg: true })),
print(argPath, { expandFirstArg: true }),
printedArguments.length > 1 ? "," : "",
hasEmptyLineFollowingFirstArg ? hardline : line,
hasEmptyLineFollowingFirstArg ? hardline : "",
@@ -161,7 +161,7 @@ function printCallArguments(path, options, print) {
if (shouldGroupLast && i === args.length - 1) {
printedExpanded = [
...printedArguments.slice(0, -1),
argPath.call((p) => print(p, { expandLastArg: true })),
print(argPath, { expandLastArg: true }),
];
}
});
+1 -1
View File
@@ -65,7 +65,7 @@ function printFunctionParameters(
if (isLastParameter && functionNode.rest) {
printed.push("...");
}
printed.push(parameterPath.call(print));
printed.push(print(parameterPath));
if (isLastParameter) {
return;
}
+2 -2
View File
@@ -250,7 +250,7 @@ function printArrowFunctionExpression(path, options, print, args) {
let body;
let chainShouldBreak = false;
path.call(function rec(path) {
(function rec(path) {
const doc = printArrowFunctionSignature(path, options, print, args);
signatures.push(
signatures.length === 0 ? doc : printComments(path, doc, options)
@@ -272,7 +272,7 @@ function printArrowFunctionExpression(path, options, print, args) {
node = node.body;
path.call(rec, "body");
}
});
})(path);
if (signatures.length > 1) {
return printArrowChain(
+1 -1
View File
@@ -135,7 +135,7 @@ function printMemberChain(path, options, print) {
} else {
printedNodes.unshift({
node,
printed: path.call(print),
printed: print(path),
});
}
}
+1 -1
View File
@@ -169,7 +169,7 @@ function printUnionType(path, options, print) {
// // comment
// | child2
const printed = path.map((typePath) => {
let printedType = typePath.call(print);
let printedType = print(typePath);
if (!shouldHug) {
printedType = align(2, printedType);
}
+1 -1
View File
@@ -702,7 +702,7 @@ function printPathNoParens(path, options, print, args) {
path.map((casePath, index, cases) => {
const caseNode = casePath.getValue();
return [
casePath.call(print),
print(casePath),
index !== cases.length - 1 &&
isNextLineEmpty(caseNode, options)
? hardline
+7 -7
View File
@@ -411,8 +411,8 @@ function genericPrint(path, options, print) {
printChildren(path, options, print, {
processor: (childPath, index) =>
index === 0
? group([softline, childPath.call(print)])
: childPath.call(print),
? group([softline, print(childPath)])
: print(childPath),
})
),
nextNode && nextNode.type === "footnoteDefinition"
@@ -469,13 +469,13 @@ function printListItem(path, options, print, listPrefix) {
printChildren(path, options, print, {
processor: (childPath, index) => {
if (index === 0 && childPath.getValue().type !== "list") {
return align(" ".repeat(prefix.length), childPath.call(print));
return align(" ".repeat(prefix.length), print(childPath));
}
const alignment = " ".repeat(
clamp(options.tabWidth - listPrefix.length, 0, 3) // 4+ will cause indented code block
);
return [alignment, align(alignment, childPath.call(print))];
return [alignment, align(alignment, print(childPath))];
},
}),
];
@@ -565,7 +565,7 @@ function printTable(path, options, print) {
const contents = path.map(
(rowPath) =>
rowPath.map((cellPath, columnIndex) => {
const text = printDocToString(cellPath.call(print), options).formatted;
const text = printDocToString(print(cellPath), options).formatted;
const width = getStringWidth(text);
columnMaxWidths[columnIndex] = Math.max(
columnMaxWidths[columnIndex] || 3, // minimum width = 3 (---, :--, :-:, --:)
@@ -691,14 +691,14 @@ function printRoot(path, options, print) {
}
}
return childPath.call(print);
return print(childPath);
},
});
}
function printChildren(path, options, print, events = {}) {
const { postprocessor } = events;
const processor = events.processor || ((childPath) => childPath.call(print));
const processor = events.processor || ((childPath) => print(childPath));
const node = path.getValue();
const parts = [];