types.java

来自「是一款用JAVA 编写的编译器 具有很强的编译功能」· Java 代码 · 共 1,804 行 · 第 1/5 页

JAVA
1,804
字号
    boolean containsType(List<Type> ts, List<Type> ss) {        while (ts.nonEmpty() && ss.nonEmpty()               && containsType(ts.head, ss.head)) {            ts = ts.tail;            ss = ss.tail;        }        return ts.isEmpty() && ss.isEmpty();    }    /**     * Check if t contains s.     *     * <p>T contains S if:     *     * <p>{@code L(T) <: L(S) && U(S) <: U(T)}     *     * <p>This relation is only used by ClassType.isSubtype(), that     * is,     *     * <p>{@code C<S> <: C<T> if T contains S.}     *     * <p>Because of F-bounds, this relation can lead to infinite     * recursion.  Thus we must somehow break that recursion.  Notice     * that containsType() is only called from ClassType.isSubtype().     * Since the arguments have already been checked against their     * bounds, we know:     *     * <p>{@code U(S) <: U(T) if T is "super" bound (U(T) *is* the bound)}     *     * <p>{@code L(T) <: L(S) if T is "extends" bound (L(T) is bottom)}     *     * @param t a type     * @param s a type     */    public boolean containsType(Type t, Type s) {        return containsType.visit(t, s);    }    // where        private TypeRelation containsType = new TypeRelation() {            private Type U(Type t) {                while (t.tag == WILDCARD) {                    WildcardType w = (WildcardType)t;                    if (w.isSuperBound())                        return w.bound == null ? syms.objectType : w.bound.bound;                    else                        t = w.type;                }                return t;            }            private Type L(Type t) {                while (t.tag == WILDCARD) {                    WildcardType w = (WildcardType)t;                    if (w.isExtendsBound())                        return syms.botType;                    else                        t = w.type;                }                return t;            }            public Boolean visitType(Type t, Type s) {                if (s.tag >= firstPartialTag)                    return containedBy(s, t);                else                    return isSameType(t, s);            }            void debugContainsType(WildcardType t, Type s) {                System.err.println();                System.err.format(" does %s contain %s?%n", t, s);                System.err.format(" %s U(%s) <: U(%s) %s = %s%n",                                  upperBound(s), s, t, U(t),                                  t.isSuperBound()                                  || isSubtypeNoCapture(upperBound(s), U(t)));                System.err.format(" %s L(%s) <: L(%s) %s = %s%n",                                  L(t), t, s, lowerBound(s),                                  t.isExtendsBound()                                  || isSubtypeNoCapture(L(t), lowerBound(s)));                System.err.println();            }            @Override            public Boolean visitWildcardType(WildcardType t, Type s) {                if (s.tag >= firstPartialTag)                    return containedBy(s, t);                else {                    // debugContainsType(t, s);                    return isSameWildcard(t, s)                        || isCaptureOf(s, t)                        || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), lowerBound(s))) &&                            (t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t))));                }            }            @Override            public Boolean visitUndetVar(UndetVar t, Type s) {                if (s.tag != WILDCARD)                    return isSameType(t, s);                else                    return false;            }            @Override            public Boolean visitErrorType(ErrorType t, Type s) {                return true;            }        };    public boolean isCaptureOf(Type s, WildcardType t) {        if (s.tag != TYPEVAR || !(s instanceof CapturedType))            return false;        return isSameWildcard(t, ((CapturedType)s).wildcard);    }    public boolean isSameWildcard(WildcardType t, Type s) {        if (s.tag != WILDCARD)            return false;        WildcardType w = (WildcardType)s;        return w.kind == t.kind && w.type == t.type;    }    public boolean containsTypeEquivalent(List<Type> ts, List<Type> ss) {        while (ts.nonEmpty() && ss.nonEmpty()               && containsTypeEquivalent(ts.head, ss.head)) {            ts = ts.tail;            ss = ss.tail;        }        return ts.isEmpty() && ss.isEmpty();    }    // </editor-fold>    // <editor-fold defaultstate="collapsed" desc="isCastable">    public boolean isCastable(Type t, Type s) {        return isCastable(t, s, Warner.noWarnings);    }    /**     * Is t is castable to s?<br>     * s is assumed to be an erased type.<br>     * (not defined for Method and ForAll types).     */    public boolean isCastable(Type t, Type s, Warner warn) {        if (t == s)            return true;        if (t.isPrimitive() != s.isPrimitive())            return allowBoxing && isConvertible(t, s, warn);        if (warn != warnStack.head) {            try {                warnStack = warnStack.prepend(warn);                return isCastable.visit(t, s);            } finally {                warnStack = warnStack.tail;            }        } else {            return isCastable.visit(t, s);        }    }    // where        private TypeRelation isCastable = new TypeRelation() {            public Boolean visitType(Type t, Type s) {                if (s.tag == ERROR)                    return true;                switch (t.tag) {                case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:                case DOUBLE:                    return s.tag <= DOUBLE;                case BOOLEAN:                    return s.tag == BOOLEAN;                case VOID:                    return false;                case BOT:                    return isSubtype(t, s);                default:                    throw new AssertionError();                }            }            @Override            public Boolean visitWildcardType(WildcardType t, Type s) {                return isCastable(upperBound(t), s, warnStack.head);            }            @Override            public Boolean visitClassType(ClassType t, Type s) {                if (s.tag == ERROR || s.tag == BOT)                    return true;                if (s.tag == TYPEVAR) {                    if (isCastable(s.getUpperBound(), t, Warner.noWarnings)) {                        warnStack.head.warnUnchecked();                        return true;                    } else {                        return false;                    }                }                if (t.isCompound()) {                    if (!visit(supertype(t), s))                        return false;                    for (Type intf : interfaces(t)) {                        if (!visit(intf, s))                            return false;                    }                    return true;                }                if (s.isCompound()) {                    // call recursively to reuse the above code                    return visitClassType((ClassType)s, t);                }                if (s.tag == CLASS || s.tag == ARRAY) {                    boolean upcast;                    if ((upcast = isSubtype(erasure(t), erasure(s)))                        || isSubtype(erasure(s), erasure(t))) {                        if (!upcast && s.tag == ARRAY) {                            if (!isReifiable(s))                                warnStack.head.warnUnchecked();                            return true;                        } else if (s.isRaw()) {                            return true;                        } else if (t.isRaw()) {                            if (!isUnbounded(s))                                warnStack.head.warnUnchecked();                            return true;                        }                        // Assume |a| <: |b|                        final Type a = upcast ? t : s;                        final Type b = upcast ? s : t;                        final boolean HIGH = true;                        final boolean LOW = false;                        final boolean DONT_REWRITE_TYPEVARS = false;                        Type aHigh = rewriteQuantifiers(a, HIGH, DONT_REWRITE_TYPEVARS);                        Type aLow  = rewriteQuantifiers(a, LOW,  DONT_REWRITE_TYPEVARS);                        Type bHigh = rewriteQuantifiers(b, HIGH, DONT_REWRITE_TYPEVARS);                        Type bLow  = rewriteQuantifiers(b, LOW,  DONT_REWRITE_TYPEVARS);                        Type lowSub = asSub(bLow, aLow.tsym);                        Type highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);                        if (highSub == null) {                            final boolean REWRITE_TYPEVARS = true;                            aHigh = rewriteQuantifiers(a, HIGH, REWRITE_TYPEVARS);                            aLow  = rewriteQuantifiers(a, LOW,  REWRITE_TYPEVARS);                            bHigh = rewriteQuantifiers(b, HIGH, REWRITE_TYPEVARS);                            bLow  = rewriteQuantifiers(b, LOW,  REWRITE_TYPEVARS);                            lowSub = asSub(bLow, aLow.tsym);                            highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);                        }                        if (highSub != null) {                            assert a.tsym == highSub.tsym && a.tsym == lowSub.tsym                                : a.tsym + " != " + highSub.tsym + " != " + lowSub.tsym;                            if (!disjointTypes(aHigh.getTypeArguments(), highSub.getTypeArguments())                                && !disjointTypes(aHigh.getTypeArguments(), lowSub.getTypeArguments())                                && !disjointTypes(aLow.getTypeArguments(), highSub.getTypeArguments())                                && !disjointTypes(aLow.getTypeArguments(), lowSub.getTypeArguments())) {                                if (upcast ? giveWarning(a, highSub) || giveWarning(a, lowSub)                                           : giveWarning(highSub, a) || giveWarning(lowSub, a))                                    warnStack.head.warnUnchecked();                                return true;                            }                        }                        if (isReifiable(s))                            return isSubtypeUnchecked(a, b);                        else                            return isSubtypeUnchecked(a, b, warnStack.head);                    }                    // Sidecast                    if (s.tag == CLASS) {                        if ((s.tsym.flags() & INTERFACE) != 0) {                            return ((t.tsym.flags() & FINAL) == 0)                                ? sideCast(t, s, warnStack.head)                                : sideCastFinal(t, s, warnStack.head);                        } else if ((t.tsym.flags() & INTERFACE) != 0) {                            return ((s.tsym.flags() & FINAL) == 0)                                ? sideCast(t, s, warnStack.head)                                : sideCastFinal(t, s, warnStack.head);                        } else {                            // unrelated class types                            return false;                        }                    }                }                return false;            }            @Override            public Boolean visitArrayType(ArrayType t, Type s) {                switch (s.tag) {                case ERROR:                case BOT:                    return true;                case TYPEVAR:                    if (isCastable(s, t, Warner.noWarnings)) {                        warnStack.head.warnUnchecked();                        return true;                    } else {                        return false;                    }                case CLASS:                    return isSubtype(t, s);                case ARRAY:                    if (elemtype(t).tag <= lastBaseTag) {                        return elemtype(t).tag == elemtype(s).tag;                    } else {                        return visit(elemtype(t), elemtype(s));                    }                default:                    return false;                }            }            @Override            public Boolean visitTypeVar(TypeVar t, Type s) {                switch (s.tag) {                case ERROR:                case BOT:                    return true;                case TYPEVAR:                    if (isSubtype(t, s)) {                        return true;                    } else if (isCastable(t.bound, s, Warner.noWarnings)) {                        warnStack.head.warnUnchecked();                        return true;                    } else {                        return false;                    }                default:                    return isCastable(t.bound, s, warnStack.head);                }            }            @Override            public Boolean visitErrorType(ErrorType t, Type s) {                return true;            }        };    // </editor-fold>    // <editor-fold defaultstate="collapsed" desc="disjointTypes">    public boolean disjointTypes(List<Type> ts, List<Type> ss) {        while (ts.tail != null && ss.tail != null) {            if (disjointType(ts.head, ss.head)) return true;            ts = ts.tail;            ss = ss.tail;        }        return false;    }    /**     * Two types or wildcards are considered disjoint if it can be     * proven that no type can be contained in both. It is     * conservative in that it is allowed to say that two types are     * not disjoint, even though they actually are.     *     * The type C<X> is castable to C<Y> exactly if X and Y are not

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?