149 return visit(t.bound); |
149 return visit(t.bound); |
150 } |
150 } |
151 }; |
151 }; |
152 // </editor-fold> |
152 // </editor-fold> |
153 |
153 |
154 // <editor-fold defaultstate="collapsed" desc="lowerBound"> |
154 // <editor-fold defaultstate="collapsed" desc="wildLowerBound"> |
155 /** |
155 /** |
156 * The "lvalue conversion".<br> |
156 * Get a wildcard's lower bound, returning non-wildcards unchanged. |
157 * The lower bound of most types is the type |
157 * @param t a type argument, either a wildcard or a type |
158 * itself. Wildcards, on the other hand have upper |
158 */ |
159 * and lower bounds. |
159 public Type wildLowerBound(Type t) { |
|
160 if (t.hasTag(WILDCARD)) { |
|
161 WildcardType w = (WildcardType) t; |
|
162 return w.isExtendsBound() ? syms.botType : wildLowerBound(w.type); |
|
163 } |
|
164 else return t; |
|
165 } |
|
166 // </editor-fold> |
|
167 |
|
168 // <editor-fold defaultstate="collapsed" desc="cvarLowerBound"> |
|
169 /** |
|
170 * Get a capture variable's lower bound, returning other types unchanged. |
160 * @param t a type |
171 * @param t a type |
161 * @return the lower bound of the given type |
172 */ |
162 */ |
173 public Type cvarLowerBound(Type t) { |
163 public Type lowerBound(Type t) { |
174 if (t.hasTag(TYPEVAR) && ((TypeVar) t).isCaptured()) { |
164 return lowerBound.visit(t); |
175 return cvarLowerBound(t.getLowerBound()); |
165 } |
176 } |
166 // where |
177 else return t; |
167 private final MapVisitor<Void> lowerBound = new MapVisitor<Void>() { |
178 } |
168 |
|
169 @Override |
|
170 public Type visitWildcardType(WildcardType t, Void ignored) { |
|
171 return t.isExtendsBound() ? syms.botType : visit(t.type); |
|
172 } |
|
173 |
|
174 @Override |
|
175 public Type visitCapturedType(CapturedType t, Void ignored) { |
|
176 return visit(t.getLowerBound()); |
|
177 } |
|
178 }; |
|
179 // </editor-fold> |
179 // </editor-fold> |
180 |
180 |
181 // <editor-fold defaultstate="collapsed" desc="isUnbounded"> |
181 // <editor-fold defaultstate="collapsed" desc="isUnbounded"> |
182 /** |
182 /** |
183 * Checks that all the arguments to a class are unbounded |
183 * Checks that all the arguments to a class are unbounded |
825 return false; |
825 return false; |
826 } |
826 } |
827 return true; |
827 return true; |
828 } |
828 } |
829 |
829 |
830 Type lower = lowerBound(s); |
830 // Generally, if 's' is a type variable, recur on lower bound; but |
831 if (s != lower) |
831 // for alpha <: CAP, alpha should get upper bound CAP |
832 return isSubtype(capture ? capture(t) : t, lower, false); |
832 if (!t.hasTag(UNDETVAR)) { |
|
833 // TODO: JDK-8039198, bounds checking sometimes passes in a wildcard as s |
|
834 Type lower = cvarLowerBound(wildLowerBound(s)); |
|
835 if (s != lower) |
|
836 return isSubtype(capture ? capture(t) : t, lower, false); |
|
837 } |
833 |
838 |
834 return isSubtype.visit(capture ? capture(t) : t, s); |
839 return isSubtype.visit(capture ? capture(t) : t, s); |
835 } |
840 } |
836 // where |
841 // where |
837 private TypeRelation isSubtype = new TypeRelation() |
842 private TypeRelation isSubtype = new TypeRelation() |
1134 |
1139 |
1135 if (s.isPartial()) |
1140 if (s.isPartial()) |
1136 return visit(s, t); |
1141 return visit(s, t); |
1137 |
1142 |
1138 if (s.isSuperBound() && !s.isExtendsBound()) |
1143 if (s.isSuperBound() && !s.isExtendsBound()) |
1139 return visit(t, upperBound(s)) && visit(t, lowerBound(s)); |
1144 return visit(t, upperBound(s)) && visit(t, wildLowerBound(s)); |
1140 |
1145 |
1141 if (t.isCompound() && s.isCompound()) { |
1146 if (t.isCompound() && s.isCompound()) { |
1142 if (!visit(supertype(t), supertype(s))) |
1147 if (!visit(supertype(t), supertype(s))) |
1143 return false; |
1148 return false; |
1144 |
1149 |
1289 Type bound = upperBound(s); |
1294 Type bound = upperBound(s); |
1290 undetvar.addBound(InferenceBound.UPPER, bound, this); |
1295 undetvar.addBound(InferenceBound.UPPER, bound, this); |
1291 break; |
1296 break; |
1292 } |
1297 } |
1293 case SUPER: { |
1298 case SUPER: { |
1294 Type bound = lowerBound(s); |
1299 Type bound = wildLowerBound(s); |
1295 undetvar.addBound(InferenceBound.LOWER, bound, this); |
1300 undetvar.addBound(InferenceBound.LOWER, bound, this); |
1296 break; |
1301 break; |
1297 } |
1302 } |
1298 } |
1303 } |
1299 return true; |
1304 return true; |
1382 // System.err.format(" %s U(%s) <: U(%s) %s = %s%n", |
1387 // System.err.format(" %s U(%s) <: U(%s) %s = %s%n", |
1383 // upperBound(s), s, t, U(t), |
1388 // upperBound(s), s, t, U(t), |
1384 // t.isSuperBound() |
1389 // t.isSuperBound() |
1385 // || isSubtypeNoCapture(upperBound(s), U(t))); |
1390 // || isSubtypeNoCapture(upperBound(s), U(t))); |
1386 // System.err.format(" %s L(%s) <: L(%s) %s = %s%n", |
1391 // System.err.format(" %s L(%s) <: L(%s) %s = %s%n", |
1387 // L(t), t, s, lowerBound(s), |
1392 // L(t), t, s, wildLowerBound(s), |
1388 // t.isExtendsBound() |
1393 // t.isExtendsBound() |
1389 // || isSubtypeNoCapture(L(t), lowerBound(s))); |
1394 // || isSubtypeNoCapture(L(t), wildLowerBound(s))); |
1390 // System.err.println(); |
1395 // System.err.println(); |
1391 // } |
1396 // } |
1392 |
1397 |
1393 @Override |
1398 @Override |
1394 public Boolean visitWildcardType(WildcardType t, Type s) { |
1399 public Boolean visitWildcardType(WildcardType t, Type s) { |
1396 return containedBy(s, t); |
1401 return containedBy(s, t); |
1397 else { |
1402 else { |
1398 // debugContainsType(t, s); |
1403 // debugContainsType(t, s); |
1399 return isSameWildcard(t, s) |
1404 return isSameWildcard(t, s) |
1400 || isCaptureOf(s, t) |
1405 || isCaptureOf(s, t) |
1401 || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), lowerBound(s))) && |
1406 || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), wildLowerBound(s))) && |
1402 (t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t)))); |
1407 (t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t)))); |
1403 } |
1408 } |
1404 } |
1409 } |
1405 |
1410 |
1406 @Override |
1411 @Override |
1758 |
1763 |
1759 if (t.isExtendsBound()) { |
1764 if (t.isExtendsBound()) { |
1760 if (s.isExtendsBound()) |
1765 if (s.isExtendsBound()) |
1761 return !isCastableRecursive(t.type, upperBound(s)); |
1766 return !isCastableRecursive(t.type, upperBound(s)); |
1762 else if (s.isSuperBound()) |
1767 else if (s.isSuperBound()) |
1763 return notSoftSubtypeRecursive(lowerBound(s), t.type); |
1768 return notSoftSubtypeRecursive(wildLowerBound(s), t.type); |
1764 } else if (t.isSuperBound()) { |
1769 } else if (t.isSuperBound()) { |
1765 if (s.isExtendsBound()) |
1770 if (s.isExtendsBound()) |
1766 return notSoftSubtypeRecursive(t.type, upperBound(s)); |
1771 return notSoftSubtypeRecursive(t.type, upperBound(s)); |
1767 } |
1772 } |
1768 return false; |
1773 return false; |
1769 } |
1774 } |
1770 }; |
1775 }; |
1771 // </editor-fold> |
1776 // </editor-fold> |
1772 |
1777 |
1773 // <editor-fold defaultstate="collapsed" desc="lowerBoundArgtypes"> |
1778 // <editor-fold defaultstate="collapsed" desc="cvarLowerBounds"> |
1774 /** |
1779 public List<Type> cvarLowerBounds(List<Type> ts) { |
1775 * Returns the lower bounds of the formals of a method. |
1780 return map(ts, cvarLowerBoundMapping); |
1776 */ |
1781 } |
1777 public List<Type> lowerBoundArgtypes(Type t) { |
1782 private final Mapping cvarLowerBoundMapping = new Mapping("cvarLowerBound") { |
1778 return lowerBounds(t.getParameterTypes()); |
|
1779 } |
|
1780 public List<Type> lowerBounds(List<Type> ts) { |
|
1781 return map(ts, lowerBoundMapping); |
|
1782 } |
|
1783 private final Mapping lowerBoundMapping = new Mapping("lowerBound") { |
|
1784 public Type apply(Type t) { |
1783 public Type apply(Type t) { |
1785 return lowerBound(t); |
1784 return cvarLowerBound(t); |
1786 } |
1785 } |
1787 }; |
1786 }; |
1788 // </editor-fold> |
1787 // </editor-fold> |
1789 |
1788 |
1790 // <editor-fold defaultstate="collapsed" desc="notSoftSubtype"> |
1789 // <editor-fold defaultstate="collapsed" desc="notSoftSubtype"> |
2249 } |
2248 } |
2250 // </editor-fold> |
2249 // </editor-fold> |
2251 |
2250 |
2252 // <editor-fold defaultstate="collapsed" desc="makeCompoundType"> |
2251 // <editor-fold defaultstate="collapsed" desc="makeCompoundType"> |
2253 /** |
2252 /** |
2254 * Make a compound type from non-empty list of types |
2253 * Make a compound type from non-empty list of types. The list should be |
|
2254 * ordered according to {@link Symbol#precedes(TypeSymbol,Types)}. |
2255 * |
2255 * |
2256 * @param bounds the types from which the compound type is formed |
2256 * @param bounds the types from which the compound type is formed |
2257 * @param supertype is objectType if all bounds are interfaces, |
2257 * @param supertype is objectType if all bounds are interfaces, |
2258 * null otherwise. |
2258 * null otherwise. |
2259 */ |
2259 */ |
3338 |
3338 |
3339 /** |
3339 /** |
3340 * Insert a type in a closure |
3340 * Insert a type in a closure |
3341 */ |
3341 */ |
3342 public List<Type> insert(List<Type> cl, Type t) { |
3342 public List<Type> insert(List<Type> cl, Type t) { |
3343 if (cl.isEmpty() || t.tsym.precedes(cl.head.tsym, this)) { |
3343 if (cl.isEmpty()) { |
3344 return cl.prepend(t); |
3344 return cl.prepend(t); |
3345 } else if (cl.head.tsym.precedes(t.tsym, this)) { |
3345 } else if (t.tsym == cl.head.tsym) { |
|
3346 return cl; |
|
3347 } else if (t.tsym.precedes(cl.head.tsym, this)) { |
|
3348 return cl.prepend(t); |
|
3349 } else { |
|
3350 // t comes after head, or the two are unrelated |
3346 return insert(cl.tail, t).prepend(cl.head); |
3351 return insert(cl.tail, t).prepend(cl.head); |
3347 } else { |
|
3348 return cl; |
|
3349 } |
3352 } |
3350 } |
3353 } |
3351 |
3354 |
3352 /** |
3355 /** |
3353 * Form the union of two closures |
3356 * Form the union of two closures |
3355 public List<Type> union(List<Type> cl1, List<Type> cl2) { |
3358 public List<Type> union(List<Type> cl1, List<Type> cl2) { |
3356 if (cl1.isEmpty()) { |
3359 if (cl1.isEmpty()) { |
3357 return cl2; |
3360 return cl2; |
3358 } else if (cl2.isEmpty()) { |
3361 } else if (cl2.isEmpty()) { |
3359 return cl1; |
3362 return cl1; |
|
3363 } else if (cl1.head.tsym == cl2.head.tsym) { |
|
3364 return union(cl1.tail, cl2.tail).prepend(cl1.head); |
3360 } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) { |
3365 } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) { |
3361 return union(cl1.tail, cl2).prepend(cl1.head); |
3366 return union(cl1.tail, cl2).prepend(cl1.head); |
3362 } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) { |
3367 } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) { |
3363 return union(cl1, cl2.tail).prepend(cl2.head); |
3368 return union(cl1, cl2.tail).prepend(cl2.head); |
3364 } else { |
3369 } else { |
3365 return union(cl1.tail, cl2.tail).prepend(cl1.head); |
3370 // unrelated types |
|
3371 return union(cl1.tail, cl2).prepend(cl1.head); |
3366 } |
3372 } |
3367 } |
3373 } |
3368 |
3374 |
3369 /** |
3375 /** |
3370 * Intersect two closures |
3376 * Intersect two closures |
3470 * compoundMin or glb. |
3476 * compoundMin or glb. |
3471 */ |
3477 */ |
3472 private List<Type> closureMin(List<Type> cl) { |
3478 private List<Type> closureMin(List<Type> cl) { |
3473 ListBuffer<Type> classes = new ListBuffer<>(); |
3479 ListBuffer<Type> classes = new ListBuffer<>(); |
3474 ListBuffer<Type> interfaces = new ListBuffer<>(); |
3480 ListBuffer<Type> interfaces = new ListBuffer<>(); |
|
3481 Set<Type> toSkip = new HashSet<>(); |
3475 while (!cl.isEmpty()) { |
3482 while (!cl.isEmpty()) { |
3476 Type current = cl.head; |
3483 Type current = cl.head; |
3477 if (current.isInterface()) |
3484 boolean keep = !toSkip.contains(current); |
3478 interfaces.append(current); |
3485 if (keep && current.hasTag(TYPEVAR)) { |
3479 else |
3486 // skip lower-bounded variables with a subtype in cl.tail |
3480 classes.append(current); |
3487 for (Type t : cl.tail) { |
3481 ListBuffer<Type> candidates = new ListBuffer<>(); |
3488 if (isSubtypeNoCapture(t, current)) { |
3482 for (Type t : cl.tail) { |
3489 keep = false; |
3483 if (!isSubtypeNoCapture(current, t)) |
3490 break; |
3484 candidates.append(t); |
3491 } |
3485 } |
3492 } |
3486 cl = candidates.toList(); |
3493 } |
|
3494 if (keep) { |
|
3495 if (current.isInterface()) |
|
3496 interfaces.append(current); |
|
3497 else |
|
3498 classes.append(current); |
|
3499 for (Type t : cl.tail) { |
|
3500 // skip supertypes of 'current' in cl.tail |
|
3501 if (isSubtypeNoCapture(current, t)) |
|
3502 toSkip.add(t); |
|
3503 } |
|
3504 } |
|
3505 cl = cl.tail; |
3487 } |
3506 } |
3488 return classes.appendList(interfaces).toList(); |
3507 return classes.appendList(interfaces).toList(); |
3489 } |
3508 } |
3490 |
3509 |
3491 /** |
3510 /** |
3641 return t; |
3660 return t; |
3642 else if (isSubtypeNoCapture(s, t)) |
3661 else if (isSubtypeNoCapture(s, t)) |
3643 return s; |
3662 return s; |
3644 |
3663 |
3645 List<Type> closure = union(closure(t), closure(s)); |
3664 List<Type> closure = union(closure(t), closure(s)); |
3646 List<Type> bounds = closureMin(closure); |
3665 return glbFlattened(closure, t); |
|
3666 } |
|
3667 //where |
|
3668 /** |
|
3669 * Perform glb for a list of non-primitive, non-error, non-compound types; |
|
3670 * redundant elements are removed. Bounds should be ordered according to |
|
3671 * {@link Symbol#precedes(TypeSymbol,Types)}. |
|
3672 * |
|
3673 * @param flatBounds List of type to glb |
|
3674 * @param errT Original type to use if the result is an error type |
|
3675 */ |
|
3676 private Type glbFlattened(List<Type> flatBounds, Type errT) { |
|
3677 List<Type> bounds = closureMin(flatBounds); |
3647 |
3678 |
3648 if (bounds.isEmpty()) { // length == 0 |
3679 if (bounds.isEmpty()) { // length == 0 |
3649 return syms.objectType; |
3680 return syms.objectType; |
3650 } else if (bounds.tail.isEmpty()) { // length == 1 |
3681 } else if (bounds.tail.isEmpty()) { // length == 1 |
3651 return bounds.head; |
3682 return bounds.head; |
3652 } else { // length > 1 |
3683 } else { // length > 1 |
3653 int classCount = 0; |
3684 int classCount = 0; |
3654 for (Type bound : bounds) |
3685 List<Type> lowers = List.nil(); |
3655 if (!bound.isInterface()) |
3686 for (Type bound : bounds) { |
|
3687 if (!bound.isInterface()) { |
3656 classCount++; |
3688 classCount++; |
3657 if (classCount > 1) |
3689 Type lower = cvarLowerBound(bound); |
3658 return createErrorType(t); |
3690 if (bound != lower && !lower.hasTag(BOT)) |
|
3691 lowers = insert(lowers, lower); |
|
3692 } |
|
3693 } |
|
3694 if (classCount > 1) { |
|
3695 if (lowers.isEmpty()) |
|
3696 return createErrorType(errT); |
|
3697 else |
|
3698 return glbFlattened(union(bounds, lowers), errT); |
|
3699 } |
3659 } |
3700 } |
3660 return makeCompoundType(bounds); |
3701 return makeCompoundType(bounds); |
3661 } |
3702 } |
3662 // </editor-fold> |
3703 // </editor-fold> |
3663 |
3704 |
4138 @Override |
4179 @Override |
4139 public Void visitWildcardType(WildcardType source, Type target) throws AdaptFailure { |
4180 public Void visitWildcardType(WildcardType source, Type target) throws AdaptFailure { |
4140 if (source.isExtendsBound()) |
4181 if (source.isExtendsBound()) |
4141 adaptRecursive(upperBound(source), upperBound(target)); |
4182 adaptRecursive(upperBound(source), upperBound(target)); |
4142 else if (source.isSuperBound()) |
4183 else if (source.isSuperBound()) |
4143 adaptRecursive(lowerBound(source), lowerBound(target)); |
4184 adaptRecursive(wildLowerBound(source), wildLowerBound(target)); |
4144 return null; |
4185 return null; |
4145 } |
4186 } |
4146 |
4187 |
4147 @Override |
4188 @Override |
4148 public Void visitTypeVar(TypeVar source, Type target) throws AdaptFailure { |
4189 public Void visitTypeVar(TypeVar source, Type target) throws AdaptFailure { |
4150 // already a mapping for $source$, in which case |
4191 // already a mapping for $source$, in which case |
4151 // the old mapping will be merged with the new |
4192 // the old mapping will be merged with the new |
4152 Type val = mapping.get(source.tsym); |
4193 Type val = mapping.get(source.tsym); |
4153 if (val != null) { |
4194 if (val != null) { |
4154 if (val.isSuperBound() && target.isSuperBound()) { |
4195 if (val.isSuperBound() && target.isSuperBound()) { |
4155 val = isSubtype(lowerBound(val), lowerBound(target)) |
4196 val = isSubtype(wildLowerBound(val), wildLowerBound(target)) |
4156 ? target : val; |
4197 ? target : val; |
4157 } else if (val.isExtendsBound() && target.isExtendsBound()) { |
4198 } else if (val.isExtendsBound() && target.isExtendsBound()) { |
4158 val = isSubtype(upperBound(val), upperBound(target)) |
4199 val = isSubtype(upperBound(val), upperBound(target)) |
4159 ? val : target; |
4200 ? val : target; |
4160 } else if (!isSameType(val, target)) { |
4201 } else if (!isSameType(val, target)) { |