Break lines before binary operators (#7111)
* Add additional binary expression comment tests Refs #3806 These cover a few edge cases I encountered while maintaining `@btmills/prettier` over the last few years. I'm adding them up front to demonstrate that the `experimentalOperatorPosition` changes in a later commit have no effect on this formatting when the flag is not enabled. * Define experimentalOperatorPosition flag Refs #3806 This merely defines the flag. A future commit will use it in updated logic. * Add experimentalOperatorPosition default tests Right now, this flag isn't implemented, so these tests duplicate the existing behavior. I'm adding them now so that when I implement the flag's logic in a future commit, the changed formatting will be obvious in the diff and easier to review. * Implement experimentalOperatorPosition flag Fixes #3806 as requested in https://github.com/prettier/prettier/pull/7111#issuecomment-2252623779 The flag's tests were already added in a previous commit, so the test changes you see in this commit are specifically due to the new flag's implementation. * Document experimentalOperatorPosition flag * Change operator position option start|end In response to https://github.com/prettier/prettier/pull/7111#discussion_r1729382119 * Add TS intersection line wrapping tests This clones TypeScript's type union operator tests in `union-parens.ts` and swaps the operators (& <-> |) to test the the type interesection operator. It also runs intersection tests with the new `experimentalOperatorPosition: "start"` flag. This does _not_ yet update the implementation to consider the flag; to ease review, I'll make that change in the next commit to isolate the impact of the change. * Apply experimentalOperatorPosition: start to type intersections The type union operator was already formatted at the beginning of lines by default, so that logic didn't need to be updated. * Update 7111.md * Update tests after rebasing I rebased from1dfe28f85toc7066780eto fix test failures related to https://github.com/prettier/prettier/pull/16601. The rebase applied cleanly, and this was the only change to tests. Since the PR has already been approved, I'll keep this as a separate commit rather than squashing into the prior commits. --------- Co-authored-by: fisker Cheung <lionkay@gmail.com> Co-authored-by: SUZUKI Sosuke <aosukeke@gmail.com>
This commit is contained in:
17 files changed
+2342
-21
No files matched your search
@@ -36,6 +36,22 @@ const options = {
|
||||
oppositeDescription:
|
||||
"Do not print semicolons, except at the beginning of lines which may need them.",
|
||||
},
|
||||
experimentalOperatorPosition: {
|
||||
category: CATEGORY_JAVASCRIPT,
|
||||
type: "choice",
|
||||
default: "end",
|
||||
description: "Where to print operators when binary expressions wrap lines.",
|
||||
choices: [
|
||||
{
|
||||
value: "start",
|
||||
description: "Print operators at the start of new lines.",
|
||||
},
|
||||
{
|
||||
value: "end",
|
||||
description: "Print operators at the end of previous lines.",
|
||||
},
|
||||
],
|
||||
},
|
||||
experimentalTernaries: {
|
||||
category: CATEGORY_JAVASCRIPT,
|
||||
type: "boolean",
|
||||
|
||||
@@ -7,8 +7,13 @@ import {
|
||||
line,
|
||||
softline,
|
||||
} from "../../document/builders.js";
|
||||
import { DOC_TYPE_FILL, DOC_TYPE_GROUP } from "../../document/constants.js";
|
||||
import { cleanDoc } from "../../document/utils.js";
|
||||
import {
|
||||
DOC_TYPE_ARRAY,
|
||||
DOC_TYPE_FILL,
|
||||
DOC_TYPE_GROUP,
|
||||
DOC_TYPE_LABEL,
|
||||
} from "../../document/constants.js";
|
||||
import { cleanDoc, getDocType } from "../../document/utils.js";
|
||||
import { printComments } from "../../main/comments/print.js";
|
||||
import {
|
||||
CommentCheckFlags,
|
||||
@@ -23,6 +28,7 @@ import {
|
||||
isObjectProperty,
|
||||
shouldFlatten,
|
||||
} from "../utils/index.js";
|
||||
import isTypeCastComment from "../utils/is-type-cast-comment.js";
|
||||
|
||||
/** @import {Doc} from "../../document/builders.js" */
|
||||
|
||||
@@ -231,6 +237,14 @@ function printBinaryishExpressions(
|
||||
node.type === "NGPipeExpression" ||
|
||||
isVueFilterSequenceExpression(path, options)) &&
|
||||
!hasLeadingOwnLineComment(options.originalText, node.right);
|
||||
const hasTypeCastComment = hasComment(
|
||||
node.right,
|
||||
CommentCheckFlags.Leading,
|
||||
isTypeCastComment,
|
||||
);
|
||||
const commentBeforeOperator =
|
||||
!hasTypeCastComment &&
|
||||
hasLeadingOwnLineComment(options.originalText, node.right);
|
||||
|
||||
const operator = node.type === "NGPipeExpression" ? "|" : node.operator;
|
||||
const rightSuffix =
|
||||
@@ -267,13 +281,28 @@ function printBinaryishExpressions(
|
||||
"right",
|
||||
)
|
||||
: print("right");
|
||||
right = [
|
||||
lineBeforeOperator ? line : "",
|
||||
operator,
|
||||
lineBeforeOperator ? " " : line,
|
||||
rightContent,
|
||||
rightSuffix,
|
||||
];
|
||||
if (options.experimentalOperatorPosition === "start") {
|
||||
let comment = "";
|
||||
if (commentBeforeOperator) {
|
||||
switch (getDocType(rightContent)) {
|
||||
case DOC_TYPE_ARRAY:
|
||||
comment = rightContent.splice(0, 1)[0];
|
||||
break;
|
||||
case DOC_TYPE_LABEL:
|
||||
comment = rightContent.contents.splice(0, 1)[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
right = [line, comment, operator, " ", rightContent, rightSuffix];
|
||||
} else {
|
||||
right = [
|
||||
lineBeforeOperator ? line : "",
|
||||
operator,
|
||||
lineBeforeOperator ? " " : line,
|
||||
rightContent,
|
||||
rightSuffix,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// If there's only a single binary expression, we want to create a group
|
||||
@@ -289,11 +318,15 @@ function printBinaryishExpressions(
|
||||
parent.type !== node.type &&
|
||||
node.left.type !== node.type &&
|
||||
node.right.type !== node.type);
|
||||
if (shouldGroup) {
|
||||
right = group(right, { shouldBreak });
|
||||
}
|
||||
|
||||
parts.push(
|
||||
lineBeforeOperator ? "" : " ",
|
||||
shouldGroup ? group(right, { shouldBreak }) : right,
|
||||
);
|
||||
if (options.experimentalOperatorPosition === "start") {
|
||||
parts.push(shouldInline || commentBeforeOperator ? " " : "", right);
|
||||
} else {
|
||||
parts.push(lineBeforeOperator ? "" : " ", right);
|
||||
}
|
||||
|
||||
// The root comments are already printed, but we need to manually print
|
||||
// the other ones since we don't call the normal print on BinaryExpression,
|
||||
|
||||
@@ -142,6 +142,9 @@ function printIntersectionType(path, options, print) {
|
||||
|
||||
// If no object is involved, go to the next line if it breaks
|
||||
if (!previousIsObjectType && !currentIsObjectType) {
|
||||
if (options.experimentalOperatorPosition === "start") {
|
||||
return indent([line, "& ", doc]);
|
||||
}
|
||||
return indent([" &", line, doc]);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user