Keep parentheses in yield expression (#19913)
Co-authored-by: fisker <lionkay@gmail.com>
This commit is contained in:
1 parent
c4c3320496
commit
f6ddf6e437
6 files changed
+163
-16
No files matched your search
@@ -0,0 +1,24 @@
|
||||
#### Keep necessary parentheses in `yield` expression (#19913 by @giaBaoJS)
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```jsx
|
||||
// Input
|
||||
function* f() {
|
||||
yield (/*
|
||||
*/ a);
|
||||
}
|
||||
|
||||
// Prettier stable
|
||||
function* f() {
|
||||
yield /*
|
||||
*/ a;
|
||||
}
|
||||
|
||||
// Prettier main
|
||||
function* f() {
|
||||
yield (
|
||||
/*
|
||||
*/ a
|
||||
);
|
||||
}
|
||||
```
|
||||
@@ -27,7 +27,8 @@ function parentNeedsParentheses(path, options, needsParentheses) {
|
||||
switch (parent.type) {
|
||||
case "ReturnStatement":
|
||||
case "ThrowStatement":
|
||||
if (willReturnOrThrowStatementBreak(path, options)) {
|
||||
case "YieldExpression":
|
||||
if (willArgumentBreakAndAddParentheses(path, options)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@@ -128,14 +129,17 @@ function parentNeedsParentheses(path, options, needsParentheses) {
|
||||
}
|
||||
}
|
||||
|
||||
function willReturnOrThrowStatementBreak(path, options) {
|
||||
function willArgumentBreakAndAddParentheses(path, options) {
|
||||
const { key, parent } = path;
|
||||
if (!(key === "argument" && isReturnOrThrowStatement(parent))) {
|
||||
if (!(
|
||||
key === "argument" &&
|
||||
(isReturnOrThrowStatement(parent) || parent.type === "YieldExpression")
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
When `ReturnStatement` or `ThrowStatement` breaks, parentheses will be added around it's argument.
|
||||
When `ReturnStatement`, `ThrowStatement`, or `YieldExpression` breaks, parentheses will be added around it's argument.
|
||||
So don't need add parentheses again.
|
||||
But we can't know how the argument printed, so only matches cases that will break for sure
|
||||
*/
|
||||
|
||||
@@ -57,6 +57,7 @@ import { printRestElement, printSpreadElement } from "./rest-element.js";
|
||||
import {
|
||||
printReturnStatement,
|
||||
printThrowStatement,
|
||||
printYieldExpression,
|
||||
} from "./return-statement.js";
|
||||
import { printSequenceExpression } from "./sequence-expression.js";
|
||||
import { printSwitchCase, printSwitchStatement } from "./switch-statement.js";
|
||||
@@ -156,10 +157,8 @@ function printEstree(path, options, print, args) {
|
||||
case "ArrowFunctionExpression":
|
||||
return printArrowFunction(path, options, print, args);
|
||||
case "YieldExpression":
|
||||
return [
|
||||
`yield${node.delegate ? "*" : ""}`,
|
||||
node.argument ? [" ", print("argument")] : "",
|
||||
];
|
||||
return printYieldExpression(path, options, print);
|
||||
|
||||
case "AwaitExpression":
|
||||
return printAwaitExpression(path, options, print);
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import { printSemicolon } from "./miscellaneous.js";
|
||||
@import {Doc} from "../../document/index.js";
|
||||
*/
|
||||
|
||||
function printReturnOrThrowArgument(path, options, print) {
|
||||
function printArgument(path, options, print) {
|
||||
const { node } = path;
|
||||
const argumentDoc = print();
|
||||
|
||||
@@ -45,19 +45,24 @@ function printReturnOrThrowStatement(path, options, print) {
|
||||
return [
|
||||
node.type === "ThrowStatement" ? "throw" : "return",
|
||||
node.argument
|
||||
? [
|
||||
" ",
|
||||
path.call(
|
||||
() => printReturnOrThrowArgument(path, options, print),
|
||||
"argument",
|
||||
),
|
||||
]
|
||||
? [" ", path.call(() => printArgument(path, options, print), "argument")]
|
||||
: "",
|
||||
printSemicolon(options),
|
||||
];
|
||||
}
|
||||
|
||||
function printYieldExpression(path, options, print) {
|
||||
const { node } = path;
|
||||
return [
|
||||
`yield${node.delegate ? "*" : ""}`,
|
||||
node.argument
|
||||
? [" ", path.call(() => printArgument(path, options, print), "argument")]
|
||||
: "",
|
||||
];
|
||||
}
|
||||
|
||||
export {
|
||||
printReturnOrThrowStatement as printReturnStatement,
|
||||
printReturnOrThrowStatement as printThrowStatement,
|
||||
printYieldExpression,
|
||||
};
|
||||
@@ -21,6 +21,91 @@ function* f() {
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`comment.js format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel", "typescript"]
|
||||
printWidth: 80 (default) |
|
||||
=====================================input======================================
|
||||
function* f() {
|
||||
// Line terminators are not allowed between \`yield\` and its argument, so the
|
||||
// parentheses must be kept.
|
||||
yield (/*
|
||||
*/ a);
|
||||
|
||||
foo(
|
||||
yield (/*
|
||||
*/ a)
|
||||
);
|
||||
|
||||
yield (// comment
|
||||
a);
|
||||
|
||||
yield (/*
|
||||
*/ a + b);
|
||||
|
||||
yield (/*
|
||||
*/ a, b);
|
||||
|
||||
yield (/* comment */
|
||||
a);
|
||||
|
||||
// Safe, the comment is printed on one line.
|
||||
yield (/* comment */ a);
|
||||
|
||||
// \`yield*\` is not restricted, but it is printed the same way.
|
||||
yield* (/*
|
||||
*/ a);
|
||||
}
|
||||
|
||||
=====================================output=====================================
|
||||
function* f() {
|
||||
// Line terminators are not allowed between \`yield\` and its argument, so the
|
||||
// parentheses must be kept.
|
||||
yield (
|
||||
/*
|
||||
*/ a
|
||||
);
|
||||
|
||||
foo(
|
||||
yield (
|
||||
/*
|
||||
*/ a
|
||||
),
|
||||
);
|
||||
|
||||
yield (
|
||||
// comment
|
||||
a
|
||||
);
|
||||
|
||||
yield (
|
||||
/*
|
||||
*/ a + b
|
||||
);
|
||||
|
||||
yield (
|
||||
/*
|
||||
*/ a, b
|
||||
);
|
||||
|
||||
yield (
|
||||
/* comment */
|
||||
a
|
||||
);
|
||||
|
||||
// Safe, the comment is printed on one line.
|
||||
yield /* comment */ a;
|
||||
|
||||
// \`yield*\` is not restricted, but it is printed the same way.
|
||||
yield* (
|
||||
/*
|
||||
*/ a
|
||||
);
|
||||
}
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`conditional.js format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["babel", "typescript"]
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
function* f() {
|
||||
// Line terminators are not allowed between `yield` and its argument, so the
|
||||
// parentheses must be kept.
|
||||
yield (/*
|
||||
*/ a);
|
||||
|
||||
foo(
|
||||
yield (/*
|
||||
*/ a)
|
||||
);
|
||||
|
||||
yield (// comment
|
||||
a);
|
||||
|
||||
yield (/*
|
||||
*/ a + b);
|
||||
|
||||
yield (/*
|
||||
*/ a, b);
|
||||
|
||||
yield (/* comment */
|
||||
a);
|
||||
|
||||
// Safe, the comment is printed on one line.
|
||||
yield (/* comment */ a);
|
||||
|
||||
// `yield*` is not restricted, but it is printed the same way.
|
||||
yield* (/*
|
||||
*/ a);
|
||||
}
|
||||
Reference in new issue
Block a user