@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(AssertStmt n, Void arg) { // An assert 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(AssertStmt n, Void arg) { // An assert 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(EmptyStmt n, Void arg) { // An empty statement can complete normally iff it is reachable. return isReachable(n); }
@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(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); } };
@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); } };
@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); } };
@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(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(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(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(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(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(); }
/** * A reachable break statement exits a statement if, within the break target, either there are no try statements * whose try blocks contain the break statement, or there are try statements whose try blocks contain the break * statement and all finally clauses of those try statements can complete normally. */ public boolean exitTheStatement(BreakStmt breakStmt) { if (!isReachable(breakStmt)) { return false; } Statement breakTarget = breakTarget(breakStmt); for (TryStmt tryStmt : containedTryStmts(breakTarget)) { if (contains(tryStmt.getTryBlock(), breakStmt)) { if (!tryStmt.getFinallyBlock().isPresent() && !canCompleteNormally(tryStmt.getFinallyBlock().get())) { return false; } } } return true; }
/** * A reachable break statement exits a statement if, within the break target, either there are no try statements * whose try blocks contain the break statement, or there are try statements whose try blocks contain the break * statement and all finally clauses of those try statements can complete normally. */ public boolean exitTheStatement(BreakStmt breakStmt) { if (!isReachable(breakStmt)) { return false; } Statement breakTarget = breakTarget(breakStmt); for (TryStmt tryStmt : containedTryStmts(breakTarget)) { if (contains(tryStmt.getTryBlock(), breakStmt)) { if (!tryStmt.getFinallyBlock().isPresent() && !canCompleteNormally(tryStmt.getFinallyBlock().get())) { return false; } } } return true; }