Java Code Examples for org.codehaus.groovy.ast.ClassNode#isArray()

The following examples show how to use org.codehaus.groovy.ast.ClassNode#isArray() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ClassCompletionVerifier.java    From groovy with Apache License 2.0 6 votes vote down vote up
private void checkGenericsUsage(ASTNode ref, ClassNode node) {
    if (node.isArray()) {
        checkGenericsUsage(ref, node.getComponentType());
    } else if (!node.isRedirectNode() && node.isUsingGenerics()) {
        addError(
                "A transform used a generics containing ClassNode "+ node + " " +
                "for "+getRefDescriptor(ref) +
                "directly. You are not supposed to do this. " +
                "Please create a new ClassNode referring to the old ClassNode " +
                "and use the new ClassNode instead of the old one. Otherwise " +
                "the compiler will create wrong descriptors and a potential " +
                "NullPointerException in TypeResolver in the OpenJDK. If this is " +
                "not your own doing, please report this bug to the writer of the " +
                "transform.",
                ref);
    }
}
 
Example 2
Source File: InstanceOfVerifier.java    From groovy with Apache License 2.0 6 votes vote down vote up
@Override
public void visitBinaryExpression(BinaryExpression expression) {
    if (expression.getOperation().isA(Types.INSTANCEOF_OPERATOR) &&
            expression.getRightExpression() instanceof ClassExpression) {
        ClassNode referenceType = expression.getRightExpression().getType();

        if (ClassHelper.isPrimitiveType(referenceType)) {
            addTypeError(expression.getRightExpression(), "primitive type " + referenceType.getName());
        } else {
            while (referenceType.isArray()) {
                referenceType = referenceType.getComponentType();
            }

            if (referenceType.isGenericsPlaceHolder()) {
                addTypeError(expression.getRightExpression(), "type parameter " + referenceType.getUnresolvedName() +
                    ". Use its erasure " + referenceType.getNameWithoutPackage() + " instead since further generic type information will be erased at runtime");
            } else if (referenceType.getGenericsTypes() != null) {
                // TODO: Cannot perform instanceof check against parameterized type Class<Type>. Use the form Class<?> instead since further eneric type information will be erased at runtime
            }
        }
    }
    super.visitBinaryExpression(expression);
}
 
Example 3
Source File: ImmutablePropertyHandler.java    From groovy with Apache License 2.0 6 votes vote down vote up
@Override
public Statement createPropGetter(PropertyNode pNode) {
    FieldNode fNode = pNode.getField();
    BlockStatement body = new BlockStatement();
    final ClassNode fieldType = fNode.getType();
    final Statement statement;
    if (fieldType.isArray() || implementsCloneable(fieldType)) {
        statement = createGetterBodyArrayOrCloneable(fNode);
    } else if (derivesFromDate(fieldType)) {
        statement = createGetterBodyDate(fNode);
    } else {
        statement = createGetterBodyDefault(fNode);
    }
    body.addStatement(statement);
    return body;
}
 
Example 4
Source File: StaticTypeCheckingSupport.java    From groovy with Apache License 2.0 5 votes vote down vote up
/**
 * @param node the node to be tested
 * @return true if the node is using generics types and one of those types is a string
 */
public static boolean isParameterizedWithString(final ClassNode node) {
    if (node.isArray()) return isParameterizedWithString(node.getComponentType());
    if (node.isUsingGenerics()) {
        GenericsType[] genericsTypes = node.getGenericsTypes();
        if (genericsTypes != null) {
            for (GenericsType genericsType : genericsTypes) {
                if (STRING_TYPE.equals(genericsType.getType())) return true;
            }
        }
    }
    return node.getSuperClass() != null && isParameterizedWithString(node.getUnresolvedSuperClass());
}
 
