Search in sources :

Example 1 with EmptyStatement

use of org.codehaus.groovy.ast.stmt.EmptyStatement in project groovy by apache.

the class AntlrParserPlugin method tryStatement.

protected Statement tryStatement(AST tryStatementNode) {
    AST tryNode = tryStatementNode.getFirstChild();
    Statement tryStatement = statement(tryNode);
    Statement finallyStatement = EmptyStatement.INSTANCE;
    AST node = tryNode.getNextSibling();
    // let's do the catch nodes
    List<CatchStatement> catches = new ArrayList<CatchStatement>();
    for (; node != null && isType(LITERAL_catch, node); node = node.getNextSibling()) {
        final List<CatchStatement> catchStatements = catchStatement(node);
        catches.addAll(catchStatements);
    }
    if (isType(LITERAL_finally, node)) {
        finallyStatement = statement(node);
        node = node.getNextSibling();
    }
    if (finallyStatement instanceof EmptyStatement && catches.isEmpty()) {
        throw new ASTRuntimeException(tryStatementNode, "A try statement must have at least one catch or finally block.");
    }
    TryCatchStatement tryCatchStatement = new TryCatchStatement(tryStatement, finallyStatement);
    configureAST(tryCatchStatement, tryStatementNode);
    for (CatchStatement statement : catches) {
        tryCatchStatement.addCatch(statement);
    }
    return tryCatchStatement;
}
Also used : AST(antlr.collections.AST) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) ForStatement(org.codehaus.groovy.ast.stmt.ForStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) AssertStatement(org.codehaus.groovy.ast.stmt.AssertStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) WhileStatement(org.codehaus.groovy.ast.stmt.WhileStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) ContinueStatement(org.codehaus.groovy.ast.stmt.ContinueStatement) BreakStatement(org.codehaus.groovy.ast.stmt.BreakStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) SynchronizedStatement(org.codehaus.groovy.ast.stmt.SynchronizedStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) SwitchStatement(org.codehaus.groovy.ast.stmt.SwitchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) ArrayList(java.util.ArrayList) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement)

Example 2 with EmptyStatement

use of org.codehaus.groovy.ast.stmt.EmptyStatement in project groovy-core by groovy.

the class FinalVariableAnalyzer method visitTryCatchFinally.

