Search in sources :

Example 61 with Type

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

the class Check method checkCompatibleSupertypes.

/** Check that all abstract methods implemented by a class are
     *  mutually compatible.
     *  @param pos          Position to be used for error reporting.
     *  @param c            The class whose interfaces are checked.
     */
void checkCompatibleSupertypes(DiagnosticPosition pos, Type c) {
    List<Type> supertypes = types.interfaces(c);
    Type supertype = types.supertype(c);
    if (supertype.tag == CLASS && (supertype.tsym.flags() & ABSTRACT) != 0)
        supertypes = supertypes.prepend(supertype);
    for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) {
        if (allowGenerics && !l.head.getTypeArguments().isEmpty() && !checkCompatibleAbstracts(pos, l.head, l.head, c))
            return;
        for (List<Type> m = supertypes; m != l; m = m.tail) if (!checkCompatibleAbstracts(pos, l.head, m.head, c))
            return;
    }
    checkCompatibleConcretes(pos, c);
}
Also used : Type(com.sun.tools.javac.code.Type)

Example 62 with Type

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

the class Check method isOverrider.

/** Is s a method symbol that overrides a method in a superclass? */
boolean isOverrider(Symbol s) {
    if (s.kind != MTH || s.isStatic())
        return false;
    MethodSymbol m = (MethodSymbol) s;
    TypeSymbol owner = (TypeSymbol) m.owner;
    for (Type sup : types.closure(owner.type)) {
        if (sup == owner.type)
            // skip "this"
            continue;
        Scope scope = sup.tsym.members();
        for (Scope.Entry e = scope.lookup(m.name); e.scope != null; e = e.next()) {
            if (!e.sym.isStatic() && m.overrides(e.sym, owner, types, true))
                return true;
        }
    }
    return false;
}
Also used : Type(com.sun.tools.javac.code.Type)

Example 63 with Type

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

the class Infer method instantiatePolymorphicSignatureInstance.

/**
     * Compute a synthetic method type corresponding to the requested polymorphic
     * method signature. The target return type is computed from the immediately
     * enclosing scope surrounding the polymorphic-signature call.
     */
Type instantiatePolymorphicSignatureInstance(Env<AttrContext> env, Type site, Name name, // sig. poly. method or null if none
MethodSymbol spMethod, List<Type> argtypes) {
    final Type restype;
    switch(env.next.tree.getTag()) {
        case JCTree.TYPECAST:
            JCTypeCast castTree = (JCTypeCast) env.next.tree;
            restype = (TreeInfo.skipParens(castTree.expr) == env.tree) ? castTree.clazz.type : syms.objectType;
            break;
        case JCTree.EXEC:
            JCTree.JCExpressionStatement execTree = (JCTree.JCExpressionStatement) env.next.tree;
            restype = (TreeInfo.skipParens(execTree.expr) == env.tree) ? syms.voidType : syms.objectType;
            break;
        default:
            restype = syms.objectType;
    }
    List<Type> paramtypes = Type.map(argtypes, implicitArgType);
    List<Type> exType = spMethod != null ? spMethod.getThrownTypes() : // make it throw all exceptions
    List.of(syms.throwableType);
    MethodType mtype = new MethodType(paramtypes, restype, exType, syms.methodClass);
    return mtype;
}
Also used : Type(com.sun.tools.javac.code.Type) JCTypeCast(com.sun.tools.javac.tree.JCTree.JCTypeCast) JCTree(com.sun.tools.javac.tree.JCTree)

Example 64 with Type

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

the class Lower method visitEnumDef.

