@ Override protected ITerminalStatement getLeastSignificantTerminalStatement_internal ( boolean [ ] bAbsolute ) { ITerminalStatement termRet = null ; bAbsolute [ 0 ] = true ; boolean bBreak = false ; ITerminalStatement lastCaseTerm = null ; if ( _cases != null ) { for ( int i = 0 ; i < _cases . length ; i ++ ) { List caseStatements = _cases [ i ] . getStatements ( ) ; if ( caseStatements != null && caseStatements . size ( ) > 0 ) { boolean bCaseAbs = true ; for ( int iStmt = 0 ; iStmt < caseStatements . size ( ) ; iStmt ++ ) { boolean [ ] bCsr = { false } ; ITerminalStatement terminalStmt = ( ( Statement ) caseStatements . get ( iStmt ) ) . getLeastSignificantTerminalStatement ( bCsr ) ; if ( terminalStmt != null ) { bCaseAbs = bCsr [ 0 ] ; if ( ! ( terminalStmt instanceof IBreakStatement ) ) { termRet = getLeastSignificant ( termRet , terminalStmt ) ; if ( i == _cases . length - 1 ) { lastCaseTerm = termRet ; } } else { bAbsolute [ 0 ] = bCaseAbs = false ; bBreak = true ; } //## todo: this can be true iff the switch-expr type is an enum and all the constants are covered in the cases and they all have the same absolute non-break terminal (not an unusual use-case) } } bAbsolute [ 0 ] = bAbsolute [ 0 ] && bCaseAbs ; } } } boolean bDefaultContributed = false ; if ( _defaultStatements != null ) { if ( _defaultStatements . size ( ) > 0 ) { if ( ! bBreak ) { // If none of the cases have a break, the cases all either fall through to the default clause // or never flow to the next stmt following this switch. Therefore, the default clause's terminal, // if one is present, establishes the switch's terminal. bAbsolute [ 0 ] = true ; } boolean bDefaultAbs = false ; for ( int i = 0 ; i < _defaultStatements . size ( ) ; i ++ ) { boolean [ ] bCsr = { false } ; ITerminalStatement terminalStmt = _defaultStatements . get ( i ) . getLeastSignificantTerminalStatement ( bCsr ) ; if ( terminalStmt != null ) { if ( ! ( terminalStmt instanceof IBreakStatement ) ) { bDefaultAbs = bCsr [ 0 ] ; termRet = getLeastSignificant ( termRet , terminalStmt ) ; bDefaultContributed = true ; } } } bAbsolute [ 0 ] = bAbsolute [ 0 ] && bDefaultAbs ; } } else if ( ! bBreak && lastCaseTerm != null && isCoveredEnumSwitch ( ) ) { // Switch is a covered Enum where all cases are non-breaking terminators // (Note the compiler generate what is effectively a default clause that throws an exception for the 'null' case or if the Enum changes where new values are added) // (Note also, the compiler generates an implicit break statement in the last case-clause if it does not terminate explicitly) termRet = getLeastSignificant ( new ThrowStatement ( ) , lastCaseTerm ) ; bAbsolute [ 0 ] = bDefaultContributed = true ; } bAbsolute [ 0 ] = bAbsolute [ 0 ] && termRet != null && bDefaultContributed ; return termRet ; }
bAbsolute is true iff there are no break terminals anywhere in any cases and the default clause s terminator is non - break and absolute