diff --git a/src/nodes/Conditional.js b/src/nodes/Conditional.js index 65dfc5189..8d66ba975 100644 --- a/src/nodes/Conditional.js +++ b/src/nodes/Conditional.js @@ -1,15 +1,8 @@ import { doc } from 'prettier'; import { printSeparatedItem } from '../common/printer-helpers.js'; -const { - breakParent, - group, - hardline, - hardlineWithoutBreakParent, - ifBreak, - indent, - line -} = doc.builders; +const { group, hardline, hardlineWithoutBreakParent, ifBreak, indent, line } = + doc.builders; let groupIndex = 0; const experimentalTernaries = (node, path, print) => { @@ -20,16 +13,11 @@ const experimentalTernaries = (node, path, print) => { node.trueExpression.type === 'Conditional' || node.falseExpression.type === 'Conditional'; - // If the current `Conditional` is nested in another `Conditional`'s - // `trueExpression`, we add a line without propagating the break group. // If the `conditionDoc` breaks into multiple lines, we add parentheses, // unless it already is a `TupleExpression`. - // This can only be done because we are sure that the `condition` must be a - // single `bool` value. const conditionDoc = path.call(print, 'condition'); const conditionGroup = group( [ - isNestedAsTrueExpression ? hardlineWithoutBreakParent : '', node.condition.type === 'TupleExpression' ? conditionDoc : ifBreak(['(', printSeparatedItem(conditionDoc), ')'], conditionDoc), @@ -41,9 +29,10 @@ const experimentalTernaries = (node, path, print) => { groupIndex += 1; // If the `conditionGroup` breaks we force a new line to separate the - // `trueExpression` and `falseExpression`. - // In the case of `Conditional`, `VariableDeclarationStatement` and - // `ReturnStatement` we avoid propagating the group breaking. + // `trueExpression` and `falseExpression` following the "curious" ternaries + // format. + // We need a `hardlineWithoutBreakParent` because `hardline` doesn't play + // well with `ifBreak`. (See https://github.com/prettier/prettier/issues/15710) const expressionSeparator = ifBreak(hardlineWithoutBreakParent, line, { groupId: conditionGroup.id }); @@ -53,9 +42,7 @@ const experimentalTernaries = (node, path, print) => { // ternaries in the parent `Conditional`s. const trueExpressionDoc = printSeparatedItem( [ - isNestedAsTrueExpression - ? hardlineWithoutBreakParent - : expressionSeparator, + isNestedAsTrueExpression ? hardline : expressionSeparator, path.call(print, 'trueExpression') ], { firstSeparator: '' } @@ -64,27 +51,19 @@ const experimentalTernaries = (node, path, print) => { // We force a new line if current `Conditional` is nested or nests a // `Conditional`. Otherwise we add a normal separator. const falseExpressionDoc = group([ - isNested || hasNestedConditional - ? hardlineWithoutBreakParent - : expressionSeparator, + isNested || hasNestedConditional ? hardline : expressionSeparator, ': ', path.call(print, 'falseExpression') ]); const document = group([ - parent.type === 'TupleExpression' || parent.type === 'FunctionCall' - ? breakParent - : '', conditionGroup, trueExpressionDoc, falseExpressionDoc ]); return parent.type === 'VariableDeclarationStatement' - ? ifBreak( - indent([hasNestedConditional ? hardline : line, document]), - document - ) + ? ifBreak(indent([line, document]), document) : document; }; diff --git a/src/parser.js b/src/parser.js index 7cf14cc0a..573482132 100644 --- a/src/parser.js +++ b/src/parser.js @@ -88,6 +88,8 @@ function parse(text, _parsers, options = _parsers) { }, Conditional(ctx) { rearrangeConditional(ctx); + // We can remove parentheses only because we are sure that the + // `condition` must be a single `bool` value. while ( ctx.condition.type === 'TupleExpression' && !ctx.condition.isArray && diff --git a/tests/format/ExperimentalTernaries/__snapshots__/jsfmt.spec.js.snap b/tests/format/ExperimentalTernaries/__snapshots__/jsfmt.spec.js.snap index 80245e828..e1526dc19 100644 --- a/tests/format/ExperimentalTernaries/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/ExperimentalTernaries/__snapshots__/jsfmt.spec.js.snap @@ -367,11 +367,7 @@ contract Conditional { ); // Conditional as a condition - ( - foo ? 1 : bar - ) ? - 3 - : 4; + (foo ? 1 : bar) ? 3 : 4; ( isCat() ? meow() : isDog() ? bark()