5252import org .codehaus .groovy .ast .expr .AttributeExpression ;
5353import org .codehaus .groovy .ast .expr .BinaryExpression ;
5454import org .codehaus .groovy .ast .expr .BitwiseNegationExpression ;
55+ import org .codehaus .groovy .ast .expr .BooleanExpression ;
5556import org .codehaus .groovy .ast .expr .CastExpression ;
5657import org .codehaus .groovy .ast .expr .ClassExpression ;
5758import org .codehaus .groovy .ast .expr .ClosureExpression ;
185186import static org .codehaus .groovy .ast .tools .GeneralUtils .castX ;
186187import static org .codehaus .groovy .ast .tools .GeneralUtils .constX ;
187188import static org .codehaus .groovy .ast .tools .GeneralUtils .getSetterName ;
189+ import static org .codehaus .groovy .ast .tools .GeneralUtils .ifElseS ;
188190import static org .codehaus .groovy .ast .tools .GeneralUtils .isOrImplements ;
189191import static org .codehaus .groovy .ast .tools .GeneralUtils .localVarX ;
190192import static org .codehaus .groovy .ast .tools .GeneralUtils .thisPropX ;
219221import static org .codehaus .groovy .syntax .Types .KEYWORD_IN ;
220222import static org .codehaus .groovy .syntax .Types .KEYWORD_INSTANCEOF ;
221223import static org .codehaus .groovy .syntax .Types .LEFT_SQUARE_BRACKET ;
224+ import static org .codehaus .groovy .syntax .Types .LOGICAL_OR ;
222225import static org .codehaus .groovy .syntax .Types .MINUS_MINUS ;
223226import static org .codehaus .groovy .syntax .Types .MOD ;
224227import static org .codehaus .groovy .syntax .Types .MOD_EQUAL ;
@@ -3793,21 +3796,8 @@ protected void typeCheckClosureCall(final Expression callArguments, final ClassN
37933796 @ Override
37943797 public void visitIfElse (final IfStatement ifElse ) {
37953798 Map <VariableExpression , List <ClassNode >> oldTracker = pushAssignmentTracking ();
3796-
37973799 try {
3798- // create a new temporary element in the if-then-else type info
3799- typeCheckingContext .pushTemporaryTypeInfo ();
3800- visitStatement (ifElse );
3801- ifElse .getBooleanExpression ().visit (this );
3802- ifElse .getIfBlock ().visit (this );
3803-
3804- // pop if-then-else temporary type info
3805- typeCheckingContext .popTemporaryTypeInfo ();
3806-
3807- // GROOVY-6099: restore assignment info as before the if branch
3808- restoreTypeBeforeConditional ();
3809-
3810- ifElse .getElseBlock ().visit (this );
3800+ visitIfElseMaybeOrBranches (ifElse , true );
38113801 } finally {
38123802 popAssignmentTracking (oldTracker );
38133803 }
@@ -3822,6 +3812,52 @@ public void visitIfElse(final IfStatement ifElse) {
38223812 }
38233813 }
38243814
3815+ private void visitIfElseMaybeOrBranches (IfStatement ifElse , boolean topLevel ) {
3816+ BooleanExpression condition = ifElse .getBooleanExpression ();
3817+ BinaryExpression lor = null ;
3818+ if (condition .getExpression () instanceof BinaryExpression ) {
3819+ lor = (BinaryExpression ) condition .getExpression ();
3820+ if (lor .getOperation ().getType () != LOGICAL_OR ) {
3821+ lor = null ;
3822+ }
3823+ }
3824+ // for logical OR, any one branch may be true branch, so traverse separately
3825+ if (lor != null ) {
3826+ IfStatement left = ifElseS (lor .getLeftExpression (), ifElse .getIfBlock (), ifElse .getElseBlock ());
3827+ // left.setSourcePosition(ifElse);
3828+ typeCheckingContext .pushTemporaryTypeInfo ();
3829+ visitIfElseMaybeOrBranches (left , false );
3830+ typeCheckingContext .popTemporaryTypeInfo ();
3831+ restoreTypeBeforeConditional ();
3832+ IfStatement right = ifElseS (lor .getRightExpression (), ifElse .getIfBlock (), ifElse .getElseBlock ());
3833+ // right.setSourcePosition(ifElse);
3834+ typeCheckingContext .pushTemporaryTypeInfo ();
3835+ visitIfElseMaybeOrBranches (right , false );
3836+ typeCheckingContext .popTemporaryTypeInfo ();
3837+ restoreTypeBeforeConditional ();
3838+ }
3839+ if (topLevel || lor == null ) {
3840+ // do it all again to get correct union type for casting (hush warnings?)
3841+ visitIfElseBranches (ifElse );
3842+ }
3843+ }
3844+
3845+ private void visitIfElseBranches (IfStatement ifElse ) {
3846+ // create a new temporary element in the if-then-else type info
3847+ typeCheckingContext .pushTemporaryTypeInfo ();
3848+ visitStatement (ifElse );
3849+ ifElse .getBooleanExpression ().visit (this );
3850+ ifElse .getIfBlock ().visit (this );
3851+
3852+ // pop if-then-else temporary type info
3853+ typeCheckingContext .popTemporaryTypeInfo ();
3854+
3855+ // GROOVY-6099: restore assignment info as before the if branch
3856+ restoreTypeBeforeConditional ();
3857+
3858+ ifElse .getElseBlock ().visit (this );
3859+ }
3860+
38253861 protected void visitInstanceofNot (final BinaryExpression be ) {
38263862 BlockStatement currentBlock = typeCheckingContext .enclosingBlocks .getFirst ();
38273863 assert currentBlock != null ;
0 commit comments