Search in sources :

Example 1 with WildcardType

use of com.sun.tools.javac.code.Type.WildcardType in project ceylon-compiler by ceylon.

the class Attr method visitApply.

/** Visitor method for method invocations.
     *  NOTE: The method part of an application will have in its type field
     *        the return type of the method, not the method's type itself!
     */
public void visitApply(JCMethodInvocation tree) {
    // The local environment of a method application is
    // a new environment nested in the current one.
    Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
    // The types of the actual method arguments.
    List<Type> argtypes;
    // The types of the actual method type arguments.
    List<Type> typeargtypes = null;
    Name methName = TreeInfo.name(tree.meth);
    boolean isConstructorCall = methName == names._this || methName == names._super;
    if (isConstructorCall) {
        // Check that this is the first statement in a constructor.
        if (checkFirstConstructorStat(tree, env)) {
            // Record the fact
            // that this is a constructor call (using isSelfCall).
            localEnv.info.isSelfCall = true;
            // Attribute arguments, yielding list of argument types.
            argtypes = attribArgs(tree.args, localEnv);
            typeargtypes = attribTypes(tree.typeargs, localEnv);
            // Variable `site' points to the class in which the called
            // constructor is defined.
            Type site = env.enclClass.sym.type;
            if (methName == names._super) {
                if (site == syms.objectType) {
                    log.error(tree.meth.pos(), "no.superclass", site);
                    site = types.createErrorType(syms.objectType);
                } else {
                    site = types.supertype(site);
                }
            }
            if (site.tag == CLASS) {
                Type encl = site.getEnclosingType();
                while (encl != null && encl.tag == TYPEVAR) encl = encl.getUpperBound();
                if (encl.tag == CLASS) {
                    if (tree.meth.getTag() == JCTree.SELECT) {
                        JCTree qualifier = ((JCFieldAccess) tree.meth).selected;
                        // We are seeing a prefixed call, of the form
                        //     <expr>.super(...).
                        // Check that the prefix expression conforms
                        // to the outer instance type of the class.
                        chk.checkRefType(qualifier.pos(), attribExpr(qualifier, localEnv, encl));
                    } else if (methName == names._super) {
                        // qualifier omitted; check for existence
                        // of an appropriate implicit qualifier.
                        rs.resolveImplicitThis(tree.meth.pos(), localEnv, site, true);
                    }
                } else if (tree.meth.getTag() == JCTree.SELECT) {
                    log.error(tree.meth.pos(), "illegal.qual.not.icls", site.tsym);
                }
                // prefix the implicit String and int parameters
                if (site.tsym == syms.enumSym && allowEnums)
                    argtypes = argtypes.prepend(syms.intType).prepend(syms.stringType);
                // Resolve the called constructor under the assumption
                // that we are referring to a superclass instance of the
                // current instance (JLS ???).
                boolean selectSuperPrev = localEnv.info.selectSuper;
                localEnv.info.selectSuper = true;
                localEnv.info.varArgs = false;
                Symbol sym = rs.resolveConstructor(tree.meth.pos(), localEnv, site, argtypes, typeargtypes);
                localEnv.info.selectSuper = selectSuperPrev;
                // Set method symbol to resolved constructor...
                TreeInfo.setSymbol(tree.meth, sym);
                // ...and check that it is legal in the current context.
                // (this will also set the tree's type)
                Type mpt = newMethTemplate(argtypes, typeargtypes);
                checkId(tree.meth, site, sym, localEnv, MTH, mpt, tree.varargsElement != null);
            }
        // Otherwise, `site' is an error type and we do nothing
        }
        result = tree.type = syms.voidType;
    } else {
        // Otherwise, we are seeing a regular method call.
        // Attribute the arguments, yielding list of argument types, ...
        argtypes = attribArgs(tree.args, localEnv);
        typeargtypes = attribAnyTypes(tree.typeargs, localEnv);
        // ... and attribute the method using as a prototype a methodtype
        // whose formal argument types is exactly the list of actual
        // arguments (this will also set the method symbol).
        Type mpt = newMethTemplate(argtypes, typeargtypes);
        localEnv.info.varArgs = false;
        Type mtype = attribExpr(tree.meth, localEnv, mpt);
        if (localEnv.info.varArgs)
            Assert.check(mtype.isErroneous() || tree.varargsElement != null);
        // Compute the result type.
        Type restype = mtype.getReturnType();
        if (restype.tag == WILDCARD)
            throw new AssertionError(mtype);
        // the same as static type of the array being cloned
        if (tree.meth.getTag() == JCTree.SELECT && allowCovariantReturns && methName == names.clone && types.isArray(((JCFieldAccess) tree.meth).selected.type))
            restype = ((JCFieldAccess) tree.meth).selected.type;
        // as a special case, x.getClass() has type Class<? extends |X|>
        if (allowGenerics && methName == names.getClass && tree.args.isEmpty()) {
            Type qualifier = (tree.meth.getTag() == JCTree.SELECT) ? ((JCFieldAccess) tree.meth).selected.type : env.enclClass.sym.type;
            restype = new ClassType(restype.getEnclosingType(), List.<Type>of(new WildcardType(types.erasure(qualifier), BoundKind.EXTENDS, syms.boundClass)), restype.tsym);
        }
        chk.checkRefTypes(tree.typeargs, typeargtypes);
        // Check that value of resulting type is admissible in the
        // current context.  Also, capture the return type
        result = check(tree, capture(restype), VAL, pkind, pt);
    }
    chk.validate(tree.typeargs, localEnv);
}
Also used : ClassType(com.sun.tools.javac.code.Type.ClassType) MethodType(com.sun.tools.javac.code.Type.MethodType) WildcardType(com.sun.tools.javac.code.Type.WildcardType) Type(com.sun.tools.javac.code.Type) ArrayType(com.sun.tools.javac.code.Type.ArrayType) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) WildcardType(com.sun.tools.javac.code.Type.WildcardType) JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Symbol(com.sun.tools.javac.code.Symbol) PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) DynamicMethodSymbol(com.sun.tools.javac.code.Symbol.DynamicMethodSymbol) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) OperatorSymbol(com.sun.tools.javac.code.Symbol.OperatorSymbol) JCTree(com.sun.tools.javac.tree.JCTree) ClassType(com.sun.tools.javac.code.Type.ClassType) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) Kinds.kindName(com.sun.tools.javac.code.Kinds.kindName) Name(com.sun.tools.javac.util.Name)

