Search in sources :

Example 11 with ExpressionStatement

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

the class Verifier method addFieldInitialization.

protected void addFieldInitialization(List list, List staticList, FieldNode fieldNode, boolean isEnumClassNode, List initStmtsAfterEnumValuesInit, Set explicitStaticPropsInEnum) {
    Expression expression = fieldNode.getInitialExpression();
    if (expression != null) {
        final FieldExpression fe = new FieldExpression(fieldNode);
        if (fieldNode.getType().equals(ClassHelper.REFERENCE_TYPE) && ((fieldNode.getModifiers() & Opcodes.ACC_SYNTHETIC) != 0)) {
            fe.setUseReferenceDirectly(true);
        }
        ExpressionStatement statement = new ExpressionStatement(new BinaryExpression(fe, Token.newSymbol(Types.EQUAL, fieldNode.getLineNumber(), fieldNode.getColumnNumber()), expression));
        if (fieldNode.isStatic()) {
            // GROOVY-3311: pre-defined constants added by groovy compiler for numbers/characters should be
            // initialized first so that code dependent on it does not see their values as empty
            Expression initialValueExpression = fieldNode.getInitialValueExpression();
            if (initialValueExpression instanceof ConstantExpression) {
                ConstantExpression cexp = (ConstantExpression) initialValueExpression;
                cexp = transformToPrimitiveConstantIfPossible(cexp);
                if (fieldNode.isFinal() && ClassHelper.isStaticConstantInitializerType(cexp.getType()) && cexp.getType().equals(fieldNode.getType())) {
                    // GROOVY-5150: primitive type constants will be initialized directly
                    return;
                }
                staticList.add(0, statement);
            } else {
                staticList.add(statement);
            }
            // to avoid double initialization in case of several constructors
            fieldNode.setInitialValueExpression(null);
            /*
                 * If it is a statement for an explicitly declared static field inside an enum, store its
                 * reference. For enums, they need to be handled differently as such init statements should
                 * come after the enum values have been initialized inside <clinit> block. GROOVY-3161.
                 */
            if (isEnumClassNode && explicitStaticPropsInEnum.contains(fieldNode.getName())) {
                initStmtsAfterEnumValuesInit.add(statement);
            }
        } else {
            list.add(statement);
        }
    }
}
Also used : BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression)

Example 12 with ExpressionStatement

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

the class InnerClassCompletionVisitor method addThisReference.

private void addThisReference(ConstructorNode node) {
    if (!shouldHandleImplicitThisForInnerClass(classNode))
        return;
    Statement code = node.getCode();
    // add "this$0" field init
    //add this parameter to node
    Parameter[] params = node.getParameters();
    Parameter[] newParams = new Parameter[params.length + 1];
    System.arraycopy(params, 0, newParams, 1, params.length);
    String name = getUniqueName(params, node);
    Parameter thisPara = new Parameter(classNode.getOuterClass().getPlainNodeReference(), name);
    newParams[0] = thisPara;
    node.setParameters(newParams);
    BlockStatement block = null;
    if (code == null) {
        block = new BlockStatement();
    } else if (!(code instanceof BlockStatement)) {
        block = new BlockStatement();
        block.addStatement(code);
    } else {
        block = (BlockStatement) code;
    }
    BlockStatement newCode = new BlockStatement();
    addFieldInit(thisPara, thisField, newCode);
    ConstructorCallExpression cce = getFirstIfSpecialConstructorCall(block);
    if (cce == null) {
        cce = new ConstructorCallExpression(ClassNode.SUPER, new TupleExpression());
        block.getStatements().add(0, new ExpressionStatement(cce));
    }
    if (shouldImplicitlyPassThisPara(cce)) {
        // add thisPara to this(...)
        TupleExpression args = (TupleExpression) cce.getArguments();
        List<Expression> expressions = args.getExpressions();
        VariableExpression ve = new VariableExpression(thisPara.getName());
        ve.setAccessedVariable(thisPara);
        expressions.add(0, ve);
    }
    if (cce.isSuperCall()) {
        // we have a call to super here, so we need to add
        // our code after that
        block.getStatements().add(1, newCode);
    }
    node.setCode(block);
}
Also used : ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) Expression(org.codehaus.groovy.ast.expr.Expression) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) Parameter(org.codehaus.groovy.ast.Parameter) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression)

Example 13 with ExpressionStatement

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

the class InnerClassCompletionVisitor method getFirstIfSpecialConstructorCall.

private static ConstructorCallExpression getFirstIfSpecialConstructorCall(BlockStatement code) {
    if (code == null)
        return null;
    final List<Statement> statementList = code.getStatements();
    if (statementList.isEmpty())
        return null;
    final Statement statement = statementList.get(0);
    if (!(statement instanceof ExpressionStatement))
        return null;
    Expression expression = ((ExpressionStatement) statement).getExpression();
    if (!(expression instanceof ConstructorCallExpression))
        return null;
    ConstructorCallExpression cce = (ConstructorCallExpression) expression;
    if (cce.isSpecialCall())
        return cce;
    return null;
}
Also used : ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) Expression(org.codehaus.groovy.ast.expr.Expression) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement)

Example 14 with ExpressionStatement

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

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 15 with ExpressionStatement

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

the class InnerClassVisitorHelper method setPropertySetterDispatcher.

protected static void setPropertySetterDispatcher(BlockStatement block, Expression thiz, Parameter[] parameters) {
    List<ConstantExpression> gStringStrings = new ArrayList<ConstantExpression>();
    gStringStrings.add(new ConstantExpression(""));
    gStringStrings.add(new ConstantExpression(""));
    List<Expression> gStringValues = new ArrayList<Expression>();
    gStringValues.add(new VariableExpression(parameters[0]));
    block.addStatement(new ExpressionStatement(new BinaryExpression(new PropertyExpression(thiz, new GStringExpression("$name", gStringStrings, gStringValues)), Token.newSymbol(Types.ASSIGN, -1, -1), new VariableExpression(parameters[1]))));
}
Also used : ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ArrayList(java.util.ArrayList)

Aggregations

ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)123 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)79 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)65 Statement (org.codehaus.groovy.ast.stmt.Statement)59 Expression (org.codehaus.groovy.ast.expr.Expression)55 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)52 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)51 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)49 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)43 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)39 ReturnStatement (org.codehaus.groovy.ast.stmt.ReturnStatement)36 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)35 Parameter (org.codehaus.groovy.ast.Parameter)30 MethodNode (org.codehaus.groovy.ast.MethodNode)29 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)29 ClassNode (org.codehaus.groovy.ast.ClassNode)27 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)26 IfStatement (org.codehaus.groovy.ast.stmt.IfStatement)26 ArrayList (java.util.ArrayList)25 BooleanExpression (org.codehaus.groovy.ast.expr.BooleanExpression)24