Search in sources :

Example 66 with ListExpression

use of org.codehaus.groovy.ast.expr.ListExpression in project groovy by apache.

the class AsmClassGenerator method visitAnnotationDefaultExpression.

private void visitAnnotationDefaultExpression(final AnnotationVisitor av, final ClassNode type, final Expression exp) {
    if (exp instanceof ClosureExpression) {
        ClassNode closureClass = controller.getClosureWriter().getOrAddClosureClass((ClosureExpression) exp, ACC_PUBLIC);
        Type t = Type.getType(BytecodeHelper.getTypeDescription(closureClass));
        av.visit(null, t);
    } else if (type.isArray()) {
        AnnotationVisitor avl = av.visitArray(null);
        ClassNode componentType = type.getComponentType();
        if (exp instanceof ListExpression) {
            ListExpression list = (ListExpression) exp;
            for (Expression lExp : list.getExpressions()) {
                visitAnnotationDefaultExpression(avl, componentType, lExp);
            }
        } else {
            visitAnnotationDefaultExpression(avl, componentType, exp);
        }
    } else if (isPrimitiveType(type) || isStringType(type)) {
        ConstantExpression constExp = (ConstantExpression) exp;
        av.visit(null, constExp.getValue());
    } else if (isClassType(type)) {
        ClassNode clazz = exp.getType();
        Type t = Type.getType(BytecodeHelper.getTypeDescription(clazz));
        av.visit(null, t);
    } else if (type.isDerivedFrom(ClassHelper.Enum_Type)) {
        PropertyExpression pExp = (PropertyExpression) exp;
        ClassExpression cExp = (ClassExpression) pExp.getObjectExpression();
        String desc = BytecodeHelper.getTypeDescription(cExp.getType());
        String name = pExp.getPropertyAsString();
        av.visitEnum(null, desc, name);
    } else if (type.implementsInterface(ClassHelper.Annotation_TYPE)) {
        AnnotationConstantExpression avExp = (AnnotationConstantExpression) exp;
        AnnotationNode value = (AnnotationNode) avExp.getValue();
        AnnotationVisitor avc = av.visitAnnotation(null, BytecodeHelper.getTypeDescription(avExp.getType()));
        visitAnnotationAttributes(value, avc);
    } else {
        throw new GroovyBugError("unexpected annotation type " + type.getName());
    }
    av.visitEnd();
}
Also used : InterfaceHelperClassNode(org.codehaus.groovy.ast.InterfaceHelperClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) AnnotationConstantExpression(org.codehaus.groovy.ast.expr.AnnotationConstantExpression) ClosureListExpression(org.codehaus.groovy.ast.expr.ClosureListExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) AnnotationConstantExpression(org.codehaus.groovy.ast.expr.AnnotationConstantExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) GroovyBugError(org.codehaus.groovy.GroovyBugError) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) ClassHelper.isStringType(org.codehaus.groovy.ast.ClassHelper.isStringType) GenericsType(org.codehaus.groovy.ast.GenericsType) ClassHelper.isObjectType(org.codehaus.groovy.ast.ClassHelper.isObjectType) ClassHelper.isClassType(org.codehaus.groovy.ast.ClassHelper.isClassType) ClassHelper.isPrimitiveType(org.codehaus.groovy.ast.ClassHelper.isPrimitiveType) Type(org.objectweb.asm.Type) UnaryMinusExpression(org.codehaus.groovy.ast.expr.UnaryMinusExpression) ClosureListExpression(org.codehaus.groovy.ast.expr.ClosureListExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) MethodReferenceExpression(org.codehaus.groovy.ast.expr.MethodReferenceExpression) TernaryExpression(org.codehaus.groovy.ast.expr.TernaryExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) PrefixExpression(org.codehaus.groovy.ast.expr.PrefixExpression) PostfixExpression(org.codehaus.groovy.ast.expr.PostfixExpression) Expression(org.codehaus.groovy.ast.expr.Expression) UnaryPlusExpression(org.codehaus.groovy.ast.expr.UnaryPlusExpression) AnnotationConstantExpression(org.codehaus.groovy.ast.expr.AnnotationConstantExpression) BitwiseNegationExpression(org.codehaus.groovy.ast.expr.BitwiseNegationExpression) MapExpression(org.codehaus.groovy.ast.expr.MapExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) NotExpression(org.codehaus.groovy.ast.expr.NotExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) EmptyExpression(org.codehaus.groovy.ast.expr.EmptyExpression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) MethodPointerExpression(org.codehaus.groovy.ast.expr.MethodPointerExpression) MapEntryExpression(org.codehaus.groovy.ast.expr.MapEntryExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) LambdaExpression(org.codehaus.groovy.ast.expr.LambdaExpression) GStringExpression(org.codehaus.groovy.ast.expr.GStringExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) RangeExpression(org.codehaus.groovy.ast.expr.RangeExpression) SpreadExpression(org.codehaus.groovy.ast.expr.SpreadExpression) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) SpreadMapExpression(org.codehaus.groovy.ast.expr.SpreadMapExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) AttributeExpression(org.codehaus.groovy.ast.expr.AttributeExpression) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) AnnotationVisitor(org.objectweb.asm.AnnotationVisitor) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression)

