Search in sources :

Example 86 with ExpressionStatement

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

the class EnumVisitor method addInit.

private void addInit(ClassNode enumClass, FieldNode minValue, FieldNode maxValue, FieldNode values, boolean isAic) {
    // constructor helper
    // This method is used instead of calling the constructor as
    // calling the constructor may require a table with MetaClass
    // selecting the constructor for each enum value. So instead we
    // use this method to have a central point for constructor selection
    // and only one table. The whole construction is needed because 
    // Reflection forbids access to the enum constructor.
    // code:
    // def $INIT(Object[] para) {
    //  return this(*para)
    // }
    ClassNode enumRef = enumClass.getPlainNodeReference();
    Parameter[] parameter = new Parameter[] { new Parameter(ClassHelper.OBJECT_TYPE.makeArray(), "para") };
    MethodNode initMethod = new MethodNode("$INIT", PUBLIC_FS | Opcodes.ACC_SYNTHETIC, enumRef, parameter, ClassNode.EMPTY_ARRAY, null);
    initMethod.setSynthetic(true);
    ConstructorCallExpression cce = new ConstructorCallExpression(ClassNode.THIS, new ArgumentListExpression(new SpreadExpression(new VariableExpression("para"))));
    BlockStatement code = new BlockStatement();
    code.addStatement(new ReturnStatement(cce));
    initMethod.setCode(code);
    enumClass.addMethod(initMethod);
    // static init
    List<FieldNode> fields = enumClass.getFields();
    List<Expression> arrayInit = new ArrayList<Expression>();
    int value = -1;
    Token assign = Token.newSymbol(Types.ASSIGN, -1, -1);
    List<Statement> block = new ArrayList<Statement>();
    FieldNode tempMin = null;
    FieldNode tempMax = null;
    for (FieldNode field : fields) {
        if ((field.getModifiers() & Opcodes.ACC_ENUM) == 0)
            continue;
        value++;
        if (tempMin == null)
            tempMin = field;
        tempMax = field;
        ClassNode enumBase = enumClass;
        ArgumentListExpression args = new ArgumentListExpression();
        args.addExpression(new ConstantExpression(field.getName()));
        args.addExpression(new ConstantExpression(value));
        if (field.getInitialExpression() == null) {
            if ((enumClass.getModifiers() & Opcodes.ACC_ABSTRACT) != 0) {
                addError(field, "The enum constant " + field.getName() + " must override abstract methods from " + enumBase.getName() + ".");
                continue;
            }
        } else {
            ListExpression oldArgs = (ListExpression) field.getInitialExpression();
            List<MapEntryExpression> savedMapEntries = new ArrayList<MapEntryExpression>();
            for (Expression exp : oldArgs.getExpressions()) {
                if (exp instanceof MapEntryExpression) {
                    savedMapEntries.add((MapEntryExpression) exp);
                    continue;
                }
                InnerClassNode inner = null;
                if (exp instanceof ClassExpression) {
                    ClassExpression clazzExp = (ClassExpression) exp;
                    ClassNode ref = clazzExp.getType();
                    if (ref instanceof EnumConstantClassNode) {
                        inner = (InnerClassNode) ref;
                    }
                }
                if (inner != null) {
                    List<MethodNode> baseMethods = enumBase.getMethods();
                    for (MethodNode methodNode : baseMethods) {
                        if (!methodNode.isAbstract())
                            continue;
                        MethodNode enumConstMethod = inner.getMethod(methodNode.getName(), methodNode.getParameters());
                        if (enumConstMethod == null || (enumConstMethod.getModifiers() & Opcodes.ACC_ABSTRACT) != 0) {
                            addError(field, "Can't have an abstract method in enum constant " + field.getName() + ". Implement method '" + methodNode.getTypeDescriptor() + "'.");
                        }
                    }
                    if (inner.getVariableScope() == null) {
                        enumBase = inner;
                        /*
                             * GROOVY-3985: Remove the final modifier from $INIT method in this case
                             * so that subclasses of enum generated for enum constants (aic) can provide
                             * their own $INIT method
                             */
                        initMethod.setModifiers(initMethod.getModifiers() & ~Opcodes.ACC_FINAL);
                        continue;
                    }
                }
                args.addExpression(exp);
            }
            if (savedMapEntries.size() > 0) {
                args.getExpressions().add(2, new MapExpression(savedMapEntries));
            }
        }
        field.setInitialValueExpression(null);
        block.add(new ExpressionStatement(new BinaryExpression(new FieldExpression(field), assign, new StaticMethodCallExpression(enumBase, "$INIT", args))));
        arrayInit.add(new FieldExpression(field));
    }
    if (!isAic) {
        if (tempMin != null) {
            block.add(new ExpressionStatement(new BinaryExpression(new FieldExpression(minValue), assign, new FieldExpression(tempMin))));
            block.add(new ExpressionStatement(new BinaryExpression(new FieldExpression(maxValue), assign, new FieldExpression(tempMax))));
            enumClass.addField(minValue);
            enumClass.addField(maxValue);
        }
        block.add(new ExpressionStatement(new BinaryExpression(new FieldExpression(values), assign, new ArrayExpression(enumClass, arrayInit))));
        enumClass.addField(values);
    }
    enumClass.addStaticInitializerStatements(block, true);
}
Also used : EnumConstantClassNode(org.codehaus.groovy.ast.EnumConstantClassNode) ArrayList(java.util.ArrayList) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Token(org.codehaus.groovy.syntax.Token) MethodNode(org.codehaus.groovy.ast.MethodNode) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) EnumConstantClassNode(org.codehaus.groovy.ast.EnumConstantClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) Parameter(org.codehaus.groovy.ast.Parameter)

