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,34 @@ 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 ( ! hasLambda && hasSuffix && ( ! hasTernary || isAssignment ) ) {
394+ return indentInParentheses ( hasTernary ? group ( expression ) : expression ) ;
395+ } else if (
396+ ancestorNode2 &&
397+ [ "guard" , "returnStatement" ] . includes ( ancestorNode2 . name )
398+ ) {
399+ return indentInParentheses ( group ( expression ) ) ;
400+ } else if ( hasTernary && hasSuffix && ! isAssignment ) {
401+ return group ( [ "(" , expression , softline , ")" ] ) ;
402+ } else {
403+ return group ( [
404+ "(" ,
405+ hasLambda || hasTernary ? expression : indent ( expression ) ,
406+ ")"
407+ ] ) ;
408+ }
390409 } ,
391410
392411 castExpression : printSingle ,
@@ -699,8 +718,8 @@ function binary(
699718 operands . unshift (
700719 levelOperator !== undefined &&
701720 needsParentheses ( nextOperator , levelOperator )
702- ? [ "(" , indent ( content ) , ")" ]
703- : content
721+ ? [ "(" , group ( indent ( content ) ) , ")" ]
722+ : group ( content )
704723 ) ;
705724 }
706725 }
@@ -711,17 +730,17 @@ function binary(
711730 ! isAssignmentOperator ( levelOperator ) &&
712731 levelOperator !== "instanceof" )
713732 ) {
714- return group ( level ) ;
733+ return level ;
715734 }
716735 if ( ! isRoot || hasNonAssignmentOperators ) {
717- return group ( indent ( level ) ) ;
736+ return indent ( level ) ;
718737 }
719738 const groupId = Symbol ( "assignment" ) ;
720- return group ( [
739+ return [
721740 level [ 0 ] ,
722741 group ( indent ( level [ 1 ] ) , { id : groupId } ) ,
723742 indentIfBreak ( level [ 2 ] , { groupId } )
724- ] ) ;
743+ ] ;
725744}
726745
727746const precedencesByOperator = new Map (
0 commit comments