types.java

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

JAVA
1,804
字号
        };    // </editor-fold>    // <editor-fold defaultstate="collapsed" desc="isAssignable">    public boolean isAssignable(Type t, Type s) {        return isAssignable(t, s, Warner.noWarnings);    }    /**     * Is t assignable to s?<br>     * Equivalent to subtype except for constant values and raw     * types.<br>     * (not defined for Method and ForAll types)     */    public boolean isAssignable(Type t, Type s, Warner warn) {        if (t.tag == ERROR)            return true;        if (t.tag <= INT && t.constValue() != null) {            int value = ((Number)t.constValue()).intValue();            switch (s.tag) {            case BYTE:                if (Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE)                    return true;                break;            case CHAR:                if (Character.MIN_VALUE <= value && value <= Character.MAX_VALUE)                    return true;                break;            case SHORT:                if (Short.MIN_VALUE <= value && value <= Short.MAX_VALUE)                    return true;                break;            case INT:                return true;            case CLASS:                switch (unboxedType(s).tag) {                case BYTE:                case CHAR:                case SHORT:                    return isAssignable(t, unboxedType(s), warn);                }                break;            }        }        return isConvertible(t, s, warn);    }    // </editor-fold>    // <editor-fold defaultstate="collapsed" desc="erasure">    /**     * The erasure of t {@code |t|} -- the type that results when all     * type parameters in t are deleted.     */    public Type erasure(Type t) {        if (t.tag <= lastBaseTag)            return t; /* fast special case */        else            return erasure.visit(t);    }    // where        private UnaryVisitor<Type> erasure = new UnaryVisitor<Type>() {            public Type visitType(Type t, Void ignored) {                if (t.tag <= lastBaseTag)                    return t; /*fast special case*/                else                    return t.map(erasureFun);            }            @Override            public Type visitWildcardType(WildcardType t, Void ignored) {                return erasure(upperBound(t));            }            @Override            public Type visitClassType(ClassType t, Void ignored) {                return t.tsym.erasure(Types.this);            }            @Override            public Type visitTypeVar(TypeVar t, Void ignored) {                return erasure(t.bound);            }            @Override            public Type visitErrorType(ErrorType t, Void ignored) {                return t;            }        };    private Mapping erasureFun = new Mapping ("erasure") {            public Type apply(Type t) { return erasure(t); }        };    public List<Type> erasure(List<Type> ts) {        return Type.map(ts, erasureFun);    }    // </editor-fold>    // <editor-fold defaultstate="collapsed" desc="makeCompoundType">    /**     * Make a compound type from non-empty list of types     *     * @param bounds            the types from which the compound type is formed     * @param supertype         is objectType if all bounds are interfaces,     *                          null otherwise.     */    public Type makeCompoundType(List<Type> bounds,                                 Type supertype) {        ClassSymbol bc =            new ClassSymbol(ABSTRACT|PUBLIC|SYNTHETIC|COMPOUND|ACYCLIC,                            Type.moreInfo                                ? names.fromString(bounds.toString())                                : names.empty,                            syms.noSymbol);        if (bounds.head.tag == TYPEVAR)            // error condition, recover            bc.erasure_field = syms.objectType;        else            bc.erasure_field = erasure(bounds.head);        bc.members_field = new Scope(bc);        ClassType bt = (ClassType)bc.type;        bt.allparams_field = List.nil();        if (supertype != null) {            bt.supertype_field = supertype;            bt.interfaces_field = bounds;        } else {            bt.supertype_field = bounds.head;            bt.interfaces_field = bounds.tail;        }        assert bt.supertype_field.tsym.completer != null            || !bt.supertype_field.isInterface()            : bt.supertype_field;        return bt;    }    /**     * Same as {@link #makeCompoundType(List,Type)}, except that the     * second parameter is computed directly. Note that this might     * cause a symbol completion.  Hence, this version of     * makeCompoundType may not be called during a classfile read.     */    public Type makeCompoundType(List<Type> bounds) {        Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?            supertype(bounds.head) : null;        return makeCompoundType(bounds, supertype);    }    /**     * A convenience wrapper for {@link #makeCompoundType(List)}; the     * arguments are converted to a list and passed to the other     * method.  Note that this might cause a symbol completion.     * Hence, this version of makeCompoundType may not be called     * during a classfile read.     */    public Type makeCompoundType(Type bound1, Type bound2) {        return makeCompoundType(List.of(bound1, bound2));    }    // </editor-fold>    // <editor-fold defaultstate="collapsed" desc="supertype">    public Type supertype(Type t) {        return supertype.visit(t);    }    // where        private UnaryVisitor<Type> supertype = new UnaryVisitor<Type>() {            public Type visitType(Type t, Void ignored) {                // A note on wildcards: there is no good way to                // determine a supertype for a super bounded wildcard.                return null;            }            @Override            public Type visitClassType(ClassType t, Void ignored) {                if (t.supertype_field == null) {                    Type supertype = ((ClassSymbol)t.tsym).getSuperclass();                    // An interface has no superclass; its supertype is Object.                    if (t.isInterface())                        supertype = ((ClassType)t.tsym.type).supertype_field;                    if (t.supertype_field == null) {                        List<Type> actuals = classBound(t).allparams();                        List<Type> formals = t.tsym.type.allparams();                        if (actuals.isEmpty()) {                            if (formals.isEmpty())                                // Should not happen.  See comments below in interfaces                                t.supertype_field = supertype;                            else                                t.supertype_field = erasure(supertype);                        } else {                            t.supertype_field = subst(supertype, formals, actuals);                        }                    }                }                return t.supertype_field;            }            /**             * The supertype is always a class type. If the type             * variable's bounds start with a class type, this is also             * the supertype.  Otherwise, the supertype is             * java.lang.Object.             */            @Override            public Type visitTypeVar(TypeVar t, Void ignored) {                if (t.bound.tag == TYPEVAR ||                    (!t.bound.isCompound() && !t.bound.isInterface())) {                    return t.bound;                } else {                    return supertype(t.bound);                }            }            @Override            public Type visitArrayType(ArrayType t, Void ignored) {                if (t.elemtype.isPrimitive() || isSameType(t.elemtype, syms.objectType))                    return arraySuperType();                else                    return new ArrayType(supertype(t.elemtype), t.tsym);            }            @Override            public Type visitErrorType(ErrorType t, Void ignored) {                return t;            }        };    // </editor-fold>    // <editor-fold defaultstate="collapsed" desc="interfaces">    /**     * Return the interfaces implemented by this class.     */    public List<Type> interfaces(Type t) {        return interfaces.visit(t);    }    // where        private UnaryVisitor<List<Type>> interfaces = new UnaryVisitor<List<Type>>() {            public List<Type> visitType(Type t, Void ignored) {                return List.nil();            }            @Override            public List<Type> visitClassType(ClassType t, Void ignored) {                if (t.interfaces_field == null) {                    List<Type> interfaces = ((ClassSymbol)t.tsym).getInterfaces();                    if (t.interfaces_field == null) {                        // If t.interfaces_field is null, then t must                        // be a parameterized type (not to be confused                        // with a generic type declaration).                        // Terminology:                        //    Parameterized type: List<String>                        //    Generic type declaration: class List<E> { ... }                        // So t corresponds to List<String> and                        // t.tsym.type corresponds to List<E>.                        // The reason t must be parameterized type is                        // that completion will happen as a side                        // effect of calling                        // ClassSymbol.getInterfaces.  Since                        // t.interfaces_field is null after                        // completion, we can assume that t is not the                        // type of a class/interface declaration.                        assert t != t.tsym.type : t.toString();                        List<Type> actuals = t.allparams();                        List<Type> formals = t.tsym.type.allparams();                        if (actuals.isEmpty()) {                            if (formals.isEmpty()) {                                // In this case t is not generic (nor raw).                                // So this should not happen.                                t.interfaces_field = interfaces;                            } else {                                t.interfaces_field = erasure(interfaces);                            }                        } else {                            t.interfaces_field =                                upperBounds(subst(interfaces, formals, actuals));                        }                    }                }                return t.interfaces_field;            }            @Override            public List<Type> visitTypeVar(TypeVar t, Void ignored) {                if (t.bound.isCompound())                    return interfaces(t.bound);                if (t.bound.isInterface())                    return List.of(t.bound);                return List.nil();            }        };    // </editor-fold>    // <editor-fold defaultstate="collapsed" desc="isDerivedRaw">    Map<Type,Boolean> isDerivedRawCache = new HashMap<Type,Boolean>();    public boolean isDerivedRaw(Type t) {        Boolean result = isDerivedRawCache.get(t);        if (result == null) {            result = isDerivedRawInternal(t);            isDerivedRawCache.put(t, result);        }        return result;    }    public boolean isDerivedRawInternal(Type t) {        if (t.isErroneous())            return false;        return            t.isRaw() ||            supertype(t) != null && isDerivedRaw(supertype(t)) ||            isDerivedRaw(interfaces(t));    }    public boolean isDerivedRaw(List<Type> ts) {        List<Type> l = ts;        while (l.nonEmpty() && !isDerivedRaw(l.head)) l = l.tail;        return l.nonEmpty();    }    // </editor-fold>    // <editor-fold defaultstate="collapsed" desc="setBounds">    /**     * Set the bounds field of the given type variable to reflect a     * (possibly multiple) list of bounds.     * @param t                 a type variable     * @param bounds            the bounds, must be nonempty     * @param supertype         is objectType if all bounds are interfaces,     *                          null otherwise.     */    public void setBounds(TypeVar t, List<Type> bounds, Type supertype) {        if (bounds.tail.isEmpty())            t.bound = bounds.head;        else            t.bound = makeCompoundType(bounds, supertype);        t.rank_field = -1;    }    /**     * Same as {@link #setBounds(Type.TypeVar,List,Type)}, except that     * third parameter is computed directly.  Note that this test     * might cause a symbol completion.  Hence, this version of     * setBounds may not be called during a classfile read.     */    public void setBounds(TypeVar t, List<Type> bounds) {        Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?            supertype(bounds.head) : null;        setBounds(t, bounds, supertype);        t.rank_field = -1;    }    // </editor-fold>    // <editor-fold defaultstate="collapsed" desc="getBounds">    /**     * Return list of bounds of the given type variable.     */    public List<Type> getBounds(TypeVar t) {        if (t.bound.isErroneous() || !t.bound.isCompound())            return List.of(t.bound);        else if ((erasure(t).tsym.fl

⌨️ 快捷键说明

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