Search in sources :

Example 66 with Type

use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.

the class Types method closureMin.

/**
 * Return the minimum types of a closure, suitable for computing
 * compoundMin or glb.
 */
private List<Type> closureMin(List<Type> cl) {
    ListBuffer<Type> classes = new ListBuffer<>();
    ListBuffer<Type> interfaces = new ListBuffer<>();
    Set<Type> toSkip = new HashSet<>();
    while (!cl.isEmpty()) {
        Type current = cl.head;
        boolean keep = !toSkip.contains(current);
        if (keep && current.hasTag(TYPEVAR)) {
            // skip lower-bounded variables with a subtype in cl.tail
            for (Type t : cl.tail) {
                if (isSubtypeNoCapture(t, current)) {
                    keep = false;
                    break;
                }
            }
        }
        if (keep) {
            if (current.isInterface())
                interfaces.append(current);
            else
                classes.append(current);
            for (Type t : cl.tail) {
                // skip supertypes of 'current' in cl.tail
                if (isSubtypeNoCapture(current, t))
                    toSkip.add(t);
            }
        }
        cl = cl.tail;
    }
    return classes.appendList(interfaces).toList();
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) HashSet(java.util.HashSet)

Example 67 with Type

use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.

the class Types method capture.

public Type capture(Type t) {
    if (!t.hasTag(CLASS)) {
        return t;
    }
    if (t.getEnclosingType() != Type.noType) {
        Type capturedEncl = capture(t.getEnclosingType());
        if (capturedEncl != t.getEnclosingType()) {
            Type type1 = memberType(capturedEncl, t.tsym);
            t = subst(type1, t.tsym.type.getTypeArguments(), t.getTypeArguments());
        }
    }
    t = t.unannotatedType();
    ClassType cls = (ClassType) t;
    if (cls.isRaw() || !cls.isParameterized())
        return cls;
    ClassType G = (ClassType) cls.asElement().asType();
    List<Type> A = G.getTypeArguments();
    List<Type> T = cls.getTypeArguments();
    List<Type> S = freshTypeVariables(T);
    List<Type> currentA = A;
    List<Type> currentT = T;
    List<Type> currentS = S;
    boolean captured = false;
    while (!currentA.isEmpty() && !currentT.isEmpty() && !currentS.isEmpty()) {
        if (currentS.head != currentT.head) {
            captured = true;
            WildcardType Ti = (WildcardType) currentT.head.unannotatedType();
            Type Ui = currentA.head.getUpperBound();
            CapturedType Si = (CapturedType) currentS.head.unannotatedType();
            if (Ui == null)
                Ui = syms.objectType;
            switch(Ti.kind) {
                case UNBOUND:
                    Si.bound = subst(Ui, A, S);
                    Si.lower = syms.botType;
                    break;
                case EXTENDS:
                    Si.bound = glb(Ti.getExtendsBound(), subst(Ui, A, S));
                    Si.lower = syms.botType;
                    break;
                case SUPER:
                    Si.bound = subst(Ui, A, S);
                    Si.lower = Ti.getSuperBound();
                    break;
            }
            Type tmpBound = Si.bound.hasTag(UNDETVAR) ? ((UndetVar) Si.bound).qtype : Si.bound;
            Type tmpLower = Si.lower.hasTag(UNDETVAR) ? ((UndetVar) Si.lower).qtype : Si.lower;
            if (!Si.bound.hasTag(ERROR) && !Si.lower.hasTag(ERROR) && isSameType(tmpBound, tmpLower, false)) {
                currentS.head = Si.bound;
            }
        }
        currentA = currentA.tail;
        currentT = currentT.tail;
        currentS = currentS.tail;
    }
    if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty())
        // some "rare" type involved
        return erasure(t);
    if (captured)
        return new ClassType(cls.getEnclosingType(), S, cls.tsym);
    else
        return t;
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type)

Example 68 with Type

use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.

the class Types method sideCastFinal.

private boolean sideCastFinal(Type from, Type to, Warner warn) {
    // We are casting from type $from$ to type $to$, which are
    // unrelated types one of which is final and the other of
    // which is an interface.  This method
    // tries to reject a cast by transferring type parameters
    // from the final class to the interface.
    boolean reverse = false;
    Type target = to;
    if ((to.tsym.flags() & INTERFACE) == 0) {
        Assert.check((from.tsym.flags() & INTERFACE) != 0);
        reverse = true;
        to = from;
        from = target;
    }
    Assert.check((from.tsym.flags() & FINAL) != 0);
    Type t1 = asSuper(from, to.tsym);
    if (t1 == null)
        return false;
    Type t2 = to;
    if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
        return false;
    if (!allowCovariantReturns)
        // reject if there is a common method signature with
        // incompatible return types.
        chk.checkCompatibleAbstracts(warn.pos(), from, to);
    if (!isReifiable(target) && (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2)))
        warn.warn(LintCategory.UNCHECKED);
    return true;
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type)

