<s> package org . eclipse . jdt . internal . compiler . flow ; import java . util . ArrayList ; import org . eclipse . jdt . internal . compiler . ast . ASTNode ; import org . eclipse . jdt . internal . compiler . ast . Expression ; import org . eclipse . jdt . internal . compiler . ast . Reference ; import org . eclipse . jdt . internal . compiler . codegen . BranchLabel ; import org . eclipse . jdt . internal . compiler . lookup . BlockScope ; import org . eclipse . jdt . internal . compiler . lookup . FieldBinding ; import org . eclipse . jdt . internal . compiler . lookup . LocalVariableBinding ; import org . eclipse . jdt . internal . compiler . lookup . ReferenceBinding ; import org . eclipse . jdt . internal . compiler . lookup . Scope ; import org . eclipse . jdt . internal . compiler . lookup . TypeIds ; import org . eclipse . jdt . internal . compiler . lookup . VariableBinding ; public class LoopingFlowContext extends SwitchFlowContext { public BranchLabel continueLabel ; public UnconditionalFlowInfo initsOnContinue = FlowInfo . DEAD_END ; private UnconditionalFlowInfo upstreamNullFlowInfo ; private LoopingFlowContext innerFlowContexts [ ] = null ; private UnconditionalFlowInfo innerFlowInfos [ ] = null ; private int innerFlowContextsCount = 0 ; private LabelFlowContext breakTargetContexts [ ] = null ; private int breakTargetsCount = 0 ; Reference finalAssignments [ ] ; VariableBinding finalVariables [ ] ; int assignCount = 0 ; LocalVariableBinding [ ] nullLocals ; Expression [ ] nullReferences ; int [ ] nullCheckTypes ; int nullCount ; static private class EscapingExceptionCatchSite { final ReferenceBinding caughtException ; final ExceptionHandlingFlowContext catchingContext ; public EscapingExceptionCatchSite ( ExceptionHandlingFlowContext catchingContext , ReferenceBinding caughtException ) { this . catchingContext = catchingContext ; this . caughtException = caughtException ; } void simulateThrowAfterLoopBack ( FlowInfo flowInfo ) { this . catchingContext . recordHandlingException ( this . caughtException , flowInfo . unconditionalInits ( ) , null , null , null , true ) ; } } private ArrayList escapingExceptionCatchSites = null ; Scope associatedScope ; public LoopingFlowContext ( FlowContext parent , FlowInfo upstreamNullFlowInfo , ASTNode associatedNode , BranchLabel breakLabel , BranchLabel continueLabel , Scope associatedScope ) { super ( parent , associatedNode , breakLabel ) ; this . tagBits |= FlowContext . PREEMPT_NULL_DIAGNOSTIC ; this . continueLabel = continueLabel ; this . associatedScope = associatedScope ; this . upstreamNullFlowInfo = upstreamNullFlowInfo . unconditionalCopy ( ) ; } public void complainOnDeferredFinalChecks ( BlockScope scope , FlowInfo flowInfo ) { for ( int i = 0 ; i < this . assignCount ; i ++ ) { VariableBinding variable = this . finalVariables [ i ] ; if ( variable == null ) continue ; boolean complained = false ; if ( variable instanceof FieldBinding ) { if ( flowInfo . isPotentiallyAssigned ( ( FieldBinding ) variable ) ) { complained = true ; scope . problemReporter ( ) . duplicateInitializationOfBlankFinalField ( ( FieldBinding ) variable , this . finalAssignments [ i ] ) ; } } else { if ( flowInfo . isPotentiallyAssigned ( ( LocalVariableBinding ) variable ) ) { complained = true ; scope . problemReporter ( ) . duplicateInitializationOfFinalLocal ( ( LocalVariableBinding ) variable , this . finalAssignments [ i ] ) ; } } if ( complained ) { FlowContext context = this . parent ; while ( context != null ) { context . removeFinalAssignmentIfAny ( this . finalAssignments [ i ] ) ; context = context . parent ; } } } } public void complainOnDeferredNullChecks ( BlockScope scope , FlowInfo callerFlowInfo ) { for ( int i = 0 ; i < this . innerFlowContextsCount ; i ++ ) { this . upstreamNullFlowInfo . addPotentialNullInfoFrom ( this . innerFlowContexts [ i ] . upstreamNullFlowInfo ) . addPotentialNullInfoFrom ( this . innerFlowInfos [ i ] ) ; } this . innerFlowContextsCount = 0 ; UnconditionalFlowInfo flowInfo = this . upstreamNullFlowInfo . addPotentialNullInfoFrom ( callerFlowInfo . unconditionalInitsWithoutSideEffect ( ) ) ; if ( ( this . tagBits & FlowContext . DEFER_NULL_DIAGNOSTIC ) != 0 ) { for ( int i = 0 ; i < this . nullCount ; i ++ ) { LocalVariableBinding local = this . nullLocals [ i ] ; Expression expression = this . nullReferences [ i ] ; switch ( this . nullCheckTypes [ i ] ) { case CAN_ONLY_NON_NULL | IN_COMPARISON_NULL : case CAN_ONLY_NON_NULL | IN_COMPARISON_NON_NULL : if ( flowInfo . isDefinitelyNonNull ( local ) ) { this . nullReferences [ i ] = null ; if ( this . nullCheckTypes [ i ] == ( CAN_ONLY_NON_NULL | IN_COMPARISON_NON_NULL ) ) { if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableRedundantCheckOnNonNull ( local , expression ) ; } } else { if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableNonNullComparedToNull ( local , expression ) ; } } continue ; } break ; case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL : case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL : if ( flowInfo . isDefinitelyNonNull ( local ) ) { this . nullReferences [ i ] = null ; if ( this . nullCheckTypes [ i ] == ( CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL ) ) { if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableRedundantCheckOnNonNull ( local , expression ) ; } } else { if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableNonNullComparedToNull ( local , expression ) ; } } continue ; } if ( flowInfo . isDefinitelyNull ( local ) ) { this . nullReferences [ i ] = null ; if ( this . nullCheckTypes [ i ] == ( CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL ) ) { if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableRedundantCheckOnNull ( local , expression ) ; } } else { if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableNullComparedToNonNull ( local , expression ) ; } } continue ; } break ; case CAN_ONLY_NULL | IN_COMPARISON_NULL : case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL : case CAN_ONLY_NULL | IN_ASSIGNMENT : case CAN_ONLY_NULL | IN_INSTANCEOF : if ( flowInfo . isDefinitelyNull ( local ) ) { this . nullReferences [ i ] = null ; switch ( this . nullCheckTypes [ i ] & CONTEXT_MASK ) { case FlowContext . IN_COMPARISON_NULL : if ( ( ( this . nullCheckTypes [ i ] & CHECK_MASK ) == CAN_ONLY_NULL ) && ( expression . implicitConversion & TypeIds . UNBOXING ) != 0 ) { scope . problemReporter ( ) . localVariableNullReference ( local , expression ) ; continue ; } if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableRedundantCheckOnNull ( local , expression ) ; } continue ; case FlowContext . IN_COMPARISON_NON_NULL : if ( ( ( this . nullCheckTypes [ i ] & CHECK_MASK ) == CAN_ONLY_NULL ) && ( expression . implicitConversion & TypeIds . UNBOXING ) != 0 ) { scope . problemReporter ( ) . localVariableNullReference ( local , expression ) ; continue ; } if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableNullComparedToNonNull ( local , expression ) ; } continue ; case FlowContext . IN_ASSIGNMENT : scope . problemReporter ( ) . localVariableRedundantNullAssignment ( local , expression ) ; continue ; case FlowContext . IN_INSTANCEOF : scope . problemReporter ( ) . localVariableNullInstanceof ( local , expression ) ; continue ; } } else if ( flowInfo . isPotentiallyNull ( local ) ) { switch ( this . nullCheckTypes [ i ] & CONTEXT_MASK ) { case FlowContext . IN_COMPARISON_NULL : this . nullReferences [ i ] = null ; if ( ( ( this . nullCheckTypes [ i ] & CHECK_MASK ) == CAN_ONLY_NULL ) && ( expression . implicitConversion & TypeIds . UNBOXING ) != 0 ) { scope . problemReporter ( ) . localVariablePotentialNullReference ( local , expression ) ; continue ; } break ; case FlowContext . IN_COMPARISON_NON_NULL : this . nullReferences [ i ] = null ; if ( ( ( this . nullCheckTypes [ i ] & CHECK_MASK ) == CAN_ONLY_NULL ) && ( expression . implicitConversion & TypeIds . UNBOXING ) != 0 ) { scope . problemReporter ( ) . localVariablePotentialNullReference ( local , expression ) ; continue ; } break ; } } break ; case MAY_NULL : if ( flowInfo . isDefinitelyNull ( local ) ) { this . nullReferences [ i ] = null ; scope . problemReporter ( ) . localVariableNullReference ( local , expression ) ; continue ; } break ; default : } this . parent . recordUsingNullReference ( scope , local , expression , this . nullCheckTypes [ i ] , flowInfo ) ; } } else { for ( int i = 0 ; i < this . nullCount ; i ++ ) { Expression expression = this . nullReferences [ i ] ; LocalVariableBinding local = this . nullLocals [ i ] ; switch ( this . nullCheckTypes [ i ] ) { case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL : case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL : if ( flowInfo . isDefinitelyNonNull ( local ) ) { this . nullReferences [ i ] = null ; if ( this . nullCheckTypes [ i ] == ( CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL ) ) { if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableRedundantCheckOnNonNull ( local , expression ) ; } } else { if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableNonNullComparedToNull ( local , expression ) ; } } continue ; } case CAN_ONLY_NULL | IN_COMPARISON_NULL : case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL : case CAN_ONLY_NULL | IN_ASSIGNMENT : case CAN_ONLY_NULL | IN_INSTANCEOF : if ( flowInfo . isDefinitelyNull ( local ) ) { this . nullReferences [ i ] = null ; switch ( this . nullCheckTypes [ i ] & CONTEXT_MASK ) { case FlowContext . IN_COMPARISON_NULL : if ( ( ( this . nullCheckTypes [ i ] & CHECK_MASK ) == CAN_ONLY_NULL ) && ( expression . implicitConversion & TypeIds . UNBOXING ) != 0 ) { scope . problemReporter ( ) . localVariableNullReference ( local , expression ) ; continue ; } if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableRedundantCheckOnNull ( local , expression ) ; } continue ; case FlowContext . IN_COMPARISON_NON_NULL : if ( ( ( this . nullCheckTypes [ i ] & CHECK_MASK ) == CAN_ONLY_NULL ) && ( expression . implicitConversion & TypeIds . UNBOXING ) != 0 ) { scope . problemReporter ( ) . localVariableNullReference ( local , expression ) ; continue ; } if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableNullComparedToNonNull ( local , expression ) ; } continue ; case FlowContext . IN_ASSIGNMENT : scope . problemReporter ( ) . localVariableRedundantNullAssignment ( local , expression ) ; continue ; case FlowContext . IN_INSTANCEOF : scope . problemReporter ( ) . localVariableNullInstanceof ( local , expression ) ; continue ; } } else if ( flowInfo . isPotentiallyNull ( local ) ) { switch ( this . nullCheckTypes [ i ] & CONTEXT_MASK ) { case FlowContext . IN_COMPARISON_NULL : this . nullReferences [ i ] = null ; if ( ( ( this . nullCheckTypes [ i ] & CHECK_MASK ) == CAN_ONLY_NULL ) && ( expression . implicitConversion & TypeIds . UNBOXING ) != 0 ) { scope . problemReporter ( ) . localVariablePotentialNullReference ( local , expression ) ; continue ; } break ; case FlowContext . IN_COMPARISON_NON_NULL : this . nullReferences [ i ] = null ; if ( ( ( this . nullCheckTypes [ i ] & CHECK_MASK ) == CAN_ONLY_NULL ) && ( expression . implicitConversion & TypeIds . UNBOXING ) != 0 ) { scope . problemReporter ( ) . localVariablePotentialNullReference ( local , expression ) ; continue ; } break ; } } break ; case MAY_NULL : if ( flowInfo . isDefinitelyNull ( local ) ) { this . nullReferences [ i ] = null ; scope . problemReporter ( ) . localVariableNullReference ( local , expression ) ; continue ; } if ( flowInfo . isPotentiallyNull ( local ) ) { this . nullReferences [ i ] = null ; scope . problemReporter ( ) . localVariablePotentialNullReference ( local , expression ) ; continue ; } break ; default : } } } this . initsOnBreak . addPotentialNullInfoFrom ( flowInfo ) ; for ( int i = 0 ; i < this . breakTargetsCount ; i ++ ) { this . breakTargetContexts [ i ] . initsOnBreak . addPotentialNullInfoFrom ( flowInfo ) ; } } public BranchLabel continueLabel ( ) { return this . continueLabel ; } public String individualToString ( ) { StringBuffer buffer = new StringBuffer ( "" ) ; buffer . append ( "" ) . append ( this . initsOnBreak . toString ( ) ) . append ( ']' ) ; buffer . append ( "" ) . append ( this . initsOnContinue . toString ( ) ) . append ( ']' ) ; buffer . append ( "" ) . append ( this . assignCount ) . append ( ']' ) ; buffer . append ( "" ) . append ( this . nullCount ) . append ( ']' ) ; return buffer . toString ( ) ; } public boolean isContinuable ( ) { return true ; } public boolean isContinuedTo ( ) { return this . initsOnContinue != FlowInfo . DEAD_END ; } public void recordBreakTo ( FlowContext targetContext ) { if ( targetContext instanceof LabelFlowContext ) { int current ; if ( ( current = this . breakTargetsCount ++ ) == 0 ) { this . breakTargetContexts = new LabelFlowContext [ 2 ] ; } else if ( current == this . breakTargetContexts . length ) { System . arraycopy ( this . breakTargetContexts , 0 , this . breakTargetContexts = new LabelFlowContext [ current + 2 ] , 0 , current ) ; } this . breakTargetContexts [ current ] = ( LabelFlowContext ) targetContext ; } } public void recordContinueFrom ( FlowContext innerFlowContext , FlowInfo flowInfo ) { if ( ( flowInfo . tagBits & FlowInfo . UNREACHABLE_OR_DEAD ) == 0 ) { if ( ( this . initsOnContinue . tagBits & FlowInfo . UNREACHABLE_OR_DEAD ) == 0 ) { this . initsOnContinue = this . initsOnContinue . mergedWith ( flowInfo . unconditionalInitsWithoutSideEffect ( ) ) ; } else { this . initsOnContinue = flowInfo . unconditionalCopy ( ) ; } FlowContext inner = innerFlowContext ; while ( inner != this && ! ( inner instanceof LoopingFlowContext ) ) { inner = inner . parent ; } if ( inner == this ) { this . upstreamNullFlowInfo . addPotentialNullInfoFrom ( flowInfo . unconditionalInitsWithoutSideEffect ( ) ) ; } else { int length = 0 ; if ( this . innerFlowContexts == null ) { this . innerFlowContexts = new LoopingFlowContext [ 5 ] ; this . innerFlowInfos = new UnconditionalFlowInfo [ 5 ] ; } else if ( this . innerFlowContextsCount == ( length = this . innerFlowContexts . length ) - 1 ) { System . arraycopy ( this . innerFlowContexts , 0 , ( this . innerFlowContexts = new LoopingFlowContext [ length + 5 ] ) , 0 , length ) ; System . arraycopy ( this . innerFlowInfos , 0 , ( this . innerFlowInfos = new UnconditionalFlowInfo [ length + 5 ] ) , 0 , length ) ; } this . innerFlowContexts [ this . innerFlowContextsCount ] = ( LoopingFlowContext ) inner ; this . innerFlowInfos [ this . innerFlowContextsCount ++ ] = flowInfo . unconditionalInitsWithoutSideEffect ( ) ; } } } protected boolean recordFinalAssignment ( VariableBinding binding , Reference finalAssignment ) { if ( binding instanceof LocalVariableBinding ) { Scope scope = ( ( LocalVariableBinding ) binding ) . declaringScope ; while ( ( scope = scope . parent ) != null ) { if ( scope == this . associatedScope ) return false ; } } if ( this . assignCount == 0 ) { this . finalAssignments = new Reference [ 5 ] ; this . finalVariables = new VariableBinding [ 5 ] ; } else { if ( this . assignCount == this . finalAssignments . length ) System . arraycopy ( this . finalAssignments , 0 , ( this . finalAssignments = new Reference [ this . assignCount * 2 ] ) , 0 , this . assignCount ) ; System . arraycopy ( this . finalVariables , 0 , ( this . finalVariables = new VariableBinding [ this . assignCount * 2 ] ) , 0 , this . assignCount ) ; } this . finalAssignments [ this . assignCount ] = finalAssignment ; this . finalVariables [ this . assignCount ++ ] = binding ; return true ; } protected void recordNullReference ( LocalVariableBinding local , Expression expression , int status ) { if ( this . nullCount == 0 ) { this . nullLocals = new LocalVariableBinding [ 5 ] ; this . nullReferences = new Expression [ 5 ] ; this . nullCheckTypes = new int [ 5 ] ; } else if ( this . nullCount == this . nullLocals . length ) { System . arraycopy ( this . nullLocals , 0 , this . nullLocals = new LocalVariableBinding [ this . nullCount * 2 ] , 0 , this . nullCount ) ; System . arraycopy ( this . nullReferences , 0 , this . nullReferences = new Expression [ this . nullCount * 2 ] , 0 , this . nullCount ) ; System . arraycopy ( this . nullCheckTypes , 0 , this . nullCheckTypes = new int [ this . nullCount * 2 ] , 0 , this . nullCount ) ; } this . nullLocals [ this . nullCount ] = local ; this . nullReferences [ this . nullCount ] = expression ; this . nullCheckTypes [ this . nullCount ++ ] = status ; } public void recordUsingNullReference ( Scope scope , LocalVariableBinding local , Expression reference , int checkType , FlowInfo flowInfo ) { if ( ( flowInfo . tagBits & FlowInfo . UNREACHABLE ) != 0 || flowInfo . isDefinitelyUnknown ( local ) ) { return ; } switch ( checkType ) { case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL : case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL : if ( flowInfo . isDefinitelyNonNull ( local ) ) { if ( checkType == ( CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL ) ) { if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableRedundantCheckOnNonNull ( local , reference ) ; } if ( ! flowInfo . isMarkedAsNullOrNonNullInAssertExpression ( local ) ) { flowInfo . initsWhenFalse ( ) . setReachMode ( FlowInfo . UNREACHABLE_BY_NULLANALYSIS ) ; } } else { if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableNonNullComparedToNull ( local , reference ) ; } if ( ! flowInfo . isMarkedAsNullOrNonNullInAssertExpression ( local ) ) { flowInfo . initsWhenTrue ( ) . setReachMode ( FlowInfo . UNREACHABLE_BY_NULLANALYSIS ) ; } } } else if ( flowInfo . isDefinitelyNull ( local ) ) { if ( checkType == ( CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL ) ) { if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableRedundantCheckOnNull ( local , reference ) ; } if ( ! flowInfo . isMarkedAsNullOrNonNullInAssertExpression ( local ) ) { flowInfo . initsWhenFalse ( ) . setReachMode ( FlowInfo . UNREACHABLE_BY_NULLANALYSIS ) ; } } else { if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableNullComparedToNonNull ( local , reference ) ; } if ( ! flowInfo . isMarkedAsNullOrNonNullInAssertExpression ( local ) ) { flowInfo . initsWhenTrue ( ) . setReachMode ( FlowInfo . UNREACHABLE_BY_NULLANALYSIS ) ; } } } else if ( this . upstreamNullFlowInfo . isDefinitelyNonNull ( local ) && ! flowInfo . isPotentiallyNull ( local ) && ! flowInfo . isPotentiallyUnknown ( local ) ) { flowInfo . markAsDefinitelyNonNull ( local ) ; if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { recordNullReference ( local , reference , checkType ) ; } } else if ( flowInfo . cannotBeDefinitelyNullOrNonNull ( local ) ) { return ; } else { if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { if ( flowInfo . isPotentiallyNonNull ( local ) ) { recordNullReference ( local , reference , CAN_ONLY_NON_NULL | checkType & CONTEXT_MASK ) ; } else if ( flowInfo . isPotentiallyNull ( local ) ) { recordNullReference ( local , reference , CAN_ONLY_NULL | checkType & CONTEXT_MASK ) ; } else { recordNullReference ( local , reference , checkType ) ; } } } return ; case CAN_ONLY_NULL | IN_COMPARISON_NULL : case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL : case CAN_ONLY_NULL | IN_ASSIGNMENT : case CAN_ONLY_NULL | IN_INSTANCEOF : if ( flowInfo . isPotentiallyNonNull ( local ) || flowInfo . isPotentiallyUnknown ( local ) || flowInfo . isProtectedNonNull ( local ) ) { return ; } if ( flowInfo . isDefinitelyNull ( local ) ) { switch ( checkType & CONTEXT_MASK ) { case FlowContext . IN_COMPARISON_NULL : if ( ( ( checkType & CHECK_MASK ) == CAN_ONLY_NULL ) && ( reference . implicitConversion & TypeIds . UNBOXING ) != 0 ) { scope . problemReporter ( ) . localVariableNullReference ( local , reference ) ; return ; } if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableRedundantCheckOnNull ( local , reference ) ; } if ( ! flowInfo . isMarkedAsNullOrNonNullInAssertExpression ( local ) ) { flowInfo . initsWhenFalse ( ) . setReachMode ( FlowInfo . UNREACHABLE_BY_NULLANALYSIS ) ; } return ; case FlowContext . IN_COMPARISON_NON_NULL : if ( ( ( checkType & CHECK_MASK ) == CAN_ONLY_NULL ) && ( reference . implicitConversion & TypeIds . UNBOXING ) != 0 ) { scope . problemReporter ( ) . localVariableNullReference ( local , reference ) ; return ; } if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 ) { scope . problemReporter ( ) . localVariableNullComparedToNonNull ( local , reference ) ; } if ( ! flowInfo . isMarkedAsNullOrNonNullInAssertExpression ( local ) ) { flowInfo . initsWhenTrue ( ) . setReachMode ( FlowInfo . UNREACHABLE_BY_NULLANALYSIS ) ; } return ; case FlowContext . IN_ASSIGNMENT : scope . problemReporter ( ) . localVariableRedundantNullAssignment ( local , reference ) ; return ; case FlowContext . IN_INSTANCEOF : scope . problemReporter ( ) . localVariableNullInstanceof ( local , reference ) ; return ; } } else if ( flowInfo . isPotentiallyNull ( local ) ) { switch ( checkType & CONTEXT_MASK ) { case FlowContext . IN_COMPARISON_NULL : if ( ( ( checkType & CHECK_MASK ) == CAN_ONLY_NULL ) && ( reference . implicitConversion & TypeIds . UNBOXING ) != 0 ) { scope . problemReporter ( ) . localVariablePotentialNullReference ( local , reference ) ; return ; } break ; case FlowContext . IN_COMPARISON_NON_NULL : if ( ( ( checkType & CHECK_MASK ) == CAN_ONLY_NULL ) && ( reference . implicitConversion & TypeIds . UNBOXING ) != 0 ) { scope . problemReporter ( ) . localVariablePotentialNullReference ( local , reference ) ; return ; } break ; } } if ( ( this . tagBits & FlowContext . HIDE_NULL_COMPARISON_WARNING ) == 0 || ( checkType & CONTEXT_MASK ) == FlowContext . IN_ASSIGNMENT || ( checkType & CONTEXT_MASK ) == FlowContext . IN_INSTANCEOF ) { recordNullReference ( local , reference , checkType ) ; } return ; case MAY_NULL : if ( flowInfo . isDefinitelyNonNull ( local ) ) { return ; } if ( flowInfo . isDefinitelyNull ( local ) ) { scope . problemReporter ( ) . localVariableNullReference ( local , reference ) ; return ; } if ( flowInfo . isPotentiallyNull ( local ) ) { scope . problemReporter ( ) . localVariablePotentialNullReference ( local , reference ) ; return ; } recordNullReference ( local , reference , checkType ) ; return ; default : } } void removeFinalAssignmentIfAny ( Reference reference ) { for ( int i = 0 ; i < this . assignCount ; i ++ ) { if ( this . finalAssignments [ i ] == reference ) { this . finalAssignments [ i ] = null ; this . finalVariables [ i ] = null ; return ; } } } public void simulateThrowAfterLoopBack ( FlowInfo flowInfo ) { if ( this . escapingExceptionCatchSites != null ) { for ( int i = 0 , exceptionCount = this . escapingExceptionCatchSites . size ( ) ; i < exceptionCount ; i ++ ) { ( ( EscapingExceptionCatchSite ) this . escapingExceptionCatchSites . get ( i ) ) . simulateThrowAfterLoopBack ( flowInfo ) ; } this . escapingExceptionCatchSites = null ; } } public void recordCatchContextOfEscapingException ( ExceptionHandlingFlowContext catchingContext , ReferenceBinding caughtException ) { if ( this . escapingExceptionCatchSites == null ) { this . escapingExceptionCatchSites = new ArrayList ( 5 ) ; } this . escapingExceptionCatchSites . add ( new EscapingExceptionCatchSite ( catchingContext , caughtException ) ) ; } public boolean hasEscapingExceptions ( ) { return this . escapingExceptionCatchSites != null ; } } </s>