<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 . classfmt . ClassFileConstants ; import org . eclipse . jdt . internal . compiler . codegen . * ; import org . eclipse . jdt . internal . compiler . flow . * ; import org . eclipse . jdt . internal . compiler . lookup . * ; public class WhileStatement extends Statement { public Expression condition ; public Statement action ; private BranchLabel breakLabel , continueLabel ; int preCondInitStateIndex = - 1 ; int condIfTrueInitStateIndex = - 1 ; int mergedInitStateIndex = - 1 ; public WhileStatement ( Expression condition , Statement action , int s , int e ) { this . condition = condition ; this . action = action ; if ( action instanceof EmptyStatement ) action . bits |= IsUsefulEmptyStatement ; this . sourceStart = s ; this . sourceEnd = e ; } public FlowInfo analyseCode ( BlockScope currentScope , FlowContext flowContext , FlowInfo flowInfo ) { this . breakLabel = new BranchLabel ( ) ; this . continueLabel = new BranchLabel ( ) ; int initialComplaintLevel = ( flowInfo . reachMode ( ) & FlowInfo . UNREACHABLE ) != 0 ? Statement . COMPLAINED_FAKE_REACHABLE : Statement . NOT_COMPLAINED ; Constant cst = this . condition . constant ; boolean isConditionTrue = cst != Constant . NotAConstant && cst . booleanValue ( ) == true ; boolean isConditionFalse = cst != Constant . NotAConstant && cst . booleanValue ( ) == false ; cst = this . condition . optimizedBooleanConstant ( ) ; boolean isConditionOptimizedTrue = cst != Constant . NotAConstant && cst . booleanValue ( ) == true ; boolean isConditionOptimizedFalse = cst != Constant . NotAConstant && cst . booleanValue ( ) == false ; this . preCondInitStateIndex = currentScope . methodScope ( ) . recordInitializationStates ( flowInfo ) ; LoopingFlowContext condLoopContext ; FlowInfo condInfo = flowInfo . nullInfoLessUnconditionalCopy ( ) ; condInfo = this . condition . analyseCode ( currentScope , ( condLoopContext = new LoopingFlowContext ( flowContext , flowInfo , this , null , null , currentScope ) ) , condInfo ) ; LoopingFlowContext loopingContext ; FlowInfo actionInfo ; FlowInfo exitBranch ; if ( this . action == null || ( this . action . isEmptyBlock ( ) && currentScope . compilerOptions ( ) . complianceLevel <= ClassFileConstants . JDK1_3 ) ) { condLoopContext . complainOnDeferredFinalChecks ( currentScope , condInfo ) ; condLoopContext . complainOnDeferredNullChecks ( currentScope , condInfo . unconditionalInits ( ) ) ; if ( isConditionTrue ) { return FlowInfo . DEAD_END ; } else { FlowInfo mergedInfo = flowInfo . copy ( ) . addInitializationsFrom ( condInfo . initsWhenFalse ( ) ) ; if ( isConditionOptimizedTrue ) { mergedInfo . setReachMode ( FlowInfo . UNREACHABLE ) ; } this . mergedInitStateIndex = currentScope . methodScope ( ) . recordInitializationStates ( mergedInfo ) ; return mergedInfo ; } } else { loopingContext = new LoopingFlowContext ( flowContext , flowInfo , this , this . breakLabel , this . continueLabel , currentScope ) ; if ( isConditionFalse ) { actionInfo = FlowInfo . DEAD_END ; } else { actionInfo = condInfo . initsWhenTrue ( ) . copy ( ) ; if ( isConditionOptimizedFalse ) { actionInfo . setReachMode ( FlowInfo . UNREACHABLE ) ; } } this . condIfTrueInitStateIndex = currentScope . methodScope ( ) . recordInitializationStates ( condInfo . initsWhenTrue ( ) ) ; if ( this . action . complainIfUnreachable ( actionInfo , currentScope , initialComplaintLevel ) < Statement . COMPLAINED_UNREACHABLE ) { actionInfo = this . action . analyseCode ( currentScope , loopingContext , actionInfo ) ; } exitBranch = flowInfo . copy ( ) ; if ( ( actionInfo . tagBits & loopingContext . initsOnContinue . tagBits & FlowInfo . UNREACHABLE ) != 0 ) { this . continueLabel = null ; exitBranch . addInitializationsFrom ( condInfo . initsWhenFalse ( ) ) ; } else { condLoopContext . complainOnDeferredFinalChecks ( currentScope , condInfo ) ; actionInfo = actionInfo . mergedWith ( loopingContext . initsOnContinue . unconditionalInits ( ) ) ; condLoopContext . complainOnDeferredNullChecks ( currentScope , actionInfo ) ; loopingContext . complainOnDeferredFinalChecks ( currentScope , actionInfo ) ; loopingContext . complainOnDeferredNullChecks ( currentScope , actionInfo ) ; exitBranch . addPotentialInitializationsFrom ( actionInfo . unconditionalInits ( ) ) . addInitializationsFrom ( condInfo . initsWhenFalse ( ) ) ; } if ( loopingContext . hasEscapingExceptions ( ) ) { FlowInfo loopbackFlowInfo = flowInfo . copy ( ) ; if ( this . continueLabel != null ) { loopbackFlowInfo . mergedWith ( actionInfo . unconditionalCopy ( ) ) ; } loopingContext . simulateThrowAfterLoopBack ( loopbackFlowInfo ) ; } } FlowInfo mergedInfo = FlowInfo . mergedOptimizedBranches ( ( loopingContext . initsOnBreak . tagBits & FlowInfo . UNREACHABLE ) != 0 ? loopingContext . initsOnBreak : flowInfo . addInitializationsFrom ( loopingContext . initsOnBreak ) , isConditionOptimizedTrue , exitBranch , isConditionOptimizedFalse , ! isConditionTrue ) ; this . mergedInitStateIndex = currentScope . methodScope ( ) . recordInitializationStates ( mergedInfo ) ; return mergedInfo ; } public void generateCode ( BlockScope currentScope , CodeStream codeStream ) { if ( ( this . bits & IsReachable ) == 0 ) { return ; } int pc = codeStream . position ; Constant cst = this . condition . optimizedBooleanConstant ( ) ; boolean isConditionOptimizedFalse = cst != Constant . NotAConstant && cst . booleanValue ( ) == false ; if ( isConditionOptimizedFalse ) { this . condition . generateCode ( currentScope , codeStream , false ) ; if ( this . mergedInitStateIndex != - 1 ) { codeStream . removeNotDefinitelyAssignedVariables ( currentScope , this . mergedInitStateIndex ) ; codeStream . addDefinitelyAssignedVariables ( currentScope , this . mergedInitStateIndex ) ; } codeStream . recordPositionsFrom ( pc , this . sourceStart ) ; return ; } this . breakLabel . initialize ( codeStream ) ; if ( this . continueLabel == null ) { if ( this . condition . constant == Constant . NotAConstant ) { this . condition . generateOptimizedBoolean ( currentScope , codeStream , null , this . breakLabel , true ) ; } } else { this . continueLabel . initialize ( codeStream ) ; if ( ! ( ( ( this . condition . constant != Constant . NotAConstant ) && ( this . condition . constant . booleanValue ( ) == true ) ) || ( this . action == null ) || this . action . isEmptyBlock ( ) ) ) { int jumpPC = codeStream . position ; codeStream . goto_ ( this . continueLabel ) ; codeStream . recordPositionsFrom ( jumpPC , this . condition . sourceStart ) ; } } BranchLabel actionLabel = new BranchLabel ( codeStream ) ; if ( this . action != null ) { actionLabel . tagBits |= BranchLabel . USED ; if ( this . condIfTrueInitStateIndex != - 1 ) { codeStream . addDefinitelyAssignedVariables ( currentScope , this . condIfTrueInitStateIndex ) ; } actionLabel . place ( ) ; this . action . generateCode ( currentScope , codeStream ) ; if ( this . preCondInitStateIndex != - 1 ) { codeStream . removeNotDefinitelyAssignedVariables ( currentScope , this . preCondInitStateIndex ) ; } } else { actionLabel . place ( ) ; } if ( this . continueLabel != null ) { this . continueLabel . place ( ) ; this . condition . generateOptimizedBoolean ( currentScope , codeStream , actionLabel , null , true ) ; } if ( this . mergedInitStateIndex != - 1 ) { codeStream . removeNotDefinitelyAssignedVariables ( currentScope , this . mergedInitStateIndex ) ; codeStream . addDefinitelyAssignedVariables ( currentScope , this . mergedInitStateIndex ) ; } this . breakLabel . place ( ) ; codeStream . recordPositionsFrom ( pc , this . sourceStart ) ; } public void resolve ( BlockScope scope ) { TypeBinding type = this . condition . resolveTypeExpecting ( scope , TypeBinding . BOOLEAN ) ; this . condition . computeConversion ( scope , type , type ) ; if ( this . action != null ) this . action . resolve ( scope ) ; } public StringBuffer printStatement ( int tab , StringBuffer output ) { printIndent ( tab , output ) . append ( "while (" ) ; this . condition . printExpression ( 0 , output ) . append ( ')' ) ; if ( this . action == null ) output . append ( ';' ) ; else this . action . printStatement ( tab + 1 , output ) ; return output ; } public void traverse ( ASTVisitor visitor , BlockScope blockScope ) { if ( visitor . visit ( this , blockScope ) ) { this . condition . traverse ( visitor , blockScope ) ; if ( this . action != null ) this . action . traverse ( visitor , blockScope ) ; } visitor . endVisit ( this , blockScope ) ; } } </s>