11import type {
22 FqnOrRefTypeCtx ,
3+ PrimaryCstNode ,
34 StringTemplateCstNode ,
45 TextBlockTemplateCstNode
56} from "java-parser" ;
@@ -12,6 +13,7 @@ import {
1213 each ,
1314 findBaseIndent ,
1415 flatMap ,
16+ hasAssignmentOperators ,
1517 hasLeadingComments ,
1618 hasNonAssignmentOperators ,
1719 indentInParentheses ,
@@ -117,8 +119,11 @@ export default {
117119
118120 conditionalExpression ( path , print , options ) {
119121 const binaryExpression = call ( path , print , "binaryExpression" ) ;
122+ const grandparentNodeName = ( path . getNode ( 4 ) as JavaNonTerminal | null )
123+ ?. name ;
124+ const isInParentheses = grandparentNodeName === "parenthesisExpression" ;
120125 if ( ! path . node . children . QuestionMark ) {
121- return binaryExpression ;
126+ return isInParentheses ? binaryExpression : group ( binaryExpression ) ;
122127 }
123128 const [ consequent , alternate ] = map ( path , print , "expression" ) ;
124129 const suffix = [
@@ -127,16 +132,16 @@ export default {
127132 line ,
128133 [ ": " , options . useTabs ? indent ( alternate ) : align ( 2 , alternate ) ]
129134 ] ;
130- const isNestedTernary =
131- ( path . getNode ( 4 ) as JavaNonTerminal | null ) ?. name ===
132- "conditionalExpression" ;
135+ const isNestedTernary = grandparentNodeName === "conditionalExpression" ;
133136 const alignedSuffix =
134137 ! isNestedTernary || options . useTabs
135138 ? suffix
136139 : align ( Math . max ( 0 , options . tabWidth - 2 ) , suffix ) ;
137- return isNestedTernary
138- ? [ binaryExpression , alignedSuffix ]
139- : group ( [ binaryExpression , indent ( alignedSuffix ) ] ) ;
140+ if ( isNestedTernary ) {
141+ return [ group ( binaryExpression ) , alignedSuffix ] ;
142+ }
143+ const parts = [ group ( binaryExpression ) , indent ( alignedSuffix ) ] ;
144+ return isInParentheses ? parts : group ( parts ) ;
140145 } ,
141146
142147 binaryExpression ( path , print , options ) {
@@ -373,20 +378,37 @@ export default {
373378
374379 parenthesisExpression ( path , print ) {
375380 const expression = call ( path , print , "expression" ) ;
376- const ancestorName = ( path . getNode ( 14 ) as JavaNonTerminal | null ) ?. name ;
377- const binaryExpression = path . getNode ( 8 ) as JavaNonTerminal | null ;
381+ const ancestorNode1 = path . getNode ( 4 ) as PrimaryCstNode | null ;
382+ const ancestorNode2 = path . getNode ( 14 ) as JavaNonTerminal | null ;
378383 const { conditionalExpression, lambdaExpression } =
379384 path . node . children . expression [ 0 ] . children ;
380385 const hasLambda = lambdaExpression !== undefined ;
381386 const hasTernary =
382387 conditionalExpression ?. [ 0 ] . children . QuestionMark !== undefined ;
383- return ancestorName &&
384- [ "guard" , "returnStatement" ] . includes ( ancestorName ) &&
385- binaryExpression &&
386- binaryExpression . name === "binaryExpression" &&
387- Object . keys ( binaryExpression . children ) . length === 1
388- ? indentInParentheses ( expression )
389- : [ "(" , hasLambda || hasTernary ? expression : indent ( expression ) , ")" ] ;
388+ const hasSuffix = ancestorNode1 ?. children . primarySuffix !== undefined ;
389+ const isAssignment =
390+ ( ancestorNode2 ?. name === "binaryExpression" &&
391+ hasAssignmentOperators ( ancestorNode2 ) ) ||
392+ ancestorNode2 ?. name === "variableInitializer" ;
393+ if (
394+ ( ! hasLambda && hasSuffix && ( ! hasTernary || isAssignment ) ) ||
395+ ( ancestorNode2 &&
396+ [ "guard" , "returnStatement" ] . includes ( ancestorNode2 . name ) )
397+ ) {
398+ return indentInParentheses (
399+ hasTernary || ancestorNode2 ?. name === "returnStatement"
400+ ? group ( expression )
401+ : expression
402+ ) ;
403+ } else if ( hasTernary && hasSuffix && ! isAssignment ) {
404+ return group ( [ "(" , expression , softline , ")" ] ) ;
405+ } else {
406+ return group ( [
407+ "(" ,
408+ hasLambda || hasTernary ? expression : indent ( expression ) ,
409+ ")"
410+ ] ) ;
411+ }
390412 } ,
391413
392414 castExpression : printSingle ,
@@ -699,8 +721,8 @@ function binary(
699721 operands . unshift (
700722 levelOperator !== undefined &&
701723 needsParentheses ( nextOperator , levelOperator )
702- ? [ "(" , indent ( content ) , ")" ]
703- : content
724+ ? [ "(" , group ( indent ( content ) ) , ")" ]
725+ : group ( content )
704726 ) ;
705727 }
706728 }
@@ -711,17 +733,17 @@ function binary(
711733 ! isAssignmentOperator ( levelOperator ) &&
712734 levelOperator !== "instanceof" )
713735 ) {
714- return group ( level ) ;
736+ return level ;
715737 }
716738 if ( ! isRoot || hasNonAssignmentOperators ) {
717- return group ( indent ( level ) ) ;
739+ return indent ( level ) ;
718740 }
719741 const groupId = Symbol ( "assignment" ) ;
720- return group ( [
742+ return [
721743 level [ 0 ] ,
722744 group ( indent ( level [ 1 ] ) , { id : groupId } ) ,
723745 indentIfBreak ( level [ 2 ] , { groupId } )
724- ] ) ;
746+ ] ;
725747}
726748
727749const precedencesByOperator = new Map (
0 commit comments