Example 2 with WildcardType

use of com.sun.tools.javac.code.Type.WildcardType in project lombok by rzwitserloot.

the class JavacResolution method typeToJCTree0.

private static JCExpression typeToJCTree0(Type type, JavacAST ast, boolean allowCompound, boolean allowVoid) throws TypeNotConvertibleException {
    // NB: There's such a thing as maker.Type(type), but this doesn't work very well; it screws up anonymous classes, captures, and adds an extra prefix dot for some reason too.
    //  -- so we write our own take on that here.
    JavacTreeMaker maker = ast.getTreeMaker();
    if (CTC_BOT.equals(typeTag(type)))
        return createJavaLangObject(ast);
    if (CTC_VOID.equals(typeTag(type)))
        return allowVoid ? primitiveToJCTree(type.getKind(), maker) : createJavaLangObject(ast);
    if (type.isPrimitive())
        return primitiveToJCTree(type.getKind(), maker);
    if (type.isErroneous())
        throw new TypeNotConvertibleException("Type cannot be resolved");
    TypeSymbol symbol = type.asElement();
    List<Type> generics = type.getTypeArguments();
    JCExpression replacement = null;
    if (symbol == null)
        throw new TypeNotConvertibleException("Null or compound type");
    if (symbol.name.length() == 0) {
        // Anonymous inner class
        if (type instanceof ClassType) {
            List<Type> ifaces = ((ClassType) type).interfaces_field;
            Type supertype = ((ClassType) type).supertype_field;
            if (ifaces != null && ifaces.length() == 1) {
                return typeToJCTree(ifaces.get(0), ast, allowCompound, allowVoid);
            }
            if (supertype != null)
                return typeToJCTree(supertype, ast, allowCompound, allowVoid);
        }
        throw new TypeNotConvertibleException("Anonymous inner class");
    }
    if (type instanceof CapturedType || type instanceof WildcardType) {
        Type lower, upper;
        if (type instanceof WildcardType) {
            upper = ((WildcardType) type).getExtendsBound();
            lower = ((WildcardType) type).getSuperBound();
        } else {
            lower = type.getLowerBound();
            upper = type.getUpperBound();
        }
        if (allowCompound) {
            if (lower == null || CTC_BOT.equals(typeTag(lower))) {
                if (upper == null || upper.toString().equals("java.lang.Object")) {
                    return maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
                }
                if (upper.getTypeArguments().contains(type)) {
                    return maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
                }
                return maker.Wildcard(maker.TypeBoundKind(BoundKind.EXTENDS), typeToJCTree(upper, ast, false, false));
            } else {
                return maker.Wildcard(maker.TypeBoundKind(BoundKind.SUPER), typeToJCTree(lower, ast, false, false));
            }
        }
        if (upper != null) {
            if (upper.getTypeArguments().contains(type)) {
                return maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
            }
            return typeToJCTree(upper, ast, allowCompound, allowVoid);
        }
        return createJavaLangObject(ast);
    }
    String qName;
    if (symbol.isLocal()) {
        qName = symbol.getSimpleName().toString();
    } else if (symbol.type != null && symbol.type.getEnclosingType() != null && typeTag(symbol.type.getEnclosingType()).equals(typeTag("CLASS"))) {
        replacement = typeToJCTree0(type.getEnclosingType(), ast, false, false);
        qName = symbol.getSimpleName().toString();
    } else {
        qName = symbol.getQualifiedName().toString();
    }
    if (qName.isEmpty())
        throw new TypeNotConvertibleException("unknown type");
    if (qName.startsWith("<"))
        throw new TypeNotConvertibleException(qName);
    String[] baseNames = qName.split("\\.");
    int i = 0;
    if (replacement == null) {
        replacement = maker.Ident(ast.toName(baseNames[0]));
        i = 1;
    }
    for (; i < baseNames.length; i++) {
        replacement = maker.Select(replacement, ast.toName(baseNames[i]));
    }
    return genericsToJCTreeNodes(generics, ast, replacement);
}
Also used : ClassType(com.sun.tools.javac.code.Type.ClassType) CapturedType(com.sun.tools.javac.code.Type.CapturedType) ArrayType(com.sun.tools.javac.code.Type.ArrayType) WildcardType(com.sun.tools.javac.code.Type.WildcardType) Type(com.sun.tools.javac.code.Type) WildcardType(com.sun.tools.javac.code.Type.WildcardType) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) CapturedType(com.sun.tools.javac.code.Type.CapturedType) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) ClassType(com.sun.tools.javac.code.Type.ClassType)

