Search in sources :

Example 71 with FieldNode

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

the class AutoCloneASTTransformation method addSimpleCloneHelperMethod.

private static void addSimpleCloneHelperMethod(ClassNode cNode, List<FieldNode> fieldNodes, List<String> excludes) {
    Parameter methodParam = new Parameter(GenericsUtils.nonGeneric(cNode), "other");
    final Expression other = varX(methodParam);
    boolean hasParent = cNode.getSuperClass() != ClassHelper.OBJECT_TYPE;
    BlockStatement methodBody = new BlockStatement();
    if (hasParent) {
        methodBody.addStatement(stmt(callSuperX("cloneOrCopyMembers", args(other))));
    }
    for (FieldNode fieldNode : fieldNodes) {
        String name = fieldNode.getName();
        if (excludes != null && excludes.contains(name))
            continue;
        ClassNode fieldType = fieldNode.getType();
        Expression direct = propX(varX("this"), name);
        Expression to = propX(other, name);
        Statement assignDirect = assignS(to, direct);
        Statement assignCloned = assignS(to, castX(fieldType, callCloneDirectX(direct)));
        Statement assignClonedDynamic = assignS(to, castX(fieldType, callCloneDynamicX(direct)));
        if (isCloneableType(fieldType)) {
            methodBody.addStatement(assignCloned);
        } else if (!possiblyCloneable(fieldType)) {
            methodBody.addStatement(assignDirect);
        } else {
            methodBody.addStatement(ifElseS(isInstanceOfX(direct, CLONEABLE_TYPE), assignClonedDynamic, assignDirect));
        }
    }
    ClassNode[] exceptions = { make(CloneNotSupportedException.class) };
    cNode.addMethod("cloneOrCopyMembers", ACC_PROTECTED, ClassHelper.VOID_TYPE, params(methodParam), exceptions, methodBody);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) 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) Statement(org.codehaus.groovy.ast.stmt.Statement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Parameter(org.codehaus.groovy.ast.Parameter) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement)

Example 72 with FieldNode

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

the class CategoryASTTransformation method ensureNoInstanceFieldOrProperty.

private static boolean ensureNoInstanceFieldOrProperty(final SourceUnit source, final ClassNode parent) {
    boolean valid = true;
    for (FieldNode fieldNode : parent.getFields()) {
        if (!fieldNode.isStatic() && fieldNode.getLineNumber() > 0) {
            // if <0, probably an AST transform or internal code (like generated metaclass field, ...)
            addUnsupportedError(fieldNode, source);
            valid = false;
        }
    }
    for (PropertyNode propertyNode : parent.getProperties()) {
        if (!propertyNode.isStatic() && propertyNode.getLineNumber() > 0) {
            // if <0, probably an AST transform or internal code (like generated metaclass field, ...)
            addUnsupportedError(propertyNode, source);
            valid = false;
        }
    }
    return valid;
}
Also used : FieldNode(org.codehaus.groovy.ast.FieldNode) PropertyNode(org.codehaus.groovy.ast.PropertyNode)

Example 73 with FieldNode

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

the class EqualsAndHashCodeASTTransformation method createHashCode.

public static void createHashCode(ClassNode cNode, boolean cacheResult, boolean includeFields, boolean callSuper, List<String> excludes, List<String> includes, boolean allNames) {
    // make a public method if none exists otherwise try a private method with leading underscore
    boolean hasExistingHashCode = hasDeclaredMethod(cNode, "hashCode", 0);
    if (hasExistingHashCode && hasDeclaredMethod(cNode, "_hashCode", 0))
        return;
    final BlockStatement body = new BlockStatement();
    // TODO use pList and fList
    if (cacheResult) {
        final FieldNode hashField = cNode.addField("$hash$code", ACC_PRIVATE | ACC_SYNTHETIC, ClassHelper.int_TYPE, null);
        final Expression hash = varX(hashField);
        body.addStatement(ifS(isZeroX(hash), calculateHashStatements(cNode, hash, includeFields, callSuper, excludes, includes, allNames)));
        body.addStatement(returnS(hash));
    } else {
        body.addStatement(calculateHashStatements(cNode, null, includeFields, callSuper, excludes, includes, allNames));
    }
    cNode.addMethod(new MethodNode(hasExistingHashCode ? "_hashCode" : "hashCode", hasExistingHashCode ? ACC_PRIVATE : ACC_PUBLIC, ClassHelper.int_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, body));
}
Also used : FieldNode(org.codehaus.groovy.ast.FieldNode) MethodNode(org.codehaus.groovy.ast.MethodNode) Expression(org.codehaus.groovy.ast.expr.Expression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement)

Example 74 with FieldNode

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

the class EqualsAndHashCodeASTTransformation method createEquals.