Example 67 with ListExpression

use of org.codehaus.groovy.ast.expr.ListExpression in project groovy by apache.

the class AnnotationVisitor method visitExpression.

protected void visitExpression(String attrName, Expression attrExp, ClassNode attrType) {
    if (attrType.isArray()) {
        // check needed as @Test(attr = {"elem"}) passes through the parser
        if (attrExp instanceof ListExpression) {
            ListExpression le = (ListExpression) attrExp;
            visitListExpression(attrName, le, attrType.getComponentType());
        } else if (attrExp instanceof ClosureExpression) {
            addError("Annotation list attributes must use Groovy notation [el1, el2]", attrExp);
        } else {
            // treat like a singleton list as per Java
            ListExpression listExp = new ListExpression();
            listExp.addExpression(attrExp);
            if (annotation != null) {
                annotation.setMember(attrName, listExp);
            }
            visitExpression(attrName, listExp, attrType);
        }
    } else if (ClassHelper.isPrimitiveType(attrType)) {
        visitConstantExpression(attrName, getConstantExpression(attrExp, attrType), ClassHelper.getWrapper(attrType));
    } else if (isStringType(attrType)) {
        visitConstantExpression(attrName, getConstantExpression(attrExp, attrType), ClassHelper.STRING_TYPE);
    } else if (isClassType(attrType)) {
        if (!(attrExp instanceof ClassExpression || attrExp instanceof ClosureExpression)) {
            addError("Only classes and closures can be used for attribute '" + attrName + "'", attrExp);
        }
    } else if (attrType.isDerivedFrom(ClassHelper.Enum_Type)) {
        if (attrExp instanceof PropertyExpression) {
            visitEnumExpression(attrName, (PropertyExpression) attrExp, attrType);
        } else if (attrExp instanceof ConstantExpression) {
            visitConstantExpression(attrName, getConstantExpression(attrExp, attrType), attrType);
        } else {
            addError("Expected enum value for attribute " + attrName, attrExp);
        }
    } else if (isValidAnnotationClass(attrType)) {
        if (attrExp instanceof AnnotationConstantExpression) {
            visitAnnotationExpression(attrName, (AnnotationConstantExpression) attrExp, attrType);
        } else {
            addError("Expected annotation of type '" + attrType.getName() + "' for attribute " + attrName, attrExp);
        }
    } else {
        addError("Unexpected type " + attrType.getName(), attrExp);
    }
}
Also used : AnnotationConstantExpression(org.codehaus.groovy.ast.expr.AnnotationConstantExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) AnnotationConstantExpression(org.codehaus.groovy.ast.expr.AnnotationConstantExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression)

Example 68 with ListExpression

use of org.codehaus.groovy.ast.expr.ListExpression in project groovy by apache.

the class MixinASTTransformation method visit.

