Types方法之isSameType-isSuperType-isSubType

时间:2024-04-20 15:05:03

4、isSameType() 方法

  /**
     * Is t the same type as s?
     */
    public boolean isSameType(Type t, Type s) {
        return isSameType.visit(t, s);
    }  

会对t为各种类型进行单独判断,下面来具体阐述。

(1)t为Type类型

public Boolean visitType(Type t, Type s) {
            if (t == s)
                return true;

            if (s.tag >= firstPartialTag)
                return visit(s, t);

            switch (t.tag) {
            case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
            case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE:
                return t.tag == s.tag;
            case TYPEVAR: {
                if (s.tag == TYPEVAR) {
                    //type-substitution does not preserve type-var types
                    //check that type var symbols and bounds are indeed the same
                    return t.tsym == s.tsym &&
                            visit(t.getUpperBound(), s.getUpperBound());
                }
                else {
                    //special case for s == ? super X, where upper(s) = u
                    //check that u == t, where u has been set by Type.withTypeVar
                    return s.isSuperBound() &&
                            !s.isExtendsBound() &&   // 这样可以确保为 ? super X 而不是?
                            visit(t, upperBound(s)); // 判断t是否为upperBound(s)的子类
                }
            }
            default:
                throw new AssertionError("isSameType " + t.tag);
            }
}

(2)t为visitClassType类型

@Override
public Boolean visitClassType(ClassType t, Type s) {
            if (t == s)
                return true;

            if (s.tag >= firstPartialTag)
                return visit(s, t);

            if (s.isSuperBound() && !s.isExtendsBound())
                return visit(t, upperBound(s)) && visit(t, lowerBound(s));

            if (t.isCompound() && s.isCompound()) {
                if (!visit(supertype(t), supertype(s)))
                    return false;

                HashSet<SingletonType> set = new HashSet<SingletonType>();
                for (Type x : interfaces(t))
                    set.add(new SingletonType(x));
                for (Type x : interfaces(s)) {
                    if (!set.remove(new SingletonType(x)))
                        return false;
                }
                return (set.isEmpty());
            }
            return t.tsym == s.tsym
                && visit(t.getEnclosingType(), s.getEnclosingType())
                && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments());
}

(2)t为visitArrayType类型  

@Override
public Boolean visitArrayType(ArrayType t, Type s) {
            if (t == s)
                return true;

            if (s.tag >= firstPartialTag)
                return visit(s, t);

            return s.tag == ARRAY
                && containsTypeEquivalent(t.elemtype, elemtype(s));
}

(3)t为visitForAll类型

  @Override
        public Boolean visitForAll(ForAll t, Type s) {
            if (s.tag != FORALL)
                return false;

            ForAll forAll = (ForAll)s;
            return hasSameBounds(t, forAll) &&
                    visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
        }

  

(4)t为visitUndetVar类型  

  @Override
        public Boolean visitUndetVar(UndetVar t, Type s) {
            if (s.tag == WILDCARD)
                // FIXME, this might be leftovers from before capture conversion
                return false;

            if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN)
                return true;

            if (t.inst != null)
                return visit(t.inst, s);

            t.inst = fromUnknownFun.apply(s);
            for (List<Type> l = t.lobounds; l.nonEmpty(); l = l.tail) {
                if (!isSubtype(l.head, t.inst))
                    return false;
            }
            for (List<Type> l = t.hibounds; l.nonEmpty(); l = l.tail) {
                if (!isSubtype(t.inst, l.head))
                    return false;
            }
            return true;
        }

(5)others