Example 5
Source File: BinaryExpressionMultiTypeDispatcher.java    From groovy with Apache License 2.0 5 votes vote down vote up
@Override
protected void assignToArray(final Expression orig, final Expression receiver, final Expression index, final Expression rhsValueLoader, final boolean safe) {
    ClassNode current = controller.getClassNode();
    ClassNode arrayType = controller.getTypeChooser().resolveType(receiver, current);
    ClassNode arrayComponentType = arrayType.getComponentType();
    int operationType = getOperandType(arrayComponentType);
    BinaryExpressionWriter bew = binExpWriter[operationType];
    AsmClassGenerator acg = controller.getAcg();

    if (bew.arraySet(true) && arrayType.isArray() && !safe) {
        OperandStack operandStack   =   controller.getOperandStack();

        // load the array
        receiver.visit(acg);
        operandStack.doGroovyCast(arrayType);

        // load index
        index.visit(acg);
        operandStack.doGroovyCast(int_TYPE);

        // load rhs
        rhsValueLoader.visit(acg);
        operandStack.doGroovyCast(arrayComponentType);

        // store value in array
        bew.arraySet(false);

        // load return value && correct operand stack stack
        operandStack.remove(3);
        rhsValueLoader.visit(acg);
    } else {
        super.assignToArray(orig, receiver, index, rhsValueLoader, safe);
    }
}
 
Example 6
Source File: StaticTypeCheckingSupport.java    From groovy with Apache License 2.0 5 votes vote down vote up
private static boolean inferenceCheck(final Set<GenericsTypeName> fixedGenericsPlaceHolders, final Map<GenericsTypeName, GenericsType> resolvedMethodGenerics, ClassNode type, ClassNode wrappedArgument, final boolean lastArg) {
    Map<GenericsTypeName, GenericsType> connections = new HashMap<>();
    if (isPrimitiveType(wrappedArgument)) wrappedArgument = getWrapper(wrappedArgument);

    if (lastArg &&
            type.isArray() && type.getComponentType().isGenericsPlaceHolder() &&
            !wrappedArgument.isArray() && wrappedArgument.isGenericsPlaceHolder()) {
        // GROOVY-8090: handle generics varargs, e.g. "U x = ...; Arrays.asList(x)"
        // we should connect the type of vararg(e.g. T is the type of T...) to the argument type
        type = type.getComponentType();
    }
    // the context we compare with in the end is the one of the callsite
    // so far we specified the context of the method declaration only
    // thus for each argument, we try to find the connected generics first
    extractGenericsConnections(connections, wrappedArgument, type);
    // each found connection must comply with already found connections
    boolean failure = !compatibleConnections(connections, resolvedMethodGenerics, fixedGenericsPlaceHolders);
    // and then apply the found information to refine the method level
    // information. This way the method level information slowly turns
    // into information for the callsite
    applyGenericsConnections(connections, resolvedMethodGenerics);
    // since it is possible that the callsite uses some generics as well,
    // we may have to add additional elements here
    addMissingEntries(connections, resolvedMethodGenerics);
    // to finally see if the parameter and the argument fit together,
    // we use the provided information to transform the parameter
    // into something that can exist in the callsite context
    type = applyGenericsContext(resolvedMethodGenerics, type);
    // there of course transformed parameter type and argument must fit
    failure = failure || !typeCheckMethodArgumentWithGenerics(type, wrappedArgument, lastArg);
    return failure;
}
 
Example 7
Source File: JavaStubGenerator.java    From groovy with Apache License 2.0 5 votes vote down vote up
private void printType(PrintWriter out, ClassNode type) {
    if (type.isArray()) {
        printType(out, type.getComponentType());
        out.print("[]");
    } else if (java5 && type.isGenericsPlaceHolder()) {
        out.print(type.getUnresolvedName());
    } else {
        printGenericsBounds(out, type, false);
    }
}
 
Example 8
Source File: MemberSignatureParser.java    From groovy with Apache License 2.0 5 votes vote down vote up
private static ClassNode applyErasure(ClassNode genericType, ClassNode erasure) {
    if (genericType.isArray() && erasure.isArray() && genericType.getComponentType().isGenericsPlaceHolder()) {
        genericType.setRedirect(erasure);
        genericType.getComponentType().setRedirect(erasure.getComponentType());
    } else if (genericType.isGenericsPlaceHolder()) {
        genericType.setRedirect(erasure);
    }
    return genericType;
}
 
Example 9
Source File: StaticTypeCheckingSupport.java    From groovy with Apache License 2.0 5 votes vote down vote up
/**
 * Checks that the parameterized generics of an argument are compatible with the generics of the parameter.
 *
 * @param parameterType the parameter type of a method
 * @param argumentType  the type of the argument passed to the method
 */