@Override
public void visitTryCatchFinally(final TryCatchStatement statement) {
    visitStatement(statement);
    Map<Variable, VariableState> beforeTryCatch = new HashMap<Variable, VariableState>(getState());
    statement.getTryStatement().visit(this);
    for (CatchStatement catchStatement : statement.getCatchStatements()) {
        catchStatement.visit(this);
    }
    Statement finallyStatement = statement.getFinallyStatement();
    // we need to recall which final variables are unassigned so cloning the current state
    Map<Variable, VariableState> afterTryCatchState = new HashMap<Variable, VariableState>(getState());
    if (finallyStatement instanceof EmptyStatement) {
        // dispatching to EmptyStatement will not call back visitor,
        // must call our visitEmptyStatement explicitly
        visitEmptyStatement((EmptyStatement) finallyStatement);
    } else {
        finallyStatement.visit(this);
    }
    // and now we must reset to uninitialized state variables which were only initialized during try/catch
    Map<Variable, VariableState> afterFinally = new HashMap<Variable, VariableState>(getState());
    for (Map.Entry<Variable, VariableState> entry : afterFinally.entrySet()) {
        Variable var = entry.getKey();
        VariableState afterFinallyState = entry.getValue();
        VariableState beforeTryCatchState = beforeTryCatch.get(var);
        if (afterFinallyState == VariableState.is_final && beforeTryCatchState != VariableState.is_final && afterTryCatchState.get(var) != beforeTryCatchState) {
            getState().put(var, beforeTryCatchState == null ? VariableState.is_uninitialized : beforeTryCatchState);
        }
    }
}
Also used : Variable(org.codehaus.groovy.ast.Variable) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) HashMap(java.util.HashMap) Statement(org.codehaus.groovy.ast.stmt.Statement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with EmptyStatement

use of org.codehaus.groovy.ast.stmt.EmptyStatement in project groovy by apache.

the class ReturnAdder method addReturnsIfNeeded.

private Statement addReturnsIfNeeded(final Statement statement, final VariableScope scope) {
    if (statement instanceof ReturnStatement || statement instanceof ThrowStatement || statement instanceof EmptyStatement || statement instanceof BytecodeSequence) {
        return statement;
    }
    if (statement == null) {
        ReturnStatement returnStatement = new ReturnStatement(nullX());
        listener.returnStatementAdded(returnStatement);
        return returnStatement;
    }
    if (statement instanceof ExpressionStatement) {
        Expression expression = ((ExpressionStatement) statement).getExpression();
        ReturnStatement returnStatement = new ReturnStatement(expression);
        returnStatement.copyStatementLabels(statement);
        returnStatement.setSourcePosition(statement.getLineNumber() < 0 ? expression : statement);
        listener.returnStatementAdded(returnStatement);
        return returnStatement;
    }
    if (statement instanceof SynchronizedStatement) {
        SynchronizedStatement syncStatement = (SynchronizedStatement) statement;
        Statement code = addReturnsIfNeeded(syncStatement.getCode(), scope);
        if (doAdd)
            syncStatement.setCode(code);
        return syncStatement;
    }
    if (statement instanceof IfStatement) {
        IfStatement ifElseStatement = (IfStatement) statement;
        Statement ifBlock = addReturnsIfNeeded(ifElseStatement.getIfBlock(), scope);
        Statement elseBlock = addReturnsIfNeeded(ifElseStatement.getElseBlock(), scope);
        if (doAdd) {
            ifElseStatement.setIfBlock(ifBlock);
            ifElseStatement.setElseBlock(elseBlock);
        }
        return ifElseStatement;
    }
    if (statement instanceof SwitchStatement) {
        SwitchStatement switchStatement = (SwitchStatement) statement;
        Statement defaultStatement = switchStatement.getDefaultStatement();
        List<CaseStatement> caseStatements = switchStatement.getCaseStatements();
        for (Iterator<CaseStatement> it = caseStatements.iterator(); it.hasNext(); ) {
            CaseStatement caseStatement = it.next();
            Statement code = adjustSwitchCaseCode(caseStatement.getCode(), scope, // GROOVY-9896: return if no default and last case lacks break
            defaultStatement == EmptyStatement.INSTANCE && !it.hasNext());
            if (doAdd)
                caseStatement.setCode(code);
        }
        defaultStatement = adjustSwitchCaseCode(defaultStatement, scope, true);
        if (doAdd)
            switchStatement.setDefaultStatement(defaultStatement);
        return switchStatement;
    }
    if (statement instanceof TryCatchStatement) {
        TryCatchStatement tryCatchFinally = (TryCatchStatement) statement;
        boolean[] missesReturn = new boolean[1];
        new ReturnAdder(returnStatement -> missesReturn[0] = true).addReturnsIfNeeded(tryCatchFinally.getFinallyStatement(), scope);
        boolean hasFinally = !(tryCatchFinally.getFinallyStatement() instanceof EmptyStatement);
        // there is nothing to do
        if (hasFinally && !missesReturn[0])
            return tryCatchFinally;
        // add returns to try and catch blocks
        Statement tryStatement = addReturnsIfNeeded(tryCatchFinally.getTryStatement(), scope);
        if (doAdd)
            tryCatchFinally.setTryStatement(tryStatement);
        for (CatchStatement catchStatement : tryCatchFinally.getCatchStatements()) {
            Statement code = addReturnsIfNeeded(catchStatement.getCode(), scope);
            if (doAdd)
                catchStatement.setCode(code);
        }
        return tryCatchFinally;
    }
    if (statement instanceof BlockStatement) {
        BlockStatement blockStatement = (BlockStatement) statement;
        if (blockStatement.isEmpty()) {
            ReturnStatement returnStatement = new ReturnStatement(nullX());
            returnStatement.copyStatementLabels(blockStatement);
            returnStatement.setSourcePosition(blockStatement);
            listener.returnStatementAdded(returnStatement);
            return returnStatement;
        } else {
            List<Statement> statements = blockStatement.getStatements();
            int lastIndex = statements.size() - 1;
            Statement last = addReturnsIfNeeded(statements.get(lastIndex), blockStatement.getVariableScope());
            if (doAdd)
                statements.set(lastIndex, last);
            return blockStatement;
        }
    }
    List<Statement> statements = new ArrayList<>(2);
    statements.add(statement);
    ReturnStatement returnStatement = new ReturnStatement(nullX());
    listener.returnStatementAdded(returnStatement);
    statements.add(returnStatement);
    BlockStatement blockStatement = new BlockStatement(statements, new VariableScope(scope));
    blockStatement.setSourcePosition(statement);
    return blockStatement;
}
Also used : Statement(org.codehaus.groovy.ast.stmt.Statement) VariableScope(org.codehaus.groovy.ast.VariableScope) Iterator(java.util.Iterator) BreakStatement(org.codehaus.groovy.ast.stmt.BreakStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) SynchronizedStatement(org.codehaus.groovy.ast.stmt.SynchronizedStatement) ArrayList(java.util.ArrayList) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) Objects(java.util.Objects) SwitchStatement(org.codehaus.groovy.ast.stmt.SwitchStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) List(java.util.List) MethodNode(org.codehaus.groovy.ast.MethodNode) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) GeneralUtils.nullX(org.codehaus.groovy.ast.tools.GeneralUtils.nullX) CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) Expression(org.codehaus.groovy.ast.expr.Expression) DefaultGroovyMethods.last(org.codehaus.groovy.runtime.DefaultGroovyMethods.last) Statement(org.codehaus.groovy.ast.stmt.Statement) BreakStatement(org.codehaus.groovy.ast.stmt.BreakStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) SynchronizedStatement(org.codehaus.groovy.ast.stmt.SynchronizedStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) SwitchStatement(org.codehaus.groovy.ast.stmt.SwitchStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) ArrayList(java.util.ArrayList) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) SynchronizedStatement(org.codehaus.groovy.ast.stmt.SynchronizedStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) SwitchStatement(org.codehaus.groovy.ast.stmt.SwitchStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) Expression(org.codehaus.groovy.ast.expr.Expression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) VariableScope(org.codehaus.groovy.ast.VariableScope)