Example 87 with ExpressionStatement

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

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

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

the class ConstructorNode method firstStatementIsSpecialConstructorCall.

public boolean firstStatementIsSpecialConstructorCall() {
    Statement code = getFirstStatement();
    if (code == null || !(code instanceof ExpressionStatement))
        return false;
    Expression expression = ((ExpressionStatement) code).getExpression();
    if (!(expression instanceof ConstructorCallExpression))
        return false;
    ConstructorCallExpression cce = (ConstructorCallExpression) expression;
    return cce.isSpecialCall();
}
Also used : ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) Statement(org.codehaus.groovy.ast.stmt.Statement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement)

Example 89 with ExpressionStatement

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

the class TemplateASTTransformer method createConstructor.

private void createConstructor(final ClassNode classNode) {
    Parameter[] params = new Parameter[] { new Parameter(MarkupTemplateEngine.MARKUPTEMPLATEENGINE_CLASSNODE, "engine"), new Parameter(ClassHelper.MAP_TYPE.getPlainNodeReference(), "model"), new Parameter(ClassHelper.MAP_TYPE.getPlainNodeReference(), "modelTypes"), new Parameter(TEMPLATECONFIG_CLASSNODE, "tplConfig") };
    List<Expression> vars = new LinkedList<Expression>();
    for (Parameter param : params) {
        vars.add(new VariableExpression(param));
    }
    ExpressionStatement body = new ExpressionStatement(new ConstructorCallExpression(ClassNode.SUPER, new ArgumentListExpression(vars)));
    ConstructorNode ctor = new ConstructorNode(Opcodes.ACC_PUBLIC, params, ClassNode.EMPTY_ARRAY, body);
    classNode.addConstructor(ctor);
}
Also used : ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ConstructorNode(org.codehaus.groovy.ast.ConstructorNode) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) Parameter(org.codehaus.groovy.ast.Parameter) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) LinkedList(java.util.LinkedList)

Example 90 with ExpressionStatement

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

the class StaticCompilationVisitor method addPrivateFieldsAccessors.

/**
     * Adds special accessors for private constants so that inner classes can retrieve them.
     */
@SuppressWarnings("unchecked")
private void addPrivateFieldsAccessors(ClassNode node) {
    Set<ASTNode> accessedFields = (Set<ASTNode>) node.getNodeMetaData(StaticTypesMarker.PV_FIELDS_ACCESS);
    if (accessedFields == null)
        return;
    Map<String, MethodNode> privateConstantAccessors = (Map<String, MethodNode>) node.getNodeMetaData(PRIVATE_FIELDS_ACCESSORS);
    if (privateConstantAccessors != null) {
        // already added
        return;
    }
    int acc = -1;
    privateConstantAccessors = new HashMap<String, MethodNode>();
    final int access = Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC;
    for (FieldNode fieldNode : node.getFields()) {
        if (accessedFields.contains(fieldNode)) {
            acc++;
            Parameter param = new Parameter(node.getPlainNodeReference(), "$that");
            Expression receiver = fieldNode.isStatic() ? new ClassExpression(node) : new VariableExpression(param);
            Statement stmt = new ExpressionStatement(new PropertyExpression(receiver, fieldNode.getName()));
            MethodNode accessor = node.addMethod("pfaccess$" + acc, access, fieldNode.getOriginType(), new Parameter[] { param }, ClassNode.EMPTY_ARRAY, stmt);
            privateConstantAccessors.put(fieldNode.getName(), accessor);
        }
    }
    node.setNodeMetaData(PRIVATE_FIELDS_ACCESSORS, privateConstantAccessors);
}
Also used : Statement(org.codehaus.groovy.ast.stmt.Statement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ForStatement(org.codehaus.groovy.ast.stmt.ForStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement)

Aggregations

ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)122 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)78 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)65 Statement (org.codehaus.groovy.ast.stmt.Statement)58 Expression (org.codehaus.groovy.ast.expr.Expression)54 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)44 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