langtools/src/share/classes/com/sun/tools/javac/code/Types.java
changeset 22163 3651128c74eb
parent 21712 d363f367d4c0
child 22167 e0ba35f27975
equal deleted inserted replaced
22162:3b3e23e67329 22163:3651128c74eb
    73  * If you write code that depends on this, you do so at your own risk.
    73  * If you write code that depends on this, you do so at your own risk.
    74  * This code and its internal interfaces are subject to change or
    74  * This code and its internal interfaces are subject to change or
    75  * deletion without notice.</b>
    75  * deletion without notice.</b>
    76  */
    76  */
    77 public class Types {
    77 public class Types {
    78     protected static final Context.Key<Types> typesKey =
    78     protected static final Context.Key<Types> typesKey = new Context.Key<>();
    79         new Context.Key<Types>();
       
    80 
    79 
    81     final Symtab syms;
    80     final Symtab syms;
    82     final JavacMessages messages;
    81     final JavacMessages messages;
    83     final Names names;
    82     final Names names;
    84     final boolean allowBoxing;
    83     final boolean allowBoxing;
   245                 if (t.tsym == sym)
   244                 if (t.tsym == sym)
   246                     return t;
   245                     return t;
   247                 Type base = asSuper(sym.type, t.tsym);
   246                 Type base = asSuper(sym.type, t.tsym);
   248                 if (base == null)
   247                 if (base == null)
   249                     return null;
   248                     return null;
   250                 ListBuffer<Type> from = new ListBuffer<Type>();
   249                 ListBuffer<Type> from = new ListBuffer<>();
   251                 ListBuffer<Type> to = new ListBuffer<Type>();
   250                 ListBuffer<Type> to = new ListBuffer<>();
   252                 try {
   251                 try {
   253                     adapt(base, t, from, to);
   252                     adapt(base, t, from, to);
   254                 } catch (AdaptFailure ex) {
   253                 } catch (AdaptFailure ex) {
   255                     return null;
   254                     return null;
   256                 }
   255                 }
   257                 Type res = subst(sym.type, from.toList(), to.toList());
   256                 Type res = subst(sym.type, from.toList(), to.toList());
   258                 if (!isSubtype(res, t))
   257                 if (!isSubtype(res, t))
   259                     return null;
   258                     return null;
   260                 ListBuffer<Type> openVars = new ListBuffer<Type>();
   259                 ListBuffer<Type> openVars = new ListBuffer<>();
   261                 for (List<Type> l = sym.type.allparams();
   260                 for (List<Type> l = sym.type.allparams();
   262                      l.nonEmpty(); l = l.tail)
   261                      l.nonEmpty(); l = l.tail)
   263                     if (res.contains(l.head) && !t.contains(l.head))
   262                     if (res.contains(l.head) && !t.contains(l.head))
   264                         openVars.append(l.head);
   263                         openVars.append(l.head);
   265                 if (openVars.nonEmpty()) {
   264                 if (openVars.nonEmpty()) {
   267                         // The subtype of a raw type is raw
   266                         // The subtype of a raw type is raw
   268                         res = erasure(res);
   267                         res = erasure(res);
   269                     } else {
   268                     } else {
   270                         // Unbound type arguments default to ?
   269                         // Unbound type arguments default to ?
   271                         List<Type> opens = openVars.toList();
   270                         List<Type> opens = openVars.toList();
   272                         ListBuffer<Type> qs = new ListBuffer<Type>();
   271                         ListBuffer<Type> qs = new ListBuffer<>();
   273                         for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) {
   272                         for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) {
   274                             qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head.unannotatedType()));
   273                             qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head.unannotatedType()));
   275                         }
   274                         }
   276                         res = subst(res, opens, qs.toList());
   275                         res = subst(res, opens, qs.toList());
   277                     }
   276                     }
   345      * A cache that keeps track of function descriptors associated with given
   344      * A cache that keeps track of function descriptors associated with given
   346      * functional interfaces.
   345      * functional interfaces.
   347      */
   346      */
   348     class DescriptorCache {
   347     class DescriptorCache {
   349 
   348 
   350         private WeakHashMap<TypeSymbol, Entry> _map = new WeakHashMap<TypeSymbol, Entry>();
   349         private WeakHashMap<TypeSymbol, Entry> _map = new WeakHashMap<>();
   351 
   350 
   352         class FunctionDescriptor {
   351         class FunctionDescriptor {
   353             Symbol descSym;
   352             Symbol descSym;
   354 
   353 
   355             FunctionDescriptor(Symbol descSym) {
   354             FunctionDescriptor(Symbol descSym) {
   725            return sym.kind == Kinds.MTH &&
   724            return sym.kind == Kinds.MTH &&
   726                    (sym.flags() & (ABSTRACT | DEFAULT)) == ABSTRACT &&
   725                    (sym.flags() & (ABSTRACT | DEFAULT)) == ABSTRACT &&
   727                    !overridesObjectMethod(origin, sym) &&
   726                    !overridesObjectMethod(origin, sym) &&
   728                    (interfaceCandidates(origin.type, (MethodSymbol)sym).head.flags() & DEFAULT) == 0;
   727                    (interfaceCandidates(origin.type, (MethodSymbol)sym).head.flags() & DEFAULT) == 0;
   729        }
   728        }
   730     };
   729     }
   731 
   730 
   732     // <editor-fold defaultstate="collapsed" desc="isSubtype">
   731     // <editor-fold defaultstate="collapsed" desc="isSubtype">
   733     /**
   732     /**
   734      * Is t an unchecked subtype of s?
   733      * Is t an unchecked subtype of s?
   735      */
   734      */
   862                  default:
   861                  default:
   863                      throw new AssertionError("isSubtype " + t.getTag());
   862                      throw new AssertionError("isSubtype " + t.getTag());
   864                  }
   863                  }
   865             }
   864             }
   866 
   865 
   867             private Set<TypePair> cache = new HashSet<TypePair>();
   866             private Set<TypePair> cache = new HashSet<>();
   868 
   867 
   869             private boolean containsTypeRecursive(Type t, Type s) {
   868             private boolean containsTypeRecursive(Type t, Type s) {
   870                 TypePair pair = new TypePair(t, s);
   869                 TypePair pair = new TypePair(t, s);
   871                 if (cache.add(pair)) {
   870                 if (cache.add(pair)) {
   872                     try {
   871                     try {
  1142 
  1141 
  1143                 if (t.isCompound() && s.isCompound()) {
  1142                 if (t.isCompound() && s.isCompound()) {
  1144                     if (!visit(supertype(t), supertype(s)))
  1143                     if (!visit(supertype(t), supertype(s)))
  1145                         return false;
  1144                         return false;
  1146 
  1145 
  1147                     HashSet<UniqueType> set = new HashSet<UniqueType>();
  1146                     HashSet<UniqueType> set = new HashSet<>();
  1148                     for (Type x : interfaces(t))
  1147                     for (Type x : interfaces(t))
  1149                         set.add(new UniqueType(x.unannotatedType(), Types.this));
  1148                         set.add(new UniqueType(x.unannotatedType(), Types.this));
  1150                     for (Type x : interfaces(s)) {
  1149                     for (Type x : interfaces(s)) {
  1151                         if (!set.remove(new UniqueType(x.unannotatedType(), Types.this)))
  1150                         if (!set.remove(new UniqueType(x.unannotatedType(), Types.this)))
  1152                             return false;
  1151                             return false;
  1230             }
  1229             }
  1231             @Override
  1230             @Override
  1232             protected boolean containsTypes(List<Type> ts1, List<Type> ts2) {
  1231             protected boolean containsTypes(List<Type> ts1, List<Type> ts2) {
  1233                 return containsTypeEquivalent(ts1, ts2);
  1232                 return containsTypeEquivalent(ts1, ts2);
  1234             }
  1233             }
  1235         };
  1234         }
  1236 
  1235 
  1237         /**
  1236     /**
  1238          * Strict type-equality relation - type variables are considered
  1237          * Strict type-equality relation - type variables are considered
  1239          * equals if they share the same object identity.
  1238          * equals if they share the same object identity.
  1240          */
  1239          */
  1241         TypeRelation isSameTypeStrict = new SameTypeVisitor() {
  1240         TypeRelation isSameTypeStrict = new SameTypeVisitor() {
  1242             @Override
  1241             @Override
  1705         return disjointType.visit(t, s);
  1704         return disjointType.visit(t, s);
  1706     }
  1705     }
  1707     // where
  1706     // where
  1708         private TypeRelation disjointType = new TypeRelation() {
  1707         private TypeRelation disjointType = new TypeRelation() {
  1709 
  1708 
  1710             private Set<TypePair> cache = new HashSet<TypePair>();
  1709             private Set<TypePair> cache = new HashSet<>();
  1711 
  1710 
  1712             @Override
  1711             @Override
  1713             public Boolean visitType(Type t, Type s) {
  1712             public Boolean visitType(Type t, Type s) {
  1714                 if (s.hasTag(WILDCARD))
  1713                 if (s.hasTag(WILDCARD))
  1715                     return visit(s, t);
  1714                     return visit(s, t);
  2444         return false;
  2443         return false;
  2445     }
  2444     }
  2446     // </editor-fold>
  2445     // </editor-fold>
  2447 
  2446 
  2448     // <editor-fold defaultstate="collapsed" desc="isDerivedRaw">
  2447     // <editor-fold defaultstate="collapsed" desc="isDerivedRaw">
  2449     Map<Type,Boolean> isDerivedRawCache = new HashMap<Type,Boolean>();
  2448     Map<Type,Boolean> isDerivedRawCache = new HashMap<>();
  2450 
  2449 
  2451     public boolean isDerivedRaw(Type t) {
  2450     public boolean isDerivedRaw(Type t) {
  2452         Boolean result = isDerivedRawCache.get(t);
  2451         Boolean result = isDerivedRawCache.get(t);
  2453         if (result == null) {
  2452         if (result == null) {
  2454             result = isDerivedRawInternal(t);
  2453             result = isDerivedRawInternal(t);
  2606     }
  2605     }
  2607 
  2606 
  2608     // <editor-fold defaultstate="collapsed" desc="Determining method implementation in given site">
  2607     // <editor-fold defaultstate="collapsed" desc="Determining method implementation in given site">
  2609     class ImplementationCache {
  2608     class ImplementationCache {
  2610 
  2609 
  2611         private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, Entry>>> _map =
  2610         private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, Entry>>> _map = new WeakHashMap<>();
  2612                 new WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, Entry>>>();
       
  2613 
  2611 
  2614         class Entry {
  2612         class Entry {
  2615             final MethodSymbol cachedImpl;
  2613             final MethodSymbol cachedImpl;
  2616             final Filter<Symbol> implFilter;
  2614             final Filter<Symbol> implFilter;
  2617             final boolean checkResult;
  2615             final boolean checkResult;
  2636 
  2634 
  2637         MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
  2635         MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
  2638             SoftReference<Map<TypeSymbol, Entry>> ref_cache = _map.get(ms);
  2636             SoftReference<Map<TypeSymbol, Entry>> ref_cache = _map.get(ms);
  2639             Map<TypeSymbol, Entry> cache = ref_cache != null ? ref_cache.get() : null;
  2637             Map<TypeSymbol, Entry> cache = ref_cache != null ? ref_cache.get() : null;
  2640             if (cache == null) {
  2638             if (cache == null) {
  2641                 cache = new HashMap<TypeSymbol, Entry>();
  2639                 cache = new HashMap<>();
  2642                 _map.put(ms, new SoftReference<Map<TypeSymbol, Entry>>(cache));
  2640                 _map.put(ms, new SoftReference<>(cache));
  2643             }
  2641             }
  2644             Entry e = cache.get(origin);
  2642             Entry e = cache.get(origin);
  2645             CompoundScope members = membersClosure(origin.type, true);
  2643             CompoundScope members = membersClosure(origin.type, true);
  2646             if (e == null ||
  2644             if (e == null ||
  2647                     !e.matches(implFilter, checkResult, members.getMark())) {
  2645                     !e.matches(implFilter, checkResult, members.getMark())) {
  2679     // </editor-fold>
  2677     // </editor-fold>
  2680 
  2678 
  2681     // <editor-fold defaultstate="collapsed" desc="compute transitive closure of all members in given site">
  2679     // <editor-fold defaultstate="collapsed" desc="compute transitive closure of all members in given site">
  2682     class MembersClosureCache extends SimpleVisitor<CompoundScope, Boolean> {
  2680     class MembersClosureCache extends SimpleVisitor<CompoundScope, Boolean> {
  2683 
  2681 
  2684         private WeakHashMap<TypeSymbol, Entry> _map =
  2682         private WeakHashMap<TypeSymbol, Entry> _map = new WeakHashMap<>();
  2685                 new WeakHashMap<TypeSymbol, Entry>();
       
  2686 
  2683 
  2687         class Entry {
  2684         class Entry {
  2688             final boolean skipInterfaces;
  2685             final boolean skipInterfaces;
  2689             final CompoundScope compoundScope;
  2686             final CompoundScope compoundScope;
  2690 
  2687 
  2798                             s.name == msym.name &&
  2795                             s.name == msym.name &&
  2799                             (s.flags() & SYNTHETIC) == 0 &&
  2796                             (s.flags() & SYNTHETIC) == 0 &&
  2800                             s.isInheritedIn(site.tsym, Types.this) &&
  2797                             s.isInheritedIn(site.tsym, Types.this) &&
  2801                             overrideEquivalent(memberType(site, s), memberType(site, msym));
  2798                             overrideEquivalent(memberType(site, s), memberType(site, msym));
  2802                 }
  2799                 }
  2803             };
  2800             }
  2804     // </editor-fold>
  2801     // </editor-fold>
  2805 
  2802 
  2806     /**
  2803     /**
  2807      * Does t have the same arguments as s?  It is assumed that both
  2804      * Does t have the same arguments as s?  It is assumed that both
  2808      * types are (possibly polymorphic) method types.  Monomorphic
  2805      * types are (possibly polymorphic) method types.  Monomorphic
  2854 
  2851 
  2855             @Override
  2852             @Override
  2856             public Boolean visitErrorType(ErrorType t, Type s) {
  2853             public Boolean visitErrorType(ErrorType t, Type s) {
  2857                 return false;
  2854                 return false;
  2858             }
  2855             }
  2859         };
  2856         }
  2860 
  2857 
  2861         TypeRelation hasSameArgs_strict = new HasSameArgs(true);
  2858     TypeRelation hasSameArgs_strict = new HasSameArgs(true);
  2862         TypeRelation hasSameArgs_nonstrict = new HasSameArgs(false);
  2859         TypeRelation hasSameArgs_nonstrict = new HasSameArgs(false);
  2863 
  2860 
  2864     // </editor-fold>
  2861     // </editor-fold>
  2865 
  2862 
  2866     // <editor-fold defaultstate="collapsed" desc="subst">
  2863     // <editor-fold defaultstate="collapsed" desc="subst">
  3299      * <p>A closure is a list of all the supertypes and interfaces of
  3296      * <p>A closure is a list of all the supertypes and interfaces of
  3300      * a class or interface type, ordered by ClassSymbol.precedes
  3297      * a class or interface type, ordered by ClassSymbol.precedes
  3301      * (that is, subclasses come first, arbitrary but fixed
  3298      * (that is, subclasses come first, arbitrary but fixed
  3302      * otherwise).
  3299      * otherwise).
  3303      */
  3300      */
  3304     private Map<Type,List<Type>> closureCache = new HashMap<Type,List<Type>>();
  3301     private Map<Type,List<Type>> closureCache = new HashMap<>();
  3305 
  3302 
  3306     /**
  3303     /**
  3307      * Returns the closure of a class or interface type.
  3304      * Returns the closure of a class or interface type.
  3308      */
  3305      */
  3309     public List<Type> closure(Type t) {
  3306     public List<Type> closure(Type t) {
  3402                 TypePair typePair = (TypePair)obj;
  3399                 TypePair typePair = (TypePair)obj;
  3403                 return isSameType(t1, typePair.t1)
  3400                 return isSameType(t1, typePair.t1)
  3404                     && isSameType(t2, typePair.t2);
  3401                     && isSameType(t2, typePair.t2);
  3405             }
  3402             }
  3406         }
  3403         }
  3407         Set<TypePair> mergeCache = new HashSet<TypePair>();
  3404         Set<TypePair> mergeCache = new HashSet<>();
  3408         private Type merge(Type c1, Type c2) {
  3405         private Type merge(Type c1, Type c2) {
  3409             ClassType class1 = (ClassType) c1;
  3406             ClassType class1 = (ClassType) c1;
  3410             List<Type> act1 = class1.getTypeArguments();
  3407             List<Type> act1 = class1.getTypeArguments();
  3411             ClassType class2 = (ClassType) c2;
  3408             ClassType class2 = (ClassType) c2;
  3412             List<Type> act2 = class2.getTypeArguments();
  3409             List<Type> act2 = class2.getTypeArguments();
  3413             ListBuffer<Type> merged = new ListBuffer<Type>();
  3410             ListBuffer<Type> merged = new ListBuffer<>();
  3414             List<Type> typarams = class1.tsym.type.getTypeArguments();
  3411             List<Type> typarams = class1.tsym.type.getTypeArguments();
  3415 
  3412 
  3416             while (act1.nonEmpty() && act2.nonEmpty() && typarams.nonEmpty()) {
  3413             while (act1.nonEmpty() && act2.nonEmpty() && typarams.nonEmpty()) {
  3417                 if (containsType(act1.head, act2.head)) {
  3414                 if (containsType(act1.head, act2.head)) {
  3418                     merged.append(act1.head);
  3415                     merged.append(act1.head);
  4088         Map<Symbol,Type> mapping;
  4085         Map<Symbol,Type> mapping;
  4089 
  4086 
  4090         Adapter(ListBuffer<Type> from, ListBuffer<Type> to) {
  4087         Adapter(ListBuffer<Type> from, ListBuffer<Type> to) {
  4091             this.from = from;
  4088             this.from = from;
  4092             this.to = to;
  4089             this.to = to;
  4093             mapping = new HashMap<Symbol,Type>();
  4090             mapping = new HashMap<>();
  4094         }
  4091         }
  4095 
  4092 
  4096         public void adapt(Type source, Type target) throws AdaptFailure {
  4093         public void adapt(Type source, Type target) throws AdaptFailure {
  4097             visit(source, target);
  4094             visit(source, target);
  4098             List<Type> fromList = from.toList();
  4095             List<Type> fromList = from.toList();
  4157         @Override
  4154         @Override
  4158         public Void visitType(Type source, Type target) {
  4155         public Void visitType(Type source, Type target) {
  4159             return null;
  4156             return null;
  4160         }
  4157         }
  4161 
  4158 
  4162         private Set<TypePair> cache = new HashSet<TypePair>();
  4159         private Set<TypePair> cache = new HashSet<>();
  4163 
  4160 
  4164         private void adaptRecursive(Type source, Type target) {
  4161         private void adaptRecursive(Type source, Type target) {
  4165             TypePair pair = new TypePair(source, target);
  4162             TypePair pair = new TypePair(source, target);
  4166             if (cache.add(pair)) {
  4163             if (cache.add(pair)) {
  4167                 try {
  4164                 try {
  4231             this.rewriteTypeVars = rewriteTypeVars;
  4228             this.rewriteTypeVars = rewriteTypeVars;
  4232         }
  4229         }
  4233 
  4230 
  4234         @Override
  4231         @Override
  4235         public Type visitClassType(ClassType t, Void s) {
  4232         public Type visitClassType(ClassType t, Void s) {
  4236             ListBuffer<Type> rewritten = new ListBuffer<Type>();
  4233             ListBuffer<Type> rewritten = new ListBuffer<>();
  4237             boolean changed = false;
  4234             boolean changed = false;
  4238             for (Type arg : t.allparams()) {
  4235             for (Type arg : t.allparams()) {
  4239                 Type bound = visit(arg);
  4236                 Type bound = visit(arg);
  4240                 if (arg != bound) {
  4237                 if (arg != bound) {
  4241                     changed = true;
  4238                     changed = true;