Search in sources :

Example 11 with VariableScope

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

the class InnerClassVisitor method visitConstructorCallExpression.

@Override
public void visitConstructorCallExpression(ConstructorCallExpression call) {
    super.visitConstructorCallExpression(call);
    if (!call.isUsingAnonymousInnerClass()) {
        passThisReference(call);
        return;
    }
    InnerClassNode innerClass = (InnerClassNode) call.getType();
    ClassNode outerClass = innerClass.getOuterClass();
    ClassNode superClass = innerClass.getSuperClass();
    if (superClass instanceof InnerClassNode && !superClass.isInterface() && !(superClass.isStaticClass() || ((superClass.getModifiers() & ACC_STATIC) == ACC_STATIC))) {
        insertThis0ToSuperCall(call, innerClass);
    }
    if (!innerClass.getDeclaredConstructors().isEmpty())
        return;
    if ((innerClass.getModifiers() & ACC_STATIC) != 0)
        return;
    VariableScope scope = innerClass.getVariableScope();
    if (scope == null)
        return;
    // expressions = constructor call arguments
    List<Expression> expressions = ((TupleExpression) call.getArguments()).getExpressions();
    // block = init code for the constructor we produce
    BlockStatement block = new BlockStatement();
    // parameters = parameters of the constructor
    final int additionalParamCount = 1 + scope.getReferencedLocalVariablesCount();
    List<Parameter> parameters = new ArrayList<Parameter>(expressions.size() + additionalParamCount);
    // superCallArguments = arguments for the super call == the constructor call arguments
    List<Expression> superCallArguments = new ArrayList<Expression>(expressions.size());
    // first we add a super() call for all expressions given in the 
    // constructor call expression
    int pCount = additionalParamCount;
    for (Expression expr : expressions) {
        pCount++;
        // add one parameter for each expression in the
        // constructor call
        Parameter param = new Parameter(ClassHelper.OBJECT_TYPE, "p" + pCount);
        parameters.add(param);
        // add to super call
        superCallArguments.add(new VariableExpression(param));
    }
    // add the super call
    ConstructorCallExpression cce = new ConstructorCallExpression(ClassNode.SUPER, new TupleExpression(superCallArguments));
    block.addStatement(new ExpressionStatement(cce));
    // we need to add "this" to access unknown methods/properties
    // this is saved in a field named this$0
    pCount = 0;
    expressions.add(pCount, VariableExpression.THIS_EXPRESSION);
    boolean isStatic = isStaticThis(innerClass, scope);
    ClassNode outerClassType = getClassNode(outerClass, isStatic);
    if (!isStatic && inClosure)
        outerClassType = ClassHelper.CLOSURE_TYPE;
    outerClassType = outerClassType.getPlainNodeReference();
    Parameter thisParameter = new Parameter(outerClassType, "p" + pCount);
    parameters.add(pCount, thisParameter);
    thisField = innerClass.addField("this$0", PUBLIC_SYNTHETIC, outerClassType, null);
    addFieldInit(thisParameter, thisField, block);
    // for each shared variable we add a reference and save it as field
    for (Iterator it = scope.getReferencedLocalVariablesIterator(); it.hasNext(); ) {
        pCount++;
        org.codehaus.groovy.ast.Variable var = (org.codehaus.groovy.ast.Variable) it.next();
        VariableExpression ve = new VariableExpression(var);
        ve.setClosureSharedVariable(true);
        ve.setUseReferenceDirectly(true);
        expressions.add(pCount, ve);
        ClassNode rawReferenceType = ClassHelper.REFERENCE_TYPE.getPlainNodeReference();
        Parameter p = new Parameter(rawReferenceType, "p" + pCount);
        parameters.add(pCount, p);
        p.setOriginType(var.getOriginType());
        final VariableExpression initial = new VariableExpression(p);
        initial.setSynthetic(true);
        initial.setUseReferenceDirectly(true);
        final FieldNode pField = innerClass.addFieldFirst(ve.getName(), PUBLIC_SYNTHETIC, rawReferenceType, initial);
        pField.setHolder(true);
        pField.setOriginType(ClassHelper.getWrapper(var.getOriginType()));
    }
    innerClass.addConstructor(ACC_SYNTHETIC, parameters.toArray(new Parameter[parameters.size()]), ClassNode.EMPTY_ARRAY, block);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ArrayList(java.util.ArrayList) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) Iterator(java.util.Iterator) Parameter(org.codehaus.groovy.ast.Parameter) VariableScope(org.codehaus.groovy.ast.VariableScope)

Example 12 with VariableScope

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

the class ReturnAdder method addReturnsIfNeeded.

