11import type {
2+ BinaryExpressionCstNode ,
23 FqnOrRefTypeCtx ,
4+ PrimaryCstNode ,
35 StringTemplateCstNode ,
46 TextBlockTemplateCstNode
57} from "java-parser" ;
@@ -12,6 +14,7 @@ import {
1214 each ,
1315 findBaseIndent ,
1416 flatMap ,
17+ hasAssignmentOperators ,
1518 hasLeadingComments ,
1619 hasNonAssignmentOperators ,
1720 indentInParentheses ,
@@ -117,8 +120,11 @@ export default {
117120
118121 conditionalExpression ( path , print , options ) {
119122 const binaryExpression = call ( path , print , "binaryExpression" ) ;
123+ const grandparentNodeName = ( path . getNode ( 4 ) as JavaNonTerminal | null )
124+ ?. name ;
125+ const isInParentheses = grandparentNodeName === "parenthesisExpression" ;
120126 if ( ! path . node . children . QuestionMark ) {
121- return binaryExpression ;
127+ return isInParentheses ? binaryExpression : group ( binaryExpression ) ;
122128 }
123129 const [ consequent , alternate ] = map ( path , print , "expression" ) ;
124130 const suffix = [
@@ -127,16 +133,16 @@ export default {
127133 line ,
128134 [ ": " , options . useTabs ? indent ( alternate ) : align ( 2 , alternate ) ]
129135 ] ;
130- const isNestedTernary =
131- ( path . getNode ( 4 ) as JavaNonTerminal | null ) ?. name ===
132- "conditionalExpression" ;
136+ const isNestedTernary = grandparentNodeName === "conditionalExpression" ;
133137 const alignedSuffix =
134138 ! isNestedTernary || options . useTabs
135139 ? suffix
136140 : align ( Math . max ( 0 , options . tabWidth - 2 ) , suffix ) ;
137- return isNestedTernary
138- ? [ binaryExpression , alignedSuffix ]
139- : group ( [ binaryExpression , indent ( alignedSuffix ) ] ) ;
141+ if ( isNestedTernary ) {
142+ return [ group ( binaryExpression ) , alignedSuffix ] ;
143+ }
144+ const parts = [ group ( binaryExpression ) , indent ( alignedSuffix ) ] ;
145+ return isInParentheses ? parts : group ( parts ) ;
140146 } ,
141147
142148 binaryExpression ( path , print , options ) {
@@ -373,20 +379,39 @@ export default {
373379
374380 parenthesisExpression ( path , print ) {
375381 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 ;
382+ const primaryAncestor = path . getNode ( 4 ) as PrimaryCstNode | null ;
383+ const binaryExpressionAncestor = path . getNode (
384+ 8
385+ ) as BinaryExpressionCstNode | null ;
386+ const outerAncestor = path . getNode ( 14 ) as JavaNonTerminal | null ;
378387 const { conditionalExpression, lambdaExpression } =
379388 path . node . children . expression [ 0 ] . children ;
380389 const hasLambda = lambdaExpression !== undefined ;
381390 const hasTernary =
382391 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 ) , ")" ] ;
392+ const hasSuffix = primaryAncestor ?. children . primarySuffix !== undefined ;
393+ const isAssignment =
394+ ( outerAncestor ?. name === "binaryExpression" &&
395+ hasAssignmentOperators ( outerAncestor ) ) ||
396+ outerAncestor ?. name === "variableInitializer" ;
397+ if ( ! hasLambda && hasSuffix && ( ! hasTernary || isAssignment ) ) {
398+ return indentInParentheses ( hasTernary ? group ( expression ) : expression ) ;
399+ } else if (
400+ binaryExpressionAncestor &&
401+ Object . keys ( binaryExpressionAncestor . children ) . length === 1 &&
402+ outerAncestor &&
403+ [ "guard" , "returnStatement" ] . includes ( outerAncestor . name )
404+ ) {
405+ return indentInParentheses ( group ( expression ) ) ;
406+ } else if ( hasTernary && hasSuffix && ! isAssignment ) {
407+ return group ( [ "(" , expression , softline , ")" ] ) ;
408+ } else {
409+ return group ( [
410+ "(" ,
411+ hasLambda || hasTernary ? expression : indent ( expression ) ,
412+ ")"
413+ ] ) ;
414+ }
390415 } ,
391416
392417 castExpression : printSingle ,
@@ -699,8 +724,8 @@ function binary(
699724 operands . unshift (
700725 levelOperator !== undefined &&
701726 needsParentheses ( nextOperator , levelOperator )
702- ? [ "(" , indent ( content ) , ")" ]
703- : content
727+ ? [ "(" , group ( indent ( content ) ) , ")" ]
728+ : group ( content )
704729 ) ;
705730 }
706731 }
@@ -711,17 +736,17 @@ function binary(
711736 ! isAssignmentOperator ( levelOperator ) &&
712737 levelOperator !== "instanceof" )
713738 ) {
714- return group ( level ) ;
739+ return level ;
715740 }
716741 if ( ! isRoot || hasNonAssignmentOperators ) {
717- return group ( indent ( level ) ) ;
742+ return indent ( level ) ;
718743 }
719744 const groupId = Symbol ( "assignment" ) ;
720- return group ( [
745+ return [
721746 level [ 0 ] ,
722747 group ( indent ( level [ 1 ] ) , { id : groupId } ) ,
723748 indentIfBreak ( level [ 2 ] , { groupId } )
724- ] ) ;
749+ ] ;
725750}
726751
727752const precedencesByOperator = new Map (
0 commit comments