Search in sources :

Example 1 with FieldNode

use of org.codehaus.groovy.ast.FieldNode in project groovy by apache.

the class AntlrParserPlugin method fieldDef.

protected void fieldDef(AST fieldDef) {
    List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
    AST node = fieldDef.getFirstChild();
    int modifiers = 0;
    if (isType(MODIFIERS, node)) {
        modifiers = modifiers(node, annotations, modifiers);
        node = node.getNextSibling();
    }
    if (classNode.isInterface()) {
        modifiers |= Opcodes.ACC_STATIC | Opcodes.ACC_FINAL;
        if ((modifiers & (Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED)) == 0) {
            modifiers |= Opcodes.ACC_PUBLIC;
        }
    }
    ClassNode type = null;
    if (isType(TYPE, node)) {
        type = makeTypeWithArguments(node);
        node = node.getNextSibling();
    }
    String name = identifier(node);
    node = node.getNextSibling();
    Expression initialValue = null;
    if (node != null) {
        assertNodeType(ASSIGN, node);
        initialValue = expression(node.getFirstChild());
    }
    if (classNode.isInterface() && initialValue == null && type != null) {
        initialValue = getDefaultValueForPrimitive(type);
    }
    FieldNode fieldNode = new FieldNode(name, modifiers, type, classNode, initialValue);
    fieldNode.addAnnotations(annotations);
    configureAST(fieldNode, fieldDef);
    if (!hasVisibility(modifiers)) {
        // let's set the modifiers on the field
        int fieldModifiers = 0;
        int flags = Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT | Opcodes.ACC_VOLATILE | Opcodes.ACC_FINAL;
        if (!hasVisibility(modifiers)) {
            modifiers |= Opcodes.ACC_PUBLIC;
            fieldModifiers |= Opcodes.ACC_PRIVATE;
        }
        // let's pass along any other modifiers we need
        fieldModifiers |= (modifiers & flags);
        fieldNode.setModifiers(fieldModifiers);
        fieldNode.setSynthetic(true);
        // in the case that there is already a field, we would
        // like to use that field, instead of the default field
        // for the property
        FieldNode storedNode = classNode.getDeclaredField(fieldNode.getName());
        if (storedNode != null && !classNode.hasProperty(name)) {
            fieldNode = storedNode;
            // we remove it here, because addProperty will add it
            // again and we want to avoid it showing up multiple
            // times in the fields list.
            classNode.getFields().remove(storedNode);
        }
        PropertyNode propertyNode = new PropertyNode(fieldNode, modifiers, null, null);
        configureAST(propertyNode, fieldDef);
        classNode.addProperty(propertyNode);
    } else {
        fieldNode.setModifiers(modifiers);
        // if there is a property of that name, then a field of that
        // name already exists, which means this new field here should
        // be used instead of the field the property originally has.
        PropertyNode pn = classNode.getProperty(name);
        if (pn != null && pn.getField().isSynthetic()) {
            classNode.getFields().remove(pn.getField());
            pn.setField(fieldNode);
        }
        classNode.addField(fieldNode);
    }
}
Also used : EnumConstantClassNode(org.codehaus.groovy.ast.EnumConstantClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) AST(antlr.collections.AST) FieldNode(org.codehaus.groovy.ast.FieldNode) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) PropertyNode(org.codehaus.groovy.ast.PropertyNode) ArrayList(java.util.ArrayList)

Example 2 with FieldNode

use of org.codehaus.groovy.ast.FieldNode in project groovy by apache.

the class AntlrParserPlugin method enumConstantDef.