private Statement addReturnsIfNeeded(Statement statement, VariableScope scope) {
    if (statement instanceof ReturnStatement || statement instanceof BytecodeSequence || statement instanceof ThrowStatement) {
        return statement;
    }
    if (statement instanceof EmptyStatement) {
        final ReturnStatement returnStatement = new ReturnStatement(ConstantExpression.NULL);
        listener.returnStatementAdded(returnStatement);
        return returnStatement;
    }
    if (statement instanceof ExpressionStatement) {
        ExpressionStatement expStmt = (ExpressionStatement) statement;
        Expression expr = expStmt.getExpression();
        ReturnStatement ret = new ReturnStatement(expr);
        ret.setSourcePosition(expr);
        ret.setStatementLabel(statement.getStatementLabel());
        listener.returnStatementAdded(ret);
        return ret;
    }
    if (statement instanceof SynchronizedStatement) {
        SynchronizedStatement sync = (SynchronizedStatement) statement;
        final Statement code = addReturnsIfNeeded(sync.getCode(), scope);
        if (doAdd)
            sync.setCode(code);
        return sync;
    }
    if (statement instanceof IfStatement) {
        IfStatement ifs = (IfStatement) statement;
        final Statement ifBlock = addReturnsIfNeeded(ifs.getIfBlock(), scope);
        final Statement elseBlock = addReturnsIfNeeded(ifs.getElseBlock(), scope);
        if (doAdd) {
            ifs.setIfBlock(ifBlock);
            ifs.setElseBlock(elseBlock);
        }
        return ifs;
    }
    if (statement instanceof SwitchStatement) {
        SwitchStatement swi = (SwitchStatement) statement;
        for (CaseStatement caseStatement : swi.getCaseStatements()) {
            final Statement code = adjustSwitchCaseCode(caseStatement.getCode(), scope, false);
            if (doAdd)
                caseStatement.setCode(code);
        }
        final Statement defaultStatement = adjustSwitchCaseCode(swi.getDefaultStatement(), scope, true);
        if (doAdd)
            swi.setDefaultStatement(defaultStatement);
        return swi;
    }
    if (statement instanceof TryCatchStatement) {
        TryCatchStatement trys = (TryCatchStatement) statement;
        final boolean[] missesReturn = new boolean[1];
        new ReturnAdder(new ReturnStatementListener() {

            @Override
            public void returnStatementAdded(ReturnStatement returnStatement) {
                missesReturn[0] = true;
            }
        }).addReturnsIfNeeded(trys.getFinallyStatement(), scope);
        boolean hasFinally = !(trys.getFinallyStatement() instanceof EmptyStatement);
        // there is nothing to do
        if (hasFinally && !missesReturn[0])
            return trys;
        // add returns to try and catch blocks
        final Statement tryStatement = addReturnsIfNeeded(trys.getTryStatement(), scope);
        if (doAdd)
            trys.setTryStatement(tryStatement);
        final int len = trys.getCatchStatements().size();
        for (int i = 0; i != len; ++i) {
            final CatchStatement catchStatement = trys.getCatchStatement(i);
            final Statement code = addReturnsIfNeeded(catchStatement.getCode(), scope);
            if (doAdd)
                catchStatement.setCode(code);
        }
        return trys;
    }
    if (statement instanceof BlockStatement) {
        BlockStatement block = (BlockStatement) statement;
        final List list = block.getStatements();
        if (!list.isEmpty()) {
            int idx = list.size() - 1;
            Statement last = addReturnsIfNeeded((Statement) list.get(idx), block.getVariableScope());
            if (doAdd)
                list.set(idx, last);
            if (!statementReturns(last)) {
                final ReturnStatement returnStatement = new ReturnStatement(ConstantExpression.NULL);
                listener.returnStatementAdded(returnStatement);
                if (doAdd)
                    list.add(returnStatement);
            }
        } else {
            ReturnStatement ret = new ReturnStatement(ConstantExpression.NULL);
            ret.setSourcePosition(block);
            listener.returnStatementAdded(ret);
            return ret;
        }
        BlockStatement newBlock = new BlockStatement(list, block.getVariableScope());
        newBlock.setSourcePosition(block);
        return newBlock;
    }
    if (statement == null) {
        final ReturnStatement returnStatement = new ReturnStatement(ConstantExpression.NULL);
        listener.returnStatementAdded(returnStatement);
        return returnStatement;
    } else {
        final List list = new ArrayList();
        list.add(statement);
        final ReturnStatement returnStatement = new ReturnStatement(ConstantExpression.NULL);
        listener.returnStatementAdded(returnStatement);
        list.add(returnStatement);
        BlockStatement newBlock = new BlockStatement(list, new VariableScope(scope));
        newBlock.setSourcePosition(statement);
        return newBlock;
    }
}
Also used : ArrayList(java.util.ArrayList) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) Expression(org.codehaus.groovy.ast.expr.Expression) List(java.util.List) ArrayList(java.util.ArrayList) VariableScope(org.codehaus.groovy.ast.VariableScope)

Example 13 with VariableScope

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

the class AutoNewLineTransformer method visitClosureExpression.

