Search in sources :

Example 11 with PropertyNode

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

the class AbstractASTTransformation method checkPropertyList.

protected boolean checkPropertyList(ClassNode cNode, List<String> propertyNameList, String listName, AnnotationNode anno, String typeName, boolean includeFields, boolean includeSuperProperties, boolean allProperties, boolean includeSuperFields) {
    if (propertyNameList == null || propertyNameList.isEmpty()) {
        return true;
    }
    final List<String> pNames = new ArrayList<String>();
    for (PropertyNode pNode : BeanUtils.getAllProperties(cNode, includeSuperProperties, false, allProperties)) {
        pNames.add(pNode.getField().getName());
    }
    boolean result = true;
    if (includeFields || includeSuperFields) {
        final List<String> fNames = new ArrayList<String>();
        if (includeFields) {
            fNames.addAll(getInstanceNonPropertyFieldNames(cNode));
        }
        if (includeSuperFields) {
            List<FieldNode> superNonPropertyFields = getSuperNonPropertyFields(cNode.getSuperClass());
            for (FieldNode fn : superNonPropertyFields) {
                fNames.add(fn.getName());
            }
        }
        for (String pName : propertyNameList) {
            if (!pNames.contains(pName) && !fNames.contains(pName)) {
                addError("Error during " + typeName + " processing: '" + listName + "' property or field '" + pName + "' does not exist.", anno);
                result = false;
            }
        }
    } else {
        for (String pName : propertyNameList) {
            if (!pNames.contains(pName)) {
                addError("Error during " + typeName + " processing: '" + listName + "' property '" + pName + "' does not exist.", anno);
                result = false;
            }
        }
    }
    return result;
}
Also used : FieldNode(org.codehaus.groovy.ast.FieldNode) PropertyNode(org.codehaus.groovy.ast.PropertyNode) ArrayList(java.util.ArrayList)

Example 12 with PropertyNode

use of org.codehaus.groovy.ast.PropertyNode 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 13 with PropertyNode

use of org.codehaus.groovy.ast.PropertyNode 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 14 with PropertyNode

use of org.codehaus.groovy.ast.PropertyNode 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 15 with PropertyNode

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

the class StaticTypeCheckingVisitor method visitVariableExpression.

@Override
public void visitVariableExpression(VariableExpression vexp) {
    super.visitVariableExpression(vexp);
    if (storeTypeForThis(vexp))
        return;
    if (storeTypeForSuper(vexp))
        return;
    if (vexp.getAccessedVariable() instanceof PropertyNode) {
        // overloaded setters, the type of the property node is arbitrary!
        if (tryVariableExpressionAsProperty(vexp, vexp.getName())) {
            BinaryExpression enclosingBinaryExpression = typeCheckingContext.getEnclosingBinaryExpression();
            if (enclosingBinaryExpression != null) {
                Expression leftExpression = enclosingBinaryExpression.getLeftExpression();
                Expression rightExpression = enclosingBinaryExpression.getRightExpression();
                SetterInfo setterInfo = removeSetterInfo(leftExpression);
                if (setterInfo != null) {
                    if (!ensureValidSetter(vexp, leftExpression, rightExpression, setterInfo)) {
                        return;
                    }
                }
            }
        }
    }
    TypeCheckingContext.EnclosingClosure enclosingClosure = typeCheckingContext.getEnclosingClosure();
    if (enclosingClosure != null) {
        String name = vexp.getName();
        if (name.equals("owner") || name.equals("thisObject")) {
            storeType(vexp, typeCheckingContext.getEnclosingClassNode());
            return;
        } else if ("delegate".equals(name)) {
            DelegationMetadata md = getDelegationMetadata(enclosingClosure.getClosureExpression());
            ClassNode type = typeCheckingContext.getEnclosingClassNode();
            if (md != null)
                type = md.getType();
            storeType(vexp, type);
            return;
        }
    }
    if (!(vexp.getAccessedVariable() instanceof DynamicVariable))
        return;
    // a dynamic variable is either an undeclared variable
    // or a member of a class used in a 'with'
    DynamicVariable dyn = (DynamicVariable) vexp.getAccessedVariable();
    // first, we must check the 'with' context
    String dynName = dyn.getName();
    if (tryVariableExpressionAsProperty(vexp, dynName))
        return;
    if (!extension.handleUnresolvedVariableExpression(vexp)) {
        addStaticTypeError("The variable [" + vexp.getName() + "] is undeclared.", vexp);
    }
}
Also used : LowestUpperBoundClassNode(org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) DynamicVariable(org.codehaus.groovy.ast.DynamicVariable) PropertyNode(org.codehaus.groovy.ast.PropertyNode)

Aggregations

PropertyNode (org.codehaus.groovy.ast.PropertyNode)71 ClassNode (org.codehaus.groovy.ast.ClassNode)36 FieldNode (org.codehaus.groovy.ast.FieldNode)30 ArrayList (java.util.ArrayList)25 MethodNode (org.codehaus.groovy.ast.MethodNode)19 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)16 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)12 Parameter (org.codehaus.groovy.ast.Parameter)11 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)10 Expression (org.codehaus.groovy.ast.expr.Expression)10 LowestUpperBoundClassNode (org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode)8 AnnotationNode (org.codehaus.groovy.ast.AnnotationNode)7 ConstructorNode (org.codehaus.groovy.ast.ConstructorNode)6 DynamicVariable (org.codehaus.groovy.ast.DynamicVariable)6 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)6 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)6 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)6 SyntaxErrorMessage (org.codehaus.groovy.control.messages.SyntaxErrorMessage)6 SyntaxException (org.codehaus.groovy.syntax.SyntaxException)6 HashSet (java.util.HashSet)5