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 + -
显示快捷键?