/** Translate an enum class. */
private void visitEnumDef(JCClassDecl tree) {
    make_at(tree.pos());
    // add the supertype, if needed
    if (tree.extending == null)
        tree.extending = make.Type(types.supertype(tree.type));
    // classOfType adds a cache field to tree.defs unless
    // target.hasClassLiterals().
    JCExpression e_class = classOfType(tree.sym.type, tree.pos()).setType(types.erasure(syms.classType));
    // process each enumeration constant, adding implicit constructor parameters
    int nextOrdinal = 0;
    ListBuffer<JCExpression> values = new ListBuffer<JCExpression>();
    ListBuffer<JCTree> enumDefs = new ListBuffer<JCTree>();
    ListBuffer<JCTree> otherDefs = new ListBuffer<JCTree>();
    for (List<JCTree> defs = tree.defs; defs.nonEmpty(); defs = defs.tail) {
        if (defs.head.getTag() == JCTree.VARDEF && (((JCVariableDecl) defs.head).mods.flags & ENUM) != 0) {
            JCVariableDecl var = (JCVariableDecl) defs.head;
            visitEnumConstantDef(var, nextOrdinal++);
            values.append(make.QualIdent(var.sym));
            enumDefs.append(var);
        } else {
            otherDefs.append(defs.head);
        }
    }
    // private static final T[] #VALUES = { a, b, c };
    Name valuesName = names.fromString(target.syntheticNameChar() + "VALUES");
    while (// avoid name clash
    tree.sym.members().lookup(valuesName).scope != null) valuesName = names.fromString(valuesName + "" + target.syntheticNameChar());
    Type arrayType = new ArrayType(types.erasure(tree.type), syms.arrayClass);
    VarSymbol valuesVar = new VarSymbol(PRIVATE | FINAL | STATIC | SYNTHETIC, valuesName, arrayType, tree.type.tsym);
    JCNewArray newArray = make.NewArray(make.Type(types.erasure(tree.type)), List.<JCExpression>nil(), values.toList());
    newArray.type = arrayType;
    enumDefs.append(make.VarDef(valuesVar, newArray));
    tree.sym.members().enter(valuesVar);
    Symbol valuesSym = lookupMethod(tree.pos(), names.values, tree.type, List.<Type>nil());
    List<JCStatement> valuesBody;
    if (useClone()) {
        // return (T[]) $VALUES.clone();
        JCTypeCast valuesResult = make.TypeCast(valuesSym.type.getReturnType(), make.App(make.Select(make.Ident(valuesVar), syms.arrayCloneMethod)));
        valuesBody = List.<JCStatement>of(make.Return(valuesResult));
    } else {
        // template: T[] $result = new T[$values.length];
        Name resultName = names.fromString(target.syntheticNameChar() + "result");
        while (// avoid name clash
        tree.sym.members().lookup(resultName).scope != null) resultName = names.fromString(resultName + "" + target.syntheticNameChar());
        VarSymbol resultVar = new VarSymbol(FINAL | SYNTHETIC, resultName, arrayType, valuesSym);
        JCNewArray resultArray = make.NewArray(make.Type(types.erasure(tree.type)), List.of(make.Select(make.Ident(valuesVar), syms.lengthVar)), null);
        resultArray.type = arrayType;
        JCVariableDecl decl = make.VarDef(resultVar, resultArray);
        // template: System.arraycopy($VALUES, 0, $result, 0, $VALUES.length);
        if (systemArraycopyMethod == null) {
            systemArraycopyMethod = new MethodSymbol(PUBLIC | STATIC, names.fromString("arraycopy"), new MethodType(List.<Type>of(syms.objectType, syms.intType, syms.objectType, syms.intType, syms.intType), syms.voidType, List.<Type>nil(), syms.methodClass), syms.systemType.tsym);
        }
        JCStatement copy = make.Exec(make.App(make.Select(make.Ident(syms.systemType.tsym), systemArraycopyMethod), List.of(make.Ident(valuesVar), make.Literal(0), make.Ident(resultVar), make.Literal(0), make.Select(make.Ident(valuesVar), syms.lengthVar))));
        // template: return $result;
        JCStatement ret = make.Return(make.Ident(resultVar));
        valuesBody = List.<JCStatement>of(decl, copy, ret);
    }
    JCMethodDecl valuesDef = make.MethodDef((MethodSymbol) valuesSym, make.Block(0, valuesBody));
    enumDefs.append(valuesDef);
    if (debugLower)
        System.err.println(tree.sym + ".valuesDef = " + valuesDef);
    /** The template for the following code is:
         *
         *     public static E valueOf(String name) {
         *         return (E)Enum.valueOf(E.class, name);
         *     }
         *
         *  where E is tree.sym
         */
    MethodSymbol valueOfSym = lookupMethod(tree.pos(), names.valueOf, tree.sym.type, List.of(syms.stringType));
    Assert.check((valueOfSym.flags() & STATIC) != 0);
    VarSymbol nameArgSym = valueOfSym.params.head;
    JCIdent nameVal = make.Ident(nameArgSym);
    JCStatement enum_ValueOf = make.Return(make.TypeCast(tree.sym.type, makeCall(make.Ident(syms.enumSym), names.valueOf, List.of(e_class, nameVal))));
    JCMethodDecl valueOf = make.MethodDef(valueOfSym, make.Block(0, List.of(enum_ValueOf)));
    nameVal.sym = valueOf.params.head.sym;
    if (debugLower)
        System.err.println(tree.sym + ".valueOf = " + valueOf);
    enumDefs.append(valueOf);
    enumDefs.appendList(otherDefs.toList());
    tree.defs = enumDefs.toList();
    // Add the necessary members for the EnumCompatibleMode
    if (target.compilerBootstrap(tree.sym)) {
        addEnumCompatibleMembers(tree);
    }
}
Also used : Symbol(com.sun.tools.javac.code.Symbol) JCTree(com.sun.tools.javac.tree.JCTree) Type(com.sun.tools.javac.code.Type)

Example 65 with Type

use of com.sun.tools.javac.code.Type 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)

Aggregations

Type (com.sun.tools.javac.code.Type)254 Symbol (com.sun.tools.javac.code.Symbol)64 ClassType (com.sun.tools.javac.code.Type.ClassType)55 ArrayType (com.sun.tools.javac.code.Type.ArrayType)47 MethodType (com.sun.tools.javac.code.Type.MethodType)42 WildcardType (com.sun.tools.javac.code.Type.WildcardType)42 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)36 UnionClassType (com.sun.tools.javac.code.Type.UnionClassType)33 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)32 JCTree (com.sun.tools.javac.tree.JCTree)27 TypeSymbol (com.sun.tools.javac.code.Symbol.TypeSymbol)24 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)23 Types (com.sun.tools.javac.code.Types)22 ExpressionTree (com.sun.source.tree.ExpressionTree)21 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)17 ArrayList (java.util.ArrayList)17 PackageSymbol (com.sun.tools.javac.code.Symbol.PackageSymbol)16 Tree (com.sun.source.tree.Tree)14 Name (com.sun.tools.javac.util.Name)14 DynamicMethodSymbol (com.sun.tools.javac.code.Symbol.DynamicMethodSymbol)13