@Override
public void visitClosureExpression(final ClosureExpression expression) {
    super.visitClosureExpression(expression);
    if (inBuilderMethod) {
        Statement oldCode = expression.getCode();
        BlockStatement block = oldCode instanceof BlockStatement ? ((BlockStatement) oldCode) : new BlockStatement(Arrays.asList(oldCode), new VariableScope());
        List<Statement> statements = block.getStatements();
        if (!statements.isEmpty()) {
            Statement first = statements.get(0);
            Statement last = statements.get(statements.size() - 1);
            if (expression.getLineNumber() < first.getLineNumber()) {
                // there's a new line between { -> ... and the first statement
                statements.add(0, createNewLine(expression));
            }
            if (expression.getLastLineNumber() > last.getLastLineNumber()) {
                // there's a new line between { -> ... and the first statement
                statements.add(createNewLine(expression));
            }
        }
        expression.setCode(block);
    }
}
Also used : Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableScope(org.codehaus.groovy.ast.VariableScope)

Example 14 with VariableScope

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

the class AutoCloneASTTransformation method createCloneSerialization.

private void createCloneSerialization(ClassNode cNode) {
    final BlockStatement body = new BlockStatement();
    // def baos = new ByteArrayOutputStream()
    final Expression baos = varX("baos");
    body.addStatement(declS(baos, ctorX(BAOS_TYPE)));
    // baos.withObjectOutputStream{ it.writeObject(this) }
    MethodCallExpression writeObject = callX(castX(OOS_TYPE, varX("it")), "writeObject", varX("this"));
    writeObject.setImplicitThis(false);
    ClosureExpression writeClos = closureX(block(stmt(writeObject)));
    writeClos.setVariableScope(new VariableScope());
    body.addStatement(stmt(callX(baos, "withObjectOutputStream", args(writeClos))));
    // def bais = new ByteArrayInputStream(baos.toByteArray())
    final Expression bais = varX("bais");
    body.addStatement(declS(bais, ctorX(BAIS_TYPE, args(callX(baos, "toByteArray")))));
    // return bais.withObjectInputStream(getClass().classLoader){ (<type>) it.readObject() }
    MethodCallExpression readObject = callX(castX(OIS_TYPE, varX("it")), "readObject");
    readObject.setImplicitThis(false);
    ClosureExpression readClos = closureX(block(stmt(castX(GenericsUtils.nonGeneric(cNode), readObject))));
    readClos.setVariableScope(new VariableScope());
    Expression classLoader = callX(callThisX("getClass"), "getClassLoader");
    body.addStatement(returnS(callX(bais, "withObjectInputStream", args(classLoader, readClos))));
    new VariableScopeVisitor(sourceUnit, true).visitClass(cNode);
    ClassNode[] exceptions = { make(CloneNotSupportedException.class) };
    cNode.addMethod("clone", ACC_PUBLIC, GenericsUtils.nonGeneric(cNode), Parameter.EMPTY_ARRAY, exceptions, body);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) VariableScopeVisitor(org.codehaus.groovy.classgen.VariableScopeVisitor) VariableScope(org.codehaus.groovy.ast.VariableScope)

Example 15 with VariableScope

use of org.codehaus.groovy.ast.VariableScope in project spring-boot by spring-projects.

the class ResolveDependencyCoordinatesTransformationTests method transformationOfAnnotationOnLocalVariable.

@Test
public void transformationOfAnnotationOnLocalVariable() {
    ClassNode classNode = new ClassNode("Test", 0, new ClassNode(Object.class));
    this.moduleNode.addClass(classNode);
    DeclarationExpression declarationExpression = new DeclarationExpression(new VariableExpression("test"), null, new ConstantExpression("test"));
    declarationExpression.addAnnotation(this.grabAnnotation);
    BlockStatement code = new BlockStatement(Arrays.asList((Statement) new ExpressionStatement(declarationExpression)), new VariableScope());
    MethodNode methodNode = new MethodNode("test", 0, new ClassNode(Void.class), new Parameter[0], new ClassNode[0], code);
    classNode.addMethod(methodNode);
    assertGrabAnnotationHasBeenTransformed();
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) MethodNode(org.codehaus.groovy.ast.MethodNode) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableScope(org.codehaus.groovy.ast.VariableScope) Test(org.junit.Test)

Aggregations

VariableScope (org.codehaus.groovy.ast.VariableScope)20 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)11 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)11 ClassNode (org.codehaus.groovy.ast.ClassNode)10 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)10 Expression (org.codehaus.groovy.ast.expr.Expression)10 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)9 Parameter (org.codehaus.groovy.ast.Parameter)8 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)8 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)7 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)7 ArrayList (java.util.ArrayList)6 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)6 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)6 MethodNode (org.codehaus.groovy.ast.MethodNode)5 Variable (org.codehaus.groovy.ast.Variable)5 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)5 Iterator (java.util.Iterator)4 List (java.util.List)4 FieldNode (org.codehaus.groovy.ast.FieldNode)4