Tue, 25 Sep 2012 11:56:46 +0100
7177306: Regression: unchecked method call does not erase return type
Summary: Spurious extra call to Attr.checkMethod when method call is unchecked
Reviewed-by: jjg, dlsmith
1 /*
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.tools.javac.code;
28 import java.lang.ref.SoftReference;
29 import java.util.*;
31 import com.sun.tools.javac.util.*;
32 import com.sun.tools.javac.util.List;
34 import com.sun.tools.javac.jvm.ClassReader;
35 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
36 import com.sun.tools.javac.code.Lint.LintCategory;
37 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
38 import com.sun.tools.javac.comp.Check;
40 import static com.sun.tools.javac.code.Scope.*;
41 import static com.sun.tools.javac.code.Type.*;
42 import static com.sun.tools.javac.code.TypeTags.*;
43 import static com.sun.tools.javac.code.Symbol.*;
44 import static com.sun.tools.javac.code.Flags.*;
45 import static com.sun.tools.javac.code.BoundKind.*;
46 import static com.sun.tools.javac.util.ListBuffer.lb;
48 /**
49 * Utility class containing various operations on types.
50 *
51 * <p>Unless other names are more illustrative, the following naming
52 * conventions should be observed in this file:
53 *
54 * <dl>
55 * <dt>t</dt>
56 * <dd>If the first argument to an operation is a type, it should be named t.</dd>
57 * <dt>s</dt>
58 * <dd>Similarly, if the second argument to an operation is a type, it should be named s.</dd>
59 * <dt>ts</dt>
60 * <dd>If an operations takes a list of types, the first should be named ts.</dd>
61 * <dt>ss</dt>
62 * <dd>A second list of types should be named ss.</dd>
63 * </dl>
64 *
65 * <p><b>This is NOT part of any supported API.
66 * If you write code that depends on this, you do so at your own risk.
67 * This code and its internal interfaces are subject to change or
68 * deletion without notice.</b>
69 */
70 public class Types {
71 protected static final Context.Key<Types> typesKey =
72 new Context.Key<Types>();
74 final Symtab syms;
75 final JavacMessages messages;
76 final Names names;
77 final boolean allowBoxing;
78 final boolean allowCovariantReturns;
79 final boolean allowObjectToPrimitiveCast;
80 final ClassReader reader;
81 final Check chk;
82 List<Warner> warnStack = List.nil();
83 final Name capturedName;
85 // <editor-fold defaultstate="collapsed" desc="Instantiating">
86 public static Types instance(Context context) {
87 Types instance = context.get(typesKey);
88 if (instance == null)
89 instance = new Types(context);
90 return instance;
91 }
93 protected Types(Context context) {
94 context.put(typesKey, this);
95 syms = Symtab.instance(context);
96 names = Names.instance(context);
97 Source source = Source.instance(context);
98 allowBoxing = source.allowBoxing();
99 allowCovariantReturns = source.allowCovariantReturns();
100 allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast();
101 reader = ClassReader.instance(context);
102 chk = Check.instance(context);
103 capturedName = names.fromString("<captured wildcard>");
104 messages = JavacMessages.instance(context);
105 }
106 // </editor-fold>
108 // <editor-fold defaultstate="collapsed" desc="upperBound">
109 /**
110 * The "rvalue conversion".<br>
111 * The upper bound of most types is the type
112 * itself. Wildcards, on the other hand have upper
113 * and lower bounds.
114 * @param t a type
115 * @return the upper bound of the given type
116 */
117 public Type upperBound(Type t) {
118 return upperBound.visit(t);
119 }
120 // where
121 private final MapVisitor<Void> upperBound = new MapVisitor<Void>() {
123 @Override
124 public Type visitWildcardType(WildcardType t, Void ignored) {
125 if (t.isSuperBound())
126 return t.bound == null ? syms.objectType : t.bound.bound;
127 else
128 return visit(t.type);
129 }
131 @Override
132 public Type visitCapturedType(CapturedType t, Void ignored) {
133 return visit(t.bound);
134 }
135 };
136 // </editor-fold>
138 // <editor-fold defaultstate="collapsed" desc="lowerBound">
139 /**
140 * The "lvalue conversion".<br>
141 * The lower bound of most types is the type
142 * itself. Wildcards, on the other hand have upper
143 * and lower bounds.
144 * @param t a type
145 * @return the lower bound of the given type
146 */
147 public Type lowerBound(Type t) {
148 return lowerBound.visit(t);
149 }
150 // where
151 private final MapVisitor<Void> lowerBound = new MapVisitor<Void>() {
153 @Override
154 public Type visitWildcardType(WildcardType t, Void ignored) {
155 return t.isExtendsBound() ? syms.botType : visit(t.type);
156 }
158 @Override
159 public Type visitCapturedType(CapturedType t, Void ignored) {
160 return visit(t.getLowerBound());
161 }
162 };
163 // </editor-fold>
165 // <editor-fold defaultstate="collapsed" desc="isUnbounded">
166 /**
167 * Checks that all the arguments to a class are unbounded
168 * wildcards or something else that doesn't make any restrictions
169 * on the arguments. If a class isUnbounded, a raw super- or
170 * subclass can be cast to it without a warning.
171 * @param t a type
172 * @return true iff the given type is unbounded or raw
173 */
174 public boolean isUnbounded(Type t) {
175 return isUnbounded.visit(t);
176 }
177 // where
178 private final UnaryVisitor<Boolean> isUnbounded = new UnaryVisitor<Boolean>() {
180 public Boolean visitType(Type t, Void ignored) {
181 return true;
182 }
184 @Override
185 public Boolean visitClassType(ClassType t, Void ignored) {
186 List<Type> parms = t.tsym.type.allparams();
187 List<Type> args = t.allparams();
188 while (parms.nonEmpty()) {
189 WildcardType unb = new WildcardType(syms.objectType,
190 BoundKind.UNBOUND,
191 syms.boundClass,
192 (TypeVar)parms.head);
193 if (!containsType(args.head, unb))
194 return false;
195 parms = parms.tail;
196 args = args.tail;
197 }
198 return true;
199 }
200 };
201 // </editor-fold>
203 // <editor-fold defaultstate="collapsed" desc="asSub">
204 /**
205 * Return the least specific subtype of t that starts with symbol
206 * sym. If none exists, return null. The least specific subtype
207 * is determined as follows:
208 *
209 * <p>If there is exactly one parameterized instance of sym that is a
210 * subtype of t, that parameterized instance is returned.<br>
211 * Otherwise, if the plain type or raw type `sym' is a subtype of
212 * type t, the type `sym' itself is returned. Otherwise, null is
213 * returned.
214 */
215 public Type asSub(Type t, Symbol sym) {
216 return asSub.visit(t, sym);
217 }
218 // where
219 private final SimpleVisitor<Type,Symbol> asSub = new SimpleVisitor<Type,Symbol>() {
221 public Type visitType(Type t, Symbol sym) {
222 return null;
223 }
225 @Override
226 public Type visitClassType(ClassType t, Symbol sym) {
227 if (t.tsym == sym)
228 return t;
229 Type base = asSuper(sym.type, t.tsym);
230 if (base == null)
231 return null;
232 ListBuffer<Type> from = new ListBuffer<Type>();
233 ListBuffer<Type> to = new ListBuffer<Type>();
234 try {
235 adapt(base, t, from, to);
236 } catch (AdaptFailure ex) {
237 return null;
238 }
239 Type res = subst(sym.type, from.toList(), to.toList());
240 if (!isSubtype(res, t))
241 return null;
242 ListBuffer<Type> openVars = new ListBuffer<Type>();
243 for (List<Type> l = sym.type.allparams();
244 l.nonEmpty(); l = l.tail)
245 if (res.contains(l.head) && !t.contains(l.head))
246 openVars.append(l.head);
247 if (openVars.nonEmpty()) {
248 if (t.isRaw()) {
249 // The subtype of a raw type is raw
250 res = erasure(res);
251 } else {
252 // Unbound type arguments default to ?
253 List<Type> opens = openVars.toList();
254 ListBuffer<Type> qs = new ListBuffer<Type>();
255 for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) {
256 qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head));
257 }
258 res = subst(res, opens, qs.toList());
259 }
260 }
261 return res;
262 }
264 @Override
265 public Type visitErrorType(ErrorType t, Symbol sym) {
266 return t;
267 }
268 };
269 // </editor-fold>
271 // <editor-fold defaultstate="collapsed" desc="isConvertible">
272 /**
273 * Is t a subtype of or convertible via boxing/unboxing
274 * conversion to s?
275 */
276 public boolean isConvertible(Type t, Type s, Warner warn) {
277 if (t.tag == ERROR)
278 return true;
279 boolean tPrimitive = t.isPrimitive();
280 boolean sPrimitive = s.isPrimitive();
281 if (tPrimitive == sPrimitive) {
282 return isSubtypeUnchecked(t, s, warn);
283 }
284 if (!allowBoxing) return false;
285 return tPrimitive
286 ? isSubtype(boxedClass(t).type, s)
287 : isSubtype(unboxedType(t), s);
288 }
290 /**
291 * Is t a subtype of or convertiable via boxing/unboxing
292 * convertions to s?
293 */
294 public boolean isConvertible(Type t, Type s) {
295 return isConvertible(t, s, Warner.noWarnings);
296 }
297 // </editor-fold>
299 // <editor-fold defaultstate="collapsed" desc="isSubtype">
300 /**
301 * Is t an unchecked subtype of s?
302 */
303 public boolean isSubtypeUnchecked(Type t, Type s) {
304 return isSubtypeUnchecked(t, s, Warner.noWarnings);
305 }
306 /**
307 * Is t an unchecked subtype of s?
308 */
309 public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
310 boolean result = isSubtypeUncheckedInternal(t, s, warn);
311 if (result) {
312 checkUnsafeVarargsConversion(t, s, warn);
313 }
314 return result;
315 }
316 //where
317 private boolean isSubtypeUncheckedInternal(Type t, Type s, Warner warn) {
318 if (t.tag == ARRAY && s.tag == ARRAY) {
319 if (((ArrayType)t).elemtype.tag <= lastBaseTag) {
320 return isSameType(elemtype(t), elemtype(s));
321 } else {
322 return isSubtypeUnchecked(elemtype(t), elemtype(s), warn);
323 }
324 } else if (isSubtype(t, s)) {
325 return true;
326 }
327 else if (t.tag == TYPEVAR) {
328 return isSubtypeUnchecked(t.getUpperBound(), s, warn);
329 }
330 else if (!s.isRaw()) {
331 Type t2 = asSuper(t, s.tsym);
332 if (t2 != null && t2.isRaw()) {
333 if (isReifiable(s))
334 warn.silentWarn(LintCategory.UNCHECKED);
335 else
336 warn.warn(LintCategory.UNCHECKED);
337 return true;
338 }
339 }
340 return false;
341 }
343 private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {
344 if (t.tag != ARRAY || isReifiable(t)) return;
345 ArrayType from = (ArrayType)t;
346 boolean shouldWarn = false;
347 switch (s.tag) {
348 case ARRAY:
349 ArrayType to = (ArrayType)s;
350 shouldWarn = from.isVarargs() &&
351 !to.isVarargs() &&
352 !isReifiable(from);
353 break;
354 case CLASS:
355 shouldWarn = from.isVarargs();
356 break;
357 }
358 if (shouldWarn) {
359 warn.warn(LintCategory.VARARGS);
360 }
361 }
363 /**
364 * Is t a subtype of s?<br>
365 * (not defined for Method and ForAll types)
366 */
367 final public boolean isSubtype(Type t, Type s) {
368 return isSubtype(t, s, true);
369 }
370 final public boolean isSubtypeNoCapture(Type t, Type s) {
371 return isSubtype(t, s, false);
372 }
373 public boolean isSubtype(Type t, Type s, boolean capture) {
374 if (t == s)
375 return true;
377 if (s.tag >= firstPartialTag)
378 return isSuperType(s, t);
380 if (s.isCompound()) {
381 for (Type s2 : interfaces(s).prepend(supertype(s))) {
382 if (!isSubtype(t, s2, capture))
383 return false;
384 }
385 return true;
386 }
388 Type lower = lowerBound(s);
389 if (s != lower)
390 return isSubtype(capture ? capture(t) : t, lower, false);
392 return isSubtype.visit(capture ? capture(t) : t, s);
393 }
394 // where
395 private TypeRelation isSubtype = new TypeRelation()
396 {
397 public Boolean visitType(Type t, Type s) {
398 switch (t.tag) {
399 case BYTE: case CHAR:
400 return (t.tag == s.tag ||
401 t.tag + 2 <= s.tag && s.tag <= DOUBLE);
402 case SHORT: case INT: case LONG: case FLOAT: case DOUBLE:
403 return t.tag <= s.tag && s.tag <= DOUBLE;
404 case BOOLEAN: case VOID:
405 return t.tag == s.tag;
406 case TYPEVAR:
407 return isSubtypeNoCapture(t.getUpperBound(), s);
408 case BOT:
409 return
410 s.tag == BOT || s.tag == CLASS ||
411 s.tag == ARRAY || s.tag == TYPEVAR;
412 case WILDCARD: //we shouldn't be here - avoids crash (see 7034495)
413 case NONE:
414 return false;
415 default:
416 throw new AssertionError("isSubtype " + t.tag);
417 }
418 }
420 private Set<TypePair> cache = new HashSet<TypePair>();
422 private boolean containsTypeRecursive(Type t, Type s) {
423 TypePair pair = new TypePair(t, s);
424 if (cache.add(pair)) {
425 try {
426 return containsType(t.getTypeArguments(),
427 s.getTypeArguments());
428 } finally {
429 cache.remove(pair);
430 }
431 } else {
432 return containsType(t.getTypeArguments(),
433 rewriteSupers(s).getTypeArguments());
434 }
435 }
437 private Type rewriteSupers(Type t) {
438 if (!t.isParameterized())
439 return t;
440 ListBuffer<Type> from = lb();
441 ListBuffer<Type> to = lb();
442 adaptSelf(t, from, to);
443 if (from.isEmpty())
444 return t;
445 ListBuffer<Type> rewrite = lb();
446 boolean changed = false;
447 for (Type orig : to.toList()) {
448 Type s = rewriteSupers(orig);
449 if (s.isSuperBound() && !s.isExtendsBound()) {
450 s = new WildcardType(syms.objectType,
451 BoundKind.UNBOUND,
452 syms.boundClass);
453 changed = true;
454 } else if (s != orig) {
455 s = new WildcardType(upperBound(s),
456 BoundKind.EXTENDS,
457 syms.boundClass);
458 changed = true;
459 }
460 rewrite.append(s);
461 }
462 if (changed)
463 return subst(t.tsym.type, from.toList(), rewrite.toList());
464 else
465 return t;
466 }
468 @Override
469 public Boolean visitClassType(ClassType t, Type s) {
470 Type sup = asSuper(t, s.tsym);
471 return sup != null
472 && sup.tsym == s.tsym
473 // You're not allowed to write
474 // Vector<Object> vec = new Vector<String>();
475 // But with wildcards you can write
476 // Vector<? extends Object> vec = new Vector<String>();
477 // which means that subtype checking must be done
478 // here instead of same-type checking (via containsType).
479 && (!s.isParameterized() || containsTypeRecursive(s, sup))
480 && isSubtypeNoCapture(sup.getEnclosingType(),
481 s.getEnclosingType());
482 }
484 @Override
485 public Boolean visitArrayType(ArrayType t, Type s) {
486 if (s.tag == ARRAY) {
487 if (t.elemtype.tag <= lastBaseTag)
488 return isSameType(t.elemtype, elemtype(s));
489 else
490 return isSubtypeNoCapture(t.elemtype, elemtype(s));
491 }
493 if (s.tag == CLASS) {
494 Name sname = s.tsym.getQualifiedName();
495 return sname == names.java_lang_Object
496 || sname == names.java_lang_Cloneable
497 || sname == names.java_io_Serializable;
498 }
500 return false;
501 }
503 @Override
504 public Boolean visitUndetVar(UndetVar t, Type s) {
505 //todo: test against origin needed? or replace with substitution?
506 if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN) {
507 return true;
508 } else if (s.tag == BOT) {
509 //if 's' is 'null' there's no instantiated type U for which
510 //U <: s (but 'null' itself, which is not a valid type)
511 return false;
512 }
514 t.addBound(InferenceBound.UPPER, s, Types.this);
515 return true;
516 }
518 @Override
519 public Boolean visitErrorType(ErrorType t, Type s) {
520 return true;
521 }
522 };
524 /**
525 * Is t a subtype of every type in given list `ts'?<br>
526 * (not defined for Method and ForAll types)<br>
527 * Allows unchecked conversions.
528 */
529 public boolean isSubtypeUnchecked(Type t, List<Type> ts, Warner warn) {
530 for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
531 if (!isSubtypeUnchecked(t, l.head, warn))
532 return false;
533 return true;
534 }
536 /**
537 * Are corresponding elements of ts subtypes of ss? If lists are
538 * of different length, return false.
539 */
540 public boolean isSubtypes(List<Type> ts, List<Type> ss) {
541 while (ts.tail != null && ss.tail != null
542 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
543 isSubtype(ts.head, ss.head)) {
544 ts = ts.tail;
545 ss = ss.tail;
546 }
547 return ts.tail == null && ss.tail == null;
548 /*inlined: ts.isEmpty() && ss.isEmpty();*/
549 }
551 /**
552 * Are corresponding elements of ts subtypes of ss, allowing
553 * unchecked conversions? If lists are of different length,
554 * return false.
555 **/
556 public boolean isSubtypesUnchecked(List<Type> ts, List<Type> ss, Warner warn) {
557 while (ts.tail != null && ss.tail != null
558 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
559 isSubtypeUnchecked(ts.head, ss.head, warn)) {
560 ts = ts.tail;
561 ss = ss.tail;
562 }
563 return ts.tail == null && ss.tail == null;
564 /*inlined: ts.isEmpty() && ss.isEmpty();*/
565 }
566 // </editor-fold>
568 // <editor-fold defaultstate="collapsed" desc="isSuperType">
569 /**
570 * Is t a supertype of s?
571 */
572 public boolean isSuperType(Type t, Type s) {
573 switch (t.tag) {
574 case ERROR:
575 return true;
576 case UNDETVAR: {
577 UndetVar undet = (UndetVar)t;
578 if (t == s ||
579 undet.qtype == s ||
580 s.tag == ERROR ||
581 s.tag == BOT) return true;
582 undet.addBound(InferenceBound.LOWER, s, this);
583 return true;
584 }
585 default:
586 return isSubtype(s, t);
587 }
588 }
589 // </editor-fold>
591 // <editor-fold defaultstate="collapsed" desc="isSameType">
592 /**
593 * Are corresponding elements of the lists the same type? If
594 * lists are of different length, return false.
595 */
596 public boolean isSameTypes(List<Type> ts, List<Type> ss) {
597 while (ts.tail != null && ss.tail != null
598 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
599 isSameType(ts.head, ss.head)) {
600 ts = ts.tail;
601 ss = ss.tail;
602 }
603 return ts.tail == null && ss.tail == null;
604 /*inlined: ts.isEmpty() && ss.isEmpty();*/
605 }
607 /**
608 * Is t the same type as s?
609 */
610 public boolean isSameType(Type t, Type s) {
611 return isSameType.visit(t, s);
612 }
613 // where
614 private TypeRelation isSameType = new TypeRelation() {
616 public Boolean visitType(Type t, Type s) {
617 if (t == s)
618 return true;
620 if (s.tag >= firstPartialTag)
621 return visit(s, t);
623 switch (t.tag) {
624 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
625 case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE:
626 return t.tag == s.tag;
627 case TYPEVAR: {
628 if (s.tag == TYPEVAR) {
629 //type-substitution does not preserve type-var types
630 //check that type var symbols and bounds are indeed the same
631 return t.tsym == s.tsym &&
632 visit(t.getUpperBound(), s.getUpperBound());
633 }
634 else {
635 //special case for s == ? super X, where upper(s) = u
636 //check that u == t, where u has been set by Type.withTypeVar
637 return s.isSuperBound() &&
638 !s.isExtendsBound() &&
639 visit(t, upperBound(s));
640 }
641 }
642 default:
643 throw new AssertionError("isSameType " + t.tag);
644 }
645 }
647 @Override
648 public Boolean visitWildcardType(WildcardType t, Type s) {
649 if (s.tag >= firstPartialTag)
650 return visit(s, t);
651 else
652 return false;
653 }
655 @Override
656 public Boolean visitClassType(ClassType t, Type s) {
657 if (t == s)
658 return true;
660 if (s.tag >= firstPartialTag)
661 return visit(s, t);
663 if (s.isSuperBound() && !s.isExtendsBound())
664 return visit(t, upperBound(s)) && visit(t, lowerBound(s));
666 if (t.isCompound() && s.isCompound()) {
667 if (!visit(supertype(t), supertype(s)))
668 return false;
670 HashSet<SingletonType> set = new HashSet<SingletonType>();
671 for (Type x : interfaces(t))
672 set.add(new SingletonType(x));
673 for (Type x : interfaces(s)) {
674 if (!set.remove(new SingletonType(x)))
675 return false;
676 }
677 return (set.isEmpty());
678 }
679 return t.tsym == s.tsym
680 && visit(t.getEnclosingType(), s.getEnclosingType())
681 && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments());
682 }
684 @Override
685 public Boolean visitArrayType(ArrayType t, Type s) {
686 if (t == s)
687 return true;
689 if (s.tag >= firstPartialTag)
690 return visit(s, t);
692 return s.tag == ARRAY
693 && containsTypeEquivalent(t.elemtype, elemtype(s));
694 }
696 @Override
697 public Boolean visitMethodType(MethodType t, Type s) {
698 // isSameType for methods does not take thrown
699 // exceptions into account!
700 return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType());
701 }
703 @Override
704 public Boolean visitPackageType(PackageType t, Type s) {
705 return t == s;
706 }
708 @Override
709 public Boolean visitForAll(ForAll t, Type s) {
710 if (s.tag != FORALL)
711 return false;
713 ForAll forAll = (ForAll)s;
714 return hasSameBounds(t, forAll)
715 && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
716 }
718 @Override
719 public Boolean visitUndetVar(UndetVar t, Type s) {
720 if (s.tag == WILDCARD)
721 // FIXME, this might be leftovers from before capture conversion
722 return false;
724 if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN)
725 return true;
727 t.addBound(InferenceBound.EQ, s, Types.this);
729 return true;
730 }
732 @Override
733 public Boolean visitErrorType(ErrorType t, Type s) {
734 return true;
735 }
736 };
737 // </editor-fold>
739 // <editor-fold defaultstate="collapsed" desc="Contains Type">
740 public boolean containedBy(Type t, Type s) {
741 switch (t.tag) {
742 case UNDETVAR:
743 if (s.tag == WILDCARD) {
744 UndetVar undetvar = (UndetVar)t;
745 WildcardType wt = (WildcardType)s;
746 switch(wt.kind) {
747 case UNBOUND: //similar to ? extends Object
748 case EXTENDS: {
749 Type bound = upperBound(s);
750 undetvar.addBound(InferenceBound.UPPER, bound, this);
751 break;
752 }
753 case SUPER: {
754 Type bound = lowerBound(s);
755 undetvar.addBound(InferenceBound.LOWER, bound, this);
756 break;
757 }
758 }
759 return true;
760 } else {
761 return isSameType(t, s);
762 }
763 case ERROR:
764 return true;
765 default:
766 return containsType(s, t);
767 }
768 }
770 boolean containsType(List<Type> ts, List<Type> ss) {
771 while (ts.nonEmpty() && ss.nonEmpty()
772 && containsType(ts.head, ss.head)) {
773 ts = ts.tail;
774 ss = ss.tail;
775 }
776 return ts.isEmpty() && ss.isEmpty();
777 }
779 /**
780 * Check if t contains s.
781 *
782 * <p>T contains S if:
783 *
784 * <p>{@code L(T) <: L(S) && U(S) <: U(T)}
785 *
786 * <p>This relation is only used by ClassType.isSubtype(), that
787 * is,
788 *
789 * <p>{@code C<S> <: C<T> if T contains S.}
790 *
791 * <p>Because of F-bounds, this relation can lead to infinite
792 * recursion. Thus we must somehow break that recursion. Notice
793 * that containsType() is only called from ClassType.isSubtype().
794 * Since the arguments have already been checked against their
795 * bounds, we know:
796 *
797 * <p>{@code U(S) <: U(T) if T is "super" bound (U(T) *is* the bound)}
798 *
799 * <p>{@code L(T) <: L(S) if T is "extends" bound (L(T) is bottom)}
800 *
801 * @param t a type
802 * @param s a type
803 */
804 public boolean containsType(Type t, Type s) {
805 return containsType.visit(t, s);
806 }
807 // where
808 private TypeRelation containsType = new TypeRelation() {
810 private Type U(Type t) {
811 while (t.tag == WILDCARD) {
812 WildcardType w = (WildcardType)t;
813 if (w.isSuperBound())
814 return w.bound == null ? syms.objectType : w.bound.bound;
815 else
816 t = w.type;
817 }
818 return t;
819 }
821 private Type L(Type t) {
822 while (t.tag == WILDCARD) {
823 WildcardType w = (WildcardType)t;
824 if (w.isExtendsBound())
825 return syms.botType;
826 else
827 t = w.type;
828 }
829 return t;
830 }
832 public Boolean visitType(Type t, Type s) {
833 if (s.tag >= firstPartialTag)
834 return containedBy(s, t);
835 else
836 return isSameType(t, s);
837 }
839 // void debugContainsType(WildcardType t, Type s) {
840 // System.err.println();
841 // System.err.format(" does %s contain %s?%n", t, s);
842 // System.err.format(" %s U(%s) <: U(%s) %s = %s%n",
843 // upperBound(s), s, t, U(t),
844 // t.isSuperBound()
845 // || isSubtypeNoCapture(upperBound(s), U(t)));
846 // System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
847 // L(t), t, s, lowerBound(s),
848 // t.isExtendsBound()
849 // || isSubtypeNoCapture(L(t), lowerBound(s)));
850 // System.err.println();
851 // }
853 @Override
854 public Boolean visitWildcardType(WildcardType t, Type s) {
855 if (s.tag >= firstPartialTag)
856 return containedBy(s, t);
857 else {
858 // debugContainsType(t, s);
859 return isSameWildcard(t, s)
860 || isCaptureOf(s, t)
861 || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), lowerBound(s))) &&
862 (t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t))));
863 }
864 }
866 @Override
867 public Boolean visitUndetVar(UndetVar t, Type s) {
868 if (s.tag != WILDCARD)
869 return isSameType(t, s);
870 else
871 return false;
872 }
874 @Override
875 public Boolean visitErrorType(ErrorType t, Type s) {
876 return true;
877 }
878 };
880 public boolean isCaptureOf(Type s, WildcardType t) {
881 if (s.tag != TYPEVAR || !((TypeVar)s).isCaptured())
882 return false;
883 return isSameWildcard(t, ((CapturedType)s).wildcard);
884 }
886 public boolean isSameWildcard(WildcardType t, Type s) {
887 if (s.tag != WILDCARD)
888 return false;
889 WildcardType w = (WildcardType)s;
890 return w.kind == t.kind && w.type == t.type;
891 }
893 public boolean containsTypeEquivalent(List<Type> ts, List<Type> ss) {
894 while (ts.nonEmpty() && ss.nonEmpty()
895 && containsTypeEquivalent(ts.head, ss.head)) {
896 ts = ts.tail;
897 ss = ss.tail;
898 }
899 return ts.isEmpty() && ss.isEmpty();
900 }
901 // </editor-fold>
903 // <editor-fold defaultstate="collapsed" desc="isCastable">
904 public boolean isCastable(Type t, Type s) {
905 return isCastable(t, s, Warner.noWarnings);
906 }
908 /**
909 * Is t is castable to s?<br>
910 * s is assumed to be an erased type.<br>
911 * (not defined for Method and ForAll types).
912 */
913 public boolean isCastable(Type t, Type s, Warner warn) {
914 if (t == s)
915 return true;
917 if (t.isPrimitive() != s.isPrimitive())
918 return allowBoxing && (
919 isConvertible(t, s, warn)
920 || (allowObjectToPrimitiveCast &&
921 s.isPrimitive() &&
922 isSubtype(boxedClass(s).type, t)));
923 if (warn != warnStack.head) {
924 try {
925 warnStack = warnStack.prepend(warn);
926 checkUnsafeVarargsConversion(t, s, warn);
927 return isCastable.visit(t,s);
928 } finally {
929 warnStack = warnStack.tail;
930 }
931 } else {
932 return isCastable.visit(t,s);
933 }
934 }
935 // where
936 private TypeRelation isCastable = new TypeRelation() {
938 public Boolean visitType(Type t, Type s) {
939 if (s.tag == ERROR)
940 return true;
942 switch (t.tag) {
943 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
944 case DOUBLE:
945 return s.tag <= DOUBLE;
946 case BOOLEAN:
947 return s.tag == BOOLEAN;
948 case VOID:
949 return false;
950 case BOT:
951 return isSubtype(t, s);
952 default:
953 throw new AssertionError();
954 }
955 }
957 @Override
958 public Boolean visitWildcardType(WildcardType t, Type s) {
959 return isCastable(upperBound(t), s, warnStack.head);
960 }
962 @Override
963 public Boolean visitClassType(ClassType t, Type s) {
964 if (s.tag == ERROR || s.tag == BOT)
965 return true;
967 if (s.tag == TYPEVAR) {
968 if (isCastable(t, s.getUpperBound(), Warner.noWarnings)) {
969 warnStack.head.warn(LintCategory.UNCHECKED);
970 return true;
971 } else {
972 return false;
973 }
974 }
976 if (t.isCompound()) {
977 Warner oldWarner = warnStack.head;
978 warnStack.head = Warner.noWarnings;
979 if (!visit(supertype(t), s))
980 return false;
981 for (Type intf : interfaces(t)) {
982 if (!visit(intf, s))
983 return false;
984 }
985 if (warnStack.head.hasLint(LintCategory.UNCHECKED))
986 oldWarner.warn(LintCategory.UNCHECKED);
987 return true;
988 }
990 if (s.isCompound()) {
991 // call recursively to reuse the above code
992 return visitClassType((ClassType)s, t);
993 }
995 if (s.tag == CLASS || s.tag == ARRAY) {
996 boolean upcast;
997 if ((upcast = isSubtype(erasure(t), erasure(s)))
998 || isSubtype(erasure(s), erasure(t))) {
999 if (!upcast && s.tag == ARRAY) {
1000 if (!isReifiable(s))
1001 warnStack.head.warn(LintCategory.UNCHECKED);
1002 return true;
1003 } else if (s.isRaw()) {
1004 return true;
1005 } else if (t.isRaw()) {
1006 if (!isUnbounded(s))
1007 warnStack.head.warn(LintCategory.UNCHECKED);
1008 return true;
1009 }
1010 // Assume |a| <: |b|
1011 final Type a = upcast ? t : s;
1012 final Type b = upcast ? s : t;
1013 final boolean HIGH = true;
1014 final boolean LOW = false;
1015 final boolean DONT_REWRITE_TYPEVARS = false;
1016 Type aHigh = rewriteQuantifiers(a, HIGH, DONT_REWRITE_TYPEVARS);
1017 Type aLow = rewriteQuantifiers(a, LOW, DONT_REWRITE_TYPEVARS);
1018 Type bHigh = rewriteQuantifiers(b, HIGH, DONT_REWRITE_TYPEVARS);
1019 Type bLow = rewriteQuantifiers(b, LOW, DONT_REWRITE_TYPEVARS);
1020 Type lowSub = asSub(bLow, aLow.tsym);
1021 Type highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);
1022 if (highSub == null) {
1023 final boolean REWRITE_TYPEVARS = true;
1024 aHigh = rewriteQuantifiers(a, HIGH, REWRITE_TYPEVARS);
1025 aLow = rewriteQuantifiers(a, LOW, REWRITE_TYPEVARS);
1026 bHigh = rewriteQuantifiers(b, HIGH, REWRITE_TYPEVARS);
1027 bLow = rewriteQuantifiers(b, LOW, REWRITE_TYPEVARS);
1028 lowSub = asSub(bLow, aLow.tsym);
1029 highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);
1030 }
1031 if (highSub != null) {
1032 if (!(a.tsym == highSub.tsym && a.tsym == lowSub.tsym)) {
1033 Assert.error(a.tsym + " != " + highSub.tsym + " != " + lowSub.tsym);
1034 }
1035 if (!disjointTypes(aHigh.allparams(), highSub.allparams())
1036 && !disjointTypes(aHigh.allparams(), lowSub.allparams())
1037 && !disjointTypes(aLow.allparams(), highSub.allparams())
1038 && !disjointTypes(aLow.allparams(), lowSub.allparams())) {
1039 if (upcast ? giveWarning(a, b) :
1040 giveWarning(b, a))
1041 warnStack.head.warn(LintCategory.UNCHECKED);
1042 return true;
1043 }
1044 }
1045 if (isReifiable(s))
1046 return isSubtypeUnchecked(a, b);
1047 else
1048 return isSubtypeUnchecked(a, b, warnStack.head);
1049 }
1051 // Sidecast
1052 if (s.tag == CLASS) {
1053 if ((s.tsym.flags() & INTERFACE) != 0) {
1054 return ((t.tsym.flags() & FINAL) == 0)
1055 ? sideCast(t, s, warnStack.head)
1056 : sideCastFinal(t, s, warnStack.head);
1057 } else if ((t.tsym.flags() & INTERFACE) != 0) {
1058 return ((s.tsym.flags() & FINAL) == 0)
1059 ? sideCast(t, s, warnStack.head)
1060 : sideCastFinal(t, s, warnStack.head);
1061 } else {
1062 // unrelated class types
1063 return false;
1064 }
1065 }
1066 }
1067 return false;
1068 }
1070 @Override
1071 public Boolean visitArrayType(ArrayType t, Type s) {
1072 switch (s.tag) {
1073 case ERROR:
1074 case BOT:
1075 return true;
1076 case TYPEVAR:
1077 if (isCastable(s, t, Warner.noWarnings)) {
1078 warnStack.head.warn(LintCategory.UNCHECKED);
1079 return true;
1080 } else {
1081 return false;
1082 }
1083 case CLASS:
1084 return isSubtype(t, s);
1085 case ARRAY:
1086 if (elemtype(t).tag <= lastBaseTag ||
1087 elemtype(s).tag <= lastBaseTag) {
1088 return elemtype(t).tag == elemtype(s).tag;
1089 } else {
1090 return visit(elemtype(t), elemtype(s));
1091 }
1092 default:
1093 return false;
1094 }
1095 }
1097 @Override
1098 public Boolean visitTypeVar(TypeVar t, Type s) {
1099 switch (s.tag) {
1100 case ERROR:
1101 case BOT:
1102 return true;
1103 case TYPEVAR:
1104 if (isSubtype(t, s)) {
1105 return true;
1106 } else if (isCastable(t.bound, s, Warner.noWarnings)) {
1107 warnStack.head.warn(LintCategory.UNCHECKED);
1108 return true;
1109 } else {
1110 return false;
1111 }
1112 default:
1113 return isCastable(t.bound, s, warnStack.head);
1114 }
1115 }
1117 @Override
1118 public Boolean visitErrorType(ErrorType t, Type s) {
1119 return true;
1120 }
1121 };
1122 // </editor-fold>
1124 // <editor-fold defaultstate="collapsed" desc="disjointTypes">
1125 public boolean disjointTypes(List<Type> ts, List<Type> ss) {
1126 while (ts.tail != null && ss.tail != null) {
1127 if (disjointType(ts.head, ss.head)) return true;
1128 ts = ts.tail;
1129 ss = ss.tail;
1130 }
1131 return false;
1132 }
1134 /**
1135 * Two types or wildcards are considered disjoint if it can be
1136 * proven that no type can be contained in both. It is
1137 * conservative in that it is allowed to say that two types are
1138 * not disjoint, even though they actually are.
1139 *
1140 * The type C<X> is castable to C<Y> exactly if X and Y are not
1141 * disjoint.
1142 */
1143 public boolean disjointType(Type t, Type s) {
1144 return disjointType.visit(t, s);
1145 }
1146 // where
1147 private TypeRelation disjointType = new TypeRelation() {
1149 private Set<TypePair> cache = new HashSet<TypePair>();
1151 public Boolean visitType(Type t, Type s) {
1152 if (s.tag == WILDCARD)
1153 return visit(s, t);
1154 else
1155 return notSoftSubtypeRecursive(t, s) || notSoftSubtypeRecursive(s, t);
1156 }
1158 private boolean isCastableRecursive(Type t, Type s) {
1159 TypePair pair = new TypePair(t, s);
1160 if (cache.add(pair)) {
1161 try {
1162 return Types.this.isCastable(t, s);
1163 } finally {
1164 cache.remove(pair);
1165 }
1166 } else {
1167 return true;
1168 }
1169 }
1171 private boolean notSoftSubtypeRecursive(Type t, Type s) {
1172 TypePair pair = new TypePair(t, s);
1173 if (cache.add(pair)) {
1174 try {
1175 return Types.this.notSoftSubtype(t, s);
1176 } finally {
1177 cache.remove(pair);
1178 }
1179 } else {
1180 return false;
1181 }
1182 }
1184 @Override
1185 public Boolean visitWildcardType(WildcardType t, Type s) {
1186 if (t.isUnbound())
1187 return false;
1189 if (s.tag != WILDCARD) {
1190 if (t.isExtendsBound())
1191 return notSoftSubtypeRecursive(s, t.type);
1192 else // isSuperBound()
1193 return notSoftSubtypeRecursive(t.type, s);
1194 }
1196 if (s.isUnbound())
1197 return false;
1199 if (t.isExtendsBound()) {
1200 if (s.isExtendsBound())
1201 return !isCastableRecursive(t.type, upperBound(s));
1202 else if (s.isSuperBound())
1203 return notSoftSubtypeRecursive(lowerBound(s), t.type);
1204 } else if (t.isSuperBound()) {
1205 if (s.isExtendsBound())
1206 return notSoftSubtypeRecursive(t.type, upperBound(s));
1207 }
1208 return false;
1209 }
1210 };
1211 // </editor-fold>
1213 // <editor-fold defaultstate="collapsed" desc="lowerBoundArgtypes">
1214 /**
1215 * Returns the lower bounds of the formals of a method.
1216 */
1217 public List<Type> lowerBoundArgtypes(Type t) {
1218 return map(t.getParameterTypes(), lowerBoundMapping);
1219 }
1220 private final Mapping lowerBoundMapping = new Mapping("lowerBound") {
1221 public Type apply(Type t) {
1222 return lowerBound(t);
1223 }
1224 };
1225 // </editor-fold>
1227 // <editor-fold defaultstate="collapsed" desc="notSoftSubtype">
1228 /**
1229 * This relation answers the question: is impossible that
1230 * something of type `t' can be a subtype of `s'? This is
1231 * different from the question "is `t' not a subtype of `s'?"
1232 * when type variables are involved: Integer is not a subtype of T
1233 * where <T extends Number> but it is not true that Integer cannot
1234 * possibly be a subtype of T.
1235 */
1236 public boolean notSoftSubtype(Type t, Type s) {
1237 if (t == s) return false;
1238 if (t.tag == TYPEVAR) {
1239 TypeVar tv = (TypeVar) t;
1240 return !isCastable(tv.bound,
1241 relaxBound(s),
1242 Warner.noWarnings);
1243 }
1244 if (s.tag != WILDCARD)
1245 s = upperBound(s);
1247 return !isSubtype(t, relaxBound(s));
1248 }
1250 private Type relaxBound(Type t) {
1251 if (t.tag == TYPEVAR) {
1252 while (t.tag == TYPEVAR)
1253 t = t.getUpperBound();
1254 t = rewriteQuantifiers(t, true, true);
1255 }
1256 return t;
1257 }
1258 // </editor-fold>
1260 // <editor-fold defaultstate="collapsed" desc="isReifiable">
1261 public boolean isReifiable(Type t) {
1262 return isReifiable.visit(t);
1263 }
1264 // where
1265 private UnaryVisitor<Boolean> isReifiable = new UnaryVisitor<Boolean>() {
1267 public Boolean visitType(Type t, Void ignored) {
1268 return true;
1269 }
1271 @Override
1272 public Boolean visitClassType(ClassType t, Void ignored) {
1273 if (t.isCompound())
1274 return false;
1275 else {
1276 if (!t.isParameterized())
1277 return true;
1279 for (Type param : t.allparams()) {
1280 if (!param.isUnbound())
1281 return false;
1282 }
1283 return true;
1284 }
1285 }
1287 @Override
1288 public Boolean visitArrayType(ArrayType t, Void ignored) {
1289 return visit(t.elemtype);
1290 }
1292 @Override
1293 public Boolean visitTypeVar(TypeVar t, Void ignored) {
1294 return false;
1295 }
1296 };
1297 // </editor-fold>
1299 // <editor-fold defaultstate="collapsed" desc="Array Utils">
1300 public boolean isArray(Type t) {
1301 while (t.tag == WILDCARD)
1302 t = upperBound(t);
1303 return t.tag == ARRAY;
1304 }
1306 /**
1307 * The element type of an array.
1308 */
1309 public Type elemtype(Type t) {
1310 switch (t.tag) {
1311 case WILDCARD:
1312 return elemtype(upperBound(t));
1313 case ARRAY:
1314 return ((ArrayType)t).elemtype;
1315 case FORALL:
1316 return elemtype(((ForAll)t).qtype);
1317 case ERROR:
1318 return t;
1319 default:
1320 return null;
1321 }
1322 }
1324 public Type elemtypeOrType(Type t) {
1325 Type elemtype = elemtype(t);
1326 return elemtype != null ?
1327 elemtype :
1328 t;
1329 }
1331 /**
1332 * Mapping to take element type of an arraytype
1333 */
1334 private Mapping elemTypeFun = new Mapping ("elemTypeFun") {
1335 public Type apply(Type t) { return elemtype(t); }
1336 };
1338 /**
1339 * The number of dimensions of an array type.
1340 */
1341 public int dimensions(Type t) {
1342 int result = 0;
1343 while (t.tag == ARRAY) {
1344 result++;
1345 t = elemtype(t);
1346 }
1347 return result;
1348 }
1350 /**
1351 * Returns an ArrayType with the component type t
1352 *
1353 * @param t The component type of the ArrayType
1354 * @return the ArrayType for the given component
1355 */
1356 public ArrayType makeArrayType(Type t) {
1357 if (t.tag == VOID ||
1358 t.tag >= PACKAGE) {
1359 Assert.error("Type t must not be a a VOID or PACKAGE type, " + t.toString());
1360 }
1361 return new ArrayType(t, syms.arrayClass);
1362 }
1363 // </editor-fold>
1365 // <editor-fold defaultstate="collapsed" desc="asSuper">
1366 /**
1367 * Return the (most specific) base type of t that starts with the
1368 * given symbol. If none exists, return null.
1369 *
1370 * @param t a type
1371 * @param sym a symbol
1372 */
1373 public Type asSuper(Type t, Symbol sym) {
1374 return asSuper.visit(t, sym);
1375 }
1376 // where
1377 private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() {
1379 public Type visitType(Type t, Symbol sym) {
1380 return null;
1381 }
1383 @Override
1384 public Type visitClassType(ClassType t, Symbol sym) {
1385 if (t.tsym == sym)
1386 return t;
1388 Type st = supertype(t);
1389 if (st.tag == CLASS || st.tag == TYPEVAR || st.tag == ERROR) {
1390 Type x = asSuper(st, sym);
1391 if (x != null)
1392 return x;
1393 }
1394 if ((sym.flags() & INTERFACE) != 0) {
1395 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
1396 Type x = asSuper(l.head, sym);
1397 if (x != null)
1398 return x;
1399 }
1400 }
1401 return null;
1402 }
1404 @Override
1405 public Type visitArrayType(ArrayType t, Symbol sym) {
1406 return isSubtype(t, sym.type) ? sym.type : null;
1407 }
1409 @Override
1410 public Type visitTypeVar(TypeVar t, Symbol sym) {
1411 if (t.tsym == sym)
1412 return t;
1413 else
1414 return asSuper(t.bound, sym);
1415 }
1417 @Override
1418 public Type visitErrorType(ErrorType t, Symbol sym) {
1419 return t;
1420 }
1421 };
1423 /**
1424 * Return the base type of t or any of its outer types that starts
1425 * with the given symbol. If none exists, return null.
1426 *
1427 * @param t a type
1428 * @param sym a symbol
1429 */
1430 public Type asOuterSuper(Type t, Symbol sym) {
1431 switch (t.tag) {
1432 case CLASS:
1433 do {
1434 Type s = asSuper(t, sym);
1435 if (s != null) return s;
1436 t = t.getEnclosingType();
1437 } while (t.tag == CLASS);
1438 return null;
1439 case ARRAY:
1440 return isSubtype(t, sym.type) ? sym.type : null;
1441 case TYPEVAR:
1442 return asSuper(t, sym);
1443 case ERROR:
1444 return t;
1445 default:
1446 return null;
1447 }
1448 }
1450 /**
1451 * Return the base type of t or any of its enclosing types that
1452 * starts with the given symbol. If none exists, return null.
1453 *
1454 * @param t a type
1455 * @param sym a symbol
1456 */
1457 public Type asEnclosingSuper(Type t, Symbol sym) {
1458 switch (t.tag) {
1459 case CLASS:
1460 do {
1461 Type s = asSuper(t, sym);
1462 if (s != null) return s;
1463 Type outer = t.getEnclosingType();
1464 t = (outer.tag == CLASS) ? outer :
1465 (t.tsym.owner.enclClass() != null) ? t.tsym.owner.enclClass().type :
1466 Type.noType;
1467 } while (t.tag == CLASS);
1468 return null;
1469 case ARRAY:
1470 return isSubtype(t, sym.type) ? sym.type : null;
1471 case TYPEVAR:
1472 return asSuper(t, sym);
1473 case ERROR:
1474 return t;
1475 default:
1476 return null;
1477 }
1478 }
1479 // </editor-fold>
1481 // <editor-fold defaultstate="collapsed" desc="memberType">
1482 /**
1483 * The type of given symbol, seen as a member of t.
1484 *
1485 * @param t a type
1486 * @param sym a symbol
1487 */
1488 public Type memberType(Type t, Symbol sym) {
1489 return (sym.flags() & STATIC) != 0
1490 ? sym.type
1491 : memberType.visit(t, sym);
1492 }
1493 // where
1494 private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
1496 public Type visitType(Type t, Symbol sym) {
1497 return sym.type;
1498 }
1500 @Override
1501 public Type visitWildcardType(WildcardType t, Symbol sym) {
1502 return memberType(upperBound(t), sym);
1503 }
1505 @Override
1506 public Type visitClassType(ClassType t, Symbol sym) {
1507 Symbol owner = sym.owner;
1508 long flags = sym.flags();
1509 if (((flags & STATIC) == 0) && owner.type.isParameterized()) {
1510 Type base = asOuterSuper(t, owner);
1511 //if t is an intersection type T = CT & I1 & I2 ... & In
1512 //its supertypes CT, I1, ... In might contain wildcards
1513 //so we need to go through capture conversion
1514 base = t.isCompound() ? capture(base) : base;
1515 if (base != null) {
1516 List<Type> ownerParams = owner.type.allparams();
1517 List<Type> baseParams = base.allparams();
1518 if (ownerParams.nonEmpty()) {
1519 if (baseParams.isEmpty()) {
1520 // then base is a raw type
1521 return erasure(sym.type);
1522 } else {
1523 return subst(sym.type, ownerParams, baseParams);
1524 }
1525 }
1526 }
1527 }
1528 return sym.type;
1529 }
1531 @Override
1532 public Type visitTypeVar(TypeVar t, Symbol sym) {
1533 return memberType(t.bound, sym);
1534 }
1536 @Override
1537 public Type visitErrorType(ErrorType t, Symbol sym) {
1538 return t;
1539 }
1540 };
1541 // </editor-fold>
1543 // <editor-fold defaultstate="collapsed" desc="isAssignable">
1544 public boolean isAssignable(Type t, Type s) {
1545 return isAssignable(t, s, Warner.noWarnings);
1546 }
1548 /**
1549 * Is t assignable to s?<br>
1550 * Equivalent to subtype except for constant values and raw
1551 * types.<br>
1552 * (not defined for Method and ForAll types)
1553 */
1554 public boolean isAssignable(Type t, Type s, Warner warn) {
1555 if (t.tag == ERROR)
1556 return true;
1557 if (t.tag <= INT && t.constValue() != null) {
1558 int value = ((Number)t.constValue()).intValue();
1559 switch (s.tag) {
1560 case BYTE:
1561 if (Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE)
1562 return true;
1563 break;
1564 case CHAR:
1565 if (Character.MIN_VALUE <= value && value <= Character.MAX_VALUE)
1566 return true;
1567 break;
1568 case SHORT:
1569 if (Short.MIN_VALUE <= value && value <= Short.MAX_VALUE)
1570 return true;
1571 break;
1572 case INT:
1573 return true;
1574 case CLASS:
1575 switch (unboxedType(s).tag) {
1576 case BYTE:
1577 case CHAR:
1578 case SHORT:
1579 return isAssignable(t, unboxedType(s), warn);
1580 }
1581 break;
1582 }
1583 }
1584 return isConvertible(t, s, warn);
1585 }
1586 // </editor-fold>
1588 // <editor-fold defaultstate="collapsed" desc="erasure">
1589 /**
1590 * The erasure of t {@code |t|} -- the type that results when all
1591 * type parameters in t are deleted.
1592 */
1593 public Type erasure(Type t) {
1594 return eraseNotNeeded(t)? t : erasure(t, false);
1595 }
1596 //where
1597 private boolean eraseNotNeeded(Type t) {
1598 // We don't want to erase primitive types and String type as that
1599 // operation is idempotent. Also, erasing these could result in loss
1600 // of information such as constant values attached to such types.
1601 return (t.tag <= lastBaseTag) || (syms.stringType.tsym == t.tsym);
1602 }
1604 private Type erasure(Type t, boolean recurse) {
1605 if (t.tag <= lastBaseTag)
1606 return t; /* fast special case */
1607 else
1608 return erasure.visit(t, recurse);
1609 }
1610 // where
1611 private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() {
1612 public Type visitType(Type t, Boolean recurse) {
1613 if (t.tag <= lastBaseTag)
1614 return t; /*fast special case*/
1615 else
1616 return t.map(recurse ? erasureRecFun : erasureFun);
1617 }
1619 @Override
1620 public Type visitWildcardType(WildcardType t, Boolean recurse) {
1621 return erasure(upperBound(t), recurse);
1622 }
1624 @Override
1625 public Type visitClassType(ClassType t, Boolean recurse) {
1626 Type erased = t.tsym.erasure(Types.this);
1627 if (recurse) {
1628 erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym);
1629 }
1630 return erased;
1631 }
1633 @Override
1634 public Type visitTypeVar(TypeVar t, Boolean recurse) {
1635 return erasure(t.bound, recurse);
1636 }
1638 @Override
1639 public Type visitErrorType(ErrorType t, Boolean recurse) {
1640 return t;
1641 }
1642 };
1644 private Mapping erasureFun = new Mapping ("erasure") {
1645 public Type apply(Type t) { return erasure(t); }
1646 };
1648 private Mapping erasureRecFun = new Mapping ("erasureRecursive") {
1649 public Type apply(Type t) { return erasureRecursive(t); }
1650 };
1652 public List<Type> erasure(List<Type> ts) {
1653 return Type.map(ts, erasureFun);
1654 }
1656 public Type erasureRecursive(Type t) {
1657 return erasure(t, true);
1658 }
1660 public List<Type> erasureRecursive(List<Type> ts) {
1661 return Type.map(ts, erasureRecFun);
1662 }
1663 // </editor-fold>
1665 // <editor-fold defaultstate="collapsed" desc="makeCompoundType">
1666 /**
1667 * Make a compound type from non-empty list of types
1668 *
1669 * @param bounds the types from which the compound type is formed
1670 * @param supertype is objectType if all bounds are interfaces,
1671 * null otherwise.
1672 */
1673 public Type makeCompoundType(List<Type> bounds,
1674 Type supertype) {
1675 ClassSymbol bc =
1676 new ClassSymbol(ABSTRACT|PUBLIC|SYNTHETIC|COMPOUND|ACYCLIC,
1677 Type.moreInfo
1678 ? names.fromString(bounds.toString())
1679 : names.empty,
1680 syms.noSymbol);
1681 if (bounds.head.tag == TYPEVAR)
1682 // error condition, recover
1683 bc.erasure_field = syms.objectType;
1684 else
1685 bc.erasure_field = erasure(bounds.head);
1686 bc.members_field = new Scope(bc);
1687 ClassType bt = (ClassType)bc.type;
1688 bt.allparams_field = List.nil();
1689 if (supertype != null) {
1690 bt.supertype_field = supertype;
1691 bt.interfaces_field = bounds;
1692 } else {
1693 bt.supertype_field = bounds.head;
1694 bt.interfaces_field = bounds.tail;
1695 }
1696 Assert.check(bt.supertype_field.tsym.completer != null
1697 || !bt.supertype_field.isInterface(),
1698 bt.supertype_field);
1699 return bt;
1700 }
1702 /**
1703 * Same as {@link #makeCompoundType(List,Type)}, except that the
1704 * second parameter is computed directly. Note that this might
1705 * cause a symbol completion. Hence, this version of
1706 * makeCompoundType may not be called during a classfile read.
1707 */
1708 public Type makeCompoundType(List<Type> bounds) {
1709 Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?
1710 supertype(bounds.head) : null;
1711 return makeCompoundType(bounds, supertype);
1712 }
1714 /**
1715 * A convenience wrapper for {@link #makeCompoundType(List)}; the
1716 * arguments are converted to a list and passed to the other
1717 * method. Note that this might cause a symbol completion.
1718 * Hence, this version of makeCompoundType may not be called
1719 * during a classfile read.
1720 */
1721 public Type makeCompoundType(Type bound1, Type bound2) {
1722 return makeCompoundType(List.of(bound1, bound2));
1723 }
1724 // </editor-fold>
1726 // <editor-fold defaultstate="collapsed" desc="supertype">
1727 public Type supertype(Type t) {
1728 return supertype.visit(t);
1729 }
1730 // where
1731 private UnaryVisitor<Type> supertype = new UnaryVisitor<Type>() {
1733 public Type visitType(Type t, Void ignored) {
1734 // A note on wildcards: there is no good way to
1735 // determine a supertype for a super bounded wildcard.
1736 return null;
1737 }
1739 @Override
1740 public Type visitClassType(ClassType t, Void ignored) {
1741 if (t.supertype_field == null) {
1742 Type supertype = ((ClassSymbol)t.tsym).getSuperclass();
1743 // An interface has no superclass; its supertype is Object.
1744 if (t.isInterface())
1745 supertype = ((ClassType)t.tsym.type).supertype_field;
1746 if (t.supertype_field == null) {
1747 List<Type> actuals = classBound(t).allparams();
1748 List<Type> formals = t.tsym.type.allparams();
1749 if (t.hasErasedSupertypes()) {
1750 t.supertype_field = erasureRecursive(supertype);
1751 } else if (formals.nonEmpty()) {
1752 t.supertype_field = subst(supertype, formals, actuals);
1753 }
1754 else {
1755 t.supertype_field = supertype;
1756 }
1757 }
1758 }
1759 return t.supertype_field;
1760 }
1762 /**
1763 * The supertype is always a class type. If the type
1764 * variable's bounds start with a class type, this is also
1765 * the supertype. Otherwise, the supertype is
1766 * java.lang.Object.
1767 */
1768 @Override
1769 public Type visitTypeVar(TypeVar t, Void ignored) {
1770 if (t.bound.tag == TYPEVAR ||
1771 (!t.bound.isCompound() && !t.bound.isInterface())) {
1772 return t.bound;
1773 } else {
1774 return supertype(t.bound);
1775 }
1776 }
1778 @Override
1779 public Type visitArrayType(ArrayType t, Void ignored) {
1780 if (t.elemtype.isPrimitive() || isSameType(t.elemtype, syms.objectType))
1781 return arraySuperType();
1782 else
1783 return new ArrayType(supertype(t.elemtype), t.tsym);
1784 }
1786 @Override
1787 public Type visitErrorType(ErrorType t, Void ignored) {
1788 return t;
1789 }
1790 };
1791 // </editor-fold>
1793 // <editor-fold defaultstate="collapsed" desc="interfaces">
1794 /**
1795 * Return the interfaces implemented by this class.
1796 */
1797 public List<Type> interfaces(Type t) {
1798 return interfaces.visit(t);
1799 }
1800 // where
1801 private UnaryVisitor<List<Type>> interfaces = new UnaryVisitor<List<Type>>() {
1803 public List<Type> visitType(Type t, Void ignored) {
1804 return List.nil();
1805 }
1807 @Override
1808 public List<Type> visitClassType(ClassType t, Void ignored) {
1809 if (t.interfaces_field == null) {
1810 List<Type> interfaces = ((ClassSymbol)t.tsym).getInterfaces();
1811 if (t.interfaces_field == null) {
1812 // If t.interfaces_field is null, then t must
1813 // be a parameterized type (not to be confused
1814 // with a generic type declaration).
1815 // Terminology:
1816 // Parameterized type: List<String>
1817 // Generic type declaration: class List<E> { ... }
1818 // So t corresponds to List<String> and
1819 // t.tsym.type corresponds to List<E>.
1820 // The reason t must be parameterized type is
1821 // that completion will happen as a side
1822 // effect of calling
1823 // ClassSymbol.getInterfaces. Since
1824 // t.interfaces_field is null after
1825 // completion, we can assume that t is not the
1826 // type of a class/interface declaration.
1827 Assert.check(t != t.tsym.type, t);
1828 List<Type> actuals = t.allparams();
1829 List<Type> formals = t.tsym.type.allparams();
1830 if (t.hasErasedSupertypes()) {
1831 t.interfaces_field = erasureRecursive(interfaces);
1832 } else if (formals.nonEmpty()) {
1833 t.interfaces_field =
1834 upperBounds(subst(interfaces, formals, actuals));
1835 }
1836 else {
1837 t.interfaces_field = interfaces;
1838 }
1839 }
1840 }
1841 return t.interfaces_field;
1842 }
1844 @Override
1845 public List<Type> visitTypeVar(TypeVar t, Void ignored) {
1846 if (t.bound.isCompound())
1847 return interfaces(t.bound);
1849 if (t.bound.isInterface())
1850 return List.of(t.bound);
1852 return List.nil();
1853 }
1854 };
1855 // </editor-fold>
1857 // <editor-fold defaultstate="collapsed" desc="isDerivedRaw">
1858 Map<Type,Boolean> isDerivedRawCache = new HashMap<Type,Boolean>();
1860 public boolean isDerivedRaw(Type t) {
1861 Boolean result = isDerivedRawCache.get(t);
1862 if (result == null) {
1863 result = isDerivedRawInternal(t);
1864 isDerivedRawCache.put(t, result);
1865 }
1866 return result;
1867 }
1869 public boolean isDerivedRawInternal(Type t) {
1870 if (t.isErroneous())
1871 return false;
1872 return
1873 t.isRaw() ||
1874 supertype(t) != null && isDerivedRaw(supertype(t)) ||
1875 isDerivedRaw(interfaces(t));
1876 }
1878 public boolean isDerivedRaw(List<Type> ts) {
1879 List<Type> l = ts;
1880 while (l.nonEmpty() && !isDerivedRaw(l.head)) l = l.tail;
1881 return l.nonEmpty();
1882 }
1883 // </editor-fold>
1885 // <editor-fold defaultstate="collapsed" desc="setBounds">
1886 /**
1887 * Set the bounds field of the given type variable to reflect a
1888 * (possibly multiple) list of bounds.
1889 * @param t a type variable
1890 * @param bounds the bounds, must be nonempty
1891 * @param supertype is objectType if all bounds are interfaces,
1892 * null otherwise.
1893 */
1894 public void setBounds(TypeVar t, List<Type> bounds, Type supertype) {
1895 if (bounds.tail.isEmpty())
1896 t.bound = bounds.head;
1897 else
1898 t.bound = makeCompoundType(bounds, supertype);
1899 t.rank_field = -1;
1900 }
1902 /**
1903 * Same as {@link #setBounds(Type.TypeVar,List,Type)}, except that
1904 * third parameter is computed directly, as follows: if all
1905 * all bounds are interface types, the computed supertype is Object,
1906 * otherwise the supertype is simply left null (in this case, the supertype
1907 * is assumed to be the head of the bound list passed as second argument).
1908 * Note that this check might cause a symbol completion. Hence, this version of
1909 * setBounds may not be called during a classfile read.
1910 */
1911 public void setBounds(TypeVar t, List<Type> bounds) {
1912 Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?
1913 syms.objectType : null;
1914 setBounds(t, bounds, supertype);
1915 t.rank_field = -1;
1916 }
1917 // </editor-fold>
1919 // <editor-fold defaultstate="collapsed" desc="getBounds">
1920 /**
1921 * Return list of bounds of the given type variable.
1922 */
1923 public List<Type> getBounds(TypeVar t) {
1924 if (t.bound.isErroneous() || !t.bound.isCompound())
1925 return List.of(t.bound);
1926 else if ((erasure(t).tsym.flags() & INTERFACE) == 0)
1927 return interfaces(t).prepend(supertype(t));
1928 else
1929 // No superclass was given in bounds.
1930 // In this case, supertype is Object, erasure is first interface.
1931 return interfaces(t);
1932 }
1933 // </editor-fold>
1935 // <editor-fold defaultstate="collapsed" desc="classBound">
1936 /**
1937 * If the given type is a (possibly selected) type variable,
1938 * return the bounding class of this type, otherwise return the
1939 * type itself.
1940 */
1941 public Type classBound(Type t) {
1942 return classBound.visit(t);
1943 }
1944 // where
1945 private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() {
1947 public Type visitType(Type t, Void ignored) {
1948 return t;
1949 }
1951 @Override
1952 public Type visitClassType(ClassType t, Void ignored) {
1953 Type outer1 = classBound(t.getEnclosingType());
1954 if (outer1 != t.getEnclosingType())
1955 return new ClassType(outer1, t.getTypeArguments(), t.tsym);
1956 else
1957 return t;
1958 }
1960 @Override
1961 public Type visitTypeVar(TypeVar t, Void ignored) {
1962 return classBound(supertype(t));
1963 }
1965 @Override
1966 public Type visitErrorType(ErrorType t, Void ignored) {
1967 return t;
1968 }
1969 };
1970 // </editor-fold>
1972 // <editor-fold defaultstate="collapsed" desc="sub signature / override equivalence">
1973 /**
1974 * Returns true iff the first signature is a <em>sub
1975 * signature</em> of the other. This is <b>not</b> an equivalence
1976 * relation.
1977 *
1978 * @jls section 8.4.2.
1979 * @see #overrideEquivalent(Type t, Type s)
1980 * @param t first signature (possibly raw).
1981 * @param s second signature (could be subjected to erasure).
1982 * @return true if t is a sub signature of s.
1983 */
1984 public boolean isSubSignature(Type t, Type s) {
1985 return isSubSignature(t, s, true);
1986 }
1988 public boolean isSubSignature(Type t, Type s, boolean strict) {
1989 return hasSameArgs(t, s, strict) || hasSameArgs(t, erasure(s), strict);
1990 }
1992 /**
1993 * Returns true iff these signatures are related by <em>override
1994 * equivalence</em>. This is the natural extension of
1995 * isSubSignature to an equivalence relation.
1996 *
1997 * @jls section 8.4.2.
1998 * @see #isSubSignature(Type t, Type s)
1999 * @param t a signature (possible raw, could be subjected to
2000 * erasure).
2001 * @param s a signature (possible raw, could be subjected to
2002 * erasure).
2003 * @return true if either argument is a sub signature of the other.
2004 */
2005 public boolean overrideEquivalent(Type t, Type s) {
2006 return hasSameArgs(t, s) ||
2007 hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s);
2008 }
2010 // <editor-fold defaultstate="collapsed" desc="Determining method implementation in given site">
2011 class ImplementationCache {
2013 private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, Entry>>> _map =
2014 new WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, Entry>>>();
2016 class Entry {
2017 final MethodSymbol cachedImpl;
2018 final Filter<Symbol> implFilter;
2019 final boolean checkResult;
2020 final int prevMark;
2022 public Entry(MethodSymbol cachedImpl,
2023 Filter<Symbol> scopeFilter,
2024 boolean checkResult,
2025 int prevMark) {
2026 this.cachedImpl = cachedImpl;
2027 this.implFilter = scopeFilter;
2028 this.checkResult = checkResult;
2029 this.prevMark = prevMark;
2030 }
2032 boolean matches(Filter<Symbol> scopeFilter, boolean checkResult, int mark) {
2033 return this.implFilter == scopeFilter &&
2034 this.checkResult == checkResult &&
2035 this.prevMark == mark;
2036 }
2037 }
2039 MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
2040 SoftReference<Map<TypeSymbol, Entry>> ref_cache = _map.get(ms);
2041 Map<TypeSymbol, Entry> cache = ref_cache != null ? ref_cache.get() : null;
2042 if (cache == null) {
2043 cache = new HashMap<TypeSymbol, Entry>();
2044 _map.put(ms, new SoftReference<Map<TypeSymbol, Entry>>(cache));
2045 }
2046 Entry e = cache.get(origin);
2047 CompoundScope members = membersClosure(origin.type, true);
2048 if (e == null ||
2049 !e.matches(implFilter, checkResult, members.getMark())) {
2050 MethodSymbol impl = implementationInternal(ms, origin, checkResult, implFilter);
2051 cache.put(origin, new Entry(impl, implFilter, checkResult, members.getMark()));
2052 return impl;
2053 }
2054 else {
2055 return e.cachedImpl;
2056 }
2057 }
2059 private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
2060 for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = supertype(t)) {
2061 while (t.tag == TYPEVAR)
2062 t = t.getUpperBound();
2063 TypeSymbol c = t.tsym;
2064 for (Scope.Entry e = c.members().lookup(ms.name, implFilter);
2065 e.scope != null;
2066 e = e.next(implFilter)) {
2067 if (e.sym != null &&
2068 e.sym.overrides(ms, origin, Types.this, checkResult))
2069 return (MethodSymbol)e.sym;
2070 }
2071 }
2072 return null;
2073 }
2074 }
2076 private ImplementationCache implCache = new ImplementationCache();
2078 public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
2079 return implCache.get(ms, origin, checkResult, implFilter);
2080 }
2081 // </editor-fold>
2083 // <editor-fold defaultstate="collapsed" desc="compute transitive closure of all members in given site">
2084 class MembersClosureCache extends SimpleVisitor<CompoundScope, Boolean> {
2086 private WeakHashMap<TypeSymbol, Entry> _map =
2087 new WeakHashMap<TypeSymbol, Entry>();
2089 class Entry {
2090 final boolean skipInterfaces;
2091 final CompoundScope compoundScope;
2093 public Entry(boolean skipInterfaces, CompoundScope compoundScope) {
2094 this.skipInterfaces = skipInterfaces;
2095 this.compoundScope = compoundScope;
2096 }
2098 boolean matches(boolean skipInterfaces) {
2099 return this.skipInterfaces == skipInterfaces;
2100 }
2101 }
2103 List<TypeSymbol> seenTypes = List.nil();
2105 /** members closure visitor methods **/
2107 public CompoundScope visitType(Type t, Boolean skipInterface) {
2108 return null;
2109 }
2111 @Override
2112 public CompoundScope visitClassType(ClassType t, Boolean skipInterface) {
2113 if (seenTypes.contains(t.tsym)) {
2114 //this is possible when an interface is implemented in multiple
2115 //superclasses, or when a classs hierarchy is circular - in such
2116 //cases we don't need to recurse (empty scope is returned)
2117 return new CompoundScope(t.tsym);
2118 }
2119 try {
2120 seenTypes = seenTypes.prepend(t.tsym);
2121 ClassSymbol csym = (ClassSymbol)t.tsym;
2122 Entry e = _map.get(csym);
2123 if (e == null || !e.matches(skipInterface)) {
2124 CompoundScope membersClosure = new CompoundScope(csym);
2125 if (!skipInterface) {
2126 for (Type i : interfaces(t)) {
2127 membersClosure.addSubScope(visit(i, skipInterface));
2128 }
2129 }
2130 membersClosure.addSubScope(visit(supertype(t), skipInterface));
2131 membersClosure.addSubScope(csym.members());
2132 e = new Entry(skipInterface, membersClosure);
2133 _map.put(csym, e);
2134 }
2135 return e.compoundScope;
2136 }
2137 finally {
2138 seenTypes = seenTypes.tail;
2139 }
2140 }
2142 @Override
2143 public CompoundScope visitTypeVar(TypeVar t, Boolean skipInterface) {
2144 return visit(t.getUpperBound(), skipInterface);
2145 }
2146 }
2148 private MembersClosureCache membersCache = new MembersClosureCache();
2150 public CompoundScope membersClosure(Type site, boolean skipInterface) {
2151 return membersCache.visit(site, skipInterface);
2152 }
2153 // </editor-fold>
2155 /**
2156 * Does t have the same arguments as s? It is assumed that both
2157 * types are (possibly polymorphic) method types. Monomorphic
2158 * method types "have the same arguments", if their argument lists
2159 * are equal. Polymorphic method types "have the same arguments",
2160 * if they have the same arguments after renaming all type
2161 * variables of one to corresponding type variables in the other,
2162 * where correspondence is by position in the type parameter list.
2163 */
2164 public boolean hasSameArgs(Type t, Type s) {
2165 return hasSameArgs(t, s, true);
2166 }
2168 public boolean hasSameArgs(Type t, Type s, boolean strict) {
2169 return hasSameArgs(t, s, strict ? hasSameArgs_strict : hasSameArgs_nonstrict);
2170 }
2172 private boolean hasSameArgs(Type t, Type s, TypeRelation hasSameArgs) {
2173 return hasSameArgs.visit(t, s);
2174 }
2175 // where
2176 private class HasSameArgs extends TypeRelation {
2178 boolean strict;
2180 public HasSameArgs(boolean strict) {
2181 this.strict = strict;
2182 }
2184 public Boolean visitType(Type t, Type s) {
2185 throw new AssertionError();
2186 }
2188 @Override
2189 public Boolean visitMethodType(MethodType t, Type s) {
2190 return s.tag == METHOD
2191 && containsTypeEquivalent(t.argtypes, s.getParameterTypes());
2192 }
2194 @Override
2195 public Boolean visitForAll(ForAll t, Type s) {
2196 if (s.tag != FORALL)
2197 return strict ? false : visitMethodType(t.asMethodType(), s);
2199 ForAll forAll = (ForAll)s;
2200 return hasSameBounds(t, forAll)
2201 && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
2202 }
2204 @Override
2205 public Boolean visitErrorType(ErrorType t, Type s) {
2206 return false;
2207 }
2208 };
2210 TypeRelation hasSameArgs_strict = new HasSameArgs(true);
2211 TypeRelation hasSameArgs_nonstrict = new HasSameArgs(false);
2213 // </editor-fold>
2215 // <editor-fold defaultstate="collapsed" desc="subst">
2216 public List<Type> subst(List<Type> ts,
2217 List<Type> from,
2218 List<Type> to) {
2219 return new Subst(from, to).subst(ts);
2220 }
2222 /**
2223 * Substitute all occurrences of a type in `from' with the
2224 * corresponding type in `to' in 't'. Match lists `from' and `to'
2225 * from the right: If lists have different length, discard leading
2226 * elements of the longer list.
2227 */
2228 public Type subst(Type t, List<Type> from, List<Type> to) {
2229 return new Subst(from, to).subst(t);
2230 }
2232 private class Subst extends UnaryVisitor<Type> {
2233 List<Type> from;
2234 List<Type> to;
2236 public Subst(List<Type> from, List<Type> to) {
2237 int fromLength = from.length();
2238 int toLength = to.length();
2239 while (fromLength > toLength) {
2240 fromLength--;
2241 from = from.tail;
2242 }
2243 while (fromLength < toLength) {
2244 toLength--;
2245 to = to.tail;
2246 }
2247 this.from = from;
2248 this.to = to;
2249 }
2251 Type subst(Type t) {
2252 if (from.tail == null)
2253 return t;
2254 else
2255 return visit(t);
2256 }
2258 List<Type> subst(List<Type> ts) {
2259 if (from.tail == null)
2260 return ts;
2261 boolean wild = false;
2262 if (ts.nonEmpty() && from.nonEmpty()) {
2263 Type head1 = subst(ts.head);
2264 List<Type> tail1 = subst(ts.tail);
2265 if (head1 != ts.head || tail1 != ts.tail)
2266 return tail1.prepend(head1);
2267 }
2268 return ts;
2269 }
2271 public Type visitType(Type t, Void ignored) {
2272 return t;
2273 }
2275 @Override
2276 public Type visitMethodType(MethodType t, Void ignored) {
2277 List<Type> argtypes = subst(t.argtypes);
2278 Type restype = subst(t.restype);
2279 List<Type> thrown = subst(t.thrown);
2280 if (argtypes == t.argtypes &&
2281 restype == t.restype &&
2282 thrown == t.thrown)
2283 return t;
2284 else
2285 return new MethodType(argtypes, restype, thrown, t.tsym);
2286 }
2288 @Override
2289 public Type visitTypeVar(TypeVar t, Void ignored) {
2290 for (List<Type> from = this.from, to = this.to;
2291 from.nonEmpty();
2292 from = from.tail, to = to.tail) {
2293 if (t == from.head) {
2294 return to.head.withTypeVar(t);
2295 }
2296 }
2297 return t;
2298 }
2300 @Override
2301 public Type visitClassType(ClassType t, Void ignored) {
2302 if (!t.isCompound()) {
2303 List<Type> typarams = t.getTypeArguments();
2304 List<Type> typarams1 = subst(typarams);
2305 Type outer = t.getEnclosingType();
2306 Type outer1 = subst(outer);
2307 if (typarams1 == typarams && outer1 == outer)
2308 return t;
2309 else
2310 return new ClassType(outer1, typarams1, t.tsym);
2311 } else {
2312 Type st = subst(supertype(t));
2313 List<Type> is = upperBounds(subst(interfaces(t)));
2314 if (st == supertype(t) && is == interfaces(t))
2315 return t;
2316 else
2317 return makeCompoundType(is.prepend(st));
2318 }
2319 }
2321 @Override
2322 public Type visitWildcardType(WildcardType t, Void ignored) {
2323 Type bound = t.type;
2324 if (t.kind != BoundKind.UNBOUND)
2325 bound = subst(bound);
2326 if (bound == t.type) {
2327 return t;
2328 } else {
2329 if (t.isExtendsBound() && bound.isExtendsBound())
2330 bound = upperBound(bound);
2331 return new WildcardType(bound, t.kind, syms.boundClass, t.bound);
2332 }
2333 }
2335 @Override
2336 public Type visitArrayType(ArrayType t, Void ignored) {
2337 Type elemtype = subst(t.elemtype);
2338 if (elemtype == t.elemtype)
2339 return t;
2340 else
2341 return new ArrayType(upperBound(elemtype), t.tsym);
2342 }
2344 @Override
2345 public Type visitForAll(ForAll t, Void ignored) {
2346 if (Type.containsAny(to, t.tvars)) {
2347 //perform alpha-renaming of free-variables in 't'
2348 //if 'to' types contain variables that are free in 't'
2349 List<Type> freevars = newInstances(t.tvars);
2350 t = new ForAll(freevars,
2351 Types.this.subst(t.qtype, t.tvars, freevars));
2352 }
2353 List<Type> tvars1 = substBounds(t.tvars, from, to);
2354 Type qtype1 = subst(t.qtype);
2355 if (tvars1 == t.tvars && qtype1 == t.qtype) {
2356 return t;
2357 } else if (tvars1 == t.tvars) {
2358 return new ForAll(tvars1, qtype1);
2359 } else {
2360 return new ForAll(tvars1, Types.this.subst(qtype1, t.tvars, tvars1));
2361 }
2362 }
2364 @Override
2365 public Type visitErrorType(ErrorType t, Void ignored) {
2366 return t;
2367 }
2368 }
2370 public List<Type> substBounds(List<Type> tvars,
2371 List<Type> from,
2372 List<Type> to) {
2373 if (tvars.isEmpty())
2374 return tvars;
2375 ListBuffer<Type> newBoundsBuf = lb();
2376 boolean changed = false;
2377 // calculate new bounds
2378 for (Type t : tvars) {
2379 TypeVar tv = (TypeVar) t;
2380 Type bound = subst(tv.bound, from, to);
2381 if (bound != tv.bound)
2382 changed = true;
2383 newBoundsBuf.append(bound);
2384 }
2385 if (!changed)
2386 return tvars;
2387 ListBuffer<Type> newTvars = lb();
2388 // create new type variables without bounds
2389 for (Type t : tvars) {
2390 newTvars.append(new TypeVar(t.tsym, null, syms.botType));
2391 }
2392 // the new bounds should use the new type variables in place
2393 // of the old
2394 List<Type> newBounds = newBoundsBuf.toList();
2395 from = tvars;
2396 to = newTvars.toList();
2397 for (; !newBounds.isEmpty(); newBounds = newBounds.tail) {
2398 newBounds.head = subst(newBounds.head, from, to);
2399 }
2400 newBounds = newBoundsBuf.toList();
2401 // set the bounds of new type variables to the new bounds
2402 for (Type t : newTvars.toList()) {
2403 TypeVar tv = (TypeVar) t;
2404 tv.bound = newBounds.head;
2405 newBounds = newBounds.tail;
2406 }
2407 return newTvars.toList();
2408 }
2410 public TypeVar substBound(TypeVar t, List<Type> from, List<Type> to) {
2411 Type bound1 = subst(t.bound, from, to);
2412 if (bound1 == t.bound)
2413 return t;
2414 else {
2415 // create new type variable without bounds
2416 TypeVar tv = new TypeVar(t.tsym, null, syms.botType);
2417 // the new bound should use the new type variable in place
2418 // of the old
2419 tv.bound = subst(bound1, List.<Type>of(t), List.<Type>of(tv));
2420 return tv;
2421 }
2422 }
2423 // </editor-fold>
2425 // <editor-fold defaultstate="collapsed" desc="hasSameBounds">
2426 /**
2427 * Does t have the same bounds for quantified variables as s?
2428 */
2429 boolean hasSameBounds(ForAll t, ForAll s) {
2430 List<Type> l1 = t.tvars;
2431 List<Type> l2 = s.tvars;
2432 while (l1.nonEmpty() && l2.nonEmpty() &&
2433 isSameType(l1.head.getUpperBound(),
2434 subst(l2.head.getUpperBound(),
2435 s.tvars,
2436 t.tvars))) {
2437 l1 = l1.tail;
2438 l2 = l2.tail;
2439 }
2440 return l1.isEmpty() && l2.isEmpty();
2441 }
2442 // </editor-fold>
2444 // <editor-fold defaultstate="collapsed" desc="newInstances">
2445 /** Create new vector of type variables from list of variables
2446 * changing all recursive bounds from old to new list.
2447 */
2448 public List<Type> newInstances(List<Type> tvars) {
2449 List<Type> tvars1 = Type.map(tvars, newInstanceFun);
2450 for (List<Type> l = tvars1; l.nonEmpty(); l = l.tail) {
2451 TypeVar tv = (TypeVar) l.head;
2452 tv.bound = subst(tv.bound, tvars, tvars1);
2453 }
2454 return tvars1;
2455 }
2456 static private Mapping newInstanceFun = new Mapping("newInstanceFun") {
2457 public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound()); }
2458 };
2459 // </editor-fold>
2461 public Type createMethodTypeWithParameters(Type original, List<Type> newParams) {
2462 return original.accept(methodWithParameters, newParams);
2463 }
2464 // where
2465 private final MapVisitor<List<Type>> methodWithParameters = new MapVisitor<List<Type>>() {
2466 public Type visitType(Type t, List<Type> newParams) {
2467 throw new IllegalArgumentException("Not a method type: " + t);
2468 }
2469 public Type visitMethodType(MethodType t, List<Type> newParams) {
2470 return new MethodType(newParams, t.restype, t.thrown, t.tsym);
2471 }
2472 public Type visitForAll(ForAll t, List<Type> newParams) {
2473 return new ForAll(t.tvars, t.qtype.accept(this, newParams));
2474 }
2475 };
2477 public Type createMethodTypeWithThrown(Type original, List<Type> newThrown) {
2478 return original.accept(methodWithThrown, newThrown);
2479 }
2480 // where
2481 private final MapVisitor<List<Type>> methodWithThrown = new MapVisitor<List<Type>>() {
2482 public Type visitType(Type t, List<Type> newThrown) {
2483 throw new IllegalArgumentException("Not a method type: " + t);
2484 }
2485 public Type visitMethodType(MethodType t, List<Type> newThrown) {
2486 return new MethodType(t.argtypes, t.restype, newThrown, t.tsym);
2487 }
2488 public Type visitForAll(ForAll t, List<Type> newThrown) {
2489 return new ForAll(t.tvars, t.qtype.accept(this, newThrown));
2490 }
2491 };
2493 public Type createMethodTypeWithReturn(Type original, Type newReturn) {
2494 return original.accept(methodWithReturn, newReturn);
2495 }
2496 // where
2497 private final MapVisitor<Type> methodWithReturn = new MapVisitor<Type>() {
2498 public Type visitType(Type t, Type newReturn) {
2499 throw new IllegalArgumentException("Not a method type: " + t);
2500 }
2501 public Type visitMethodType(MethodType t, Type newReturn) {
2502 return new MethodType(t.argtypes, newReturn, t.thrown, t.tsym);
2503 }
2504 public Type visitForAll(ForAll t, Type newReturn) {
2505 return new ForAll(t.tvars, t.qtype.accept(this, newReturn));
2506 }
2507 };
2509 // <editor-fold defaultstate="collapsed" desc="createErrorType">
2510 public Type createErrorType(Type originalType) {
2511 return new ErrorType(originalType, syms.errSymbol);
2512 }
2514 public Type createErrorType(ClassSymbol c, Type originalType) {
2515 return new ErrorType(c, originalType);
2516 }
2518 public Type createErrorType(Name name, TypeSymbol container, Type originalType) {
2519 return new ErrorType(name, container, originalType);
2520 }
2521 // </editor-fold>
2523 // <editor-fold defaultstate="collapsed" desc="rank">
2524 /**
2525 * The rank of a class is the length of the longest path between
2526 * the class and java.lang.Object in the class inheritance
2527 * graph. Undefined for all but reference types.
2528 */
2529 public int rank(Type t) {
2530 switch(t.tag) {
2531 case CLASS: {
2532 ClassType cls = (ClassType)t;
2533 if (cls.rank_field < 0) {
2534 Name fullname = cls.tsym.getQualifiedName();
2535 if (fullname == names.java_lang_Object)
2536 cls.rank_field = 0;
2537 else {
2538 int r = rank(supertype(cls));
2539 for (List<Type> l = interfaces(cls);
2540 l.nonEmpty();
2541 l = l.tail) {
2542 if (rank(l.head) > r)
2543 r = rank(l.head);
2544 }
2545 cls.rank_field = r + 1;
2546 }
2547 }
2548 return cls.rank_field;
2549 }
2550 case TYPEVAR: {
2551 TypeVar tvar = (TypeVar)t;
2552 if (tvar.rank_field < 0) {
2553 int r = rank(supertype(tvar));
2554 for (List<Type> l = interfaces(tvar);
2555 l.nonEmpty();
2556 l = l.tail) {
2557 if (rank(l.head) > r) r = rank(l.head);
2558 }
2559 tvar.rank_field = r + 1;
2560 }
2561 return tvar.rank_field;
2562 }
2563 case ERROR:
2564 return 0;
2565 default:
2566 throw new AssertionError();
2567 }
2568 }
2569 // </editor-fold>
2571 /**
2572 * Helper method for generating a string representation of a given type
2573 * accordingly to a given locale
2574 */
2575 public String toString(Type t, Locale locale) {
2576 return Printer.createStandardPrinter(messages).visit(t, locale);
2577 }
2579 /**
2580 * Helper method for generating a string representation of a given type
2581 * accordingly to a given locale
2582 */
2583 public String toString(Symbol t, Locale locale) {
2584 return Printer.createStandardPrinter(messages).visit(t, locale);
2585 }
2587 // <editor-fold defaultstate="collapsed" desc="toString">
2588 /**
2589 * This toString is slightly more descriptive than the one on Type.
2590 *
2591 * @deprecated Types.toString(Type t, Locale l) provides better support
2592 * for localization
2593 */
2594 @Deprecated
2595 public String toString(Type t) {
2596 if (t.tag == FORALL) {
2597 ForAll forAll = (ForAll)t;
2598 return typaramsString(forAll.tvars) + forAll.qtype;
2599 }
2600 return "" + t;
2601 }
2602 // where
2603 private String typaramsString(List<Type> tvars) {
2604 StringBuilder s = new StringBuilder();
2605 s.append('<');
2606 boolean first = true;
2607 for (Type t : tvars) {
2608 if (!first) s.append(", ");
2609 first = false;
2610 appendTyparamString(((TypeVar)t), s);
2611 }
2612 s.append('>');
2613 return s.toString();
2614 }
2615 private void appendTyparamString(TypeVar t, StringBuilder buf) {
2616 buf.append(t);
2617 if (t.bound == null ||
2618 t.bound.tsym.getQualifiedName() == names.java_lang_Object)
2619 return;
2620 buf.append(" extends "); // Java syntax; no need for i18n
2621 Type bound = t.bound;
2622 if (!bound.isCompound()) {
2623 buf.append(bound);
2624 } else if ((erasure(t).tsym.flags() & INTERFACE) == 0) {
2625 buf.append(supertype(t));
2626 for (Type intf : interfaces(t)) {
2627 buf.append('&');
2628 buf.append(intf);
2629 }
2630 } else {
2631 // No superclass was given in bounds.
2632 // In this case, supertype is Object, erasure is first interface.
2633 boolean first = true;
2634 for (Type intf : interfaces(t)) {
2635 if (!first) buf.append('&');
2636 first = false;
2637 buf.append(intf);
2638 }
2639 }
2640 }
2641 // </editor-fold>
2643 // <editor-fold defaultstate="collapsed" desc="Determining least upper bounds of types">
2644 /**
2645 * A cache for closures.
2646 *
2647 * <p>A closure is a list of all the supertypes and interfaces of
2648 * a class or interface type, ordered by ClassSymbol.precedes
2649 * (that is, subclasses come first, arbitrary but fixed
2650 * otherwise).
2651 */
2652 private Map<Type,List<Type>> closureCache = new HashMap<Type,List<Type>>();
2654 /**
2655 * Returns the closure of a class or interface type.
2656 */
2657 public List<Type> closure(Type t) {
2658 List<Type> cl = closureCache.get(t);
2659 if (cl == null) {
2660 Type st = supertype(t);
2661 if (!t.isCompound()) {
2662 if (st.tag == CLASS) {
2663 cl = insert(closure(st), t);
2664 } else if (st.tag == TYPEVAR) {
2665 cl = closure(st).prepend(t);
2666 } else {
2667 cl = List.of(t);
2668 }
2669 } else {
2670 cl = closure(supertype(t));
2671 }
2672 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail)
2673 cl = union(cl, closure(l.head));
2674 closureCache.put(t, cl);
2675 }
2676 return cl;
2677 }
2679 /**
2680 * Insert a type in a closure
2681 */
2682 public List<Type> insert(List<Type> cl, Type t) {
2683 if (cl.isEmpty() || t.tsym.precedes(cl.head.tsym, this)) {
2684 return cl.prepend(t);
2685 } else if (cl.head.tsym.precedes(t.tsym, this)) {
2686 return insert(cl.tail, t).prepend(cl.head);
2687 } else {
2688 return cl;
2689 }
2690 }
2692 /**
2693 * Form the union of two closures
2694 */
2695 public List<Type> union(List<Type> cl1, List<Type> cl2) {
2696 if (cl1.isEmpty()) {
2697 return cl2;
2698 } else if (cl2.isEmpty()) {
2699 return cl1;
2700 } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) {
2701 return union(cl1.tail, cl2).prepend(cl1.head);
2702 } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) {
2703 return union(cl1, cl2.tail).prepend(cl2.head);
2704 } else {
2705 return union(cl1.tail, cl2.tail).prepend(cl1.head);
2706 }
2707 }
2709 /**
2710 * Intersect two closures
2711 */
2712 public List<Type> intersect(List<Type> cl1, List<Type> cl2) {
2713 if (cl1 == cl2)
2714 return cl1;
2715 if (cl1.isEmpty() || cl2.isEmpty())
2716 return List.nil();
2717 if (cl1.head.tsym.precedes(cl2.head.tsym, this))
2718 return intersect(cl1.tail, cl2);
2719 if (cl2.head.tsym.precedes(cl1.head.tsym, this))
2720 return intersect(cl1, cl2.tail);
2721 if (isSameType(cl1.head, cl2.head))
2722 return intersect(cl1.tail, cl2.tail).prepend(cl1.head);
2723 if (cl1.head.tsym == cl2.head.tsym &&
2724 cl1.head.tag == CLASS && cl2.head.tag == CLASS) {
2725 if (cl1.head.isParameterized() && cl2.head.isParameterized()) {
2726 Type merge = merge(cl1.head,cl2.head);
2727 return intersect(cl1.tail, cl2.tail).prepend(merge);
2728 }
2729 if (cl1.head.isRaw() || cl2.head.isRaw())
2730 return intersect(cl1.tail, cl2.tail).prepend(erasure(cl1.head));
2731 }
2732 return intersect(cl1.tail, cl2.tail);
2733 }
2734 // where
2735 class TypePair {
2736 final Type t1;
2737 final Type t2;
2738 TypePair(Type t1, Type t2) {
2739 this.t1 = t1;
2740 this.t2 = t2;
2741 }
2742 @Override
2743 public int hashCode() {
2744 return 127 * Types.hashCode(t1) + Types.hashCode(t2);
2745 }
2746 @Override
2747 public boolean equals(Object obj) {
2748 if (!(obj instanceof TypePair))
2749 return false;
2750 TypePair typePair = (TypePair)obj;
2751 return isSameType(t1, typePair.t1)
2752 && isSameType(t2, typePair.t2);
2753 }
2754 }
2755 Set<TypePair> mergeCache = new HashSet<TypePair>();
2756 private Type merge(Type c1, Type c2) {
2757 ClassType class1 = (ClassType) c1;
2758 List<Type> act1 = class1.getTypeArguments();
2759 ClassType class2 = (ClassType) c2;
2760 List<Type> act2 = class2.getTypeArguments();
2761 ListBuffer<Type> merged = new ListBuffer<Type>();
2762 List<Type> typarams = class1.tsym.type.getTypeArguments();
2764 while (act1.nonEmpty() && act2.nonEmpty() && typarams.nonEmpty()) {
2765 if (containsType(act1.head, act2.head)) {
2766 merged.append(act1.head);
2767 } else if (containsType(act2.head, act1.head)) {
2768 merged.append(act2.head);
2769 } else {
2770 TypePair pair = new TypePair(c1, c2);
2771 Type m;
2772 if (mergeCache.add(pair)) {
2773 m = new WildcardType(lub(upperBound(act1.head),
2774 upperBound(act2.head)),
2775 BoundKind.EXTENDS,
2776 syms.boundClass);
2777 mergeCache.remove(pair);
2778 } else {
2779 m = new WildcardType(syms.objectType,
2780 BoundKind.UNBOUND,
2781 syms.boundClass);
2782 }
2783 merged.append(m.withTypeVar(typarams.head));
2784 }
2785 act1 = act1.tail;
2786 act2 = act2.tail;
2787 typarams = typarams.tail;
2788 }
2789 Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
2790 return new ClassType(class1.getEnclosingType(), merged.toList(), class1.tsym);
2791 }
2793 /**
2794 * Return the minimum type of a closure, a compound type if no
2795 * unique minimum exists.
2796 */
2797 private Type compoundMin(List<Type> cl) {
2798 if (cl.isEmpty()) return syms.objectType;
2799 List<Type> compound = closureMin(cl);
2800 if (compound.isEmpty())
2801 return null;
2802 else if (compound.tail.isEmpty())
2803 return compound.head;
2804 else
2805 return makeCompoundType(compound);
2806 }
2808 /**
2809 * Return the minimum types of a closure, suitable for computing
2810 * compoundMin or glb.
2811 */
2812 private List<Type> closureMin(List<Type> cl) {
2813 ListBuffer<Type> classes = lb();
2814 ListBuffer<Type> interfaces = lb();
2815 while (!cl.isEmpty()) {
2816 Type current = cl.head;
2817 if (current.isInterface())
2818 interfaces.append(current);
2819 else
2820 classes.append(current);
2821 ListBuffer<Type> candidates = lb();
2822 for (Type t : cl.tail) {
2823 if (!isSubtypeNoCapture(current, t))
2824 candidates.append(t);
2825 }
2826 cl = candidates.toList();
2827 }
2828 return classes.appendList(interfaces).toList();
2829 }
2831 /**
2832 * Return the least upper bound of pair of types. if the lub does
2833 * not exist return null.
2834 */
2835 public Type lub(Type t1, Type t2) {
2836 return lub(List.of(t1, t2));
2837 }
2839 /**
2840 * Return the least upper bound (lub) of set of types. If the lub
2841 * does not exist return the type of null (bottom).
2842 */
2843 public Type lub(List<Type> ts) {
2844 final int ARRAY_BOUND = 1;
2845 final int CLASS_BOUND = 2;
2846 int boundkind = 0;
2847 for (Type t : ts) {
2848 switch (t.tag) {
2849 case CLASS:
2850 boundkind |= CLASS_BOUND;
2851 break;
2852 case ARRAY:
2853 boundkind |= ARRAY_BOUND;
2854 break;
2855 case TYPEVAR:
2856 do {
2857 t = t.getUpperBound();
2858 } while (t.tag == TYPEVAR);
2859 if (t.tag == ARRAY) {
2860 boundkind |= ARRAY_BOUND;
2861 } else {
2862 boundkind |= CLASS_BOUND;
2863 }
2864 break;
2865 default:
2866 if (t.isPrimitive())
2867 return syms.errType;
2868 }
2869 }
2870 switch (boundkind) {
2871 case 0:
2872 return syms.botType;
2874 case ARRAY_BOUND:
2875 // calculate lub(A[], B[])
2876 List<Type> elements = Type.map(ts, elemTypeFun);
2877 for (Type t : elements) {
2878 if (t.isPrimitive()) {
2879 // if a primitive type is found, then return
2880 // arraySuperType unless all the types are the
2881 // same
2882 Type first = ts.head;
2883 for (Type s : ts.tail) {
2884 if (!isSameType(first, s)) {
2885 // lub(int[], B[]) is Cloneable & Serializable
2886 return arraySuperType();
2887 }
2888 }
2889 // all the array types are the same, return one
2890 // lub(int[], int[]) is int[]
2891 return first;
2892 }
2893 }
2894 // lub(A[], B[]) is lub(A, B)[]
2895 return new ArrayType(lub(elements), syms.arrayClass);
2897 case CLASS_BOUND:
2898 // calculate lub(A, B)
2899 while (ts.head.tag != CLASS && ts.head.tag != TYPEVAR)
2900 ts = ts.tail;
2901 Assert.check(!ts.isEmpty());
2902 //step 1 - compute erased candidate set (EC)
2903 List<Type> cl = erasedSupertypes(ts.head);
2904 for (Type t : ts.tail) {
2905 if (t.tag == CLASS || t.tag == TYPEVAR)
2906 cl = intersect(cl, erasedSupertypes(t));
2907 }
2908 //step 2 - compute minimal erased candidate set (MEC)
2909 List<Type> mec = closureMin(cl);
2910 //step 3 - for each element G in MEC, compute lci(Inv(G))
2911 List<Type> candidates = List.nil();
2912 for (Type erasedSupertype : mec) {
2913 List<Type> lci = List.of(asSuper(ts.head, erasedSupertype.tsym));
2914 for (Type t : ts) {
2915 lci = intersect(lci, List.of(asSuper(t, erasedSupertype.tsym)));
2916 }
2917 candidates = candidates.appendList(lci);
2918 }
2919 //step 4 - let MEC be { G1, G2 ... Gn }, then we have that
2920 //lub = lci(Inv(G1)) & lci(Inv(G2)) & ... & lci(Inv(Gn))
2921 return compoundMin(candidates);
2923 default:
2924 // calculate lub(A, B[])
2925 List<Type> classes = List.of(arraySuperType());
2926 for (Type t : ts) {
2927 if (t.tag != ARRAY) // Filter out any arrays
2928 classes = classes.prepend(t);
2929 }
2930 // lub(A, B[]) is lub(A, arraySuperType)
2931 return lub(classes);
2932 }
2933 }
2934 // where
2935 List<Type> erasedSupertypes(Type t) {
2936 ListBuffer<Type> buf = lb();
2937 for (Type sup : closure(t)) {
2938 if (sup.tag == TYPEVAR) {
2939 buf.append(sup);
2940 } else {
2941 buf.append(erasure(sup));
2942 }
2943 }
2944 return buf.toList();
2945 }
2947 private Type arraySuperType = null;
2948 private Type arraySuperType() {
2949 // initialized lazily to avoid problems during compiler startup
2950 if (arraySuperType == null) {
2951 synchronized (this) {
2952 if (arraySuperType == null) {
2953 // JLS 10.8: all arrays implement Cloneable and Serializable.
2954 arraySuperType = makeCompoundType(List.of(syms.serializableType,
2955 syms.cloneableType),
2956 syms.objectType);
2957 }
2958 }
2959 }
2960 return arraySuperType;
2961 }
2962 // </editor-fold>
2964 // <editor-fold defaultstate="collapsed" desc="Greatest lower bound">
2965 public Type glb(List<Type> ts) {
2966 Type t1 = ts.head;
2967 for (Type t2 : ts.tail) {
2968 if (t1.isErroneous())
2969 return t1;
2970 t1 = glb(t1, t2);
2971 }
2972 return t1;
2973 }
2974 //where
2975 public Type glb(Type t, Type s) {
2976 if (s == null)
2977 return t;
2978 else if (t.isPrimitive() || s.isPrimitive())
2979 return syms.errType;
2980 else if (isSubtypeNoCapture(t, s))
2981 return t;
2982 else if (isSubtypeNoCapture(s, t))
2983 return s;
2985 List<Type> closure = union(closure(t), closure(s));
2986 List<Type> bounds = closureMin(closure);
2988 if (bounds.isEmpty()) { // length == 0
2989 return syms.objectType;
2990 } else if (bounds.tail.isEmpty()) { // length == 1
2991 return bounds.head;
2992 } else { // length > 1
2993 int classCount = 0;
2994 for (Type bound : bounds)
2995 if (!bound.isInterface())
2996 classCount++;
2997 if (classCount > 1)
2998 return createErrorType(t);
2999 }
3000 return makeCompoundType(bounds);
3001 }
3002 // </editor-fold>
3004 // <editor-fold defaultstate="collapsed" desc="hashCode">
3005 /**
3006 * Compute a hash code on a type.
3007 */
3008 public static int hashCode(Type t) {
3009 return hashCode.visit(t);
3010 }
3011 // where
3012 private static final UnaryVisitor<Integer> hashCode = new UnaryVisitor<Integer>() {
3014 public Integer visitType(Type t, Void ignored) {
3015 return t.tag;
3016 }
3018 @Override
3019 public Integer visitClassType(ClassType t, Void ignored) {
3020 int result = visit(t.getEnclosingType());
3021 result *= 127;
3022 result += t.tsym.flatName().hashCode();
3023 for (Type s : t.getTypeArguments()) {
3024 result *= 127;
3025 result += visit(s);
3026 }
3027 return result;
3028 }
3030 @Override
3031 public Integer visitWildcardType(WildcardType t, Void ignored) {
3032 int result = t.kind.hashCode();
3033 if (t.type != null) {
3034 result *= 127;
3035 result += visit(t.type);
3036 }
3037 return result;
3038 }
3040 @Override
3041 public Integer visitArrayType(ArrayType t, Void ignored) {
3042 return visit(t.elemtype) + 12;
3043 }
3045 @Override
3046 public Integer visitTypeVar(TypeVar t, Void ignored) {
3047 return System.identityHashCode(t.tsym);
3048 }
3050 @Override
3051 public Integer visitUndetVar(UndetVar t, Void ignored) {
3052 return System.identityHashCode(t);
3053 }
3055 @Override
3056 public Integer visitErrorType(ErrorType t, Void ignored) {
3057 return 0;
3058 }
3059 };
3060 // </editor-fold>
3062 // <editor-fold defaultstate="collapsed" desc="Return-Type-Substitutable">
3063 /**
3064 * Does t have a result that is a subtype of the result type of s,
3065 * suitable for covariant returns? It is assumed that both types
3066 * are (possibly polymorphic) method types. Monomorphic method
3067 * types are handled in the obvious way. Polymorphic method types
3068 * require renaming all type variables of one to corresponding
3069 * type variables in the other, where correspondence is by
3070 * position in the type parameter list. */
3071 public boolean resultSubtype(Type t, Type s, Warner warner) {
3072 List<Type> tvars = t.getTypeArguments();
3073 List<Type> svars = s.getTypeArguments();
3074 Type tres = t.getReturnType();
3075 Type sres = subst(s.getReturnType(), svars, tvars);
3076 return covariantReturnType(tres, sres, warner);
3077 }
3079 /**
3080 * Return-Type-Substitutable.
3081 * @jls section 8.4.5
3082 */
3083 public boolean returnTypeSubstitutable(Type r1, Type r2) {
3084 if (hasSameArgs(r1, r2))
3085 return resultSubtype(r1, r2, Warner.noWarnings);
3086 else
3087 return covariantReturnType(r1.getReturnType(),
3088 erasure(r2.getReturnType()),
3089 Warner.noWarnings);
3090 }
3092 public boolean returnTypeSubstitutable(Type r1,
3093 Type r2, Type r2res,
3094 Warner warner) {
3095 if (isSameType(r1.getReturnType(), r2res))
3096 return true;
3097 if (r1.getReturnType().isPrimitive() || r2res.isPrimitive())
3098 return false;
3100 if (hasSameArgs(r1, r2))
3101 return covariantReturnType(r1.getReturnType(), r2res, warner);
3102 if (!allowCovariantReturns)
3103 return false;
3104 if (isSubtypeUnchecked(r1.getReturnType(), r2res, warner))
3105 return true;
3106 if (!isSubtype(r1.getReturnType(), erasure(r2res)))
3107 return false;
3108 warner.warn(LintCategory.UNCHECKED);
3109 return true;
3110 }
3112 /**
3113 * Is t an appropriate return type in an overrider for a
3114 * method that returns s?
3115 */
3116 public boolean covariantReturnType(Type t, Type s, Warner warner) {
3117 return
3118 isSameType(t, s) ||
3119 allowCovariantReturns &&
3120 !t.isPrimitive() &&
3121 !s.isPrimitive() &&
3122 isAssignable(t, s, warner);
3123 }
3124 // </editor-fold>
3126 // <editor-fold defaultstate="collapsed" desc="Box/unbox support">
3127 /**
3128 * Return the class that boxes the given primitive.
3129 */
3130 public ClassSymbol boxedClass(Type t) {
3131 return reader.enterClass(syms.boxedName[t.tag]);
3132 }
3134 /**
3135 * Return the boxed type if 't' is primitive, otherwise return 't' itself.
3136 */
3137 public Type boxedTypeOrType(Type t) {
3138 return t.isPrimitive() ?
3139 boxedClass(t).type :
3140 t;
3141 }
3143 /**
3144 * Return the primitive type corresponding to a boxed type.
3145 */
3146 public Type unboxedType(Type t) {
3147 if (allowBoxing) {
3148 for (int i=0; i<syms.boxedName.length; i++) {
3149 Name box = syms.boxedName[i];
3150 if (box != null &&
3151 asSuper(t, reader.enterClass(box)) != null)
3152 return syms.typeOfTag[i];
3153 }
3154 }
3155 return Type.noType;
3156 }
3157 // </editor-fold>
3159 // <editor-fold defaultstate="collapsed" desc="Capture conversion">
3160 /*
3161 * JLS 5.1.10 Capture Conversion:
3162 *
3163 * Let G name a generic type declaration with n formal type
3164 * parameters A1 ... An with corresponding bounds U1 ... Un. There
3165 * exists a capture conversion from G<T1 ... Tn> to G<S1 ... Sn>,
3166 * where, for 1 <= i <= n:
3167 *
3168 * + If Ti is a wildcard type argument (4.5.1) of the form ? then
3169 * Si is a fresh type variable whose upper bound is
3170 * Ui[A1 := S1, ..., An := Sn] and whose lower bound is the null
3171 * type.
3172 *
3173 * + If Ti is a wildcard type argument of the form ? extends Bi,
3174 * then Si is a fresh type variable whose upper bound is
3175 * glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is
3176 * the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is
3177 * a compile-time error if for any two classes (not interfaces)
3178 * Vi and Vj,Vi is not a subclass of Vj or vice versa.
3179 *
3180 * + If Ti is a wildcard type argument of the form ? super Bi,
3181 * then Si is a fresh type variable whose upper bound is
3182 * Ui[A1 := S1, ..., An := Sn] and whose lower bound is Bi.
3183 *
3184 * + Otherwise, Si = Ti.
3185 *
3186 * Capture conversion on any type other than a parameterized type
3187 * (4.5) acts as an identity conversion (5.1.1). Capture
3188 * conversions never require a special action at run time and
3189 * therefore never throw an exception at run time.
3190 *
3191 * Capture conversion is not applied recursively.
3192 */
3193 /**
3194 * Capture conversion as specified by the JLS.
3195 */
3197 public List<Type> capture(List<Type> ts) {
3198 List<Type> buf = List.nil();
3199 for (Type t : ts) {
3200 buf = buf.prepend(capture(t));
3201 }
3202 return buf.reverse();
3203 }
3204 public Type capture(Type t) {
3205 if (t.tag != CLASS)
3206 return t;
3207 if (t.getEnclosingType() != Type.noType) {
3208 Type capturedEncl = capture(t.getEnclosingType());
3209 if (capturedEncl != t.getEnclosingType()) {
3210 Type type1 = memberType(capturedEncl, t.tsym);
3211 t = subst(type1, t.tsym.type.getTypeArguments(), t.getTypeArguments());
3212 }
3213 }
3214 ClassType cls = (ClassType)t;
3215 if (cls.isRaw() || !cls.isParameterized())
3216 return cls;
3218 ClassType G = (ClassType)cls.asElement().asType();
3219 List<Type> A = G.getTypeArguments();
3220 List<Type> T = cls.getTypeArguments();
3221 List<Type> S = freshTypeVariables(T);
3223 List<Type> currentA = A;
3224 List<Type> currentT = T;
3225 List<Type> currentS = S;
3226 boolean captured = false;
3227 while (!currentA.isEmpty() &&
3228 !currentT.isEmpty() &&
3229 !currentS.isEmpty()) {
3230 if (currentS.head != currentT.head) {
3231 captured = true;
3232 WildcardType Ti = (WildcardType)currentT.head;
3233 Type Ui = currentA.head.getUpperBound();
3234 CapturedType Si = (CapturedType)currentS.head;
3235 if (Ui == null)
3236 Ui = syms.objectType;
3237 switch (Ti.kind) {
3238 case UNBOUND:
3239 Si.bound = subst(Ui, A, S);
3240 Si.lower = syms.botType;
3241 break;
3242 case EXTENDS:
3243 Si.bound = glb(Ti.getExtendsBound(), subst(Ui, A, S));
3244 Si.lower = syms.botType;
3245 break;
3246 case SUPER:
3247 Si.bound = subst(Ui, A, S);
3248 Si.lower = Ti.getSuperBound();
3249 break;
3250 }
3251 if (Si.bound == Si.lower)
3252 currentS.head = Si.bound;
3253 }
3254 currentA = currentA.tail;
3255 currentT = currentT.tail;
3256 currentS = currentS.tail;
3257 }
3258 if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty())
3259 return erasure(t); // some "rare" type involved
3261 if (captured)
3262 return new ClassType(cls.getEnclosingType(), S, cls.tsym);
3263 else
3264 return t;
3265 }
3266 // where
3267 public List<Type> freshTypeVariables(List<Type> types) {
3268 ListBuffer<Type> result = lb();
3269 for (Type t : types) {
3270 if (t.tag == WILDCARD) {
3271 Type bound = ((WildcardType)t).getExtendsBound();
3272 if (bound == null)
3273 bound = syms.objectType;
3274 result.append(new CapturedType(capturedName,
3275 syms.noSymbol,
3276 bound,
3277 syms.botType,
3278 (WildcardType)t));
3279 } else {
3280 result.append(t);
3281 }
3282 }
3283 return result.toList();
3284 }
3285 // </editor-fold>
3287 // <editor-fold defaultstate="collapsed" desc="Internal utility methods">
3288 private List<Type> upperBounds(List<Type> ss) {
3289 if (ss.isEmpty()) return ss;
3290 Type head = upperBound(ss.head);
3291 List<Type> tail = upperBounds(ss.tail);
3292 if (head != ss.head || tail != ss.tail)
3293 return tail.prepend(head);
3294 else
3295 return ss;
3296 }
3298 private boolean sideCast(Type from, Type to, Warner warn) {
3299 // We are casting from type $from$ to type $to$, which are
3300 // non-final unrelated types. This method
3301 // tries to reject a cast by transferring type parameters
3302 // from $to$ to $from$ by common superinterfaces.
3303 boolean reverse = false;
3304 Type target = to;
3305 if ((to.tsym.flags() & INTERFACE) == 0) {
3306 Assert.check((from.tsym.flags() & INTERFACE) != 0);
3307 reverse = true;
3308 to = from;
3309 from = target;
3310 }
3311 List<Type> commonSupers = superClosure(to, erasure(from));
3312 boolean giveWarning = commonSupers.isEmpty();
3313 // The arguments to the supers could be unified here to
3314 // get a more accurate analysis
3315 while (commonSupers.nonEmpty()) {
3316 Type t1 = asSuper(from, commonSupers.head.tsym);
3317 Type t2 = commonSupers.head; // same as asSuper(to, commonSupers.head.tsym);
3318 if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
3319 return false;
3320 giveWarning = giveWarning || (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2));
3321 commonSupers = commonSupers.tail;
3322 }
3323 if (giveWarning && !isReifiable(reverse ? from : to))
3324 warn.warn(LintCategory.UNCHECKED);
3325 if (!allowCovariantReturns)
3326 // reject if there is a common method signature with
3327 // incompatible return types.
3328 chk.checkCompatibleAbstracts(warn.pos(), from, to);
3329 return true;
3330 }
3332 private boolean sideCastFinal(Type from, Type to, Warner warn) {
3333 // We are casting from type $from$ to type $to$, which are
3334 // unrelated types one of which is final and the other of
3335 // which is an interface. This method
3336 // tries to reject a cast by transferring type parameters
3337 // from the final class to the interface.
3338 boolean reverse = false;
3339 Type target = to;
3340 if ((to.tsym.flags() & INTERFACE) == 0) {
3341 Assert.check((from.tsym.flags() & INTERFACE) != 0);
3342 reverse = true;
3343 to = from;
3344 from = target;
3345 }
3346 Assert.check((from.tsym.flags() & FINAL) != 0);
3347 Type t1 = asSuper(from, to.tsym);
3348 if (t1 == null) return false;
3349 Type t2 = to;
3350 if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
3351 return false;
3352 if (!allowCovariantReturns)
3353 // reject if there is a common method signature with
3354 // incompatible return types.
3355 chk.checkCompatibleAbstracts(warn.pos(), from, to);
3356 if (!isReifiable(target) &&
3357 (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2)))
3358 warn.warn(LintCategory.UNCHECKED);
3359 return true;
3360 }
3362 private boolean giveWarning(Type from, Type to) {
3363 Type subFrom = asSub(from, to.tsym);
3364 return to.isParameterized() &&
3365 (!(isUnbounded(to) ||
3366 isSubtype(from, to) ||
3367 ((subFrom != null) && containsType(to.allparams(), subFrom.allparams()))));
3368 }
3370 private List<Type> superClosure(Type t, Type s) {
3371 List<Type> cl = List.nil();
3372 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
3373 if (isSubtype(s, erasure(l.head))) {
3374 cl = insert(cl, l.head);
3375 } else {
3376 cl = union(cl, superClosure(l.head, s));
3377 }
3378 }
3379 return cl;
3380 }
3382 private boolean containsTypeEquivalent(Type t, Type s) {
3383 return
3384 isSameType(t, s) || // shortcut
3385 containsType(t, s) && containsType(s, t);
3386 }
3388 // <editor-fold defaultstate="collapsed" desc="adapt">
3389 /**
3390 * Adapt a type by computing a substitution which maps a source
3391 * type to a target type.
3392 *
3393 * @param source the source type
3394 * @param target the target type
3395 * @param from the type variables of the computed substitution
3396 * @param to the types of the computed substitution.
3397 */
3398 public void adapt(Type source,
3399 Type target,
3400 ListBuffer<Type> from,
3401 ListBuffer<Type> to) throws AdaptFailure {
3402 new Adapter(from, to).adapt(source, target);
3403 }
3405 class Adapter extends SimpleVisitor<Void, Type> {
3407 ListBuffer<Type> from;
3408 ListBuffer<Type> to;
3409 Map<Symbol,Type> mapping;
3411 Adapter(ListBuffer<Type> from, ListBuffer<Type> to) {
3412 this.from = from;
3413 this.to = to;
3414 mapping = new HashMap<Symbol,Type>();
3415 }
3417 public void adapt(Type source, Type target) throws AdaptFailure {
3418 visit(source, target);
3419 List<Type> fromList = from.toList();
3420 List<Type> toList = to.toList();
3421 while (!fromList.isEmpty()) {
3422 Type val = mapping.get(fromList.head.tsym);
3423 if (toList.head != val)
3424 toList.head = val;
3425 fromList = fromList.tail;
3426 toList = toList.tail;
3427 }
3428 }
3430 @Override
3431 public Void visitClassType(ClassType source, Type target) throws AdaptFailure {
3432 if (target.tag == CLASS)
3433 adaptRecursive(source.allparams(), target.allparams());
3434 return null;
3435 }
3437 @Override
3438 public Void visitArrayType(ArrayType source, Type target) throws AdaptFailure {
3439 if (target.tag == ARRAY)
3440 adaptRecursive(elemtype(source), elemtype(target));
3441 return null;
3442 }
3444 @Override
3445 public Void visitWildcardType(WildcardType source, Type target) throws AdaptFailure {
3446 if (source.isExtendsBound())
3447 adaptRecursive(upperBound(source), upperBound(target));
3448 else if (source.isSuperBound())
3449 adaptRecursive(lowerBound(source), lowerBound(target));
3450 return null;
3451 }
3453 @Override
3454 public Void visitTypeVar(TypeVar source, Type target) throws AdaptFailure {
3455 // Check to see if there is
3456 // already a mapping for $source$, in which case
3457 // the old mapping will be merged with the new
3458 Type val = mapping.get(source.tsym);
3459 if (val != null) {
3460 if (val.isSuperBound() && target.isSuperBound()) {
3461 val = isSubtype(lowerBound(val), lowerBound(target))
3462 ? target : val;
3463 } else if (val.isExtendsBound() && target.isExtendsBound()) {
3464 val = isSubtype(upperBound(val), upperBound(target))
3465 ? val : target;
3466 } else if (!isSameType(val, target)) {
3467 throw new AdaptFailure();
3468 }
3469 } else {
3470 val = target;
3471 from.append(source);
3472 to.append(target);
3473 }
3474 mapping.put(source.tsym, val);
3475 return null;
3476 }
3478 @Override
3479 public Void visitType(Type source, Type target) {
3480 return null;
3481 }
3483 private Set<TypePair> cache = new HashSet<TypePair>();
3485 private void adaptRecursive(Type source, Type target) {
3486 TypePair pair = new TypePair(source, target);
3487 if (cache.add(pair)) {
3488 try {
3489 visit(source, target);
3490 } finally {
3491 cache.remove(pair);
3492 }
3493 }
3494 }
3496 private void adaptRecursive(List<Type> source, List<Type> target) {
3497 if (source.length() == target.length()) {
3498 while (source.nonEmpty()) {
3499 adaptRecursive(source.head, target.head);
3500 source = source.tail;
3501 target = target.tail;
3502 }
3503 }
3504 }
3505 }
3507 public static class AdaptFailure extends RuntimeException {
3508 static final long serialVersionUID = -7490231548272701566L;
3509 }
3511 private void adaptSelf(Type t,
3512 ListBuffer<Type> from,
3513 ListBuffer<Type> to) {
3514 try {
3515 //if (t.tsym.type != t)
3516 adapt(t.tsym.type, t, from, to);
3517 } catch (AdaptFailure ex) {
3518 // Adapt should never fail calculating a mapping from
3519 // t.tsym.type to t as there can be no merge problem.
3520 throw new AssertionError(ex);
3521 }
3522 }
3523 // </editor-fold>
3525 /**
3526 * Rewrite all type variables (universal quantifiers) in the given
3527 * type to wildcards (existential quantifiers). This is used to
3528 * determine if a cast is allowed. For example, if high is true
3529 * and {@code T <: Number}, then {@code List<T>} is rewritten to
3530 * {@code List<? extends Number>}. Since {@code List<Integer> <:
3531 * List<? extends Number>} a {@code List<T>} can be cast to {@code
3532 * List<Integer>} with a warning.
3533 * @param t a type
3534 * @param high if true return an upper bound; otherwise a lower
3535 * bound
3536 * @param rewriteTypeVars only rewrite captured wildcards if false;
3537 * otherwise rewrite all type variables
3538 * @return the type rewritten with wildcards (existential
3539 * quantifiers) only
3540 */
3541 private Type rewriteQuantifiers(Type t, boolean high, boolean rewriteTypeVars) {
3542 return new Rewriter(high, rewriteTypeVars).visit(t);
3543 }
3545 class Rewriter extends UnaryVisitor<Type> {
3547 boolean high;
3548 boolean rewriteTypeVars;
3550 Rewriter(boolean high, boolean rewriteTypeVars) {
3551 this.high = high;
3552 this.rewriteTypeVars = rewriteTypeVars;
3553 }
3555 @Override
3556 public Type visitClassType(ClassType t, Void s) {
3557 ListBuffer<Type> rewritten = new ListBuffer<Type>();
3558 boolean changed = false;
3559 for (Type arg : t.allparams()) {
3560 Type bound = visit(arg);
3561 if (arg != bound) {
3562 changed = true;
3563 }
3564 rewritten.append(bound);
3565 }
3566 if (changed)
3567 return subst(t.tsym.type,
3568 t.tsym.type.allparams(),
3569 rewritten.toList());
3570 else
3571 return t;
3572 }
3574 public Type visitType(Type t, Void s) {
3575 return high ? upperBound(t) : lowerBound(t);
3576 }
3578 @Override
3579 public Type visitCapturedType(CapturedType t, Void s) {
3580 Type w_bound = t.wildcard.type;
3581 Type bound = w_bound.contains(t) ?
3582 erasure(w_bound) :
3583 visit(w_bound);
3584 return rewriteAsWildcardType(visit(bound), t.wildcard.bound, t.wildcard.kind);
3585 }
3587 @Override
3588 public Type visitTypeVar(TypeVar t, Void s) {
3589 if (rewriteTypeVars) {
3590 Type bound = t.bound.contains(t) ?
3591 erasure(t.bound) :
3592 visit(t.bound);
3593 return rewriteAsWildcardType(bound, t, EXTENDS);
3594 } else {
3595 return t;
3596 }
3597 }
3599 @Override
3600 public Type visitWildcardType(WildcardType t, Void s) {
3601 Type bound2 = visit(t.type);
3602 return t.type == bound2 ? t : rewriteAsWildcardType(bound2, t.bound, t.kind);
3603 }
3605 private Type rewriteAsWildcardType(Type bound, TypeVar formal, BoundKind bk) {
3606 switch (bk) {
3607 case EXTENDS: return high ?
3608 makeExtendsWildcard(B(bound), formal) :
3609 makeExtendsWildcard(syms.objectType, formal);
3610 case SUPER: return high ?
3611 makeSuperWildcard(syms.botType, formal) :
3612 makeSuperWildcard(B(bound), formal);
3613 case UNBOUND: return makeExtendsWildcard(syms.objectType, formal);
3614 default:
3615 Assert.error("Invalid bound kind " + bk);
3616 return null;
3617 }
3618 }
3620 Type B(Type t) {
3621 while (t.tag == WILDCARD) {
3622 WildcardType w = (WildcardType)t;
3623 t = high ?
3624 w.getExtendsBound() :
3625 w.getSuperBound();
3626 if (t == null) {
3627 t = high ? syms.objectType : syms.botType;
3628 }
3629 }
3630 return t;
3631 }
3632 }
3635 /**
3636 * Create a wildcard with the given upper (extends) bound; create
3637 * an unbounded wildcard if bound is Object.
3638 *
3639 * @param bound the upper bound
3640 * @param formal the formal type parameter that will be
3641 * substituted by the wildcard
3642 */
3643 private WildcardType makeExtendsWildcard(Type bound, TypeVar formal) {
3644 if (bound == syms.objectType) {
3645 return new WildcardType(syms.objectType,
3646 BoundKind.UNBOUND,
3647 syms.boundClass,
3648 formal);
3649 } else {
3650 return new WildcardType(bound,
3651 BoundKind.EXTENDS,
3652 syms.boundClass,
3653 formal);
3654 }
3655 }
3657 /**
3658 * Create a wildcard with the given lower (super) bound; create an
3659 * unbounded wildcard if bound is bottom (type of {@code null}).
3660 *
3661 * @param bound the lower bound
3662 * @param formal the formal type parameter that will be
3663 * substituted by the wildcard
3664 */
3665 private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
3666 if (bound.tag == BOT) {
3667 return new WildcardType(syms.objectType,
3668 BoundKind.UNBOUND,
3669 syms.boundClass,
3670 formal);
3671 } else {
3672 return new WildcardType(bound,
3673 BoundKind.SUPER,
3674 syms.boundClass,
3675 formal);
3676 }
3677 }
3679 /**
3680 * A wrapper for a type that allows use in sets.
3681 */
3682 class SingletonType {
3683 final Type t;
3684 SingletonType(Type t) {
3685 this.t = t;
3686 }
3687 public int hashCode() {
3688 return Types.hashCode(t);
3689 }
3690 public boolean equals(Object obj) {
3691 return (obj instanceof SingletonType) &&
3692 isSameType(t, ((SingletonType)obj).t);
3693 }
3694 public String toString() {
3695 return t.toString();
3696 }
3697 }
3698 // </editor-fold>
3700 // <editor-fold defaultstate="collapsed" desc="Visitors">
3701 /**
3702 * A default visitor for types. All visitor methods except
3703 * visitType are implemented by delegating to visitType. Concrete
3704 * subclasses must provide an implementation of visitType and can
3705 * override other methods as needed.
3706 *
3707 * @param <R> the return type of the operation implemented by this
3708 * visitor; use Void if no return type is needed.
3709 * @param <S> the type of the second argument (the first being the
3710 * type itself) of the operation implemented by this visitor; use
3711 * Void if a second argument is not needed.
3712 */
3713 public static abstract class DefaultTypeVisitor<R,S> implements Type.Visitor<R,S> {
3714 final public R visit(Type t, S s) { return t.accept(this, s); }
3715 public R visitClassType(ClassType t, S s) { return visitType(t, s); }
3716 public R visitWildcardType(WildcardType t, S s) { return visitType(t, s); }
3717 public R visitArrayType(ArrayType t, S s) { return visitType(t, s); }
3718 public R visitMethodType(MethodType t, S s) { return visitType(t, s); }
3719 public R visitPackageType(PackageType t, S s) { return visitType(t, s); }
3720 public R visitTypeVar(TypeVar t, S s) { return visitType(t, s); }
3721 public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); }
3722 public R visitForAll(ForAll t, S s) { return visitType(t, s); }
3723 public R visitUndetVar(UndetVar t, S s) { return visitType(t, s); }
3724 public R visitErrorType(ErrorType t, S s) { return visitType(t, s); }
3725 }
3727 /**
3728 * A default visitor for symbols. All visitor methods except
3729 * visitSymbol are implemented by delegating to visitSymbol. Concrete
3730 * subclasses must provide an implementation of visitSymbol and can
3731 * override other methods as needed.
3732 *
3733 * @param <R> the return type of the operation implemented by this
3734 * visitor; use Void if no return type is needed.
3735 * @param <S> the type of the second argument (the first being the
3736 * symbol itself) of the operation implemented by this visitor; use
3737 * Void if a second argument is not needed.
3738 */
3739 public static abstract class DefaultSymbolVisitor<R,S> implements Symbol.Visitor<R,S> {
3740 final public R visit(Symbol s, S arg) { return s.accept(this, arg); }
3741 public R visitClassSymbol(ClassSymbol s, S arg) { return visitSymbol(s, arg); }
3742 public R visitMethodSymbol(MethodSymbol s, S arg) { return visitSymbol(s, arg); }
3743 public R visitOperatorSymbol(OperatorSymbol s, S arg) { return visitSymbol(s, arg); }
3744 public R visitPackageSymbol(PackageSymbol s, S arg) { return visitSymbol(s, arg); }
3745 public R visitTypeSymbol(TypeSymbol s, S arg) { return visitSymbol(s, arg); }
3746 public R visitVarSymbol(VarSymbol s, S arg) { return visitSymbol(s, arg); }
3747 }
3749 /**
3750 * A <em>simple</em> visitor for types. This visitor is simple as
3751 * captured wildcards, for-all types (generic methods), and
3752 * undetermined type variables (part of inference) are hidden.
3753 * Captured wildcards are hidden by treating them as type
3754 * variables and the rest are hidden by visiting their qtypes.
3755 *
3756 * @param <R> the return type of the operation implemented by this
3757 * visitor; use Void if no return type is needed.
3758 * @param <S> the type of the second argument (the first being the
3759 * type itself) of the operation implemented by this visitor; use
3760 * Void if a second argument is not needed.
3761 */
3762 public static abstract class SimpleVisitor<R,S> extends DefaultTypeVisitor<R,S> {
3763 @Override
3764 public R visitCapturedType(CapturedType t, S s) {
3765 return visitTypeVar(t, s);
3766 }
3767 @Override
3768 public R visitForAll(ForAll t, S s) {
3769 return visit(t.qtype, s);
3770 }
3771 @Override
3772 public R visitUndetVar(UndetVar t, S s) {
3773 return visit(t.qtype, s);
3774 }
3775 }
3777 /**
3778 * A plain relation on types. That is a 2-ary function on the
3779 * form Type × Type → Boolean.
3780 * <!-- In plain text: Type x Type -> Boolean -->
3781 */
3782 public static abstract class TypeRelation extends SimpleVisitor<Boolean,Type> {}
3784 /**
3785 * A convenience visitor for implementing operations that only
3786 * require one argument (the type itself), that is, unary
3787 * operations.
3788 *
3789 * @param <R> the return type of the operation implemented by this
3790 * visitor; use Void if no return type is needed.
3791 */
3792 public static abstract class UnaryVisitor<R> extends SimpleVisitor<R,Void> {
3793 final public R visit(Type t) { return t.accept(this, null); }
3794 }
3796 /**
3797 * A visitor for implementing a mapping from types to types. The
3798 * default behavior of this class is to implement the identity
3799 * mapping (mapping a type to itself). This can be overridden in
3800 * subclasses.
3801 *
3802 * @param <S> the type of the second argument (the first being the
3803 * type itself) of this mapping; use Void if a second argument is
3804 * not needed.
3805 */
3806 public static class MapVisitor<S> extends DefaultTypeVisitor<Type,S> {
3807 final public Type visit(Type t) { return t.accept(this, null); }
3808 public Type visitType(Type t, S s) { return t; }
3809 }
3810 // </editor-fold>
3813 // <editor-fold defaultstate="collapsed" desc="Annotation support">
3815 public RetentionPolicy getRetention(Attribute.Compound a) {
3816 return getRetention(a.type.tsym);
3817 }
3819 public RetentionPolicy getRetention(Symbol sym) {
3820 RetentionPolicy vis = RetentionPolicy.CLASS; // the default
3821 Attribute.Compound c = sym.attribute(syms.retentionType.tsym);
3822 if (c != null) {
3823 Attribute value = c.member(names.value);
3824 if (value != null && value instanceof Attribute.Enum) {
3825 Name levelName = ((Attribute.Enum)value).value.name;
3826 if (levelName == names.SOURCE) vis = RetentionPolicy.SOURCE;
3827 else if (levelName == names.CLASS) vis = RetentionPolicy.CLASS;
3828 else if (levelName == names.RUNTIME) vis = RetentionPolicy.RUNTIME;
3829 else ;// /* fail soft */ throw new AssertionError(levelName);
3830 }
3831 }
3832 return vis;
3833 }
3834 // </editor-fold>
3835 }