protected static boolean typeCheckMethodArgumentWithGenerics(final ClassNode parameterType, final ClassNode argumentType, final boolean lastArg) {
    if (UNKNOWN_PARAMETER_TYPE == argumentType) {
        // called with null
        return !isPrimitiveType(parameterType);
    }
    if (!isAssignableTo(argumentType, parameterType) && !lastArg) {
        // incompatible assignment
        return false;
    }
    if (!isAssignableTo(argumentType, parameterType) && lastArg) {
        if (parameterType.isArray()) {
            if (!isAssignableTo(argumentType, parameterType.getComponentType())) {
                return false;
            }
        } else {
            return false;
        }
    }
    if (parameterType.isUsingGenerics() && argumentType.isUsingGenerics()) {
        GenericsType gt = GenericsUtils.buildWildcardType(parameterType);
        if (!gt.isCompatibleWith(argumentType)) {
            boolean samCoercion = isSAMType(parameterType) && argumentType.equals(CLOSURE_TYPE);
            if (!samCoercion) return false;
        }
    } else if (parameterType.isArray() && argumentType.isArray()) {
        // verify component type
        return typeCheckMethodArgumentWithGenerics(parameterType.getComponentType(), argumentType.getComponentType(), lastArg);
    } else if (lastArg && parameterType.isArray()) {
        // verify component type, but if we reach that point, the only possibility is that the argument is
        // the last one of the call, so we're in the cast of a vargs call
        // (otherwise, we face a type checker bug)
        return typeCheckMethodArgumentWithGenerics(parameterType.getComponentType(), argumentType, lastArg);
    }
    return true;
}
 
Example 10
Source File: StaticTypeCheckingSupport.java    From groovy with Apache License 2.0 5 votes vote down vote up
public static boolean implementsInterfaceOrIsSubclassOf(final ClassNode type, final ClassNode superOrInterface) {
    boolean result = (type.equals(superOrInterface)
            || type.isDerivedFrom(superOrInterface)
            || type.implementsInterface(superOrInterface)
            || type == UNKNOWN_PARAMETER_TYPE);
    if (result) {
        return true;
    }
    if (superOrInterface instanceof WideningCategories.LowestUpperBoundClassNode) {
        WideningCategories.LowestUpperBoundClassNode cn = (WideningCategories.LowestUpperBoundClassNode) superOrInterface;
        result = implementsInterfaceOrIsSubclassOf(type, cn.getSuperClass());
        if (result) {
            for (ClassNode interfaceNode : cn.getInterfaces()) {
                result = type.implementsInterface(interfaceNode);
                if (!result) break;
            }
        }
        if (result) return true;
    } else if (superOrInterface instanceof UnionTypeClassNode) {
        UnionTypeClassNode union = (UnionTypeClassNode) superOrInterface;
        for (ClassNode delegate : union.getDelegates()) {
            if (implementsInterfaceOrIsSubclassOf(type, delegate)) return true;
        }
    }
    if (type.isArray() && superOrInterface.isArray()) {
        return implementsInterfaceOrIsSubclassOf(type.getComponentType(), superOrInterface.getComponentType());
    }
    if (GROOVY_OBJECT_TYPE.equals(superOrInterface) && !type.isInterface() && isBeingCompiled(type)) {
        return true;
    }
    return false;
}
 
Example 11
Source File: InvocationWriter.java    From groovy with Apache License 2.0 5 votes vote down vote up
protected void loadArguments(final List<Expression> argumentList, final Parameter[] para) {
    if (para.length == 0) return;
    ClassNode lastParaType = para[para.length - 1].getOriginType();
    AsmClassGenerator acg = controller.getAcg();
    OperandStack operandStack = controller.getOperandStack();
    if (lastParaType.isArray() && (argumentList.size() > para.length
            || argumentList.size() == para.length - 1 || !lastIsArray(argumentList, para.length - 1))) {
        int stackLen = operandStack.getStackLength() + argumentList.size();
        MethodVisitor mv = controller.getMethodVisitor();
        controller.setMethodVisitor(mv);
        // varg call
        // first parameters as usual
        for (int i = 0, n = para.length - 1; i < n; i += 1) {
            argumentList.get(i).visit(acg);
            operandStack.doGroovyCast(para[i].getType());
        }
        // last parameters wrapped in an array
        List<Expression> lastParams = new LinkedList<>();
        for (int i = para.length - 1, n = argumentList.size(); i < n; i += 1) {
            lastParams.add(argumentList.get(i));
        }
        ArrayExpression array = new ArrayExpression(
                lastParaType.getComponentType(),
                lastParams
        );
        array.visit(acg);
        // adjust stack length
        while (operandStack.getStackLength() < stackLen) {
            operandStack.push(ClassHelper.OBJECT_TYPE);
        }
        if (argumentList.size() == para.length - 1) {
            operandStack.remove(1);
        }
    } else {
        for (int i = 0, n = argumentList.size(); i < n; i += 1) {
            argumentList.get(i).visit(acg);
            operandStack.doGroovyCast(para[i].getType());
        }
    }
}
 