public static void createEquals(ClassNode cNode, boolean includeFields, boolean callSuper, boolean useCanEqual, List<String> excludes, List<String> includes, boolean allNames) {
    if (useCanEqual)
        createCanEqual(cNode);
    // make a public method if none exists otherwise try a private method with leading underscore
    boolean hasExistingEquals = hasDeclaredMethod(cNode, "equals", 1);
    if (hasExistingEquals && hasDeclaredMethod(cNode, "_equals", 1))
        return;
    final BlockStatement body = new BlockStatement();
    VariableExpression other = varX("other");
    // some short circuit cases for efficiency
    body.addStatement(ifS(equalsNullX(other), returnS(constX(Boolean.FALSE, true))));
    body.addStatement(ifS(sameX(varX("this"), other), returnS(constX(Boolean.TRUE, true))));
    if (useCanEqual) {
        body.addStatement(ifS(notX(isInstanceOfX(other, GenericsUtils.nonGeneric(cNode))), returnS(constX(Boolean.FALSE, true))));
    } else {
        body.addStatement(ifS(notX(hasClassX(other, GenericsUtils.nonGeneric(cNode))), returnS(constX(Boolean.FALSE, true))));
    }
    VariableExpression otherTyped = varX("otherTyped", GenericsUtils.nonGeneric(cNode));
    CastExpression castExpression = new CastExpression(GenericsUtils.nonGeneric(cNode), other);
    castExpression.setStrict(true);
    body.addStatement(declS(otherTyped, castExpression));
    if (useCanEqual) {
        body.addStatement(ifS(notX(callX(otherTyped, "canEqual", varX("this"))), returnS(constX(Boolean.FALSE, true))));
    }
    List<PropertyNode> pList = getInstanceProperties(cNode);
    for (PropertyNode pNode : pList) {
        if (shouldSkip(pNode.getName(), excludes, includes, allNames))
            continue;
        boolean canBeSelf = StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(pNode.getOriginType(), cNode);
        if (!canBeSelf) {
            body.addStatement(ifS(notX(hasEqualPropertyX(otherTyped.getOriginType(), pNode, otherTyped)), returnS(constX(Boolean.FALSE, true))));
        } else {
            body.addStatement(ifS(notX(hasSamePropertyX(pNode, otherTyped)), ifElseS(differentSelfRecursivePropertyX(pNode, otherTyped), returnS(constX(Boolean.FALSE, true)), ifS(notX(bothSelfRecursivePropertyX(pNode, otherTyped)), ifS(notX(hasEqualPropertyX(otherTyped.getOriginType(), pNode, otherTyped)), returnS(constX(Boolean.FALSE, true)))))));
        }
    }
    List<FieldNode> fList = new ArrayList<FieldNode>();
    if (includeFields) {
        fList.addAll(getInstanceNonPropertyFields(cNode));
    }
    for (FieldNode fNode : fList) {
        if (shouldSkip(fNode.getName(), excludes, includes, allNames))
            continue;
        body.addStatement(ifS(notX(hasSameFieldX(fNode, otherTyped)), ifElseS(differentSelfRecursiveFieldX(fNode, otherTyped), returnS(constX(Boolean.FALSE, true)), ifS(notX(bothSelfRecursiveFieldX(fNode, otherTyped)), ifS(notX(hasEqualFieldX(fNode, otherTyped)), returnS(constX(Boolean.FALSE, true)))))));
    }
    if (callSuper) {
        body.addStatement(ifS(notX(isTrueX(callSuperX("equals", other))), returnS(constX(Boolean.FALSE, true))));
    }
    // default
    body.addStatement(returnS(constX(Boolean.TRUE, true)));
    cNode.addMethod(new MethodNode(hasExistingEquals ? "_equals" : "equals", hasExistingEquals ? ACC_PRIVATE : ACC_PUBLIC, ClassHelper.boolean_TYPE, params(param(OBJECT_TYPE, other.getName())), ClassNode.EMPTY_ARRAY, body));
}
Also used : FieldNode(org.codehaus.groovy.ast.FieldNode) MethodNode(org.codehaus.groovy.ast.MethodNode) PropertyNode(org.codehaus.groovy.ast.PropertyNode) ArrayList(java.util.ArrayList) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression)

Example 75 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)

Aggregations

FieldNode (org.codehaus.groovy.ast.FieldNode)204 ClassNode (org.codehaus.groovy.ast.ClassNode)126 Expression (org.codehaus.groovy.ast.expr.Expression)58 MethodNode (org.codehaus.groovy.ast.MethodNode)57 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)54 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)50 Parameter (org.codehaus.groovy.ast.Parameter)49 AnnotationNode (org.codehaus.groovy.ast.AnnotationNode)43 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)43 ArrayList (java.util.ArrayList)40 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)38 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)36 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)33 AnnotatedNode (org.codehaus.groovy.ast.AnnotatedNode)31 PropertyNode (org.codehaus.groovy.ast.PropertyNode)30 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)27 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)22 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)19 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)15 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)15