@@ -112,6 +112,16 @@ export function createParenthesizerRules(factory: NodeFactory): ParenthesizerRul
112112 return parenthesizerRule ;
113113 }
114114
115+ function mixingBinaryOperatorsRequiresParentheses ( a : SyntaxKind , b : SyntaxKind ) {
116+ if ( a === SyntaxKind . QuestionQuestionToken ) {
117+ return b === SyntaxKind . AmpersandAmpersandToken || b === SyntaxKind . BarBarToken ;
118+ }
119+ if ( b === SyntaxKind . QuestionQuestionToken ) {
120+ return a === SyntaxKind . AmpersandAmpersandToken || a === SyntaxKind . BarBarToken ;
121+ }
122+ return false ;
123+ }
124+
115125 /**
116126 * Determines whether the operand to a BinaryExpression needs to be parenthesized.
117127 *
@@ -121,6 +131,10 @@ export function createParenthesizerRules(factory: NodeFactory): ParenthesizerRul
121131 * BinaryExpression.
122132 */
123133 function binaryOperandNeedsParentheses ( binaryOperator : SyntaxKind , operand : Expression , isLeftSideOfBinary : boolean , leftOperand : Expression | undefined ) {
134+ const emittedOperand = skipPartiallyEmittedExpressions ( operand ) ;
135+ if ( isBinaryExpression ( emittedOperand ) && mixingBinaryOperatorsRequiresParentheses ( binaryOperator , emittedOperand . operatorToken . kind ) ) {
136+ return true ;
137+ }
124138 // If the operand has lower precedence, then it needs to be parenthesized to preserve the
125139 // intent of the expression. For example, if the operand is `a + b` and the operator is
126140 // `*`, then we need to parenthesize the operand to preserve the intended order of
@@ -140,7 +154,6 @@ export function createParenthesizerRules(factory: NodeFactory): ParenthesizerRul
140154 // the intended order of operations: `(a ** b) ** c`
141155 const binaryOperatorPrecedence = getOperatorPrecedence ( SyntaxKind . BinaryExpression , binaryOperator ) ;
142156 const binaryOperatorAssociativity = getOperatorAssociativity ( SyntaxKind . BinaryExpression , binaryOperator ) ;
143- const emittedOperand = skipPartiallyEmittedExpressions ( operand ) ;
144157 if ( ! isLeftSideOfBinary && operand . kind === SyntaxKind . ArrowFunction && binaryOperatorPrecedence > OperatorPrecedence . Assignment ) {
145158 // We need to parenthesize arrow functions on the right side to avoid it being
146159 // parsed as parenthesized expression: `a && (() => {})`
0 commit comments