Example 4 with EmptyStatement

use of org.codehaus.groovy.ast.stmt.EmptyStatement in project groovy by apache.

the class FinalVariableAnalyzer method visitSwitch.

@Override
public void visitSwitch(SwitchStatement switchS) {
    visitStatement(switchS);
    switchS.getExpression().visit(this);
    List<Statement> branches = new ArrayList<>(switchS.getCaseStatements());
    if (!(switchS.getDefaultStatement() instanceof EmptyStatement)) {
        branches.add(switchS.getDefaultStatement());
    }
    List<Map<Variable, VariableState>> afterStates = new ArrayList<>();
    // collect after states
    int lastIndex = branches.size() - 1;
    for (int i = 0; i <= lastIndex; i++) {
        pushState();
        boolean done = false;
        boolean returning = false;
        for (int j = i; !done; j++) {
            Statement branch = branches.get(j);
            // default branch
            Statement block = branch;
            if (branch instanceof CaseStatement) {
                CaseStatement caseS = (CaseStatement) branch;
                block = caseS.getCode();
                caseS.getExpression().visit(this);
            }
            block.visit(this);
            done = j == lastIndex || !fallsThrough(block);
            if (done) {
                returning = returningBlock(block);
            }
        }
        if (!returning) {
            afterStates.add(getState());
        }
        popState();
    }
    if (afterStates.isEmpty()) {
        return;
    }
    // merge branches
    Map<Variable, VariableState> beforeState = getState();
    Set<Variable> allVars = new HashSet<>(beforeState.keySet());
    for (Map<Variable, VariableState> map : afterStates) {
        allVars.addAll(map.keySet());
    }
    for (Variable var : allVars) {
        VariableState beforeValue = beforeState.get(var);
        if (beforeValue != null) {
            final VariableState merged = afterStates.get(0).get(var);
            if (merged != null) {
                if (afterStates.stream().allMatch(state -> merged.equals(state.get(var)))) {
                    beforeState.put(var, merged);
                } else {
                    VariableState different = beforeValue == VariableState.is_uninitialized ? VariableState.is_ambiguous : VariableState.is_var;
                    beforeState.put(var, different);
                }
            }
        }
    }
}
Also used : Variable(org.codehaus.groovy.ast.Variable) Statement(org.codehaus.groovy.ast.stmt.Statement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) ContinueStatement(org.codehaus.groovy.ast.stmt.ContinueStatement) BreakStatement(org.codehaus.groovy.ast.stmt.BreakStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) SwitchStatement(org.codehaus.groovy.ast.stmt.SwitchStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) ArrayList(java.util.ArrayList) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) HashMap(java.util.HashMap) Map(java.util.Map) HashSet(java.util.HashSet)

