public boolean canCompleteNormally ( Statement statement ) { if ( ! isReachable ( statement ) ) { return false ; } GenericVisitor < Boolean , Void > visitor = new GenericVisitorAdapter < Boolean , Void > ( ) { @ Override public Boolean visit ( BlockStmt n , Void arg ) { // An empty block that is not a switch block can complete normally iff it is reachable if ( n . isEmpty ( ) && ! parentIs ( statement , SwitchStmt . class ) ) { return isReachable ( statement ) ; } // A non-empty block that is not a switch block can complete normally iff the last statement in // it can complete normally. if ( ! n . isEmpty ( ) && ! parentIs ( statement , SwitchStmt . class ) ) { return canCompleteNormally ( n . getStatement ( n . getStatements ( ) . size ( ) - 1 ) ) ; } throw new UnsupportedOperationException ( ) ; } @ Override public Boolean visit ( LabeledStmt n , Void arg ) { // A labeled statement can complete normally if at least one of the following is true: // – The contained statement can complete normally. // – There is a reachable break statement that exits the labeled statement. throw new UnsupportedOperationException ( ) ; } @ Override public Boolean visit ( EmptyStmt n , Void arg ) { // An empty statement can complete normally iff it is reachable. return isReachable ( n ) ; } @ Override public Boolean visit ( LocalClassDeclarationStmt n , Void arg ) { // A local class declaration statement can complete normally iff it is reachable. return isReachable ( n ) ; } @ Override public Boolean visit ( IfStmt n , Void arg ) { if ( n . getElseStmt ( ) . isPresent ( ) ) { // An if-then-else statement can complete normally iff the then-statement can // complete normally or the else-statement can complete normally. return canCompleteNormally ( n . getThenStmt ( ) ) || canCompleteNormally ( n . getElseStmt ( ) . get ( ) ) ; } else { // An if-then statement can complete normally iff it is reachable. return isReachable ( n ) ; } } @ Override public Boolean visit ( AssertStmt n , Void arg ) { // An assert statement can complete normally iff it is reachable. return isReachable ( n ) ; } @ Override public Boolean visit ( ExpressionStmt n , Void arg ) { // A local variable declaration statement can complete normally iff it is reachable. if ( n . getExpression ( ) instanceof VariableDeclarationExpr ) { VariableDeclarationExpr expr = ( VariableDeclarationExpr ) n . getExpression ( ) ; return isReachable ( n ) ; } // An expression statement can complete normally iff it is reachable. return isReachable ( n ) ; } } ; return statement . accept ( visitor , null ) ; }
See JLS 14 . 21