Print 3 or more chained calls on multiple lines (#2673)

master
Lucas Azzola 2017-08-28 02:44:44 +10:00 committed by Christopher Chedeau
parent 1e2da6c727
commit 2e828de76f
7 changed files with 109 additions and 54 deletions

View File

@ -3464,11 +3464,7 @@ function printMemberLookup(path, options, print) {
return concat([optional, ".", property]);
}
if (
!n.property ||
(n.property.type === "Literal" && typeof n.property.value === "number") ||
n.property.type === "NumericLiteral"
) {
if (!n.property || isNumericLiteral(n.property)) {
return concat([optional, "[", property, "]"]);
}
@ -3585,14 +3581,16 @@ function printMemberChain(path, options, print) {
break;
}
}
for (; i + 1 < printedNodes.length; ++i) {
if (
isMemberish(printedNodes[i].node) &&
isMemberish(printedNodes[i + 1].node)
) {
currentGroup.push(printedNodes[i]);
} else {
break;
if (printedNodes[0].node.type !== "CallExpression") {
for (; i + 1 < printedNodes.length; ++i) {
if (
isMemberish(printedNodes[i].node) &&
isMemberish(printedNodes[i + 1].node)
) {
currentGroup.push(printedNodes[i]);
} else {
break;
}
}
}
groups.push(currentGroup);
@ -3609,7 +3607,7 @@ function printMemberChain(path, options, print) {
// beginning of the next one
if (
printedNodes[i].node.computed &&
isLiteral(printedNodes[i].node.property)
isNumericLiteral(printedNodes[i].node.property)
) {
currentGroup.push(printedNodes[i]);
continue;
@ -3702,14 +3700,20 @@ function printMemberChain(path, options, print) {
printIndentedGroup(groups.slice(shouldMerge ? 2 : 1))
]);
// If there's a comment, we don't want to print in one line.
if (hasComment) {
return group(expanded);
}
const callExpressionCount = printedNodes.filter(
tuple => tuple.node.type === "CallExpression"
).length;
// If any group but the last one has a hard line, we want to force expand
// it. If the last group is a function it's okay to inline if it fits.
if (printedGroups.slice(0, -1).some(willBreak)) {
// We don't want to print in one line if there's:
// * A comment.
// * 3 or more chained calls.
// * Any group but the last one has a hard line.
// If the last group is a function it's okay to inline if it fits.
if (
hasComment ||
callExpressionCount >= 3 ||
printedGroups.slice(0, -1).some(willBreak)
) {
return group(expanded);
}
@ -4724,6 +4728,13 @@ function isLiteral(node) {
);
}
function isNumericLiteral(node) {
return (
node.type === "NumericLiteral" ||
(node.type === "Literal" && typeof node.value === "number")
);
}
function isStringLiteral(node) {
return (
node.type === "StringLiteral" ||

View File

@ -153,11 +153,13 @@ async function* refuse_return() {
return 0;
}
}
refuse_return().return("string").then(result => {
if (result.done) {
(result.value: string); // error: number | void ~> string
}
});
refuse_return()
.return("string")
.then(result => {
if (result.done) {
(result.value: string); // error: number | void ~> string
}
});
`;
@ -204,11 +206,13 @@ async function* catch_return() {
}
async () => {
catch_return().throw("").then(({ value }) => {
if (value !== undefined) {
(value: void); // error: number ~> void
}
});
catch_return()
.throw("")
.then(({ value }) => {
if (value !== undefined) {
(value: void); // error: number ~> void
}
});
};
async function* yield_return() {
@ -221,11 +225,13 @@ async function* yield_return() {
}
async () => {
yield_return().throw("").then(({ value }) => {
if (value !== undefined) {
(value: void); // error: number ~> void
}
});
yield_return()
.throw("")
.then(({ value }) => {
if (value !== undefined) {
(value: void); // error: number ~> void
}
});
};
`;

View File

@ -70,7 +70,10 @@ let tests = [
hmac.update(buf, "utf8"); // 1 error: no encoding when passing a buffer
// it's also chainable
(hmac.update("some data to hash").update(buf).digest(): Buffer);
(hmac
.update("some data to hash")
.update(buf)
.digest(): Buffer);
(hmac.digest("hex"): string);
(hmac.digest(): Buffer);

View File

@ -587,10 +587,12 @@ Promise.reject(0)
});
// resolvedPromise<T> -> catch() -> then():?T
Promise.resolve(0).catch(function(err) {}).then(function(num) {
var a: ?number = num;
var b: string = num; // Error: string ~> number
});
Promise.resolve(0)
.catch(function(err) {})
.then(function(num) {
var a: ?number = num;
var b: string = num; // Error: string ~> number
});
`;

View File

@ -27,10 +27,13 @@ const veryVeryVeryVeryVeryVeryVeryLong =
const small = doc.expandedStates[doc.expandedStates.length - 1];
const promises = [
promise.resolve().then(console.log).catch(err => {
console.log(err);
return null;
}),
promise
.resolve()
.then(console.log)
.catch(err => {
console.log(err);
return null;
}),
redis.fetch(),
other.fetch()
];

View File

@ -205,6 +205,26 @@ const {
`;
exports[`break-multiple.js 1`] = `
object.foo().bar().baz();
foo().bar().baz();
foo().bar.baz();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
object
.foo()
.bar()
.baz();
foo()
.bar()
.baz();
foo().bar.baz();
`;
exports[`comment.js 1`] = `
function f() {
return observableFromSubscribeFunction()
@ -519,14 +539,16 @@ if (testConfig.ENABLE_ONLINE_TESTS === "true") {
describe("POST /users/me/pet", function() {
it("saves pet", function() {
function assert(pet) {
expect(pet).to.have.property("OwnerAddress").that.deep.equals({
AddressLine1: "Alexanderstrasse",
AddressLine2: "",
PostalCode: "10999",
Region: "Berlin",
City: "Berlin",
Country: "DE"
});
expect(pet)
.to.have.property("OwnerAddress")
.that.deep.equals({
AddressLine1: "Alexanderstrasse",
AddressLine2: "",
PostalCode: "10999",
Region: "Berlin",
City: "Berlin",
Country: "DE"
});
}
});
});
@ -557,7 +579,10 @@ method().then(x => x)
({}.a().b());
({}).a().b();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method().then(x => x)["abc"](x => x)[abc](x => x);
method()
.then(x => x)
["abc"](x => x)
[abc](x => x);
({}.a().b());
({}.a().b());

View File

@ -0,0 +1,5 @@
object.foo().bar().baz();
foo().bar().baz();
foo().bar.baz();