Example 5 with EmptyStatement

use of org.codehaus.groovy.ast.stmt.EmptyStatement in project groovy by apache.

the class FinalVariableAnalyzer method fallsThrough.

/**
 * @return true if the block falls through, i.e. no break/return
 */
private boolean fallsThrough(Statement statement) {
    if (statement instanceof EmptyStatement) {
        return true;
    }
    if (statement instanceof ReturnStatement) {
        // from ReturnAdder
        return false;
    }
    // currently only possibility
    BlockStatement block = (BlockStatement) statement;
    if (block.getStatements().size() == 0) {
        return true;
    }
    Statement last = DefaultGroovyMethods.last(block.getStatements());
    boolean completesAbruptly = last instanceof ReturnStatement || last instanceof BreakStatement || last instanceof ThrowStatement || last instanceof ContinueStatement;
    return !completesAbruptly;
}
Also used : BreakStatement(org.codehaus.groovy.ast.stmt.BreakStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) ContinueStatement(org.codehaus.groovy.ast.stmt.ContinueStatement) BreakStatement(org.codehaus.groovy.ast.stmt.BreakStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) SwitchStatement(org.codehaus.groovy.ast.stmt.SwitchStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) ContinueStatement(org.codehaus.groovy.ast.stmt.ContinueStatement)

Aggregations

EmptyStatement (org.codehaus.groovy.ast.stmt.EmptyStatement)15 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)14 IfStatement (org.codehaus.groovy.ast.stmt.IfStatement)14 Statement (org.codehaus.groovy.ast.stmt.Statement)14 ReturnStatement (org.codehaus.groovy.ast.stmt.ReturnStatement)12 CatchStatement (org.codehaus.groovy.ast.stmt.CatchStatement)11 TryCatchStatement (org.codehaus.groovy.ast.stmt.TryCatchStatement)11 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)9 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)7 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)7 StaticMethodCallExpression (org.codehaus.groovy.ast.expr.StaticMethodCallExpression)7 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)7 CaseStatement (org.codehaus.groovy.ast.stmt.CaseStatement)7 SwitchStatement (org.codehaus.groovy.ast.stmt.SwitchStatement)7 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)6 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)6 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)6 Expression (org.codehaus.groovy.ast.expr.Expression)6 ThrowStatement (org.codehaus.groovy.ast.stmt.ThrowStatement)6 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)5