@Override
public void visit(ASTNode[] nodes, SourceUnit source) {
    init(nodes, source);
    AnnotationNode node = (AnnotationNode) nodes[0];
    AnnotatedNode parent = (AnnotatedNode) nodes[1];
    if (!MY_TYPE.equals(node.getClassNode()))
        return;
    final Expression expr = node.getMember("value");
    if (expr == null) {
        return;
    }
    Expression useClasses = null;
    if (expr instanceof ClassExpression) {
        useClasses = expr;
    } else if (expr instanceof ListExpression) {
        ListExpression listExpression = (ListExpression) expr;
        for (Expression ex : listExpression.getExpressions()) {
            if (!(ex instanceof ClassExpression))
                return;
        }
        useClasses = expr;
    }
    if (useClasses == null)
        return;
    if (parent instanceof ClassNode) {
        ClassNode annotatedClass = (ClassNode) parent;
        final Parameter[] noparams = Parameter.EMPTY_ARRAY;
        MethodNode clinit = annotatedClass.getDeclaredMethod("<clinit>", noparams);
        if (clinit == null) {
            clinit = annotatedClass.addMethod("<clinit>", ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC, ClassHelper.VOID_TYPE, noparams, null, new BlockStatement());
            clinit.setSynthetic(true);
        }
        final BlockStatement code = (BlockStatement) clinit.getCode();
        code.addStatement(stmt(callX(propX(classX(annotatedClass), "metaClass"), "mixin", useClasses)));
    }
}
Also used : ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement)

Example 69 with ListExpression

use of org.codehaus.groovy.ast.expr.ListExpression in project groovy by apache.

the class Annotations method annotationValueToExpression.

private static Expression annotationValueToExpression(Object value, AsmReferenceResolver resolver) {
    if (value instanceof TypeWrapper) {
        ClassNode type = resolver.resolveClassNullable(Type.getType(((TypeWrapper) value).desc).getClassName());
        return type != null ? new ClassExpression(type) : null;
    }
    if (value instanceof EnumConstantWrapper) {
        EnumConstantWrapper wrapper = (EnumConstantWrapper) value;
        return new PropertyExpression(new ClassExpression(resolver.resolveType(Type.getType(wrapper.enumDesc))), wrapper.constant);
    }
    if (value instanceof AnnotationStub) {
        AnnotationNode annotationNode = createAnnotationNode((AnnotationStub) value, resolver);
        return annotationNode != null ? new AnnotationConstantExpression(annotationNode) : nullX();
    }
    if (value != null && value.getClass().isArray()) {
        ListExpression elementExprs = new ListExpression();
        int len = Array.getLength(value);
        for (int i = 0; i != len; ++i) {
            elementExprs.addExpression(annotationValueToExpression(Array.get(value, i), resolver));
        }
        return elementExprs;
    }
    if (value instanceof List) {
        ListExpression elementExprs = new ListExpression();
        for (Object o : (List) value) {
            elementExprs.addExpression(annotationValueToExpression(o, resolver));
        }
        return elementExprs;
    }
    return new ConstantExpression(value);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) AnnotationConstantExpression(org.codehaus.groovy.ast.expr.AnnotationConstantExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) AnnotationConstantExpression(org.codehaus.groovy.ast.expr.AnnotationConstantExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) List(java.util.List)

Example 70 with ListExpression

use of org.codehaus.groovy.ast.expr.ListExpression in project groovy by apache.

the class StaticTypeCheckingSupport method checkCompatibleAssignmentTypes.

/**
 * Everything that can be done by {@code castToType} should be allowed for assignment.
 *
 * @see org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation#castToType(Object,Class)
 */