Example 12
Source File: StaticTypesStatementWriter.java    From groovy with Apache License 2.0 5 votes vote down vote up
@Override
protected void writeForInLoop(final ForStatement loop) {
    controller.getAcg().onLineNumber(loop,"visitForLoop");
    writeStatementLabel(loop);

    CompileStack compileStack = controller.getCompileStack();
    MethodVisitor mv = controller.getMethodVisitor();
    OperandStack operandStack = controller.getOperandStack();

    compileStack.pushLoop(loop.getVariableScope(), loop.getStatementLabels());

    // Identify type of collection
    TypeChooser typeChooser = controller.getTypeChooser();
    Expression collectionExpression = loop.getCollectionExpression();
    ClassNode collectionType = typeChooser.resolveType(collectionExpression, controller.getClassNode());
    Parameter loopVariable = loop.getVariable();
    int size = operandStack.getStackLength();
    if (collectionType.isArray() && loopVariable.getOriginType().equals(collectionType.getComponentType())) {
        writeOptimizedForEachLoop(compileStack, operandStack, mv, loop, collectionExpression, collectionType, loopVariable);
    } else if (ENUMERATION_CLASSNODE.equals(collectionType)) {
        writeEnumerationBasedForEachLoop(compileStack, operandStack, mv, loop, collectionExpression, collectionType, loopVariable);
    } else {
        writeIteratorBasedForEachLoop(compileStack, operandStack, mv, loop, collectionExpression, collectionType, loopVariable);
    }
    operandStack.popDownTo(size);
    compileStack.pop();
}
 
Example 13
Source File: ExpressionUtils.java    From groovy with Apache License 2.0 5 votes vote down vote up
/**
 * Determine if a type is derived from Number (or array thereof).
 *
 * @param targetType the candidate type
 * @param recurse true if we can have multi-dimension arrays; should be false for annotation member types
 * @return true if the type equals the targetType or array thereof
 */
public static boolean isNumberOrArrayOfNumber(final ClassNode targetType, final boolean recurse) {
    if (targetType == null) return false;
    return targetType.isDerivedFrom(ClassHelper.Number_TYPE) ||
            (targetType.isArray() && recurse
            ? isNumberOrArrayOfNumber(targetType.getComponentType(), recurse)
            : targetType.isArray() && targetType.getComponentType().isDerivedFrom(ClassHelper.Number_TYPE));
}
 
Example 14
Source File: GroovydocVisitor.java    From groovy with Apache License 2.0 5 votes vote down vote up
private String makeType(ClassNode node) {
    final ClassNode cn = node.isArray() ? node.getComponentType() : node;
    return cn.getName().replace('.', '/').replace('$', '.')
        + genericTypesAsString(cn.getGenericsTypes())
        + (node.isArray() ? "[]" : "")
        ;
}
 
