types.java

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

JAVA
1,804
字号
     * disjoint.     */    public boolean disjointType(Type t, Type s) {        return disjointType.visit(t, s);    }    // where        private TypeRelation disjointType = new TypeRelation() {            private Set<TypePair> cache = new HashSet<TypePair>();            public Boolean visitType(Type t, Type s) {                if (s.tag == WILDCARD)                    return visit(s, t);                else                    return notSoftSubtypeRecursive(t, s) || notSoftSubtypeRecursive(s, t);            }            private boolean isCastableRecursive(Type t, Type s) {                TypePair pair = new TypePair(t, s);                if (cache.add(pair)) {                    try {                        return Types.this.isCastable(t, s);                    } finally {                        cache.remove(pair);                    }                } else {                    return true;                }            }            private boolean notSoftSubtypeRecursive(Type t, Type s) {                TypePair pair = new TypePair(t, s);                if (cache.add(pair)) {                    try {                        return Types.this.notSoftSubtype(t, s);                    } finally {                        cache.remove(pair);                    }                } else {                    return false;                }            }            @Override            public Boolean visitWildcardType(WildcardType t, Type s) {                if (t.isUnbound())                    return false;                if (s.tag != WILDCARD) {                    if (t.isExtendsBound())                        return notSoftSubtypeRecursive(s, t.type);                    else // isSuperBound()                        return notSoftSubtypeRecursive(t.type, s);                }                if (s.isUnbound())                    return false;                if (t.isExtendsBound()) {                    if (s.isExtendsBound())                        return !isCastableRecursive(t.type, upperBound(s));                    else if (s.isSuperBound())                        return notSoftSubtypeRecursive(lowerBound(s), t.type);                } else if (t.isSuperBound()) {                    if (s.isExtendsBound())                        return notSoftSubtypeRecursive(t.type, upperBound(s));                }                return false;            }        };    // </editor-fold>    // <editor-fold defaultstate="collapsed" desc="lowerBoundArgtypes">    /**     * Returns the lower bounds of the formals of a method.     */    public List<Type> lowerBoundArgtypes(Type t) {        return map(t.getParameterTypes(), lowerBoundMapping);    }    private final Mapping lowerBoundMapping = new Mapping("lowerBound") {            public Type apply(Type t) {                return lowerBound(t);            }        };    // </editor-fold>    // <editor-fold defaultstate="collapsed" desc="notSoftSubtype">    /**     * This relation answers the question: is impossible that     * something of type `t' can be a subtype of `s'? This is     * different from the question "is `t' not a subtype of `s'?"     * when type variables are involved: Integer is not a subtype of T     * where <T extends Number> but it is not true that Integer cannot     * possibly be a subtype of T.     */    public boolean notSoftSubtype(Type t, Type s) {        if (t == s) return false;        if (t.tag == TYPEVAR) {            TypeVar tv = (TypeVar) t;            if (s.tag == TYPEVAR)                s = s.getUpperBound();            return !isCastable(tv.bound,                               s,                               Warner.noWarnings);        }        if (s.tag != WILDCARD)            s = upperBound(s);        if (s.tag == TYPEVAR)            s = s.getUpperBound();        return !isSubtype(t, s);    }    // </editor-fold>    // <editor-fold defaultstate="collapsed" desc="isReifiable">    public boolean isReifiable(Type t) {        return isReifiable.visit(t);    }    // where        private UnaryVisitor<Boolean> isReifiable = new UnaryVisitor<Boolean>() {            public Boolean visitType(Type t, Void ignored) {                return true;            }            @Override            public Boolean visitClassType(ClassType t, Void ignored) {                if (!t.isParameterized())                    return true;                for (Type param : t.allparams()) {                    if (!param.isUnbound())                        return false;                }                return true;            }            @Override            public Boolean visitArrayType(ArrayType t, Void ignored) {                return visit(t.elemtype);            }            @Override            public Boolean visitTypeVar(TypeVar t, Void ignored) {                return false;            }        };    // </editor-fold>    // <editor-fold defaultstate="collapsed" desc="Array Utils">    public boolean isArray(Type t) {        while (t.tag == WILDCARD)            t = upperBound(t);        return t.tag == ARRAY;    }    /**     * The element type of an array.     */    public Type elemtype(Type t) {        switch (t.tag) {        case WILDCARD:            return elemtype(upperBound(t));        case ARRAY:            return ((ArrayType)t).elemtype;        case FORALL:            return elemtype(((ForAll)t).qtype);        case ERROR:            return t;        default:            return null;        }    }    /**     * Mapping to take element type of an arraytype     */    private Mapping elemTypeFun = new Mapping ("elemTypeFun") {        public Type apply(Type t) { return elemtype(t); }    };    /**     * The number of dimensions of an array type.     */    public int dimensions(Type t) {        int result = 0;        while (t.tag == ARRAY) {            result++;            t = elemtype(t);        }        return result;    }    // </editor-fold>    // <editor-fold defaultstate="collapsed" desc="asSuper">    /**     * Return the (most specific) base type of t that starts with the     * given symbol.  If none exists, return null.     *     * @param t a type     * @param sym a symbol     */    public Type asSuper(Type t, Symbol sym) {        return asSuper.visit(t, sym);    }    // where        private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() {            public Type visitType(Type t, Symbol sym) {                return null;            }            @Override            public Type visitClassType(ClassType t, Symbol sym) {                if (t.tsym == sym)                    return t;                Type st = supertype(t);                if (st.tag == CLASS || st.tag == ERROR) {                    Type x = asSuper(st, sym);                    if (x != null)                        return x;                }                if ((sym.flags() & INTERFACE) != 0) {                    for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {                        Type x = asSuper(l.head, sym);                        if (x != null)                            return x;                    }                }                return null;            }            @Override            public Type visitArrayType(ArrayType t, Symbol sym) {                return isSubtype(t, sym.type) ? sym.type : null;            }            @Override            public Type visitTypeVar(TypeVar t, Symbol sym) {                return asSuper(t.bound, sym);            }            @Override            public Type visitErrorType(ErrorType t, Symbol sym) {                return t;            }        };    /**     * Return the base type of t or any of its outer types that starts     * with the given symbol.  If none exists, return null.     *     * @param t a type     * @param sym a symbol     */    public Type asOuterSuper(Type t, Symbol sym) {        switch (t.tag) {        case CLASS:            do {                Type s = asSuper(t, sym);                if (s != null) return s;                t = t.getEnclosingType();            } while (t.tag == CLASS);            return null;        case ARRAY:            return isSubtype(t, sym.type) ? sym.type : null;        case TYPEVAR:            return asSuper(t, sym);        case ERROR:            return t;        default:            return null;        }    }    /**     * Return the base type of t or any of its enclosing types that     * starts with the given symbol.  If none exists, return null.     *     * @param t a type     * @param sym a symbol     */    public Type asEnclosingSuper(Type t, Symbol sym) {        switch (t.tag) {        case CLASS:            do {                Type s = asSuper(t, sym);                if (s != null) return s;                Type outer = t.getEnclosingType();                t = (outer.tag == CLASS) ? outer :                    (t.tsym.owner.enclClass() != null) ? t.tsym.owner.enclClass().type :                    Type.noType;            } while (t.tag == CLASS);            return null;        case ARRAY:            return isSubtype(t, sym.type) ? sym.type : null;        case TYPEVAR:            return asSuper(t, sym);        case ERROR:            return t;        default:            return null;        }    }    // </editor-fold>    // <editor-fold defaultstate="collapsed" desc="memberType">    /**     * The type of given symbol, seen as a member of t.     *     * @param t a type     * @param sym a symbol     */    public Type memberType(Type t, Symbol sym) {        return (sym.flags() & STATIC) != 0            ? sym.type            : memberType.visit(t, sym);    }    // where        private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {            public Type visitType(Type t, Symbol sym) {                return sym.type;            }            @Override            public Type visitWildcardType(WildcardType t, Symbol sym) {                return memberType(upperBound(t), sym);            }            @Override            public Type visitClassType(ClassType t, Symbol sym) {                Symbol owner = sym.owner;                long flags = sym.flags();                if (((flags & STATIC) == 0) && owner.type.isParameterized()) {                    Type base = asOuterSuper(t, owner);                    if (base != null) {                        List<Type> ownerParams = owner.type.allparams();                        List<Type> baseParams = base.allparams();                        if (ownerParams.nonEmpty()) {                            if (baseParams.isEmpty()) {                                // then base is a raw type                                return erasure(sym.type);                            } else {                                return subst(sym.type, ownerParams, baseParams);                            }                        }                    }                }                return sym.type;            }            @Override            public Type visitTypeVar(TypeVar t, Symbol sym) {                return memberType(t.bound, sym);            }            @Override            public Type visitErrorType(ErrorType t, Symbol sym) {                return t;            }

⌨️ 快捷键说明

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