public static boolean checkCompatibleAssignmentTypes(final ClassNode left, final ClassNode right, final Expression rightExpression, final boolean allowConstructorCoercion) {
    if (!isPrimitiveType(left) && isNullConstant(rightExpression)) {
        return true;
    }
    if (left.isArray()) {
        if (right.isArray()) {
            return checkCompatibleAssignmentTypes(left.getComponentType(), right.getComponentType(), rightExpression, false);
        }
        if (GeneralUtils.isOrImplements(right, Collection_TYPE) && !(rightExpression instanceof ListExpression)) {
            GenericsType elementType = GenericsUtils.parameterizeType(right, Collection_TYPE).getGenericsTypes()[0];
            return // Object[] can accept any collection element type(s)
            OBJECT_TYPE.equals(left.getComponentType()) || (elementType.getLowerBound() == null && isCovariant(extractType(elementType), left.getComponentType()));
        // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ GROOVY-8984: "? super T" is only compatible with an Object[] target
        }
        if (GeneralUtils.isOrImplements(right, BaseStream_TYPE)) {
            GenericsType elementType = GenericsUtils.parameterizeType(right, BaseStream_TYPE).getGenericsTypes()[0];
            return // Object[] can accept any stream API element type(s)
            isObjectType(left.getComponentType()) || (elementType.getLowerBound() == null && isCovariant(extractType(elementType), getWrapper(left.getComponentType())));
        }
    }
    ClassNode leftRedirect = left.redirect();
    ClassNode rightRedirect = right.redirect();
    if (leftRedirect == rightRedirect)
        return true;
    if (rightRedirect == void_WRAPPER_TYPE)
        return leftRedirect == VOID_TYPE;
    if (rightRedirect == VOID_TYPE)
        return leftRedirect == void_WRAPPER_TYPE;
    if (isNumberType(rightRedirect) || isNumberCategory(rightRedirect)) {
        if (isBigDecimalType(leftRedirect) || Number_TYPE.equals(leftRedirect)) {
            // any number can be assigned to BigDecimal or Number
            return true;
        }
        if (isBigIntegerType(leftRedirect)) {
            return isBigIntCategory(getUnwrapper(rightRedirect)) || rightRedirect.isDerivedFrom(BigInteger_TYPE);
        }
    }
    // anything can be assigned to an Object, String, [Bb]oolean or Class receiver; except null to boolean
    if (isWildcardLeftHandSide(left) && !(leftRedirect == boolean_TYPE && isNullConstant(rightExpression)))
        return true;
    if (leftRedirect == char_TYPE && rightRedirect == Character_TYPE)
        return true;
    if (leftRedirect == Character_TYPE && rightRedirect == char_TYPE)
        return true;
    if ((leftRedirect == char_TYPE || leftRedirect == Character_TYPE) && rightRedirect == STRING_TYPE) {
        return rightExpression instanceof ConstantExpression && rightExpression.getText().length() == 1;
    }
    // if left is an enum and right is String or GString we do valueOf
    if (leftRedirect.isDerivedFrom(Enum_Type) && (rightRedirect == STRING_TYPE || isGStringType(rightRedirect))) {
        return true;
    }
    // if right is array, map or collection we try invoking the constructor
    if (allowConstructorCoercion && isGroovyConstructorCompatible(rightExpression)) {
        // TODO: in case of the array we could maybe make a partial check
        if (rightRedirect.isArray() && !leftRedirect.isArray()) {
            return false;
        }
        return true;
    }
    // simple check on being subclass
    if (right.isDerivedFrom(left) || (left.isInterface() && right.implementsInterface(left)))
        return true;
    // if left and right are primitives or numbers allow
    if (isPrimitiveType(leftRedirect) && isPrimitiveType(rightRedirect))
        return true;
    if (isNumberType(leftRedirect) && isNumberType(rightRedirect))
        return true;
    // left is a float/double and right is a BigDecimal
    if (isFloatingCategory(leftRedirect) && isBigDecimalType(rightRedirect)) {
        return true;
    }
    if (isGroovyObjectType(leftRedirect) && isBeingCompiled(right)) {
        return true;
    }
    if (right.isDerivedFrom(CLOSURE_TYPE) && isSAMType(left)) {
        return true;
    }
    if (left.isGenericsPlaceHolder()) {
        return left.getGenericsTypes()[0].isCompatibleWith(right);
    }
    // GROOVY-7316, GROOVY-10256: "Type x = m()" given "def <T> T m()"; T adapts to target
    return right.isGenericsPlaceHolder() && right.asGenericsType().isCompatibleWith(left);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) GenericsType(org.codehaus.groovy.ast.GenericsType)

Aggregations

ListExpression (org.codehaus.groovy.ast.expr.ListExpression)103 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)77 Expression (org.codehaus.groovy.ast.expr.Expression)77 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)70 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)53 ClassNode (org.codehaus.groovy.ast.ClassNode)49 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)43 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)42 MapExpression (org.codehaus.groovy.ast.expr.MapExpression)38 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)38 ArrayExpression (org.codehaus.groovy.ast.expr.ArrayExpression)37 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)32 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)32 ArrayList (java.util.ArrayList)31 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)30 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)28 AnnotationConstantExpression (org.codehaus.groovy.ast.expr.AnnotationConstantExpression)25 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)25 MapEntryExpression (org.codehaus.groovy.ast.expr.MapEntryExpression)23 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)22