protected void enumConstantDef(AST node) {
    enumConstantBeingDef = true;
    assertNodeType(ENUM_CONSTANT_DEF, node);
    List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
    AST element = node.getFirstChild();
    if (isType(ANNOTATIONS, element)) {
        processAnnotations(annotations, element);
        element = element.getNextSibling();
    }
    String identifier = identifier(element);
    Expression init = null;
    element = element.getNextSibling();
    if (element != null) {
        init = expression(element);
        ClassNode innerClass;
        if (element.getNextSibling() == null) {
            innerClass = getAnonymousInnerClassNode(init);
            if (innerClass != null) {
                init = null;
            }
        } else {
            element = element.getNextSibling();
            Expression next = expression(element);
            innerClass = getAnonymousInnerClassNode(next);
        }
        if (innerClass != null) {
            // we have to handle an enum constant with a class overriding
            // a method in which case we need to configure the inner class
            innerClass.setSuperClass(classNode.getPlainNodeReference());
            innerClass.setModifiers(classNode.getModifiers() | Opcodes.ACC_FINAL);
            // we use a ClassExpression for transportation to EnumVisitor
            Expression inner = new ClassExpression(innerClass);
            if (init == null) {
                ListExpression le = new ListExpression();
                le.addExpression(inner);
                init = le;
            } else {
                if (init instanceof ListExpression) {
                    ((ListExpression) init).addExpression(inner);
                } else {
                    ListExpression le = new ListExpression();
                    le.addExpression(init);
                    le.addExpression(inner);
                    init = le;
                }
            }
            // and remove the final modifier from classNode to allow the sub class
            classNode.setModifiers(classNode.getModifiers() & ~Opcodes.ACC_FINAL);
        } else if (isType(ELIST, element)) {
            if (init instanceof ListExpression && !((ListExpression) init).isWrapped()) {
                ListExpression le = new ListExpression();
                le.addExpression(init);
                init = le;
            }
        }
    }
    FieldNode enumField = EnumHelper.addEnumConstant(classNode, identifier, init);
    enumField.addAnnotations(annotations);
    configureAST(enumField, node);
    enumConstantBeingDef = false;
}
Also used : EnumConstantClassNode(org.codehaus.groovy.ast.EnumConstantClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) AST(antlr.collections.AST) FieldNode(org.codehaus.groovy.ast.FieldNode) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) ArrayList(java.util.ArrayList)

Example 3 with FieldNode

use of org.codehaus.groovy.ast.FieldNode in project groovy by apache.

the class TupleConstructorASTTransformation method createConstructor.