Example 3 with WildcardType

use of com.sun.tools.javac.code.Type.WildcardType in project ceylon-compiler by ceylon.

the class Attr method visitWildcard.

public void visitWildcard(JCWildcard tree) {
    //- System.err.println("visitWildcard("+tree+");");//DEBUG
    Type type = (tree.kind.kind == BoundKind.UNBOUND) ? syms.objectType : attribType(tree.inner, env);
    result = check(tree, new WildcardType(chk.checkRefType(tree.pos(), type), tree.kind.kind, syms.boundClass), TYP, pkind, pt);
}
Also used : ClassType(com.sun.tools.javac.code.Type.ClassType) MethodType(com.sun.tools.javac.code.Type.MethodType) WildcardType(com.sun.tools.javac.code.Type.WildcardType) Type(com.sun.tools.javac.code.Type) ArrayType(com.sun.tools.javac.code.Type.ArrayType) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) WildcardType(com.sun.tools.javac.code.Type.WildcardType)

Example 4 with WildcardType

use of com.sun.tools.javac.code.Type.WildcardType in project ceylon-compiler by ceylon.

the class JavacType method getLowerBound.

@Override
public TypeMirror getLowerBound() {
    if (!lowerBoundSet && type instanceof WildcardType) {
        Type bound = ((WildcardType) type).getSuperBound();
        if (bound != null) {
            lowerBound = new JavacType(bound);
        }
        lowerBoundSet = true;
    }
    return lowerBound;
}
Also used : WildcardType(com.sun.tools.javac.code.Type.WildcardType) ArrayType(com.sun.tools.javac.code.Type.ArrayType) WildcardType(com.sun.tools.javac.code.Type.WildcardType) Type(com.sun.tools.javac.code.Type)

Aggregations

Type (com.sun.tools.javac.code.Type)4 ArrayType (com.sun.tools.javac.code.Type.ArrayType)4 WildcardType (com.sun.tools.javac.code.Type.WildcardType)4 ClassType (com.sun.tools.javac.code.Type.ClassType)3 TypeSymbol (com.sun.tools.javac.code.Symbol.TypeSymbol)2 MethodType (com.sun.tools.javac.code.Type.MethodType)2 UnionClassType (com.sun.tools.javac.code.Type.UnionClassType)2 Kinds.kindName (com.sun.tools.javac.code.Kinds.kindName)1 Symbol (com.sun.tools.javac.code.Symbol)1 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)1 DynamicMethodSymbol (com.sun.tools.javac.code.Symbol.DynamicMethodSymbol)1 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)1 OperatorSymbol (com.sun.tools.javac.code.Symbol.OperatorSymbol)1 PackageSymbol (com.sun.tools.javac.code.Symbol.PackageSymbol)1 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)1 CapturedType (com.sun.tools.javac.code.Type.CapturedType)1 JCTree (com.sun.tools.javac.tree.JCTree)1 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)1 JCFieldAccess (com.sun.tools.javac.tree.JCTree.JCFieldAccess)1 Name (com.sun.tools.javac.util.Name)1