<s> package org . eclipse . jdt . internal . compiler . ast ; import org . eclipse . jdt . internal . compiler . ASTVisitor ; import org . eclipse . jdt . internal . compiler . impl . * ; import org . eclipse . jdt . internal . compiler . codegen . * ; import org . eclipse . jdt . internal . compiler . flow . * ; import org . eclipse . jdt . internal . compiler . lookup . * ; public class OR_OR_Expression extends BinaryExpression { int rightInitStateIndex = - 1 ; int mergedInitStateIndex = - 1 ; public OR_OR_Expression ( Expression left , Expression right , int operator ) { super ( left , right , operator ) ; } public FlowInfo analyseCode ( BlockScope currentScope , FlowContext flowContext , FlowInfo flowInfo ) { Constant cst = this . left . optimizedBooleanConstant ( ) ; boolean isLeftOptimizedTrue = cst != Constant . NotAConstant && cst . booleanValue ( ) == true ; boolean isLeftOptimizedFalse = cst != Constant . NotAConstant && cst . booleanValue ( ) == false ; if ( isLeftOptimizedFalse ) { FlowInfo mergedInfo = this . left . analyseCode ( currentScope , flowContext , flowInfo ) . unconditionalInits ( ) ; mergedInfo = this . right . analyseCode ( currentScope , flowContext , mergedInfo ) ; this . mergedInitStateIndex = currentScope . methodScope ( ) . recordInitializationStates ( mergedInfo ) ; return mergedInfo ; } FlowInfo leftInfo = this . left . analyseCode ( currentScope , flowContext , flowInfo ) ; FlowInfo rightInfo = leftInfo . initsWhenFalse ( ) . unconditionalCopy ( ) ; this . rightInitStateIndex = currentScope . methodScope ( ) . recordInitializationStates ( rightInfo ) ; int previousMode = rightInfo . reachMode ( ) ; if ( isLeftOptimizedTrue ) { if ( ( rightInfo . reachMode ( ) & FlowInfo . UNREACHABLE ) == 0 ) { currentScope . problemReporter ( ) . fakeReachable ( this . right ) ; rightInfo . setReachMode ( FlowInfo . UNREACHABLE_OR_DEAD ) ; } } rightInfo = this . right . analyseCode ( currentScope , flowContext , rightInfo ) ; if ( ( this . left . implicitConversion & TypeIds . UNBOXING ) != 0 ) { this . left . checkNPE ( currentScope , flowContext , flowInfo ) ; } if ( ( this . right . implicitConversion & TypeIds . UNBOXING ) != 0 ) { this . right . checkNPE ( currentScope , flowContext , flowInfo ) ; } FlowInfo leftInfoWhenTrueForMerging = leftInfo . initsWhenTrue ( ) . unconditionalCopy ( ) . addPotentialInitializationsFrom ( rightInfo . unconditionalInitsWithoutSideEffect ( ) ) ; FlowInfo mergedInfo = FlowInfo . conditional ( leftInfoWhenTrueForMerging . unconditionalInits ( ) . mergedWith ( rightInfo . safeInitsWhenTrue ( ) . setReachMode ( previousMode ) . unconditionalInits ( ) ) , rightInfo . initsWhenFalse ( ) ) ; this . mergedInitStateIndex = currentScope . methodScope ( ) . recordInitializationStates ( mergedInfo ) ; return mergedInfo ; } public void generateCode ( BlockScope currentScope , CodeStream codeStream , boolean valueRequired ) { int pc = codeStream . position ; if ( this . constant != Constant . NotAConstant ) { if ( valueRequired ) codeStream . generateConstant ( this . constant , this . implicitConversion ) ; codeStream . recordPositionsFrom ( pc , this . sourceStart ) ; return ; } Constant cst = this . right . constant ; if ( cst != Constant . NotAConstant ) { if ( cst . booleanValue ( ) == true ) { this . left . generateCode ( currentScope , codeStream , false ) ; if ( valueRequired ) codeStream . iconst_1 ( ) ; } else { this . left . generateCode ( currentScope , codeStream , valueRequired ) ; } if ( this . mergedInitStateIndex != - 1 ) { codeStream . removeNotDefinitelyAssignedVariables ( currentScope , this . mergedInitStateIndex ) ; } codeStream . generateImplicitConversion ( this . implicitConversion ) ; codeStream . updateLastRecordedEndPC ( currentScope , codeStream . position ) ; codeStream . recordPositionsFrom ( pc , this . sourceStart ) ; return ; } BranchLabel trueLabel = new BranchLabel ( codeStream ) , endLabel ; cst = this . left . optimizedBooleanConstant ( ) ; boolean leftIsConst = cst != Constant . NotAConstant ; boolean leftIsTrue = leftIsConst && cst . booleanValue ( ) == true ; cst = this . right . optimizedBooleanConstant ( ) ; boolean rightIsConst = cst != Constant . NotAConstant ; boolean rightIsTrue = rightIsConst && cst . booleanValue ( ) == true ; generateOperands : { if ( leftIsConst ) { this . left . generateCode ( currentScope , codeStream , false ) ; if ( leftIsTrue ) { break generateOperands ; } } else { this . left . generateOptimizedBoolean ( currentScope , codeStream , trueLabel , null , true ) ; } if ( this . rightInitStateIndex != - 1 ) { codeStream . addDefinitelyAssignedVariables ( currentScope , this . rightInitStateIndex ) ; } if ( rightIsConst ) { this . right . generateCode ( currentScope , codeStream , false ) ; } else { this . right . generateOptimizedBoolean ( currentScope , codeStream , trueLabel , null , valueRequired ) ; } } if ( this . mergedInitStateIndex != - 1 ) { codeStream . removeNotDefinitelyAssignedVariables ( currentScope , this . mergedInitStateIndex ) ; } if ( valueRequired ) { if ( leftIsConst && leftIsTrue ) { codeStream . iconst_1 ( ) ; codeStream . updateLastRecordedEndPC ( currentScope , codeStream . position ) ; } else { if ( rightIsConst && rightIsTrue ) { codeStream . iconst_1 ( ) ; codeStream . updateLastRecordedEndPC ( currentScope , codeStream . position ) ; } else { codeStream . iconst_0 ( ) ; } if ( trueLabel . forwardReferenceCount ( ) > 0 ) { if ( ( this . bits & IsReturnedValue ) != 0 ) { codeStream . generateImplicitConversion ( this . implicitConversion ) ; codeStream . generateReturnBytecode ( this ) ; trueLabel . place ( ) ; codeStream . iconst_1 ( ) ; } else { codeStream . goto_ ( endLabel = new BranchLabel ( codeStream ) ) ; codeStream . decrStackSize ( 1 ) ; trueLabel . place ( ) ; codeStream . iconst_1 ( ) ; endLabel . place ( ) ; } } else { trueLabel . place ( ) ; } } codeStream . generateImplicitConversion ( this . implicitConversion ) ; codeStream . updateLastRecordedEndPC ( currentScope , codeStream . position ) ; } else { trueLabel . place ( ) ; } } public void generateOptimizedBoolean ( BlockScope currentScope , CodeStream codeStream , BranchLabel trueLabel , BranchLabel falseLabel , boolean valueRequired ) { if ( this . constant != Constant . NotAConstant ) { super . generateOptimizedBoolean ( currentScope , codeStream , trueLabel , falseLabel , valueRequired ) ; return ; } Constant cst = this . right . constant ; if ( cst != Constant . NotAConstant && cst . booleanValue ( ) == false ) { int pc = codeStream . position ; this . left . generateOptimizedBoolean ( currentScope , codeStream , trueLabel , falseLabel , valueRequired ) ; if ( this . mergedInitStateIndex != - 1 ) { codeStream . removeNotDefinitelyAssignedVariables ( currentScope , this . mergedInitStateIndex ) ; } codeStream . recordPositionsFrom ( pc , this . sourceStart ) ; return ; } cst = this . left . optimizedBooleanConstant ( ) ; boolean leftIsConst = cst != Constant . NotAConstant ; boolean leftIsTrue = leftIsConst && cst . booleanValue ( ) == true ; cst = this . right . optimizedBooleanConstant ( ) ; boolean rightIsConst = cst != Constant . NotAConstant ; boolean rightIsTrue = rightIsConst && cst . booleanValue ( ) == true ; generateOperands : { if ( falseLabel == null ) { if ( trueLabel != null ) { this . left . generateOptimizedBoolean ( currentScope , codeStream , trueLabel , null , ! leftIsConst ) ; if ( leftIsTrue ) { if ( valueRequired ) codeStream . goto_ ( trueLabel ) ; codeStream . updateLastRecordedEndPC ( currentScope , codeStream . position ) ; break generateOperands ; } if ( this . rightInitStateIndex != - 1 ) { codeStream . addDefinitelyAssignedVariables ( currentScope , this . rightInitStateIndex ) ; } this . right . generateOptimizedBoolean ( currentScope , codeStream , trueLabel , null , valueRequired && ! rightIsConst ) ; if ( valueRequired && rightIsTrue ) { codeStream . goto_ ( trueLabel ) ; codeStream . updateLastRecordedEndPC ( currentScope , codeStream . position ) ; } } } else { if ( trueLabel == null ) { BranchLabel internalTrueLabel = new BranchLabel ( codeStream ) ; this . left . generateOptimizedBoolean ( currentScope , codeStream , internalTrueLabel , null , ! leftIsConst ) ; if ( leftIsTrue ) { internalTrueLabel . place ( ) ; break generateOperands ; } if ( this . rightInitStateIndex != - 1 ) { codeStream . addDefinitelyAssignedVariables ( currentScope , this . rightInitStateIndex ) ; } this . right . generateOptimizedBoolean ( currentScope , codeStream , null , falseLabel , valueRequired && ! rightIsConst ) ; if ( valueRequired && rightIsConst && ! rightIsTrue ) { codeStream . goto_ ( falseLabel ) ; codeStream . updateLastRecordedEndPC ( currentScope , codeStream . position ) ; } internalTrueLabel . place ( ) ; } else { } } } if ( this . mergedInitStateIndex != - 1 ) { codeStream . removeNotDefinitelyAssignedVariables ( currentScope , this . mergedInitStateIndex ) ; } } public boolean isCompactableOperation ( ) { return false ; } public TypeBinding resolveType ( BlockScope scope ) { TypeBinding result = super . resolveType ( scope ) ; Binding leftDirect = Expression . getDirectBinding ( this . left ) ; if ( leftDirect != null && leftDirect == Expression . getDirectBinding ( this . right ) ) { if ( ! ( this . right instanceof Assignment ) ) scope . problemReporter ( ) . comparingIdenticalExpressions ( this ) ; } return result ; } public void traverse ( ASTVisitor visitor , BlockScope scope ) { if ( visitor . visit ( this , scope ) ) { this . left . traverse ( visitor , scope ) ; this . right . traverse ( visitor , scope ) ; } visitor . endVisit ( this , scope ) ; } } </s>