fix unstable formatting of logical expressions (#7026)

This commit is contained in:
Georgii Dolzhykov authored and GitHub committed 2019-11-22 00:14:34 +02:00
1 parent 35cc90192d
commit bf2989718b
6 files changed
+113 -34

No files matched your search

@@ -0,0 +1,26 @@
#### Fix unstable formatting of logical expressions ([#7026](https://github.com/prettier/prettier/pull/7026) by [@thorn0](https://github.com/thorn0))
<!-- prettier-ignore -->
```jsx
// Input
const averredBathersBoxroomBuggyNurl =
bifornCringerMoshedPerplexSawder === 1 ||
(askTrovenaBeenaDependsRowans === 2 || glimseGlyphsHazardNoopsTieTie === 3);
// Prettier stable (first output)
const averredBathersBoxroomBuggyNurl =
bifornCringerMoshedPerplexSawder === 1 ||
askTrovenaBeenaDependsRowans === 2 || glimseGlyphsHazardNoopsTieTie === 3;
// Prettier stable (second output)
const averredBathersBoxroomBuggyNurl =
bifornCringerMoshedPerplexSawder === 1 ||
askTrovenaBeenaDependsRowans === 2 ||
glimseGlyphsHazardNoopsTieTie === 3;
// Prettier master (first output)
const averredBathersBoxroomBuggyNurl =
bifornCringerMoshedPerplexSawder === 1 ||
askTrovenaBeenaDependsRowans === 2 ||
glimseGlyphsHazardNoopsTieTie === 3;
```
-33
View File
@@ -37,11 +37,6 @@ function clean(ast, newObj, parent) {
return null;
}
// We remove unneeded parens around same-operator LogicalExpressions
if (isUnbalancedLogicalTree(newObj)) {
return rebalanceLogicalTree(newObj);
}
// (TypeScript) Ignore `static` in `constructor(static p) {}`
// and `export` in `constructor(export p) {}`
if (
@@ -199,32 +194,4 @@ function clean(ast, newObj, parent) {
}
}
function isUnbalancedLogicalTree(newObj) {
return (
newObj.type === "LogicalExpression" &&
newObj.right.type === "LogicalExpression" &&
newObj.operator === newObj.right.operator
);
}
function rebalanceLogicalTree(newObj) {
if (isUnbalancedLogicalTree(newObj)) {
return rebalanceLogicalTree({
type: "LogicalExpression",
operator: newObj.operator,
left: rebalanceLogicalTree({
type: "LogicalExpression",
operator: newObj.operator,
left: newObj.left,
right: newObj.right.left,
loc: {}
}),
right: newObj.right.right,
loc: {}
});
}
return newObj;
}
module.exports = clean;
+18 -1
View File
@@ -59,7 +59,24 @@ function locEnd(node) {
return loc;
}
function composeLoc(startNode, endNode = startNode) {
const loc = {};
if (typeof startNode.start === "number") {
loc.start = startNode.start;
loc.end = endNode.end;
}
if (Array.isArray(startNode.range)) {
loc.range = [startNode.range[0], endNode.range[1]];
}
loc.loc = {
start: startNode.loc.start,
end: endNode.loc.end
};
return loc;
}
module.exports = {
locStart,
locEnd
locEnd,
composeLoc
};
+44
View File
@@ -1,10 +1,18 @@
"use strict";
const { getLast } = require("../common/util");
const { composeLoc } = require("./loc");
function postprocess(ast, options) {
visitNode(ast, node => {
switch (node.type) {
case "LogicalExpression": {
// We remove unneeded parens around same-operator LogicalExpressions
if (isUnbalancedLogicalTree(node)) {
return rebalanceLogicalTree(node);
}
break;
}
// fix unexpected locEnd caused by --no-semi style
case "VariableDeclaration": {
const lastDeclaration = getLast(node.declarations);
@@ -101,4 +109,40 @@ function visitNode(node, fn, parent, property) {
}
}
function isUnbalancedLogicalTree(node) {
return (
node.type === "LogicalExpression" &&
node.right.type === "LogicalExpression" &&
node.operator === node.right.operator
);
}
function rebalanceLogicalTree(node) {
if (!isUnbalancedLogicalTree(node)) {
return node;
}
return rebalanceLogicalTree(
Object.assign(
{
type: "LogicalExpression",
operator: node.operator,
left: rebalanceLogicalTree(
Object.assign(
{
type: "LogicalExpression",
operator: node.operator,
left: node.left,
right: node.right.left
},
composeLoc(node.left, node.right.left)
)
),
right: node.right.right
},
composeLoc(node)
)
);
}
module.exports = postprocess;
@@ -1,5 +1,26 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`issue-7024.js 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
printWidth: 80
| printWidth
=====================================input======================================
const radioSelectedAttr =
(isAnyValueSelected &&
node.getAttribute(radioAttr.toLowerCase()) === radioValue) ||
((!isAnyValueSelected && values[a].default === true) || a === 0);
=====================================output=====================================
const radioSelectedAttr =
(isAnyValueSelected &&
node.getAttribute(radioAttr.toLowerCase()) === radioValue) ||
(!isAnyValueSelected && values[a].default === true) ||
a === 0;
================================================================================
`;
exports[`logical_expression_operators.js 1`] = `
====================================options=====================================
parsers: ["babel", "flow", "typescript"]
+4
View File
@@ -0,0 +1,4 @@
const radioSelectedAttr =
(isAnyValueSelected &&
node.getAttribute(radioAttr.toLowerCase()) === radioValue) ||
((!isAnyValueSelected && values[a].default === true) || a === 0);