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 ;
184185import static org .codehaus .groovy .ast .tools .GeneralUtils .castX ;
185186import static org .codehaus .groovy .ast .tools .GeneralUtils .constX ;
186187import static org .codehaus .groovy .ast .tools .GeneralUtils .getSetterName ;
188+ import static org .codehaus .groovy .ast .tools .GeneralUtils .ifElseS ;
187189import static org .codehaus .groovy .ast .tools .GeneralUtils .isOrImplements ;
188190import static org .codehaus .groovy .ast .tools .GeneralUtils .localVarX ;
189191import static org .codehaus .groovy .ast .tools .GeneralUtils .thisPropX ;
218220import static org .codehaus .groovy .syntax .Types .KEYWORD_IN ;
219221import static org .codehaus .groovy .syntax .Types .KEYWORD_INSTANCEOF ;
220222import static org .codehaus .groovy .syntax .Types .LEFT_SQUARE_BRACKET ;
223+ import static org .codehaus .groovy .syntax .Types .LOGICAL_OR ;
221224import static org .codehaus .groovy .syntax .Types .MINUS_MINUS ;
222225import static org .codehaus .groovy .syntax .Types .MOD ;
223226import static org .codehaus .groovy .syntax .Types .MOD_EQUAL ;
@@ -3798,21 +3801,8 @@ protected void typeCheckClosureCall(final Expression callArguments, final ClassN
37983801 @ Override
37993802 public void visitIfElse (final IfStatement ifElse ) {
38003803 Map <VariableExpression , List <ClassNode >> oldTracker = pushAssignmentTracking ();
3801-
38023804 try {
3803- // create a new temporary element in the if-then-else type info
3804- typeCheckingContext .pushTemporaryTypeInfo ();
3805- visitStatement (ifElse );
3806- ifElse .getBooleanExpression ().visit (this );
3807- ifElse .getIfBlock ().visit (this );
3808-
3809- // pop if-then-else temporary type info
3810- typeCheckingContext .popTemporaryTypeInfo ();
3811-
3812- // GROOVY-6099: restore assignment info as before the if branch
3813- restoreTypeBeforeConditional ();
3814-
3815- ifElse .getElseBlock ().visit (this );
3805+ visitIfElseMaybeOrBranches (ifElse , true );
38163806 } finally {
38173807 popAssignmentTracking (oldTracker );
38183808 }
@@ -3827,6 +3817,52 @@ public void visitIfElse(final IfStatement ifElse) {
38273817 }
38283818 }
38293819
3820+ private void visitIfElseMaybeOrBranches (IfStatement ifElse , boolean topLevel ) {
3821+ BooleanExpression condition = ifElse .getBooleanExpression ();
3822+ BinaryExpression lor = null ;
3823+ if (condition .getExpression () instanceof BinaryExpression ) {
3824+ lor = (BinaryExpression ) condition .getExpression ();
3825+ if (lor .getOperation ().getType () != LOGICAL_OR ) {
3826+ lor = null ;
3827+ }
3828+ }
3829+ // for logical OR, any one branch may be true branch, so traverse separately
3830+ if (lor != null ) {
3831+ IfStatement left = ifElseS (lor .getLeftExpression (), ifElse .getIfBlock (), ifElse .getElseBlock ());
3832+ // left.setSourcePosition(ifElse);
3833+ typeCheckingContext .pushTemporaryTypeInfo ();
3834+ visitIfElseMaybeOrBranches (left , false );
3835+ typeCheckingContext .popTemporaryTypeInfo ();
3836+ restoreTypeBeforeConditional ();
3837+ IfStatement right = ifElseS (lor .getRightExpression (), ifElse .getIfBlock (), ifElse .getElseBlock ());
3838+ // right.setSourcePosition(ifElse);
3839+ typeCheckingContext .pushTemporaryTypeInfo ();
3840+ visitIfElseMaybeOrBranches (right , false );
3841+ typeCheckingContext .popTemporaryTypeInfo ();
3842+ restoreTypeBeforeConditional ();
3843+ }
3844+ if (topLevel || lor == null ) {
3845+ // do it all again to get correct union type for casting (hush warnings?)
3846+ visitIfElseBranches (ifElse );
3847+ }
3848+ }
3849+
3850+ private void visitIfElseBranches (IfStatement ifElse ) {
3851+ // create a new temporary element in the if-then-else type info
3852+ typeCheckingContext .pushTemporaryTypeInfo ();
3853+ visitStatement (ifElse );
3854+ ifElse .getBooleanExpression ().visit (this );
3855+ ifElse .getIfBlock ().visit (this );
3856+
3857+ // pop if-then-else temporary type info
3858+ typeCheckingContext .popTemporaryTypeInfo ();
3859+
3860+ // GROOVY-6099: restore assignment info as before the if branch
3861+ restoreTypeBeforeConditional ();
3862+
3863+ ifElse .getElseBlock ().visit (this );
3864+ }
3865+
38303866 protected void visitInstanceofNot (final BinaryExpression be ) {
38313867 BlockStatement currentBlock = typeCheckingContext .enclosingBlocks .getFirst ();
38323868 assert currentBlock != null ;
0 commit comments