src/share/classes/com/sun/tools/javac/code/Types.java

Print this page




1522 
1523             @Override
1524             public Boolean visitWildcardType(WildcardType t, Type s) {
1525                 return isCastable(wildUpperBound(t), s, warnStack.head);
1526             }
1527 
1528             @Override
1529             public Boolean visitClassType(ClassType t, Type s) {
1530                 if (s.hasTag(ERROR) || s.hasTag(BOT))
1531                     return true;
1532 
1533                 if (s.hasTag(TYPEVAR)) {
1534                     if (isCastable(t, s.getUpperBound(), noWarnings)) {
1535                         warnStack.head.warn(LintCategory.UNCHECKED);
1536                         return true;
1537                     } else {
1538                         return false;
1539                     }
1540                 }
1541 
1542                 if (t.isCompound() || s.isCompound()) {
1543                     return !t.isCompound() ?
1544                             visitIntersectionType((IntersectionClassType)s.unannotatedType(), t, true) :
1545                             visitIntersectionType((IntersectionClassType)t.unannotatedType(), s, false);
1546                 }
1547 
1548                 if (s.hasTag(CLASS) || s.hasTag(ARRAY)) {
1549                     boolean upcast;
1550                     if ((upcast = isSubtype(erasure(t), erasure(s)))
1551                         || isSubtype(erasure(s), erasure(t))) {
1552                         if (!upcast && s.hasTag(ARRAY)) {
1553                             if (!isReifiable(s))
1554                                 warnStack.head.warn(LintCategory.UNCHECKED);
1555                             return true;
1556                         } else if (s.isRaw()) {
1557                             return true;
1558                         } else if (t.isRaw()) {
1559                             if (!isUnbounded(s))
1560                                 warnStack.head.warn(LintCategory.UNCHECKED);
1561                             return true;
1562                         }
1563                         // Assume |a| <: |b|


2238             public Type apply(Type t) { return erasure(t); }
2239         };
2240 
2241     private Mapping erasureRecFun = new Mapping ("erasureRecursive") {
2242         public Type apply(Type t) { return erasureRecursive(t); }
2243     };
2244 
2245     public List<Type> erasure(List<Type> ts) {
2246         return Type.map(ts, erasureFun);
2247     }
2248 
2249     public Type erasureRecursive(Type t) {
2250         return erasure(t, true);
2251     }
2252 
2253     public List<Type> erasureRecursive(List<Type> ts) {
2254         return Type.map(ts, erasureRecFun);
2255     }
2256     // </editor-fold>
2257 
2258     // <editor-fold defaultstate="collapsed" desc="makeCompoundType">
2259     /**
2260      * Make a compound type from non-empty list of types.  The list should be
2261      * ordered according to {@link Symbol#precedes(TypeSymbol,Types)}.

2262      *
2263      * @param bounds            the types from which the compound type is formed
2264      * @param supertype         is objectType if all bounds are interfaces,
2265      *                          null otherwise.
2266      */
2267     public Type makeCompoundType(List<Type> bounds) {
2268         return makeCompoundType(bounds, bounds.head.tsym.isInterface());
2269     }
2270     public Type makeCompoundType(List<Type> bounds, boolean allInterfaces) {










2271         Assert.check(bounds.nonEmpty());
2272         Type firstExplicitBound = bounds.head;
2273         if (allInterfaces) {
2274             bounds = bounds.prepend(syms.objectType);
2275         }
2276         ClassSymbol bc =
2277             new ClassSymbol(ABSTRACT|PUBLIC|SYNTHETIC|COMPOUND|ACYCLIC,
2278                             Type.moreInfo
2279                                 ? names.fromString(bounds.toString())
2280                                 : names.empty,
2281                             null,
2282                             syms.noSymbol);
2283         bc.type = new IntersectionClassType(bounds, bc, allInterfaces);

2284         bc.erasure_field = (bounds.head.hasTag(TYPEVAR)) ?
2285                 syms.objectType : // error condition, recover
2286                 erasure(firstExplicitBound);
2287         bc.members_field = new Scope(bc);
2288         return bc.type;
2289     }
2290 
2291     /**
2292      * A convenience wrapper for {@link #makeCompoundType(List)}; the
2293      * arguments are converted to a list and passed to the other
2294      * method.  Note that this might cause a symbol completion.
2295      * Hence, this version of makeCompoundType may not be called
2296      * during a classfile read.
2297      */
2298     public Type makeCompoundType(Type bound1, Type bound2) {
2299         return makeCompoundType(List.of(bound1, bound2));
2300     }
2301     // </editor-fold>
2302 
2303     // <editor-fold defaultstate="collapsed" desc="supertype">
2304     public Type supertype(Type t) {
2305         return supertype.visit(t);
2306     }
2307     // where
2308         private UnaryVisitor<Type> supertype = new UnaryVisitor<Type>() {
2309 
2310             public Type visitType(Type t, Void ignored) {
2311                 // A note on wildcards: there is no good way to
2312                 // determine a supertype for a super bounded wildcard.
2313                 return Type.noType;
2314             }
2315 
2316             @Override
2317             public Type visitClassType(ClassType t, Void ignored) {
2318                 if (t.supertype_field == null) {
2319                     Type supertype = ((ClassSymbol)t.tsym).getSuperclass();


2419 
2420             @Override
2421             public List<Type> visitTypeVar(TypeVar t, Void ignored) {
2422                 if (t.bound.isCompound())
2423                     return interfaces(t.bound);
2424 
2425                 if (t.bound.isInterface())
2426                     return List.of(t.bound);
2427 
2428                 return List.nil();
2429             }
2430         };
2431 
2432     public List<Type> directSupertypes(Type t) {
2433         return directSupertypes.visit(t);
2434     }
2435     // where
2436         private final UnaryVisitor<List<Type>> directSupertypes = new UnaryVisitor<List<Type>>() {
2437 
2438             public List<Type> visitType(final Type type, final Void ignored) {
2439                 if (!type.isCompound()) {
2440                     final Type sup = supertype(type);
2441                     return (sup == Type.noType || sup == type || sup == null)
2442                         ? interfaces(type)
2443                         : interfaces(type).prepend(sup);
2444                 } else {
2445                     return visitIntersectionType((IntersectionClassType) type);
2446                 }
2447             }
2448 
2449             private List<Type> visitIntersectionType(final IntersectionClassType it) {
2450                 return it.getExplicitComponents();
2451             }
2452 
2453         };
2454 
2455     public boolean isDirectSuperInterface(TypeSymbol isym, TypeSymbol origin) {
2456         for (Type i2 : interfaces(origin.type)) {
2457             if (isym == i2.tsym) return true;
2458         }
2459         return false;


2473     }
2474 
2475     public boolean isDerivedRawInternal(Type t) {
2476         if (t.isErroneous())
2477             return false;
2478         return
2479             t.isRaw() ||
2480             supertype(t) != Type.noType && isDerivedRaw(supertype(t)) ||
2481             isDerivedRaw(interfaces(t));
2482     }
2483 
2484     public boolean isDerivedRaw(List<Type> ts) {
2485         List<Type> l = ts;
2486         while (l.nonEmpty() && !isDerivedRaw(l.head)) l = l.tail;
2487         return l.nonEmpty();
2488     }
2489     // </editor-fold>
2490 
2491     // <editor-fold defaultstate="collapsed" desc="setBounds">
2492     /**
2493      * Set the bounds field of the given type variable to reflect a
2494      * (possibly multiple) list of bounds.




2495      * @param t                 a type variable
2496      * @param bounds            the bounds, must be nonempty
2497      * @param supertype         is objectType if all bounds are interfaces,
2498      *                          null otherwise.
2499      */
2500     public void setBounds(TypeVar t, List<Type> bounds) {
2501         setBounds(t, bounds, bounds.head.tsym.isInterface());
2502     }
2503 
2504     /**
2505      * Same as {@link #setBounds(Type.TypeVar,List,Type)}, except that
2506      * third parameter is computed directly, as follows: if all
2507      * all bounds are interface types, the computed supertype is Object,
2508      * otherwise the supertype is simply left null (in this case, the supertype
2509      * is assumed to be the head of the bound list passed as second argument).
2510      * Note that this check might cause a symbol completion. Hence, this version of
2511      * setBounds may not be called during a classfile read.
2512      */
2513     public void setBounds(TypeVar t, List<Type> bounds, boolean allInterfaces) {
2514         t.bound = bounds.tail.isEmpty() ?
2515                 bounds.head :
2516                 makeCompoundType(bounds, allInterfaces);
2517         t.rank_field = -1;
2518     }
2519     // </editor-fold>
2520 
2521     // <editor-fold defaultstate="collapsed" desc="getBounds">
2522     /**
2523      * Return list of bounds of the given type variable.
2524      */
2525     public List<Type> getBounds(TypeVar t) {
2526         if (t.bound.hasTag(NONE))
2527             return List.nil();
2528         else if (t.bound.isErroneous() || !t.bound.isCompound())
2529             return List.of(t.bound);
2530         else if ((erasure(t).tsym.flags() & INTERFACE) == 0)
2531             return interfaces(t).prepend(supertype(t));
2532         else
2533             // No superclass was given in bounds.
2534             // In this case, supertype is Object, erasure is first interface.
2535             return interfaces(t);
2536     }


3046             return t;
3047         }
3048 
3049         @Override
3050         public Type visitClassType(ClassType t, Void ignored) {
3051             if (!t.isCompound()) {
3052                 List<Type> typarams = t.getTypeArguments();
3053                 List<Type> typarams1 = subst(typarams);
3054                 Type outer = t.getEnclosingType();
3055                 Type outer1 = subst(outer);
3056                 if (typarams1 == typarams && outer1 == outer)
3057                     return t;
3058                 else
3059                     return new ClassType(outer1, typarams1, t.tsym);
3060             } else {
3061                 Type st = subst(supertype(t));
3062                 List<Type> is = subst(interfaces(t));
3063                 if (st == supertype(t) && is == interfaces(t))
3064                     return t;
3065                 else
3066                     return makeCompoundType(is.prepend(st));
3067             }
3068         }
3069 
3070         @Override
3071         public Type visitWildcardType(WildcardType t, Void ignored) {
3072             Type bound = t.type;
3073             if (t.kind != BoundKind.UNBOUND)
3074                 bound = subst(bound);
3075             if (bound == t.type) {
3076                 return t;
3077             } else {
3078                 if (t.isExtendsBound() && bound.isExtendsBound())
3079                     bound = wildUpperBound(bound);
3080                 return new WildcardType(bound, t.kind, syms.boundClass, t.bound);
3081             }
3082         }
3083 
3084         @Override
3085         public Type visitArrayType(ArrayType t, Void ignored) {
3086             Type elemtype = subst(t.elemtype);


3549                 act1 = act1.tail;
3550                 act2 = act2.tail;
3551                 typarams = typarams.tail;
3552             }
3553             Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
3554             return new ClassType(class1.getEnclosingType(), merged.toList(), class1.tsym);
3555         }
3556 
3557     /**
3558      * Return the minimum type of a closure, a compound type if no
3559      * unique minimum exists.
3560      */
3561     private Type compoundMin(List<Type> cl) {
3562         if (cl.isEmpty()) return syms.objectType;
3563         List<Type> compound = closureMin(cl);
3564         if (compound.isEmpty())
3565             return null;
3566         else if (compound.tail.isEmpty())
3567             return compound.head;
3568         else
3569             return makeCompoundType(compound);
3570     }
3571 
3572     /**
3573      * Return the minimum types of a closure, suitable for computing
3574      * compoundMin or glb.
3575      */
3576     private List<Type> closureMin(List<Type> cl) {
3577         ListBuffer<Type> classes = new ListBuffer<>();
3578         ListBuffer<Type> interfaces = new ListBuffer<>();
3579         Set<Type> toSkip = new HashSet<>();
3580         while (!cl.isEmpty()) {
3581             Type current = cl.head;
3582             boolean keep = !toSkip.contains(current);
3583             if (keep && current.hasTag(TYPEVAR)) {
3584                 // skip lower-bounded variables with a subtype in cl.tail
3585                 for (Type t : cl.tail) {
3586                     if (isSubtypeNoCapture(t, current)) {
3587                         keep = false;
3588                         break;
3589                     }


3727     // where
3728         List<Type> erasedSupertypes(Type t) {
3729             ListBuffer<Type> buf = new ListBuffer<>();
3730             for (Type sup : closure(t)) {
3731                 if (sup.hasTag(TYPEVAR)) {
3732                     buf.append(sup);
3733                 } else {
3734                     buf.append(erasure(sup));
3735                 }
3736             }
3737             return buf.toList();
3738         }
3739 
3740         private Type arraySuperType = null;
3741         private Type arraySuperType() {
3742             // initialized lazily to avoid problems during compiler startup
3743             if (arraySuperType == null) {
3744                 synchronized (this) {
3745                     if (arraySuperType == null) {
3746                         // JLS 10.8: all arrays implement Cloneable and Serializable.
3747                         arraySuperType = makeCompoundType(List.of(syms.serializableType,
3748                                                                   syms.cloneableType), true);
3749                     }
3750                 }
3751             }
3752             return arraySuperType;
3753         }
3754     // </editor-fold>
3755 
3756     // <editor-fold defaultstate="collapsed" desc="Greatest lower bound">
3757     public Type glb(List<Type> ts) {
3758         Type t1 = ts.head;
3759         for (Type t2 : ts.tail) {
3760             if (t1.isErroneous())
3761                 return t1;
3762             t1 = glb(t1, t2);
3763         }
3764         return t1;
3765     }
3766     //where
3767     public Type glb(Type t, Type s) {


3794         } else if (bounds.tail.isEmpty()) { // length == 1
3795             return bounds.head;
3796         } else {                            // length > 1
3797             int classCount = 0;
3798             List<Type> lowers = List.nil();
3799             for (Type bound : bounds) {
3800                 if (!bound.isInterface()) {
3801                     classCount++;
3802                     Type lower = cvarLowerBound(bound);
3803                     if (bound != lower && !lower.hasTag(BOT))
3804                         lowers = insert(lowers, lower);
3805                 }
3806             }
3807             if (classCount > 1) {
3808                 if (lowers.isEmpty())
3809                     return createErrorType(errT);
3810                 else
3811                     return glbFlattened(union(bounds, lowers), errT);
3812             }
3813         }
3814         return makeCompoundType(bounds);
3815     }
3816     // </editor-fold>
3817 
3818     // <editor-fold defaultstate="collapsed" desc="hashCode">
3819     /**
3820      * Compute a hash code on a type.
3821      */
3822     public int hashCode(Type t) {
3823         return hashCode.visit(t);
3824     }
3825     // where
3826         private static final UnaryVisitor<Integer> hashCode = new UnaryVisitor<Integer>() {
3827 
3828             public Integer visitType(Type t, Void ignored) {
3829                 return t.getTag().ordinal();
3830             }
3831 
3832             @Override
3833             public Integer visitClassType(ClassType t, Void ignored) {
3834                 int result = visit(t.getEnclosingType());




1522 
1523             @Override
1524             public Boolean visitWildcardType(WildcardType t, Type s) {
1525                 return isCastable(wildUpperBound(t), s, warnStack.head);
1526             }
1527 
1528             @Override
1529             public Boolean visitClassType(ClassType t, Type s) {
1530                 if (s.hasTag(ERROR) || s.hasTag(BOT))
1531                     return true;
1532 
1533                 if (s.hasTag(TYPEVAR)) {
1534                     if (isCastable(t, s.getUpperBound(), noWarnings)) {
1535                         warnStack.head.warn(LintCategory.UNCHECKED);
1536                         return true;
1537                     } else {
1538                         return false;
1539                     }
1540                 }
1541 
1542                 if (t.isIntersection() || s.isIntersection()) {
1543                     return !t.isIntersection() ?
1544                             visitIntersectionType((IntersectionClassType)s.unannotatedType(), t, true) :
1545                             visitIntersectionType((IntersectionClassType)t.unannotatedType(), s, false);
1546                 }
1547 
1548                 if (s.hasTag(CLASS) || s.hasTag(ARRAY)) {
1549                     boolean upcast;
1550                     if ((upcast = isSubtype(erasure(t), erasure(s)))
1551                         || isSubtype(erasure(s), erasure(t))) {
1552                         if (!upcast && s.hasTag(ARRAY)) {
1553                             if (!isReifiable(s))
1554                                 warnStack.head.warn(LintCategory.UNCHECKED);
1555                             return true;
1556                         } else if (s.isRaw()) {
1557                             return true;
1558                         } else if (t.isRaw()) {
1559                             if (!isUnbounded(s))
1560                                 warnStack.head.warn(LintCategory.UNCHECKED);
1561                             return true;
1562                         }
1563                         // Assume |a| <: |b|


2238             public Type apply(Type t) { return erasure(t); }
2239         };
2240 
2241     private Mapping erasureRecFun = new Mapping ("erasureRecursive") {
2242         public Type apply(Type t) { return erasureRecursive(t); }
2243     };
2244 
2245     public List<Type> erasure(List<Type> ts) {
2246         return Type.map(ts, erasureFun);
2247     }
2248 
2249     public Type erasureRecursive(Type t) {
2250         return erasure(t, true);
2251     }
2252 
2253     public List<Type> erasureRecursive(List<Type> ts) {
2254         return Type.map(ts, erasureRecFun);
2255     }
2256     // </editor-fold>
2257 
2258     // <editor-fold defaultstate="collapsed" desc="makeIntersectionType">
2259     /**
2260      * Make an intersection type from non-empty list of types.  The list should be ordered according to
2261      * {@link TypeSymbol#precedes(TypeSymbol, Types)}. Note that this might cause a symbol completion.
2262      * Hence, this version of makeIntersectionType may not be called during a classfile read.
2263      *
2264      * @param bounds    the types from which the intersection type is formed


2265      */
2266     public IntersectionClassType makeIntersectionType(List<Type> bounds) {
2267         return makeIntersectionType(bounds, bounds.head.tsym.isInterface());
2268     }
2269 
2270     /**
2271      * Make an intersection type from non-empty list of types.  The list should be ordered according to
2272      * {@link TypeSymbol#precedes(TypeSymbol, Types)}. This does not cause symbol completion as
2273      * an extra parameter indicates as to whether all bounds are interfaces - in which case the
2274      * supertype is implicitly assumed to be 'Object'.
2275      *
2276      * @param bounds        the types from which the intersection type is formed
2277      * @param allInterfaces are all bounds interface types?
2278      */
2279     public IntersectionClassType makeIntersectionType(List<Type> bounds, boolean allInterfaces) {
2280         Assert.check(bounds.nonEmpty());
2281         Type firstExplicitBound = bounds.head;
2282         if (allInterfaces) {
2283             bounds = bounds.prepend(syms.objectType);
2284         }
2285         ClassSymbol bc =
2286             new ClassSymbol(ABSTRACT|PUBLIC|SYNTHETIC|COMPOUND|ACYCLIC,
2287                             Type.moreInfo
2288                                 ? names.fromString(bounds.toString())
2289                                 : names.empty,
2290                             null,
2291                             syms.noSymbol);
2292         IntersectionClassType intersectionType = new IntersectionClassType(bounds, bc, allInterfaces);
2293         bc.type = intersectionType;
2294         bc.erasure_field = (bounds.head.hasTag(TYPEVAR)) ?
2295                 syms.objectType : // error condition, recover
2296                 erasure(firstExplicitBound);
2297         bc.members_field = new Scope(bc);
2298         return intersectionType;
2299     }
2300 
2301     /**
2302      * A convenience wrapper for {@link #makeIntersectionType(List)}; the
2303      * arguments are converted to a list and passed to the other
2304      * method.  Note that this might cause a symbol completion.
2305      * Hence, this version of makeIntersectionType may not be called
2306      * during a classfile read.
2307      */
2308     public Type makeIntersectionType(Type bound1, Type bound2) {
2309         return makeIntersectionType(List.of(bound1, bound2));
2310     }
2311     // </editor-fold>
2312 
2313     // <editor-fold defaultstate="collapsed" desc="supertype">
2314     public Type supertype(Type t) {
2315         return supertype.visit(t);
2316     }
2317     // where
2318         private UnaryVisitor<Type> supertype = new UnaryVisitor<Type>() {
2319 
2320             public Type visitType(Type t, Void ignored) {
2321                 // A note on wildcards: there is no good way to
2322                 // determine a supertype for a super bounded wildcard.
2323                 return Type.noType;
2324             }
2325 
2326             @Override
2327             public Type visitClassType(ClassType t, Void ignored) {
2328                 if (t.supertype_field == null) {
2329                     Type supertype = ((ClassSymbol)t.tsym).getSuperclass();


2429 
2430             @Override
2431             public List<Type> visitTypeVar(TypeVar t, Void ignored) {
2432                 if (t.bound.isCompound())
2433                     return interfaces(t.bound);
2434 
2435                 if (t.bound.isInterface())
2436                     return List.of(t.bound);
2437 
2438                 return List.nil();
2439             }
2440         };
2441 
2442     public List<Type> directSupertypes(Type t) {
2443         return directSupertypes.visit(t);
2444     }
2445     // where
2446         private final UnaryVisitor<List<Type>> directSupertypes = new UnaryVisitor<List<Type>>() {
2447 
2448             public List<Type> visitType(final Type type, final Void ignored) {
2449                 if (!type.isIntersection()) {
2450                     final Type sup = supertype(type);
2451                     return (sup == Type.noType || sup == type || sup == null)
2452                         ? interfaces(type)
2453                         : interfaces(type).prepend(sup);
2454                 } else {
2455                     return visitIntersectionType((IntersectionClassType) type);
2456                 }
2457             }
2458 
2459             private List<Type> visitIntersectionType(final IntersectionClassType it) {
2460                 return it.getExplicitComponents();
2461             }
2462 
2463         };
2464 
2465     public boolean isDirectSuperInterface(TypeSymbol isym, TypeSymbol origin) {
2466         for (Type i2 : interfaces(origin.type)) {
2467             if (isym == i2.tsym) return true;
2468         }
2469         return false;


2483     }
2484 
2485     public boolean isDerivedRawInternal(Type t) {
2486         if (t.isErroneous())
2487             return false;
2488         return
2489             t.isRaw() ||
2490             supertype(t) != Type.noType && isDerivedRaw(supertype(t)) ||
2491             isDerivedRaw(interfaces(t));
2492     }
2493 
2494     public boolean isDerivedRaw(List<Type> ts) {
2495         List<Type> l = ts;
2496         while (l.nonEmpty() && !isDerivedRaw(l.head)) l = l.tail;
2497         return l.nonEmpty();
2498     }
2499     // </editor-fold>
2500 
2501     // <editor-fold defaultstate="collapsed" desc="setBounds">
2502     /**
2503      * Same as {@link Types#setBounds(TypeVar, List, boolean)}, except that third parameter is computed directly,
2504      * as follows: if all all bounds are interface types, the computed supertype is Object,otherwise
2505      * the supertype is simply left null (in this case, the supertype is assumed to be the head of
2506      * the bound list passed as second argument). Note that this check might cause a symbol completion.
2507      * Hence, this version of setBounds may not be called during a classfile read.
2508      *
2509      * @param t         a type variable
2510      * @param bounds    the bounds, must be nonempty


2511      */
2512     public void setBounds(TypeVar t, List<Type> bounds) {
2513         setBounds(t, bounds, bounds.head.tsym.isInterface());
2514     }
2515 
2516     /**
2517      * Set the bounds field of the given type variable to reflect a (possibly multiple) list of bounds.
2518      * This does not cause symbol completion as an extra parameter indicates as to whether all bounds
2519      * are interfaces - in which case the supertype is implicitly assumed to be 'Object'.
2520      *
2521      * @param t             a type variable
2522      * @param bounds        the bounds, must be nonempty
2523      * @param allInterfaces are all bounds interface types?
2524      */
2525     public void setBounds(TypeVar t, List<Type> bounds, boolean allInterfaces) {
2526         t.bound = bounds.tail.isEmpty() ?
2527                 bounds.head :
2528                 makeIntersectionType(bounds, allInterfaces);
2529         t.rank_field = -1;
2530     }
2531     // </editor-fold>
2532 
2533     // <editor-fold defaultstate="collapsed" desc="getBounds">
2534     /**
2535      * Return list of bounds of the given type variable.
2536      */
2537     public List<Type> getBounds(TypeVar t) {
2538         if (t.bound.hasTag(NONE))
2539             return List.nil();
2540         else if (t.bound.isErroneous() || !t.bound.isCompound())
2541             return List.of(t.bound);
2542         else if ((erasure(t).tsym.flags() & INTERFACE) == 0)
2543             return interfaces(t).prepend(supertype(t));
2544         else
2545             // No superclass was given in bounds.
2546             // In this case, supertype is Object, erasure is first interface.
2547             return interfaces(t);
2548     }


3058             return t;
3059         }
3060 
3061         @Override
3062         public Type visitClassType(ClassType t, Void ignored) {
3063             if (!t.isCompound()) {
3064                 List<Type> typarams = t.getTypeArguments();
3065                 List<Type> typarams1 = subst(typarams);
3066                 Type outer = t.getEnclosingType();
3067                 Type outer1 = subst(outer);
3068                 if (typarams1 == typarams && outer1 == outer)
3069                     return t;
3070                 else
3071                     return new ClassType(outer1, typarams1, t.tsym);
3072             } else {
3073                 Type st = subst(supertype(t));
3074                 List<Type> is = subst(interfaces(t));
3075                 if (st == supertype(t) && is == interfaces(t))
3076                     return t;
3077                 else
3078                     return makeIntersectionType(is.prepend(st));
3079             }
3080         }
3081 
3082         @Override
3083         public Type visitWildcardType(WildcardType t, Void ignored) {
3084             Type bound = t.type;
3085             if (t.kind != BoundKind.UNBOUND)
3086                 bound = subst(bound);
3087             if (bound == t.type) {
3088                 return t;
3089             } else {
3090                 if (t.isExtendsBound() && bound.isExtendsBound())
3091                     bound = wildUpperBound(bound);
3092                 return new WildcardType(bound, t.kind, syms.boundClass, t.bound);
3093             }
3094         }
3095 
3096         @Override
3097         public Type visitArrayType(ArrayType t, Void ignored) {
3098             Type elemtype = subst(t.elemtype);


3561                 act1 = act1.tail;
3562                 act2 = act2.tail;
3563                 typarams = typarams.tail;
3564             }
3565             Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
3566             return new ClassType(class1.getEnclosingType(), merged.toList(), class1.tsym);
3567         }
3568 
3569     /**
3570      * Return the minimum type of a closure, a compound type if no
3571      * unique minimum exists.
3572      */
3573     private Type compoundMin(List<Type> cl) {
3574         if (cl.isEmpty()) return syms.objectType;
3575         List<Type> compound = closureMin(cl);
3576         if (compound.isEmpty())
3577             return null;
3578         else if (compound.tail.isEmpty())
3579             return compound.head;
3580         else
3581             return makeIntersectionType(compound);
3582     }
3583 
3584     /**
3585      * Return the minimum types of a closure, suitable for computing
3586      * compoundMin or glb.
3587      */
3588     private List<Type> closureMin(List<Type> cl) {
3589         ListBuffer<Type> classes = new ListBuffer<>();
3590         ListBuffer<Type> interfaces = new ListBuffer<>();
3591         Set<Type> toSkip = new HashSet<>();
3592         while (!cl.isEmpty()) {
3593             Type current = cl.head;
3594             boolean keep = !toSkip.contains(current);
3595             if (keep && current.hasTag(TYPEVAR)) {
3596                 // skip lower-bounded variables with a subtype in cl.tail
3597                 for (Type t : cl.tail) {
3598                     if (isSubtypeNoCapture(t, current)) {
3599                         keep = false;
3600                         break;
3601                     }


3739     // where
3740         List<Type> erasedSupertypes(Type t) {
3741             ListBuffer<Type> buf = new ListBuffer<>();
3742             for (Type sup : closure(t)) {
3743                 if (sup.hasTag(TYPEVAR)) {
3744                     buf.append(sup);
3745                 } else {
3746                     buf.append(erasure(sup));
3747                 }
3748             }
3749             return buf.toList();
3750         }
3751 
3752         private Type arraySuperType = null;
3753         private Type arraySuperType() {
3754             // initialized lazily to avoid problems during compiler startup
3755             if (arraySuperType == null) {
3756                 synchronized (this) {
3757                     if (arraySuperType == null) {
3758                         // JLS 10.8: all arrays implement Cloneable and Serializable.
3759                         arraySuperType = makeIntersectionType(List.of(syms.serializableType,
3760                                 syms.cloneableType), true);
3761                     }
3762                 }
3763             }
3764             return arraySuperType;
3765         }
3766     // </editor-fold>
3767 
3768     // <editor-fold defaultstate="collapsed" desc="Greatest lower bound">
3769     public Type glb(List<Type> ts) {
3770         Type t1 = ts.head;
3771         for (Type t2 : ts.tail) {
3772             if (t1.isErroneous())
3773                 return t1;
3774             t1 = glb(t1, t2);
3775         }
3776         return t1;
3777     }
3778     //where
3779     public Type glb(Type t, Type s) {


3806         } else if (bounds.tail.isEmpty()) { // length == 1
3807             return bounds.head;
3808         } else {                            // length > 1
3809             int classCount = 0;
3810             List<Type> lowers = List.nil();
3811             for (Type bound : bounds) {
3812                 if (!bound.isInterface()) {
3813                     classCount++;
3814                     Type lower = cvarLowerBound(bound);
3815                     if (bound != lower && !lower.hasTag(BOT))
3816                         lowers = insert(lowers, lower);
3817                 }
3818             }
3819             if (classCount > 1) {
3820                 if (lowers.isEmpty())
3821                     return createErrorType(errT);
3822                 else
3823                     return glbFlattened(union(bounds, lowers), errT);
3824             }
3825         }
3826         return makeIntersectionType(bounds);
3827     }
3828     // </editor-fold>
3829 
3830     // <editor-fold defaultstate="collapsed" desc="hashCode">
3831     /**
3832      * Compute a hash code on a type.
3833      */
3834     public int hashCode(Type t) {
3835         return hashCode.visit(t);
3836     }
3837     // where
3838         private static final UnaryVisitor<Integer> hashCode = new UnaryVisitor<Integer>() {
3839 
3840             public Integer visitType(Type t, Void ignored) {
3841                 return t.getTag().ordinal();
3842             }
3843 
3844             @Override
3845             public Integer visitClassType(ClassType t, Void ignored) {
3846                 int result = visit(t.getEnclosingType());