Stabilize member chain with empty line (#15522)
Co-authored-by: fisker Cheung <lionkay@gmail.com>
This commit is contained in:
1 parent
be2fe89b43
commit
224f70fb09
6 files changed
+84
-2
No files matched your search
@@ -0,0 +1,22 @@
|
|||||||
|
#### Fix non-idempotent formatting of method chain with empty line (#15522 by @seiyab)
|
||||||
|
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
```js
|
||||||
|
// Input
|
||||||
|
Foo.a()
|
||||||
|
|
||||||
|
.b();
|
||||||
|
|
||||||
|
// Prettier stable (first format)
|
||||||
|
Foo.a()
|
||||||
|
.b();
|
||||||
|
|
||||||
|
// Prettier stable (second format)
|
||||||
|
Foo.a().b();
|
||||||
|
|
||||||
|
|
||||||
|
// Prettier main
|
||||||
|
Foo.a()
|
||||||
|
|
||||||
|
.b();
|
||||||
|
```
|
||||||
@@ -34,6 +34,11 @@ import {
|
|||||||
printBindExpressionCallee,
|
printBindExpressionCallee,
|
||||||
} from "./misc.js";
|
} from "./misc.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import("../../document/builders.js").Doc} Doc
|
||||||
|
* @typedef {{ node: any, printed: Doc, needsParens?: boolean, shouldInline?: boolean, hasTrailingEmptyLine?: boolean }} PrintedNode
|
||||||
|
*/
|
||||||
|
|
||||||
// We detect calls on member expressions specially to format a
|
// We detect calls on member expressions specially to format a
|
||||||
// common pattern better. The pattern we are looking for is this:
|
// common pattern better. The pattern we are looking for is this:
|
||||||
//
|
//
|
||||||
@@ -57,6 +62,7 @@ function printMemberChain(path, options, print) {
|
|||||||
// CallExpression(MemberExpression(CallExpression(Identifier)))
|
// CallExpression(MemberExpression(CallExpression(Identifier)))
|
||||||
// and we transform it into
|
// and we transform it into
|
||||||
// [Identifier, CallExpression, MemberExpression, CallExpression]
|
// [Identifier, CallExpression, MemberExpression, CallExpression]
|
||||||
|
/** @type {PrintedNode[]}} */
|
||||||
const printedNodes = [];
|
const printedNodes = [];
|
||||||
|
|
||||||
// Here we try to retain one typed empty line after each call expression or
|
// Here we try to retain one typed empty line after each call expression or
|
||||||
@@ -87,8 +93,10 @@ function printMemberChain(path, options, print) {
|
|||||||
isCallExpression(node) &&
|
isCallExpression(node) &&
|
||||||
(isMemberish(node.callee) || isCallExpression(node.callee))
|
(isMemberish(node.callee) || isCallExpression(node.callee))
|
||||||
) {
|
) {
|
||||||
|
const hasTrailingEmptyLine = shouldInsertEmptyLineAfter(node);
|
||||||
printedNodes.unshift({
|
printedNodes.unshift({
|
||||||
node,
|
node,
|
||||||
|
hasTrailingEmptyLine,
|
||||||
printed: [
|
printed: [
|
||||||
printComments(
|
printComments(
|
||||||
path,
|
path,
|
||||||
@@ -99,7 +107,7 @@ function printMemberChain(path, options, print) {
|
|||||||
],
|
],
|
||||||
options,
|
options,
|
||||||
),
|
),
|
||||||
shouldInsertEmptyLineAfter(node) ? hardline : "",
|
hasTrailingEmptyLine ? hardline : "",
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
path.call((callee) => rec(callee), "callee");
|
path.call((callee) => rec(callee), "callee");
|
||||||
@@ -170,6 +178,7 @@ function printMemberChain(path, options, print) {
|
|||||||
// < fn()[0][1][2] >.something()
|
// < fn()[0][1][2] >.something()
|
||||||
// - then, as many MemberExpression as possible but the last one
|
// - then, as many MemberExpression as possible but the last one
|
||||||
// < this.items >.something()
|
// < this.items >.something()
|
||||||
|
/** @type {PrintedNode[][]} */
|
||||||
const groups = [];
|
const groups = [];
|
||||||
let currentGroup = [printedNodes[0]];
|
let currentGroup = [printedNodes[0]];
|
||||||
let i = 1;
|
let i = 1;
|
||||||
@@ -331,7 +340,11 @@ function printMemberChain(path, options, print) {
|
|||||||
|
|
||||||
// If we only have a single `.`, we shouldn't do anything fancy and just
|
// If we only have a single `.`, we shouldn't do anything fancy and just
|
||||||
// render everything concatenated together.
|
// render everything concatenated together.
|
||||||
if (groups.length <= cutoff && !nodeHasComment) {
|
if (
|
||||||
|
groups.length <= cutoff &&
|
||||||
|
!nodeHasComment &&
|
||||||
|
!groups.some((g) => g.at(-1).hasTrailingEmptyLine)
|
||||||
|
) {
|
||||||
if (isLongCurriedCallExpression(path)) {
|
if (isLongCurriedCallExpression(path)) {
|
||||||
return oneLine;
|
return oneLine;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,26 @@ foo(a--).bar().leet();
|
|||||||
================================================================================
|
================================================================================
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`assignment-lhs.js format 1`] = `
|
||||||
|
====================================options=====================================
|
||||||
|
parsers: ["babel", "flow", "typescript"]
|
||||||
|
printWidth: 80
|
||||||
|
| printWidth
|
||||||
|
=====================================input======================================
|
||||||
|
document.querySelector("#output-abcdef").textContent = \`metaKey pressed? \${e.metaKey}\`;
|
||||||
|
|
||||||
|
document.querySelector("p").textContent = \`Shader program did not link successfully. Error log: \${linkErrLog}\`;
|
||||||
|
|
||||||
|
=====================================output=====================================
|
||||||
|
document.querySelector("#output-abcdef").textContent =
|
||||||
|
\`metaKey pressed? \${e.metaKey}\`;
|
||||||
|
|
||||||
|
document.querySelector("p").textContent =
|
||||||
|
\`Shader program did not link successfully. Error log: \${linkErrLog}\`;
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`bracket_0.js format 1`] = `
|
exports[`bracket_0.js format 1`] = `
|
||||||
====================================options=====================================
|
====================================options=====================================
|
||||||
parsers: ["babel", "flow", "typescript"]
|
parsers: ["babel", "flow", "typescript"]
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
document.querySelector("#output-abcdef").textContent = `metaKey pressed? ${e.metaKey}`;
|
||||||
|
|
||||||
|
document.querySelector("p").textContent = `Shader program did not link successfully. Error log: ${linkErrLog}`;
|
||||||
@@ -529,6 +529,14 @@ const sel = this.connections
|
|||||||
.concat(this.activities.concat(this.operators))
|
.concat(this.activities.concat(this.operators))
|
||||||
.filter(x => x.selected);
|
.filter(x => x.selected);
|
||||||
|
|
||||||
|
Object.entries(obj)
|
||||||
|
|
||||||
|
.forEach((e) => console.log(e));
|
||||||
|
|
||||||
|
this.fetch("/foo")
|
||||||
|
|
||||||
|
.then(response => response.json());
|
||||||
|
|
||||||
=====================================output=====================================
|
=====================================output=====================================
|
||||||
fooBar
|
fooBar
|
||||||
.doSomething("Hello World")
|
.doSomething("Hello World")
|
||||||
@@ -590,6 +598,14 @@ const sel = this.connections
|
|||||||
.concat(this.activities.concat(this.operators))
|
.concat(this.activities.concat(this.operators))
|
||||||
.filter((x) => x.selected);
|
.filter((x) => x.selected);
|
||||||
|
|
||||||
|
Object.entries(obj)
|
||||||
|
|
||||||
|
.forEach((e) => console.log(e));
|
||||||
|
|
||||||
|
this.fetch("/foo")
|
||||||
|
|
||||||
|
.then((response) => response.json());
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@@ -57,3 +57,11 @@ const sel = this.connections
|
|||||||
|
|
||||||
.concat(this.activities.concat(this.operators))
|
.concat(this.activities.concat(this.operators))
|
||||||
.filter(x => x.selected);
|
.filter(x => x.selected);
|
||||||
|
|
||||||
|
Object.entries(obj)
|
||||||
|
|
||||||
|
.forEach((e) => console.log(e));
|
||||||
|
|
||||||
|
this.fetch("/foo")
|
||||||
|
|
||||||
|
.then(response => response.json());
|
||||||
Reference in new issue
Block a user