Example 15
Source File: StaticTypeCheckingSupport.java    From groovy with Apache License 2.0 4 votes vote down vote up
public static boolean checkCompatibleAssignmentTypes(final ClassNode left, final ClassNode right, final Expression rightExpression, final boolean allowConstructorCoercion) {
    ClassNode leftRedirect = left.redirect();
    ClassNode rightRedirect = right.redirect();
    if (leftRedirect == rightRedirect) return true;

    if (leftRedirect.isArray() && rightRedirect.isArray()) {
        return checkCompatibleAssignmentTypes(leftRedirect.getComponentType(), rightRedirect.getComponentType(), rightExpression, false);
    }

    if (right == VOID_TYPE || right == void_WRAPPER_TYPE) {
        return left == VOID_TYPE || left == void_WRAPPER_TYPE;
    }

    if ((isNumberType(rightRedirect) || WideningCategories.isNumberCategory(rightRedirect))) {
        if (BigDecimal_TYPE == leftRedirect) {
            // any number can be assigned to a big decimal
            return true;
        }
        if (BigInteger_TYPE == leftRedirect) {
            return WideningCategories.isBigIntCategory(getUnwrapper(rightRedirect)) || rightRedirect.isDerivedFrom(BigInteger_TYPE);
        }
    }

    // if rightExpression is null and leftExpression is not a primitive type, it's ok
    boolean rightExpressionIsNull = (rightExpression instanceof ConstantExpression && ((ConstantExpression) rightExpression).isNullExpression());
    if (rightExpressionIsNull && !isPrimitiveType(left)) {
        return true;
    }

    // on an assignment everything that can be done by a GroovyCast is allowed

    // anything can be assigned to an Object, String, Boolean or Class typed variable
    if (isWildcardLeftHandSide(leftRedirect) && !(boolean_TYPE.equals(left) && rightExpressionIsNull)) return true;

    // char as left expression
    if (leftRedirect == char_TYPE && rightRedirect == STRING_TYPE) {
        if (rightExpression instanceof ConstantExpression) {
            String value = rightExpression.getText();
            return value.length() == 1;
        }
    }
    if (leftRedirect == Character_TYPE && (rightRedirect == STRING_TYPE || rightExpressionIsNull)) {
        return rightExpressionIsNull || (rightExpression instanceof ConstantExpression && rightExpression.getText().length() == 1);
    }

    // if left is Enum and right is String or GString we do valueOf
    if (leftRedirect.isDerivedFrom(Enum_Type) && (rightRedirect == GSTRING_TYPE || rightRedirect == STRING_TYPE)) {
        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 (leftRedirect.isArray() && rightRedirect.isArray()) {
            return checkCompatibleAssignmentTypes(leftRedirect.getComponentType(), rightRedirect.getComponentType());
        } else 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 (WideningCategories.isFloatingCategory(leftRedirect) && BigDecimal_TYPE.equals(rightRedirect)) {
        return true;
    }

    if (GROOVY_OBJECT_TYPE.equals(leftRedirect) && isBeingCompiled(right)) {
        return true;
    }

    if (left.isGenericsPlaceHolder()) {
        // GROOVY-7307
        GenericsType[] genericsTypes = left.getGenericsTypes();
        if (genericsTypes != null && genericsTypes.length == 1) {
            // should always be the case, but safe guard is better
            return genericsTypes[0].isCompatibleWith(right);
        }
    }

    // GROOVY-7316: It is an apparently legal thing to allow this. It's not type safe, but it is allowed...
    return right.isGenericsPlaceHolder();
}
 
Example 16
Source File: StaticTypeCheckingSupport.java    From groovy with Apache License 2.0 4 votes vote down vote up
static String prettyPrintType(ClassNode type) {
    if (type.isArray()) {
        return prettyPrintType(type.getComponentType()) + "[]";
    }
    return type.toString(false);
}
 
Example 17
Source File: StaticTypeCheckingSupport.java    From groovy with Apache License 2.0 4 votes vote down vote up
static GenericsType[] getGenericsWithoutArray(final ClassNode type) {
    if (type.isArray()) return getGenericsWithoutArray(type.getComponentType());
    return type.getGenericsTypes();
}
 
Example 18
Source File: MemoizedASTTransformation.java    From groovy with Apache License 2.0 4 votes vote down vote up
private static String buildTypeName(ClassNode type) {
    if (type.isArray()) {
        return String.format("%sArray", buildTypeName(type.getComponentType()));
    }
    return type.getNameWithoutPackage();
}
 
Example 19
Source File: InvocationWriter.java    From groovy with Apache License 2.0 4 votes vote down vote up
private boolean lastIsArray(final List<Expression> argumentList, final int pos) {
    Expression last = argumentList.get(pos);
    ClassNode type = controller.getTypeChooser().resolveType(last, controller.getClassNode());
    return type.isArray();
}
 
Example 20
Source File: BytecodeHelper.java    From groovy with Apache License 2.0 3 votes vote down vote up
/**
 * array types are special:
 * eg.: String[]: classname: [Ljava.lang.String;
 * Object:   classname: java.lang.Object
 * int[] :   classname: [I
 * unlike getTypeDescription '.' is not replaced by '/'.
 * it seems that makes problems for
 * the class loading if '.' is replaced by '/'
 *
 * @return the ASM type description for class loading
 */
public static String getClassLoadingTypeDescription(ClassNode c) {
    String desc = TypeUtil.getDescriptionByType(c);
    if (!c.isArray()) {
        if (desc.startsWith("L") && desc.endsWith(";")) {
            desc = desc.substring(1, desc.length() - 1); // remove "L" and ";"
        }
    }
    return desc.replace('/', '.');
}