langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
changeset 29147 4cba0458106b
parent 29146 7115a5967ed1
child 29292 c10d63c667cd
equal deleted inserted replaced
29146:7115a5967ed1 29147:4cba0458106b
  1514                     } else {
  1514                     } else {
  1515                         return false;
  1515                         return false;
  1516                     }
  1516                     }
  1517                 }
  1517                 }
  1518 
  1518 
  1519                 if (t.isCompound() || s.isCompound()) {
  1519                 if (t.isIntersection() || s.isIntersection()) {
  1520                     return !t.isCompound() ?
  1520                     return !t.isIntersection() ?
  1521                             visitIntersectionType((IntersectionClassType)s, t, true) :
  1521                             visitIntersectionType((IntersectionClassType)s, t, true) :
  1522                             visitIntersectionType((IntersectionClassType)t, s, false);
  1522                             visitIntersectionType((IntersectionClassType)t, s, false);
  1523                 }
  1523                 }
  1524 
  1524 
  1525                 if (s.hasTag(CLASS) || s.hasTag(ARRAY)) {
  1525                 if (s.hasTag(CLASS) || s.hasTag(ARRAY)) {
  2243     public List<Type> erasureRecursive(List<Type> ts) {
  2243     public List<Type> erasureRecursive(List<Type> ts) {
  2244         return Type.map(ts, erasureRecFun);
  2244         return Type.map(ts, erasureRecFun);
  2245     }
  2245     }
  2246     // </editor-fold>
  2246     // </editor-fold>
  2247 
  2247 
  2248     // <editor-fold defaultstate="collapsed" desc="makeCompoundType">
  2248     // <editor-fold defaultstate="collapsed" desc="makeIntersectionType">
  2249     /**
  2249     /**
  2250      * Make a compound type from non-empty list of types.  The list should be
  2250      * Make an intersection type from non-empty list of types.  The list should be ordered according to
  2251      * ordered according to {@link Symbol#precedes(TypeSymbol,Types)}.
  2251      * {@link TypeSymbol#precedes(TypeSymbol, Types)}. Note that this might cause a symbol completion.
       
  2252      * Hence, this version of makeIntersectionType may not be called during a classfile read.
  2252      *
  2253      *
  2253      * @param bounds            the types from which the compound type is formed
  2254      * @param bounds    the types from which the intersection type is formed
  2254      * @param supertype         is objectType if all bounds are interfaces,
  2255      */
  2255      *                          null otherwise.
  2256     public IntersectionClassType makeIntersectionType(List<Type> bounds) {
  2256      */
  2257         return makeIntersectionType(bounds, bounds.head.tsym.isInterface());
  2257     public Type makeCompoundType(List<Type> bounds) {
  2258     }
  2258         return makeCompoundType(bounds, bounds.head.tsym.isInterface());
  2259 
  2259     }
  2260     /**
  2260     public Type makeCompoundType(List<Type> bounds, boolean allInterfaces) {
  2261      * Make an intersection type from non-empty list of types.  The list should be ordered according to
       
  2262      * {@link TypeSymbol#precedes(TypeSymbol, Types)}. This does not cause symbol completion as
       
  2263      * an extra parameter indicates as to whether all bounds are interfaces - in which case the
       
  2264      * supertype is implicitly assumed to be 'Object'.
       
  2265      *
       
  2266      * @param bounds        the types from which the intersection type is formed
       
  2267      * @param allInterfaces are all bounds interface types?
       
  2268      */
       
  2269     public IntersectionClassType makeIntersectionType(List<Type> bounds, boolean allInterfaces) {
  2261         Assert.check(bounds.nonEmpty());
  2270         Assert.check(bounds.nonEmpty());
  2262         Type firstExplicitBound = bounds.head;
  2271         Type firstExplicitBound = bounds.head;
  2263         if (allInterfaces) {
  2272         if (allInterfaces) {
  2264             bounds = bounds.prepend(syms.objectType);
  2273             bounds = bounds.prepend(syms.objectType);
  2265         }
  2274         }
  2268                             Type.moreInfo
  2277                             Type.moreInfo
  2269                                 ? names.fromString(bounds.toString())
  2278                                 ? names.fromString(bounds.toString())
  2270                                 : names.empty,
  2279                                 : names.empty,
  2271                             null,
  2280                             null,
  2272                             syms.noSymbol);
  2281                             syms.noSymbol);
  2273         bc.type = new IntersectionClassType(bounds, bc, allInterfaces);
  2282         IntersectionClassType intersectionType = new IntersectionClassType(bounds, bc, allInterfaces);
       
  2283         bc.type = intersectionType;
  2274         bc.erasure_field = (bounds.head.hasTag(TYPEVAR)) ?
  2284         bc.erasure_field = (bounds.head.hasTag(TYPEVAR)) ?
  2275                 syms.objectType : // error condition, recover
  2285                 syms.objectType : // error condition, recover
  2276                 erasure(firstExplicitBound);
  2286                 erasure(firstExplicitBound);
  2277         bc.members_field = WriteableScope.create(bc);
  2287         bc.members_field = WriteableScope.create(bc);
  2278         return bc.type;
  2288         return intersectionType;
  2279     }
       
  2280 
       
  2281     /**
       
  2282      * A convenience wrapper for {@link #makeCompoundType(List)}; the
       
  2283      * arguments are converted to a list and passed to the other
       
  2284      * method.  Note that this might cause a symbol completion.
       
  2285      * Hence, this version of makeCompoundType may not be called
       
  2286      * during a classfile read.
       
  2287      */
       
  2288     public Type makeCompoundType(Type bound1, Type bound2) {
       
  2289         return makeCompoundType(List.of(bound1, bound2));
       
  2290     }
  2289     }
  2291     // </editor-fold>
  2290     // </editor-fold>
  2292 
  2291 
  2293     // <editor-fold defaultstate="collapsed" desc="supertype">
  2292     // <editor-fold defaultstate="collapsed" desc="supertype">
  2294     public Type supertype(Type t) {
  2293     public Type supertype(Type t) {
  2424     }
  2423     }
  2425     // where
  2424     // where
  2426         private final UnaryVisitor<List<Type>> directSupertypes = new UnaryVisitor<List<Type>>() {
  2425         private final UnaryVisitor<List<Type>> directSupertypes = new UnaryVisitor<List<Type>>() {
  2427 
  2426 
  2428             public List<Type> visitType(final Type type, final Void ignored) {
  2427             public List<Type> visitType(final Type type, final Void ignored) {
  2429                 if (!type.isCompound()) {
  2428                 if (!type.isIntersection()) {
  2430                     final Type sup = supertype(type);
  2429                     final Type sup = supertype(type);
  2431                     return (sup == Type.noType || sup == type || sup == null)
  2430                     return (sup == Type.noType || sup == type || sup == null)
  2432                         ? interfaces(type)
  2431                         ? interfaces(type)
  2433                         : interfaces(type).prepend(sup);
  2432                         : interfaces(type).prepend(sup);
  2434                 } else {
  2433                 } else {
  2478     }
  2477     }
  2479     // </editor-fold>
  2478     // </editor-fold>
  2480 
  2479 
  2481     // <editor-fold defaultstate="collapsed" desc="setBounds">
  2480     // <editor-fold defaultstate="collapsed" desc="setBounds">
  2482     /**
  2481     /**
  2483      * Set the bounds field of the given type variable to reflect a
  2482      * Same as {@link Types#setBounds(TypeVar, List, boolean)}, except that third parameter is computed directly,
  2484      * (possibly multiple) list of bounds.
  2483      * as follows: if all all bounds are interface types, the computed supertype is Object,otherwise
  2485      * @param t                 a type variable
  2484      * the supertype is simply left null (in this case, the supertype is assumed to be the head of
  2486      * @param bounds            the bounds, must be nonempty
  2485      * the bound list passed as second argument). Note that this check might cause a symbol completion.
  2487      * @param supertype         is objectType if all bounds are interfaces,
  2486      * Hence, this version of setBounds may not be called during a classfile read.
  2488      *                          null otherwise.
  2487      *
       
  2488      * @param t         a type variable
       
  2489      * @param bounds    the bounds, must be nonempty
  2489      */
  2490      */
  2490     public void setBounds(TypeVar t, List<Type> bounds) {
  2491     public void setBounds(TypeVar t, List<Type> bounds) {
  2491         setBounds(t, bounds, bounds.head.tsym.isInterface());
  2492         setBounds(t, bounds, bounds.head.tsym.isInterface());
  2492     }
  2493     }
  2493 
  2494 
  2494     /**
  2495     /**
  2495      * Same as {@link #setBounds(Type.TypeVar,List,Type)}, except that
  2496      * Set the bounds field of the given type variable to reflect a (possibly multiple) list of bounds.
  2496      * third parameter is computed directly, as follows: if all
  2497      * This does not cause symbol completion as an extra parameter indicates as to whether all bounds
  2497      * all bounds are interface types, the computed supertype is Object,
  2498      * are interfaces - in which case the supertype is implicitly assumed to be 'Object'.
  2498      * otherwise the supertype is simply left null (in this case, the supertype
  2499      *
  2499      * is assumed to be the head of the bound list passed as second argument).
  2500      * @param t             a type variable
  2500      * Note that this check might cause a symbol completion. Hence, this version of
  2501      * @param bounds        the bounds, must be nonempty
  2501      * setBounds may not be called during a classfile read.
  2502      * @param allInterfaces are all bounds interface types?
  2502      */
  2503      */
  2503     public void setBounds(TypeVar t, List<Type> bounds, boolean allInterfaces) {
  2504     public void setBounds(TypeVar t, List<Type> bounds, boolean allInterfaces) {
  2504         t.bound = bounds.tail.isEmpty() ?
  2505         t.bound = bounds.tail.isEmpty() ?
  2505                 bounds.head :
  2506                 bounds.head :
  2506                 makeCompoundType(bounds, allInterfaces);
  2507                 makeIntersectionType(bounds, allInterfaces);
  2507         t.rank_field = -1;
  2508         t.rank_field = -1;
  2508     }
  2509     }
  2509     // </editor-fold>
  2510     // </editor-fold>
  2510 
  2511 
  2511     // <editor-fold defaultstate="collapsed" desc="getBounds">
  2512     // <editor-fold defaultstate="collapsed" desc="getBounds">
  3033                 Type st = subst(supertype(t));
  3034                 Type st = subst(supertype(t));
  3034                 List<Type> is = subst(interfaces(t));
  3035                 List<Type> is = subst(interfaces(t));
  3035                 if (st == supertype(t) && is == interfaces(t))
  3036                 if (st == supertype(t) && is == interfaces(t))
  3036                     return t;
  3037                     return t;
  3037                 else
  3038                 else
  3038                     return makeCompoundType(is.prepend(st));
  3039                     return makeIntersectionType(is.prepend(st));
  3039             }
  3040             }
  3040         }
  3041         }
  3041 
  3042 
  3042         @Override
  3043         @Override
  3043         public Type visitWildcardType(WildcardType t, Void ignored) {
  3044         public Type visitWildcardType(WildcardType t, Void ignored) {
  3542         if (compound.isEmpty())
  3543         if (compound.isEmpty())
  3543             return null;
  3544             return null;
  3544         else if (compound.tail.isEmpty())
  3545         else if (compound.tail.isEmpty())
  3545             return compound.head;
  3546             return compound.head;
  3546         else
  3547         else
  3547             return makeCompoundType(compound);
  3548             return makeIntersectionType(compound);
  3548     }
  3549     }
  3549 
  3550 
  3550     /**
  3551     /**
  3551      * Return the minimum types of a closure, suitable for computing
  3552      * Return the minimum types of a closure, suitable for computing
  3552      * compoundMin or glb.
  3553      * compoundMin or glb.
  3720             // initialized lazily to avoid problems during compiler startup
  3721             // initialized lazily to avoid problems during compiler startup
  3721             if (arraySuperType == null) {
  3722             if (arraySuperType == null) {
  3722                 synchronized (this) {
  3723                 synchronized (this) {
  3723                     if (arraySuperType == null) {
  3724                     if (arraySuperType == null) {
  3724                         // JLS 10.8: all arrays implement Cloneable and Serializable.
  3725                         // JLS 10.8: all arrays implement Cloneable and Serializable.
  3725                         arraySuperType = makeCompoundType(List.of(syms.serializableType,
  3726                         arraySuperType = makeIntersectionType(List.of(syms.serializableType,
  3726                                                                   syms.cloneableType), true);
  3727                                 syms.cloneableType), true);
  3727                     }
  3728                     }
  3728                 }
  3729                 }
  3729             }
  3730             }
  3730             return arraySuperType;
  3731             return arraySuperType;
  3731         }
  3732         }
  3787                     return createErrorType(errT);
  3788                     return createErrorType(errT);
  3788                 else
  3789                 else
  3789                     return glbFlattened(union(bounds, lowers), errT);
  3790                     return glbFlattened(union(bounds, lowers), errT);
  3790             }
  3791             }
  3791         }
  3792         }
  3792         return makeCompoundType(bounds);
  3793         return makeIntersectionType(bounds);
  3793     }
  3794     }
  3794     // </editor-fold>
  3795     // </editor-fold>
  3795 
  3796 
  3796     // <editor-fold defaultstate="collapsed" desc="hashCode">
  3797     // <editor-fold defaultstate="collapsed" desc="hashCode">
  3797     /**
  3798     /**