public static void createConstructor(AbstractASTTransformation xform, ClassNode cNode, boolean includeFields, boolean includeProperties, boolean includeSuperFields, boolean includeSuperProperties, boolean callSuper, boolean force, List<String> excludes, final List<String> includes, boolean useSetters, boolean defaults, boolean allNames, SourceUnit sourceUnit, ClosureExpression pre, ClosureExpression post) {
    // no processing if existing constructors found
    if (!cNode.getDeclaredConstructors().isEmpty() && !force)
        return;
    List<FieldNode> superList = new ArrayList<FieldNode>();
    if (includeSuperProperties) {
        superList.addAll(getSuperPropertyFields(cNode.getSuperClass()));
    }
    if (includeSuperFields) {
        superList.addAll(getSuperNonPropertyFields(cNode.getSuperClass()));
    }
    List<FieldNode> list = new ArrayList<FieldNode>();
    if (includeProperties) {
        list.addAll(getInstancePropertyFields(cNode));
    }
    if (includeFields) {
        list.addAll(getInstanceNonPropertyFields(cNode));
    }
    final List<Parameter> params = new ArrayList<Parameter>();
    final List<Expression> superParams = new ArrayList<Expression>();
    final BlockStatement preBody = new BlockStatement();
    boolean superInPre = false;
    if (pre != null) {
        superInPre = copyStatementsWithSuperAdjustment(pre, preBody);
        if (superInPre && callSuper) {
            xform.addError("Error during " + MY_TYPE_NAME + " processing, can't have a super call in 'pre' " + "closure and also 'callSuper' enabled", cNode);
        }
    }
    final BlockStatement body = new BlockStatement();
    for (FieldNode fNode : superList) {
        String name = fNode.getName();
        if (shouldSkipUndefinedAware(name, excludes, includes, allNames))
            continue;
        params.add(createParam(fNode, name, defaults, xform));
        boolean hasSetter = cNode.getProperty(name) != null && !fNode.isFinal();
        if (callSuper) {
            superParams.add(varX(name));
        } else if (!superInPre) {
            if (useSetters && hasSetter) {
                body.addStatement(stmt(callThisX(getSetterName(name), varX(name))));
            } else {
                body.addStatement(assignS(propX(varX("this"), name), varX(name)));
            }
        }
    }
    if (callSuper) {
        body.addStatement(stmt(ctorX(ClassNode.SUPER, args(superParams))));
    }
    if (!preBody.isEmpty()) {
        body.addStatements(preBody.getStatements());
    }
    for (FieldNode fNode : list) {
        String name = fNode.getName();
        if (shouldSkipUndefinedAware(name, excludes, includes, allNames))
            continue;
        Parameter nextParam = createParam(fNode, name, defaults, xform);
        params.add(nextParam);
        boolean hasSetter = cNode.getProperty(name) != null && !fNode.isFinal();
        if (useSetters && hasSetter) {
            body.addStatement(stmt(callThisX(getSetterName(name), varX(nextParam))));
        } else {
            body.addStatement(assignS(propX(varX("this"), name), varX(nextParam)));
        }
    }
    if (post != null) {
        body.addStatement(post.getCode());
    }
    if (includes != null) {
        Comparator<Parameter> includeComparator = new Comparator<Parameter>() {

            public int compare(Parameter p1, Parameter p2) {
                return new Integer(includes.indexOf(p1.getName())).compareTo(includes.indexOf(p2.getName()));
            }
        };
        Collections.sort(params, includeComparator);
    }
    cNode.addConstructor(new ConstructorNode(ACC_PUBLIC, params.toArray(new Parameter[params.size()]), ClassNode.EMPTY_ARRAY, body));
    if (sourceUnit != null && !body.isEmpty()) {
        VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(sourceUnit);
        scopeVisitor.visitClass(cNode);
    }
    // or if there is only one Map property (for backwards compatibility)
    if (!params.isEmpty() && defaults) {
        ClassNode firstParam = params.get(0).getType();
        if (params.size() > 1 || firstParam.equals(ClassHelper.OBJECT_TYPE)) {
            String message = "The class " + cNode.getName() + " was incorrectly initialized via the map constructor with null.";
            if (firstParam.equals(ClassHelper.MAP_TYPE)) {
                addMapConstructors(cNode, true, message);
            } else {
                ClassNode candidate = HMAP_TYPE;
                while (candidate != null) {
                    if (candidate.equals(firstParam)) {
                        addMapConstructors(cNode, true, message);
                        break;
                    }
                    candidate = candidate.getSuperClass();
                }
            }
        }
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) ArrayList(java.util.ArrayList) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Comparator(java.util.Comparator) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ConstructorNode(org.codehaus.groovy.ast.ConstructorNode) Parameter(org.codehaus.groovy.ast.Parameter) VariableScopeVisitor(org.codehaus.groovy.classgen.VariableScopeVisitor)

Example 4 with FieldNode

use of org.codehaus.groovy.ast.FieldNode in project groovy by apache.

the class ImmutableASTTransformation method adjustPropertyForImmutability.

private static void adjustPropertyForImmutability(PropertyNode pNode, List<PropertyNode> newNodes) {
    final FieldNode fNode = pNode.getField();
    fNode.setModifiers((pNode.getModifiers() & (~ACC_PUBLIC)) | ACC_FINAL | ACC_PRIVATE);
    adjustPropertyNode(pNode, createGetterBody(fNode));
    newNodes.add(pNode);
}
Also used : FieldNode(org.codehaus.groovy.ast.FieldNode)

Example 5 with FieldNode

use of org.codehaus.groovy.ast.FieldNode in project groovy by apache.

the class ImmutableASTTransformation method createConstructorStatement.

private Statement createConstructorStatement(ClassNode cNode, PropertyNode pNode, List<String> knownImmutableClasses, List<String> knownImmutables) {
    FieldNode fNode = pNode.getField();
    final ClassNode fieldType = fNode.getType();
    Statement statement = null;
    if (fieldType.isArray() || isOrImplements(fieldType, CLONEABLE_TYPE)) {
        statement = createConstructorStatementArrayOrCloneable(fNode);
    } else if (isKnownImmutableClass(fieldType, knownImmutableClasses) || isKnownImmutable(pNode.getName(), knownImmutables)) {
        statement = createConstructorStatementDefault(fNode);
    } else if (fieldType.isDerivedFrom(DATE_TYPE)) {
        statement = createConstructorStatementDate(fNode);
    } else if (isOrImplements(fieldType, COLLECTION_TYPE) || fieldType.isDerivedFrom(COLLECTION_TYPE) || isOrImplements(fieldType, MAP_TYPE) || fieldType.isDerivedFrom(MAP_TYPE)) {
        statement = createConstructorStatementCollection(fNode);
    } else if (fieldType.isResolved()) {
        addError(createErrorMessage(cNode.getName(), fNode.getName(), fieldType.getName(), "compiling"), fNode);
        statement = EmptyStatement.INSTANCE;
    } else {
        statement = createConstructorStatementGuarded(cNode, fNode);
    }
    return statement;
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement)

Aggregations

FieldNode (org.codehaus.groovy.ast.FieldNode)263 ClassNode (org.codehaus.groovy.ast.ClassNode)161 Expression (org.codehaus.groovy.ast.expr.Expression)91 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)80 MethodNode (org.codehaus.groovy.ast.MethodNode)79 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)75 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)67 Parameter (org.codehaus.groovy.ast.Parameter)64 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)59 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)57 AnnotationNode (org.codehaus.groovy.ast.AnnotationNode)54 ArrayList (java.util.ArrayList)53 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)51 PropertyNode (org.codehaus.groovy.ast.PropertyNode)46 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)45 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)43 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)42 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)39 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)39 AnnotatedNode (org.codehaus.groovy.ast.AnnotatedNode)32