Example 69 with Type

use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.

the class Types method sideCast.

// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="Internal utility methods">
private boolean sideCast(Type from, Type to, Warner warn) {
    // We are casting from type $from$ to type $to$, which are
    // non-final unrelated types.  This method
    // tries to reject a cast by transferring type parameters
    // from $to$ to $from$ by common superinterfaces.
    boolean reverse = false;
    Type target = to;
    if ((to.tsym.flags() & INTERFACE) == 0) {
        Assert.check((from.tsym.flags() & INTERFACE) != 0);
        reverse = true;
        to = from;
        from = target;
    }
    List<Type> commonSupers = superClosure(to, erasure(from));
    boolean giveWarning = commonSupers.isEmpty();
    // get a more accurate analysis
    while (commonSupers.nonEmpty()) {
        Type t1 = asSuper(from, commonSupers.head.tsym);
        // same as asSuper(to, commonSupers.head.tsym);
        Type t2 = commonSupers.head;
        if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
            return false;
        giveWarning = giveWarning || (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2));
        commonSupers = commonSupers.tail;
    }
    if (giveWarning && !isReifiable(reverse ? from : to))
        warn.warn(LintCategory.UNCHECKED);
    if (!allowCovariantReturns)
        // reject if there is a common method signature with
        // incompatible return types.
        chk.checkCompatibleAbstracts(warn.pos(), from, to);
    return true;
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type)

Example 70 with Type

use of org.eclipse.ceylon.langtools.tools.javac.code.Type in project ceylon by eclipse.

the class Types method substBounds.

public List<Type> substBounds(List<Type> tvars, List<Type> from, List<Type> to) {
    if (tvars.isEmpty())
        return tvars;
    ListBuffer<Type> newBoundsBuf = new ListBuffer<>();
    boolean changed = false;
    // calculate new bounds
    for (Type t : tvars) {
        TypeVar tv = (TypeVar) t;
        Type bound = subst(tv.bound, from, to);
        if (bound != tv.bound)
            changed = true;
        newBoundsBuf.append(bound);
    }
    if (!changed)
        return tvars;
    ListBuffer<Type> newTvars = new ListBuffer<>();
    // create new type variables without bounds
    for (Type t : tvars) {
        newTvars.append(new TypeVar(t.tsym, null, syms.botType));
    }
    // the new bounds should use the new type variables in place
    // of the old
    List<Type> newBounds = newBoundsBuf.toList();
    from = tvars;
    to = newTvars.toList();
    for (; !newBounds.isEmpty(); newBounds = newBounds.tail) {
        newBounds.head = subst(newBounds.head, from, to);
    }
    newBounds = newBoundsBuf.toList();
    // set the bounds of new type variables to the new bounds
    for (Type t : newTvars.toList()) {
        TypeVar tv = (TypeVar) t;
        tv.bound = newBounds.head;
        // Fix for Ceylon: try really hard not to make recursive bounds
        if (tv.bound == tv)
            tv.bound = null;
        newBounds = newBounds.tail;
    }
    return newTvars.toList();
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type)

Aggregations

Type (org.eclipse.ceylon.langtools.tools.javac.code.Type)164 Symbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol)46 DeferredType (org.eclipse.ceylon.langtools.tools.javac.comp.DeferredAttr.DeferredType)13 DiagnosticType (org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticType)13 ArrayType (org.eclipse.ceylon.langtools.tools.javac.code.Type.ArrayType)10 MethodType (org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType)10 ClassSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.ClassSymbol)9 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)9 MethodSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol)8 JavaFileObject (org.eclipse.ceylon.javax.tools.JavaFileObject)7 TypeSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.TypeSymbol)7 DiagnosticPosition (org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition)7 JavacType (org.eclipse.ceylon.compiler.java.loader.mirror.JavacType)5 PackageSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.PackageSymbol)5 FunctionalInterfaceType (org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType)5 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)5 HashSet (java.util.HashSet)4 CompletionFailure (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.CompletionFailure)4 VarSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.VarSymbol)4 FreeTypeListener (org.eclipse.ceylon.langtools.tools.javac.comp.Infer.FreeTypeListener)4