Wed, 17 Jul 2013 14:11:41 +0100
8012238: Nested method capture and inference
8008200: java/lang/Class/asSubclass/BasicUnit.java fails to compile
Summary: Inference support should be more flexible w.r.t. nested method calls returning captured types
Reviewed-by: jjg, vromero
1 /*
2 * Copyright (c) 2003, 2013, 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.HashSet;
30 import java.util.HashMap;
31 import java.util.Locale;
32 import java.util.Map;
33 import java.util.Set;
34 import java.util.WeakHashMap;
36 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
37 import com.sun.tools.javac.code.Lint.LintCategory;
38 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
39 import com.sun.tools.javac.comp.Check;
40 import com.sun.tools.javac.jvm.ClassReader;
41 import com.sun.tools.javac.util.*;
42 import static com.sun.tools.javac.code.BoundKind.*;
43 import static com.sun.tools.javac.code.Flags.*;
44 import static com.sun.tools.javac.code.Scope.*;
45 import static com.sun.tools.javac.code.Symbol.*;
46 import static com.sun.tools.javac.code.Type.*;
47 import static com.sun.tools.javac.code.TypeTag.*;
48 import static com.sun.tools.javac.jvm.ClassFile.externalize;
49 import static com.sun.tools.javac.util.ListBuffer.lb;
51 /**
52 * Utility class containing various operations on types.
53 *
54 * <p>Unless other names are more illustrative, the following naming
55 * conventions should be observed in this file:
56 *
57 * <dl>
58 * <dt>t</dt>
59 * <dd>If the first argument to an operation is a type, it should be named t.</dd>
60 * <dt>s</dt>
61 * <dd>Similarly, if the second argument to an operation is a type, it should be named s.</dd>
62 * <dt>ts</dt>
63 * <dd>If an operations takes a list of types, the first should be named ts.</dd>
64 * <dt>ss</dt>
65 * <dd>A second list of types should be named ss.</dd>
66 * </dl>
67 *
68 * <p><b>This is NOT part of any supported API.
69 * If you write code that depends on this, you do so at your own risk.
70 * This code and its internal interfaces are subject to change or
71 * deletion without notice.</b>
72 */
73 public class Types {
74 protected static final Context.Key<Types> typesKey =
75 new Context.Key<Types>();
77 final Symtab syms;
78 final JavacMessages messages;
79 final Names names;
80 final boolean allowBoxing;
81 final boolean allowCovariantReturns;
82 final boolean allowObjectToPrimitiveCast;
83 final boolean allowDefaultMethods;
84 final ClassReader reader;
85 final Check chk;
86 JCDiagnostic.Factory diags;
87 List<Warner> warnStack = List.nil();
88 final Name capturedName;
89 private final FunctionDescriptorLookupError functionDescriptorLookupError;
91 public final Warner noWarnings;
93 // <editor-fold defaultstate="collapsed" desc="Instantiating">
94 public static Types instance(Context context) {
95 Types instance = context.get(typesKey);
96 if (instance == null)
97 instance = new Types(context);
98 return instance;
99 }
101 protected Types(Context context) {
102 context.put(typesKey, this);
103 syms = Symtab.instance(context);
104 names = Names.instance(context);
105 Source source = Source.instance(context);
106 allowBoxing = source.allowBoxing();
107 allowCovariantReturns = source.allowCovariantReturns();
108 allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast();
109 allowDefaultMethods = source.allowDefaultMethods();
110 reader = ClassReader.instance(context);
111 chk = Check.instance(context);
112 capturedName = names.fromString("<captured wildcard>");
113 messages = JavacMessages.instance(context);
114 diags = JCDiagnostic.Factory.instance(context);
115 functionDescriptorLookupError = new FunctionDescriptorLookupError();
116 noWarnings = new Warner(null);
117 }
118 // </editor-fold>
120 // <editor-fold defaultstate="collapsed" desc="upperBound">
121 /**
122 * The "rvalue conversion".<br>
123 * The upper bound of most types is the type
124 * itself. Wildcards, on the other hand have upper
125 * and lower bounds.
126 * @param t a type
127 * @return the upper bound of the given type
128 */
129 public Type upperBound(Type t) {
130 return upperBound.visit(t);
131 }
132 // where
133 private final MapVisitor<Void> upperBound = new MapVisitor<Void>() {
135 @Override
136 public Type visitWildcardType(WildcardType t, Void ignored) {
137 if (t.isSuperBound())
138 return t.bound == null ? syms.objectType : t.bound.bound;
139 else
140 return visit(t.type);
141 }
143 @Override
144 public Type visitCapturedType(CapturedType t, Void ignored) {
145 return visit(t.bound);
146 }
147 };
148 // </editor-fold>
150 // <editor-fold defaultstate="collapsed" desc="lowerBound">
151 /**
152 * The "lvalue conversion".<br>
153 * The lower bound of most types is the type
154 * itself. Wildcards, on the other hand have upper
155 * and lower bounds.
156 * @param t a type
157 * @return the lower bound of the given type
158 */
159 public Type lowerBound(Type t) {
160 return lowerBound.visit(t);
161 }
162 // where
163 private final MapVisitor<Void> lowerBound = new MapVisitor<Void>() {
165 @Override
166 public Type visitWildcardType(WildcardType t, Void ignored) {
167 return t.isExtendsBound() ? syms.botType : visit(t.type);
168 }
170 @Override
171 public Type visitCapturedType(CapturedType t, Void ignored) {
172 return visit(t.getLowerBound());
173 }
174 };
175 // </editor-fold>
177 // <editor-fold defaultstate="collapsed" desc="isUnbounded">
178 /**
179 * Checks that all the arguments to a class are unbounded
180 * wildcards or something else that doesn't make any restrictions
181 * on the arguments. If a class isUnbounded, a raw super- or
182 * subclass can be cast to it without a warning.
183 * @param t a type
184 * @return true iff the given type is unbounded or raw
185 */
186 public boolean isUnbounded(Type t) {
187 return isUnbounded.visit(t);
188 }
189 // where
190 private final UnaryVisitor<Boolean> isUnbounded = new UnaryVisitor<Boolean>() {
192 public Boolean visitType(Type t, Void ignored) {
193 return true;
194 }
196 @Override
197 public Boolean visitClassType(ClassType t, Void ignored) {
198 List<Type> parms = t.tsym.type.allparams();
199 List<Type> args = t.allparams();
200 while (parms.nonEmpty()) {
201 WildcardType unb = new WildcardType(syms.objectType,
202 BoundKind.UNBOUND,
203 syms.boundClass,
204 (TypeVar)parms.head.unannotatedType());
205 if (!containsType(args.head, unb))
206 return false;
207 parms = parms.tail;
208 args = args.tail;
209 }
210 return true;
211 }
212 };
213 // </editor-fold>
215 // <editor-fold defaultstate="collapsed" desc="asSub">
216 /**
217 * Return the least specific subtype of t that starts with symbol
218 * sym. If none exists, return null. The least specific subtype
219 * is determined as follows:
220 *
221 * <p>If there is exactly one parameterized instance of sym that is a
222 * subtype of t, that parameterized instance is returned.<br>
223 * Otherwise, if the plain type or raw type `sym' is a subtype of
224 * type t, the type `sym' itself is returned. Otherwise, null is
225 * returned.
226 */
227 public Type asSub(Type t, Symbol sym) {
228 return asSub.visit(t, sym);
229 }
230 // where
231 private final SimpleVisitor<Type,Symbol> asSub = new SimpleVisitor<Type,Symbol>() {
233 public Type visitType(Type t, Symbol sym) {
234 return null;
235 }
237 @Override
238 public Type visitClassType(ClassType t, Symbol sym) {
239 if (t.tsym == sym)
240 return t;
241 Type base = asSuper(sym.type, t.tsym);
242 if (base == null)
243 return null;
244 ListBuffer<Type> from = new ListBuffer<Type>();
245 ListBuffer<Type> to = new ListBuffer<Type>();
246 try {
247 adapt(base, t, from, to);
248 } catch (AdaptFailure ex) {
249 return null;
250 }
251 Type res = subst(sym.type, from.toList(), to.toList());
252 if (!isSubtype(res, t))
253 return null;
254 ListBuffer<Type> openVars = new ListBuffer<Type>();
255 for (List<Type> l = sym.type.allparams();
256 l.nonEmpty(); l = l.tail)
257 if (res.contains(l.head) && !t.contains(l.head))
258 openVars.append(l.head);
259 if (openVars.nonEmpty()) {
260 if (t.isRaw()) {
261 // The subtype of a raw type is raw
262 res = erasure(res);
263 } else {
264 // Unbound type arguments default to ?
265 List<Type> opens = openVars.toList();
266 ListBuffer<Type> qs = new ListBuffer<Type>();
267 for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) {
268 qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head.unannotatedType()));
269 }
270 res = subst(res, opens, qs.toList());
271 }
272 }
273 return res;
274 }
276 @Override
277 public Type visitErrorType(ErrorType t, Symbol sym) {
278 return t;
279 }
280 };
281 // </editor-fold>
283 // <editor-fold defaultstate="collapsed" desc="isConvertible">
284 /**
285 * Is t a subtype of or convertible via boxing/unboxing
286 * conversion to s?
287 */
288 public boolean isConvertible(Type t, Type s, Warner warn) {
289 if (t.hasTag(ERROR)) {
290 return true;
291 }
292 boolean tPrimitive = t.isPrimitive();
293 boolean sPrimitive = s.isPrimitive();
294 if (tPrimitive == sPrimitive) {
295 return isSubtypeUnchecked(t, s, warn);
296 }
297 if (!allowBoxing) return false;
298 return tPrimitive
299 ? isSubtype(boxedClass(t).type, s)
300 : isSubtype(unboxedType(t), s);
301 }
303 /**
304 * Is t a subtype of or convertiable via boxing/unboxing
305 * convertions to s?
306 */
307 public boolean isConvertible(Type t, Type s) {
308 return isConvertible(t, s, noWarnings);
309 }
310 // </editor-fold>
312 // <editor-fold defaultstate="collapsed" desc="findSam">
314 /**
315 * Exception used to report a function descriptor lookup failure. The exception
316 * wraps a diagnostic that can be used to generate more details error
317 * messages.
318 */
319 public static class FunctionDescriptorLookupError extends RuntimeException {
320 private static final long serialVersionUID = 0;
322 JCDiagnostic diagnostic;
324 FunctionDescriptorLookupError() {
325 this.diagnostic = null;
326 }
328 FunctionDescriptorLookupError setMessage(JCDiagnostic diag) {
329 this.diagnostic = diag;
330 return this;
331 }
333 public JCDiagnostic getDiagnostic() {
334 return diagnostic;
335 }
336 }
338 /**
339 * A cache that keeps track of function descriptors associated with given
340 * functional interfaces.
341 */
342 class DescriptorCache {
344 private WeakHashMap<TypeSymbol, Entry> _map = new WeakHashMap<TypeSymbol, Entry>();
346 class FunctionDescriptor {
347 Symbol descSym;
349 FunctionDescriptor(Symbol descSym) {
350 this.descSym = descSym;
351 }
353 public Symbol getSymbol() {
354 return descSym;
355 }
357 public Type getType(Type site) {
358 site = removeWildcards(site);
359 if (!chk.checkValidGenericType(site)) {
360 //if the inferred functional interface type is not well-formed,
361 //or if it's not a subtype of the original target, issue an error
362 throw failure(diags.fragment("no.suitable.functional.intf.inst", site));
363 }
364 return memberType(site, descSym);
365 }
366 }
368 class Entry {
369 final FunctionDescriptor cachedDescRes;
370 final int prevMark;
372 public Entry(FunctionDescriptor cachedDescRes,
373 int prevMark) {
374 this.cachedDescRes = cachedDescRes;
375 this.prevMark = prevMark;
376 }
378 boolean matches(int mark) {
379 return this.prevMark == mark;
380 }
381 }
383 FunctionDescriptor get(TypeSymbol origin) throws FunctionDescriptorLookupError {
384 Entry e = _map.get(origin);
385 CompoundScope members = membersClosure(origin.type, false);
386 if (e == null ||
387 !e.matches(members.getMark())) {
388 FunctionDescriptor descRes = findDescriptorInternal(origin, members);
389 _map.put(origin, new Entry(descRes, members.getMark()));
390 return descRes;
391 }
392 else {
393 return e.cachedDescRes;
394 }
395 }
397 /**
398 * Compute the function descriptor associated with a given functional interface
399 */
400 public FunctionDescriptor findDescriptorInternal(TypeSymbol origin,
401 CompoundScope membersCache) throws FunctionDescriptorLookupError {
402 if (!origin.isInterface() || (origin.flags() & ANNOTATION) != 0) {
403 //t must be an interface
404 throw failure("not.a.functional.intf", origin);
405 }
407 final ListBuffer<Symbol> abstracts = ListBuffer.lb();
408 for (Symbol sym : membersCache.getElements(new DescriptorFilter(origin))) {
409 Type mtype = memberType(origin.type, sym);
410 if (abstracts.isEmpty() ||
411 (sym.name == abstracts.first().name &&
412 overrideEquivalent(mtype, memberType(origin.type, abstracts.first())))) {
413 abstracts.append(sym);
414 } else {
415 //the target method(s) should be the only abstract members of t
416 throw failure("not.a.functional.intf.1", origin,
417 diags.fragment("incompatible.abstracts", Kinds.kindName(origin), origin));
418 }
419 }
420 if (abstracts.isEmpty()) {
421 //t must define a suitable non-generic method
422 throw failure("not.a.functional.intf.1", origin,
423 diags.fragment("no.abstracts", Kinds.kindName(origin), origin));
424 } else if (abstracts.size() == 1) {
425 return new FunctionDescriptor(abstracts.first());
426 } else { // size > 1
427 FunctionDescriptor descRes = mergeDescriptors(origin, abstracts.toList());
428 if (descRes == null) {
429 //we can get here if the functional interface is ill-formed
430 ListBuffer<JCDiagnostic> descriptors = ListBuffer.lb();
431 for (Symbol desc : abstracts) {
432 String key = desc.type.getThrownTypes().nonEmpty() ?
433 "descriptor.throws" : "descriptor";
434 descriptors.append(diags.fragment(key, desc.name,
435 desc.type.getParameterTypes(),
436 desc.type.getReturnType(),
437 desc.type.getThrownTypes()));
438 }
439 JCDiagnostic.MultilineDiagnostic incompatibleDescriptors =
440 new JCDiagnostic.MultilineDiagnostic(diags.fragment("incompatible.descs.in.functional.intf",
441 Kinds.kindName(origin), origin), descriptors.toList());
442 throw failure(incompatibleDescriptors);
443 }
444 return descRes;
445 }
446 }
448 /**
449 * Compute a synthetic type for the target descriptor given a list
450 * of override-equivalent methods in the functional interface type.
451 * The resulting method type is a method type that is override-equivalent
452 * and return-type substitutable with each method in the original list.
453 */
454 private FunctionDescriptor mergeDescriptors(TypeSymbol origin, List<Symbol> methodSyms) {
455 //pick argument types - simply take the signature that is a
456 //subsignature of all other signatures in the list (as per JLS 8.4.2)
457 List<Symbol> mostSpecific = List.nil();
458 outer: for (Symbol msym1 : methodSyms) {
459 Type mt1 = memberType(origin.type, msym1);
460 for (Symbol msym2 : methodSyms) {
461 Type mt2 = memberType(origin.type, msym2);
462 if (!isSubSignature(mt1, mt2)) {
463 continue outer;
464 }
465 }
466 mostSpecific = mostSpecific.prepend(msym1);
467 }
468 if (mostSpecific.isEmpty()) {
469 return null;
470 }
473 //pick return types - this is done in two phases: (i) first, the most
474 //specific return type is chosen using strict subtyping; if this fails,
475 //a second attempt is made using return type substitutability (see JLS 8.4.5)
476 boolean phase2 = false;
477 Symbol bestSoFar = null;
478 while (bestSoFar == null) {
479 outer: for (Symbol msym1 : mostSpecific) {
480 Type mt1 = memberType(origin.type, msym1);
481 for (Symbol msym2 : methodSyms) {
482 Type mt2 = memberType(origin.type, msym2);
483 if (phase2 ?
484 !returnTypeSubstitutable(mt1, mt2) :
485 !isSubtypeInternal(mt1.getReturnType(), mt2.getReturnType())) {
486 continue outer;
487 }
488 }
489 bestSoFar = msym1;
490 }
491 if (phase2) {
492 break;
493 } else {
494 phase2 = true;
495 }
496 }
497 if (bestSoFar == null) return null;
499 //merge thrown types - form the intersection of all the thrown types in
500 //all the signatures in the list
501 List<Type> thrown = null;
502 for (Symbol msym1 : methodSyms) {
503 Type mt1 = memberType(origin.type, msym1);
504 thrown = (thrown == null) ?
505 mt1.getThrownTypes() :
506 chk.intersect(mt1.getThrownTypes(), thrown);
507 }
509 final List<Type> thrown1 = thrown;
510 return new FunctionDescriptor(bestSoFar) {
511 @Override
512 public Type getType(Type origin) {
513 Type mt = memberType(origin, getSymbol());
514 return createMethodTypeWithThrown(mt, thrown1);
515 }
516 };
517 }
519 boolean isSubtypeInternal(Type s, Type t) {
520 return (s.isPrimitive() && t.isPrimitive()) ?
521 isSameType(t, s) :
522 isSubtype(s, t);
523 }
525 FunctionDescriptorLookupError failure(String msg, Object... args) {
526 return failure(diags.fragment(msg, args));
527 }
529 FunctionDescriptorLookupError failure(JCDiagnostic diag) {
530 return functionDescriptorLookupError.setMessage(diag);
531 }
532 }
534 private DescriptorCache descCache = new DescriptorCache();
536 /**
537 * Find the method descriptor associated to this class symbol - if the
538 * symbol 'origin' is not a functional interface, an exception is thrown.
539 */
540 public Symbol findDescriptorSymbol(TypeSymbol origin) throws FunctionDescriptorLookupError {
541 return descCache.get(origin).getSymbol();
542 }
544 /**
545 * Find the type of the method descriptor associated to this class symbol -
546 * if the symbol 'origin' is not a functional interface, an exception is thrown.
547 */
548 public Type findDescriptorType(Type origin) throws FunctionDescriptorLookupError {
549 return descCache.get(origin.tsym).getType(origin);
550 }
552 /**
553 * Is given type a functional interface?
554 */
555 public boolean isFunctionalInterface(TypeSymbol tsym) {
556 try {
557 findDescriptorSymbol(tsym);
558 return true;
559 } catch (FunctionDescriptorLookupError ex) {
560 return false;
561 }
562 }
564 public boolean isFunctionalInterface(Type site) {
565 try {
566 findDescriptorType(site);
567 return true;
568 } catch (FunctionDescriptorLookupError ex) {
569 return false;
570 }
571 }
573 public Type removeWildcards(Type site) {
574 Type capturedSite = capture(site);
575 if (capturedSite != site) {
576 Type formalInterface = site.tsym.type;
577 ListBuffer<Type> typeargs = ListBuffer.lb();
578 List<Type> actualTypeargs = site.getTypeArguments();
579 List<Type> capturedTypeargs = capturedSite.getTypeArguments();
580 //simply replace the wildcards with its bound
581 for (Type t : formalInterface.getTypeArguments()) {
582 if (actualTypeargs.head.hasTag(WILDCARD)) {
583 WildcardType wt = (WildcardType)actualTypeargs.head.unannotatedType();
584 Type bound;
585 switch (wt.kind) {
586 case EXTENDS:
587 case UNBOUND:
588 CapturedType capVar = (CapturedType)capturedTypeargs.head.unannotatedType();
589 //use declared bound if it doesn't depend on formal type-args
590 bound = capVar.bound.containsAny(capturedSite.getTypeArguments()) ?
591 wt.type : capVar.bound;
592 break;
593 default:
594 bound = wt.type;
595 }
596 typeargs.append(bound);
597 } else {
598 typeargs.append(actualTypeargs.head);
599 }
600 actualTypeargs = actualTypeargs.tail;
601 capturedTypeargs = capturedTypeargs.tail;
602 }
603 return subst(formalInterface, formalInterface.getTypeArguments(), typeargs.toList());
604 } else {
605 return site;
606 }
607 }
608 // </editor-fold>
610 /**
611 * Scope filter used to skip methods that should be ignored (such as methods
612 * overridden by j.l.Object) during function interface conversion interface check
613 */
614 class DescriptorFilter implements Filter<Symbol> {
616 TypeSymbol origin;
618 DescriptorFilter(TypeSymbol origin) {
619 this.origin = origin;
620 }
622 @Override
623 public boolean accepts(Symbol sym) {
624 return sym.kind == Kinds.MTH &&
625 (sym.flags() & (ABSTRACT | DEFAULT)) == ABSTRACT &&
626 !overridesObjectMethod(origin, sym) &&
627 (interfaceCandidates(origin.type, (MethodSymbol)sym).head.flags() & DEFAULT) == 0;
628 }
629 };
631 // <editor-fold defaultstate="collapsed" desc="isSubtype">
632 /**
633 * Is t an unchecked subtype of s?
634 */
635 public boolean isSubtypeUnchecked(Type t, Type s) {
636 return isSubtypeUnchecked(t, s, noWarnings);
637 }
638 /**
639 * Is t an unchecked subtype of s?
640 */
641 public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
642 boolean result = isSubtypeUncheckedInternal(t, s, warn);
643 if (result) {
644 checkUnsafeVarargsConversion(t, s, warn);
645 }
646 return result;
647 }
648 //where
649 private boolean isSubtypeUncheckedInternal(Type t, Type s, Warner warn) {
650 if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) {
651 t = t.unannotatedType();
652 s = s.unannotatedType();
653 if (((ArrayType)t).elemtype.isPrimitive()) {
654 return isSameType(elemtype(t), elemtype(s));
655 } else {
656 return isSubtypeUnchecked(elemtype(t), elemtype(s), warn);
657 }
658 } else if (isSubtype(t, s)) {
659 return true;
660 } else if (t.hasTag(TYPEVAR)) {
661 return isSubtypeUnchecked(t.getUpperBound(), s, warn);
662 } else if (!s.isRaw()) {
663 Type t2 = asSuper(t, s.tsym);
664 if (t2 != null && t2.isRaw()) {
665 if (isReifiable(s)) {
666 warn.silentWarn(LintCategory.UNCHECKED);
667 } else {
668 warn.warn(LintCategory.UNCHECKED);
669 }
670 return true;
671 }
672 }
673 return false;
674 }
676 private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {
677 if (!t.hasTag(ARRAY) || isReifiable(t)) {
678 return;
679 }
680 t = t.unannotatedType();
681 s = s.unannotatedType();
682 ArrayType from = (ArrayType)t;
683 boolean shouldWarn = false;
684 switch (s.getTag()) {
685 case ARRAY:
686 ArrayType to = (ArrayType)s;
687 shouldWarn = from.isVarargs() &&
688 !to.isVarargs() &&
689 !isReifiable(from);
690 break;
691 case CLASS:
692 shouldWarn = from.isVarargs();
693 break;
694 }
695 if (shouldWarn) {
696 warn.warn(LintCategory.VARARGS);
697 }
698 }
700 /**
701 * Is t a subtype of s?<br>
702 * (not defined for Method and ForAll types)
703 */
704 final public boolean isSubtype(Type t, Type s) {
705 return isSubtype(t, s, true);
706 }
707 final public boolean isSubtypeNoCapture(Type t, Type s) {
708 return isSubtype(t, s, false);
709 }
710 public boolean isSubtype(Type t, Type s, boolean capture) {
711 if (t == s)
712 return true;
714 t = t.unannotatedType();
715 s = s.unannotatedType();
717 if (t == s)
718 return true;
720 if (s.isPartial())
721 return isSuperType(s, t);
723 if (s.isCompound()) {
724 for (Type s2 : interfaces(s).prepend(supertype(s))) {
725 if (!isSubtype(t, s2, capture))
726 return false;
727 }
728 return true;
729 }
731 Type lower = lowerBound(s);
732 if (s != lower)
733 return isSubtype(capture ? capture(t) : t, lower, false);
735 return isSubtype.visit(capture ? capture(t) : t, s);
736 }
737 // where
738 private TypeRelation isSubtype = new TypeRelation()
739 {
740 @Override
741 public Boolean visitType(Type t, Type s) {
742 switch (t.getTag()) {
743 case BYTE:
744 return (!s.hasTag(CHAR) && t.getTag().isSubRangeOf(s.getTag()));
745 case CHAR:
746 return (!s.hasTag(SHORT) && t.getTag().isSubRangeOf(s.getTag()));
747 case SHORT: case INT: case LONG:
748 case FLOAT: case DOUBLE:
749 return t.getTag().isSubRangeOf(s.getTag());
750 case BOOLEAN: case VOID:
751 return t.hasTag(s.getTag());
752 case TYPEVAR:
753 return isSubtypeNoCapture(t.getUpperBound(), s);
754 case BOT:
755 return
756 s.hasTag(BOT) || s.hasTag(CLASS) ||
757 s.hasTag(ARRAY) || s.hasTag(TYPEVAR);
758 case WILDCARD: //we shouldn't be here - avoids crash (see 7034495)
759 case NONE:
760 return false;
761 default:
762 throw new AssertionError("isSubtype " + t.getTag());
763 }
764 }
766 private Set<TypePair> cache = new HashSet<TypePair>();
768 private boolean containsTypeRecursive(Type t, Type s) {
769 TypePair pair = new TypePair(t, s);
770 if (cache.add(pair)) {
771 try {
772 return containsType(t.getTypeArguments(),
773 s.getTypeArguments());
774 } finally {
775 cache.remove(pair);
776 }
777 } else {
778 return containsType(t.getTypeArguments(),
779 rewriteSupers(s).getTypeArguments());
780 }
781 }
783 private Type rewriteSupers(Type t) {
784 if (!t.isParameterized())
785 return t;
786 ListBuffer<Type> from = lb();
787 ListBuffer<Type> to = lb();
788 adaptSelf(t, from, to);
789 if (from.isEmpty())
790 return t;
791 ListBuffer<Type> rewrite = lb();
792 boolean changed = false;
793 for (Type orig : to.toList()) {
794 Type s = rewriteSupers(orig);
795 if (s.isSuperBound() && !s.isExtendsBound()) {
796 s = new WildcardType(syms.objectType,
797 BoundKind.UNBOUND,
798 syms.boundClass);
799 changed = true;
800 } else if (s != orig) {
801 s = new WildcardType(upperBound(s),
802 BoundKind.EXTENDS,
803 syms.boundClass);
804 changed = true;
805 }
806 rewrite.append(s);
807 }
808 if (changed)
809 return subst(t.tsym.type, from.toList(), rewrite.toList());
810 else
811 return t;
812 }
814 @Override
815 public Boolean visitClassType(ClassType t, Type s) {
816 Type sup = asSuper(t, s.tsym);
817 return sup != null
818 && sup.tsym == s.tsym
819 // You're not allowed to write
820 // Vector<Object> vec = new Vector<String>();
821 // But with wildcards you can write
822 // Vector<? extends Object> vec = new Vector<String>();
823 // which means that subtype checking must be done
824 // here instead of same-type checking (via containsType).
825 && (!s.isParameterized() || containsTypeRecursive(s, sup))
826 && isSubtypeNoCapture(sup.getEnclosingType(),
827 s.getEnclosingType());
828 }
830 @Override
831 public Boolean visitArrayType(ArrayType t, Type s) {
832 if (s.hasTag(ARRAY)) {
833 if (t.elemtype.isPrimitive())
834 return isSameType(t.elemtype, elemtype(s));
835 else
836 return isSubtypeNoCapture(t.elemtype, elemtype(s));
837 }
839 if (s.hasTag(CLASS)) {
840 Name sname = s.tsym.getQualifiedName();
841 return sname == names.java_lang_Object
842 || sname == names.java_lang_Cloneable
843 || sname == names.java_io_Serializable;
844 }
846 return false;
847 }
849 @Override
850 public Boolean visitUndetVar(UndetVar t, Type s) {
851 //todo: test against origin needed? or replace with substitution?
852 if (t == s || t.qtype == s || s.hasTag(ERROR) || s.hasTag(UNKNOWN)) {
853 return true;
854 } else if (s.hasTag(BOT)) {
855 //if 's' is 'null' there's no instantiated type U for which
856 //U <: s (but 'null' itself, which is not a valid type)
857 return false;
858 }
860 t.addBound(InferenceBound.UPPER, s, Types.this);
861 return true;
862 }
864 @Override
865 public Boolean visitErrorType(ErrorType t, Type s) {
866 return true;
867 }
868 };
870 /**
871 * Is t a subtype of every type in given list `ts'?<br>
872 * (not defined for Method and ForAll types)<br>
873 * Allows unchecked conversions.
874 */
875 public boolean isSubtypeUnchecked(Type t, List<Type> ts, Warner warn) {
876 for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
877 if (!isSubtypeUnchecked(t, l.head, warn))
878 return false;
879 return true;
880 }
882 /**
883 * Are corresponding elements of ts subtypes of ss? If lists are
884 * of different length, return false.
885 */
886 public boolean isSubtypes(List<Type> ts, List<Type> ss) {
887 while (ts.tail != null && ss.tail != null
888 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
889 isSubtype(ts.head, ss.head)) {
890 ts = ts.tail;
891 ss = ss.tail;
892 }
893 return ts.tail == null && ss.tail == null;
894 /*inlined: ts.isEmpty() && ss.isEmpty();*/
895 }
897 /**
898 * Are corresponding elements of ts subtypes of ss, allowing
899 * unchecked conversions? If lists are of different length,
900 * return false.
901 **/
902 public boolean isSubtypesUnchecked(List<Type> ts, List<Type> ss, Warner warn) {
903 while (ts.tail != null && ss.tail != null
904 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
905 isSubtypeUnchecked(ts.head, ss.head, warn)) {
906 ts = ts.tail;
907 ss = ss.tail;
908 }
909 return ts.tail == null && ss.tail == null;
910 /*inlined: ts.isEmpty() && ss.isEmpty();*/
911 }
912 // </editor-fold>
914 // <editor-fold defaultstate="collapsed" desc="isSuperType">
915 /**
916 * Is t a supertype of s?
917 */
918 public boolean isSuperType(Type t, Type s) {
919 switch (t.getTag()) {
920 case ERROR:
921 return true;
922 case UNDETVAR: {
923 UndetVar undet = (UndetVar)t;
924 if (t == s ||
925 undet.qtype == s ||
926 s.hasTag(ERROR) ||
927 s.hasTag(BOT)) {
928 return true;
929 }
930 undet.addBound(InferenceBound.LOWER, s, this);
931 return true;
932 }
933 default:
934 return isSubtype(s, t);
935 }
936 }
937 // </editor-fold>
939 // <editor-fold defaultstate="collapsed" desc="isSameType">
940 /**
941 * Are corresponding elements of the lists the same type? If
942 * lists are of different length, return false.
943 */
944 public boolean isSameTypes(List<Type> ts, List<Type> ss) {
945 return isSameTypes(ts, ss, false);
946 }
947 public boolean isSameTypes(List<Type> ts, List<Type> ss, boolean strict) {
948 while (ts.tail != null && ss.tail != null
949 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
950 isSameType(ts.head, ss.head, strict)) {
951 ts = ts.tail;
952 ss = ss.tail;
953 }
954 return ts.tail == null && ss.tail == null;
955 /*inlined: ts.isEmpty() && ss.isEmpty();*/
956 }
958 /**
959 * A polymorphic signature method (JLS SE 7, 8.4.1) is a method that
960 * (i) is declared in the java.lang.invoke.MethodHandle class, (ii) takes
961 * a single variable arity parameter (iii) whose declared type is Object[],
962 * (iv) has a return type of Object and (v) is native.
963 */
964 public boolean isSignaturePolymorphic(MethodSymbol msym) {
965 List<Type> argtypes = msym.type.getParameterTypes();
966 return (msym.flags_field & NATIVE) != 0 &&
967 msym.owner == syms.methodHandleType.tsym &&
968 argtypes.tail.tail == null &&
969 argtypes.head.hasTag(TypeTag.ARRAY) &&
970 msym.type.getReturnType().tsym == syms.objectType.tsym &&
971 ((ArrayType)argtypes.head).elemtype.tsym == syms.objectType.tsym;
972 }
974 /**
975 * Is t the same type as s?
976 */
977 public boolean isSameType(Type t, Type s) {
978 return isSameType(t, s, false);
979 }
980 public boolean isSameType(Type t, Type s, boolean strict) {
981 return strict ?
982 isSameTypeStrict.visit(t, s) :
983 isSameTypeLoose.visit(t, s);
984 }
985 public boolean isSameAnnotatedType(Type t, Type s) {
986 return isSameAnnotatedType.visit(t, s);
987 }
988 // where
989 abstract class SameTypeVisitor extends TypeRelation {
991 public Boolean visitType(Type t, Type s) {
992 if (t == s)
993 return true;
995 if (s.isPartial())
996 return visit(s, t);
998 switch (t.getTag()) {
999 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
1000 case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE:
1001 return t.hasTag(s.getTag());
1002 case TYPEVAR: {
1003 if (s.hasTag(TYPEVAR)) {
1004 //type-substitution does not preserve type-var types
1005 //check that type var symbols and bounds are indeed the same
1006 return sameTypeVars((TypeVar)t.unannotatedType(), (TypeVar)s.unannotatedType());
1007 }
1008 else {
1009 //special case for s == ? super X, where upper(s) = u
1010 //check that u == t, where u has been set by Type.withTypeVar
1011 return s.isSuperBound() &&
1012 !s.isExtendsBound() &&
1013 visit(t, upperBound(s));
1014 }
1015 }
1016 default:
1017 throw new AssertionError("isSameType " + t.getTag());
1018 }
1019 }
1021 abstract boolean sameTypeVars(TypeVar tv1, TypeVar tv2);
1023 @Override
1024 public Boolean visitWildcardType(WildcardType t, Type s) {
1025 if (s.isPartial())
1026 return visit(s, t);
1027 else
1028 return false;
1029 }
1031 @Override
1032 public Boolean visitClassType(ClassType t, Type s) {
1033 if (t == s)
1034 return true;
1036 if (s.isPartial())
1037 return visit(s, t);
1039 if (s.isSuperBound() && !s.isExtendsBound())
1040 return visit(t, upperBound(s)) && visit(t, lowerBound(s));
1042 if (t.isCompound() && s.isCompound()) {
1043 if (!visit(supertype(t), supertype(s)))
1044 return false;
1046 HashSet<UniqueType> set = new HashSet<UniqueType>();
1047 for (Type x : interfaces(t))
1048 set.add(new UniqueType(x, Types.this));
1049 for (Type x : interfaces(s)) {
1050 if (!set.remove(new UniqueType(x, Types.this)))
1051 return false;
1052 }
1053 return (set.isEmpty());
1054 }
1055 return t.tsym == s.tsym
1056 && visit(t.getEnclosingType(), s.getEnclosingType())
1057 && containsTypes(t.getTypeArguments(), s.getTypeArguments());
1058 }
1060 abstract protected boolean containsTypes(List<Type> ts1, List<Type> ts2);
1062 @Override
1063 public Boolean visitArrayType(ArrayType t, Type s) {
1064 if (t == s)
1065 return true;
1067 if (s.isPartial())
1068 return visit(s, t);
1070 return s.hasTag(ARRAY)
1071 && containsTypeEquivalent(t.elemtype, elemtype(s));
1072 }
1074 @Override
1075 public Boolean visitMethodType(MethodType t, Type s) {
1076 // isSameType for methods does not take thrown
1077 // exceptions into account!
1078 return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType());
1079 }
1081 @Override
1082 public Boolean visitPackageType(PackageType t, Type s) {
1083 return t == s;
1084 }
1086 @Override
1087 public Boolean visitForAll(ForAll t, Type s) {
1088 if (!s.hasTag(FORALL)) {
1089 return false;
1090 }
1092 ForAll forAll = (ForAll)s;
1093 return hasSameBounds(t, forAll)
1094 && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
1095 }
1097 @Override
1098 public Boolean visitUndetVar(UndetVar t, Type s) {
1099 if (s.hasTag(WILDCARD)) {
1100 // FIXME, this might be leftovers from before capture conversion
1101 return false;
1102 }
1104 if (t == s || t.qtype == s || s.hasTag(ERROR) || s.hasTag(UNKNOWN)) {
1105 return true;
1106 }
1108 t.addBound(InferenceBound.EQ, s, Types.this);
1110 return true;
1111 }
1113 @Override
1114 public Boolean visitErrorType(ErrorType t, Type s) {
1115 return true;
1116 }
1117 }
1119 /**
1120 * Standard type-equality relation - type variables are considered
1121 * equals if they share the same type symbol.
1122 */
1123 TypeRelation isSameTypeLoose = new LooseSameTypeVisitor();
1125 private class LooseSameTypeVisitor extends SameTypeVisitor {
1126 @Override
1127 boolean sameTypeVars(TypeVar tv1, TypeVar tv2) {
1128 return tv1.tsym == tv2.tsym && visit(tv1.getUpperBound(), tv2.getUpperBound());
1129 }
1130 @Override
1131 protected boolean containsTypes(List<Type> ts1, List<Type> ts2) {
1132 return containsTypeEquivalent(ts1, ts2);
1133 }
1134 };
1136 /**
1137 * Strict type-equality relation - type variables are considered
1138 * equals if they share the same object identity.
1139 */
1140 TypeRelation isSameTypeStrict = new SameTypeVisitor() {
1141 @Override
1142 boolean sameTypeVars(TypeVar tv1, TypeVar tv2) {
1143 return tv1 == tv2;
1144 }
1145 @Override
1146 protected boolean containsTypes(List<Type> ts1, List<Type> ts2) {
1147 return isSameTypes(ts1, ts2, true);
1148 }
1150 @Override
1151 public Boolean visitWildcardType(WildcardType t, Type s) {
1152 if (!s.hasTag(WILDCARD)) {
1153 return false;
1154 } else {
1155 WildcardType t2 = (WildcardType)s.unannotatedType();
1156 return t.kind == t2.kind &&
1157 isSameType(t.type, t2.type, true);
1158 }
1159 }
1160 };
1162 /**
1163 * A version of LooseSameTypeVisitor that takes AnnotatedTypes
1164 * into account.
1165 */
1166 TypeRelation isSameAnnotatedType = new LooseSameTypeVisitor() {
1167 @Override
1168 public Boolean visitAnnotatedType(AnnotatedType t, Type s) {
1169 if (!s.isAnnotated())
1170 return false;
1171 if (!t.getAnnotationMirrors().containsAll(s.getAnnotationMirrors()))
1172 return false;
1173 if (!s.getAnnotationMirrors().containsAll(t.getAnnotationMirrors()))
1174 return false;
1175 return visit(t.underlyingType, s);
1176 }
1177 };
1178 // </editor-fold>
1180 // <editor-fold defaultstate="collapsed" desc="Contains Type">
1181 public boolean containedBy(Type t, Type s) {
1182 switch (t.getTag()) {
1183 case UNDETVAR:
1184 if (s.hasTag(WILDCARD)) {
1185 UndetVar undetvar = (UndetVar)t;
1186 WildcardType wt = (WildcardType)s.unannotatedType();
1187 switch(wt.kind) {
1188 case UNBOUND: //similar to ? extends Object
1189 case EXTENDS: {
1190 Type bound = upperBound(s);
1191 undetvar.addBound(InferenceBound.UPPER, bound, this);
1192 break;
1193 }
1194 case SUPER: {
1195 Type bound = lowerBound(s);
1196 undetvar.addBound(InferenceBound.LOWER, bound, this);
1197 break;
1198 }
1199 }
1200 return true;
1201 } else {
1202 return isSameType(t, s);
1203 }
1204 case ERROR:
1205 return true;
1206 default:
1207 return containsType(s, t);
1208 }
1209 }
1211 boolean containsType(List<Type> ts, List<Type> ss) {
1212 while (ts.nonEmpty() && ss.nonEmpty()
1213 && containsType(ts.head, ss.head)) {
1214 ts = ts.tail;
1215 ss = ss.tail;
1216 }
1217 return ts.isEmpty() && ss.isEmpty();
1218 }
1220 /**
1221 * Check if t contains s.
1222 *
1223 * <p>T contains S if:
1224 *
1225 * <p>{@code L(T) <: L(S) && U(S) <: U(T)}
1226 *
1227 * <p>This relation is only used by ClassType.isSubtype(), that
1228 * is,
1229 *
1230 * <p>{@code C<S> <: C<T> if T contains S.}
1231 *
1232 * <p>Because of F-bounds, this relation can lead to infinite
1233 * recursion. Thus we must somehow break that recursion. Notice
1234 * that containsType() is only called from ClassType.isSubtype().
1235 * Since the arguments have already been checked against their
1236 * bounds, we know:
1237 *
1238 * <p>{@code U(S) <: U(T) if T is "super" bound (U(T) *is* the bound)}
1239 *
1240 * <p>{@code L(T) <: L(S) if T is "extends" bound (L(T) is bottom)}
1241 *
1242 * @param t a type
1243 * @param s a type
1244 */
1245 public boolean containsType(Type t, Type s) {
1246 return containsType.visit(t, s);
1247 }
1248 // where
1249 private TypeRelation containsType = new TypeRelation() {
1251 private Type U(Type t) {
1252 while (t.hasTag(WILDCARD)) {
1253 WildcardType w = (WildcardType)t.unannotatedType();
1254 if (w.isSuperBound())
1255 return w.bound == null ? syms.objectType : w.bound.bound;
1256 else
1257 t = w.type;
1258 }
1259 return t;
1260 }
1262 private Type L(Type t) {
1263 while (t.hasTag(WILDCARD)) {
1264 WildcardType w = (WildcardType)t.unannotatedType();
1265 if (w.isExtendsBound())
1266 return syms.botType;
1267 else
1268 t = w.type;
1269 }
1270 return t;
1271 }
1273 public Boolean visitType(Type t, Type s) {
1274 if (s.isPartial())
1275 return containedBy(s, t);
1276 else
1277 return isSameType(t, s);
1278 }
1280 // void debugContainsType(WildcardType t, Type s) {
1281 // System.err.println();
1282 // System.err.format(" does %s contain %s?%n", t, s);
1283 // System.err.format(" %s U(%s) <: U(%s) %s = %s%n",
1284 // upperBound(s), s, t, U(t),
1285 // t.isSuperBound()
1286 // || isSubtypeNoCapture(upperBound(s), U(t)));
1287 // System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
1288 // L(t), t, s, lowerBound(s),
1289 // t.isExtendsBound()
1290 // || isSubtypeNoCapture(L(t), lowerBound(s)));
1291 // System.err.println();
1292 // }
1294 @Override
1295 public Boolean visitWildcardType(WildcardType t, Type s) {
1296 if (s.isPartial())
1297 return containedBy(s, t);
1298 else {
1299 // debugContainsType(t, s);
1300 return isSameWildcard(t, s)
1301 || isCaptureOf(s, t)
1302 || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), lowerBound(s))) &&
1303 (t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t))));
1304 }
1305 }
1307 @Override
1308 public Boolean visitUndetVar(UndetVar t, Type s) {
1309 if (!s.hasTag(WILDCARD)) {
1310 return isSameType(t, s);
1311 } else {
1312 return false;
1313 }
1314 }
1316 @Override
1317 public Boolean visitErrorType(ErrorType t, Type s) {
1318 return true;
1319 }
1320 };
1322 public boolean isCaptureOf(Type s, WildcardType t) {
1323 if (!s.hasTag(TYPEVAR) || !((TypeVar)s.unannotatedType()).isCaptured())
1324 return false;
1325 return isSameWildcard(t, ((CapturedType)s.unannotatedType()).wildcard);
1326 }
1328 public boolean isSameWildcard(WildcardType t, Type s) {
1329 if (!s.hasTag(WILDCARD))
1330 return false;
1331 WildcardType w = (WildcardType)s.unannotatedType();
1332 return w.kind == t.kind && w.type == t.type;
1333 }
1335 public boolean containsTypeEquivalent(List<Type> ts, List<Type> ss) {
1336 while (ts.nonEmpty() && ss.nonEmpty()
1337 && containsTypeEquivalent(ts.head, ss.head)) {
1338 ts = ts.tail;
1339 ss = ss.tail;
1340 }
1341 return ts.isEmpty() && ss.isEmpty();
1342 }
1343 // </editor-fold>
1345 /**
1346 * Can t and s be compared for equality? Any primitive ==
1347 * primitive or primitive == object comparisons here are an error.
1348 * Unboxing and correct primitive == primitive comparisons are
1349 * already dealt with in Attr.visitBinary.
1350 *
1351 */
1352 public boolean isEqualityComparable(Type s, Type t, Warner warn) {
1353 if (t.isNumeric() && s.isNumeric())
1354 return true;
1356 boolean tPrimitive = t.isPrimitive();
1357 boolean sPrimitive = s.isPrimitive();
1358 if (!tPrimitive && !sPrimitive) {
1359 return isCastable(s, t, warn) || isCastable(t, s, warn);
1360 } else {
1361 return false;
1362 }
1363 }
1365 // <editor-fold defaultstate="collapsed" desc="isCastable">
1366 public boolean isCastable(Type t, Type s) {
1367 return isCastable(t, s, noWarnings);
1368 }
1370 /**
1371 * Is t is castable to s?<br>
1372 * s is assumed to be an erased type.<br>
1373 * (not defined for Method and ForAll types).
1374 */
1375 public boolean isCastable(Type t, Type s, Warner warn) {
1376 if (t == s)
1377 return true;
1379 if (t.isPrimitive() != s.isPrimitive())
1380 return allowBoxing && (
1381 isConvertible(t, s, warn)
1382 || (allowObjectToPrimitiveCast &&
1383 s.isPrimitive() &&
1384 isSubtype(boxedClass(s).type, t)));
1385 if (warn != warnStack.head) {
1386 try {
1387 warnStack = warnStack.prepend(warn);
1388 checkUnsafeVarargsConversion(t, s, warn);
1389 return isCastable.visit(t,s);
1390 } finally {
1391 warnStack = warnStack.tail;
1392 }
1393 } else {
1394 return isCastable.visit(t,s);
1395 }
1396 }
1397 // where
1398 private TypeRelation isCastable = new TypeRelation() {
1400 public Boolean visitType(Type t, Type s) {
1401 if (s.hasTag(ERROR))
1402 return true;
1404 switch (t.getTag()) {
1405 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
1406 case DOUBLE:
1407 return s.isNumeric();
1408 case BOOLEAN:
1409 return s.hasTag(BOOLEAN);
1410 case VOID:
1411 return false;
1412 case BOT:
1413 return isSubtype(t, s);
1414 default:
1415 throw new AssertionError();
1416 }
1417 }
1419 @Override
1420 public Boolean visitWildcardType(WildcardType t, Type s) {
1421 return isCastable(upperBound(t), s, warnStack.head);
1422 }
1424 @Override
1425 public Boolean visitClassType(ClassType t, Type s) {
1426 if (s.hasTag(ERROR) || s.hasTag(BOT))
1427 return true;
1429 if (s.hasTag(TYPEVAR)) {
1430 if (isCastable(t, s.getUpperBound(), noWarnings)) {
1431 warnStack.head.warn(LintCategory.UNCHECKED);
1432 return true;
1433 } else {
1434 return false;
1435 }
1436 }
1438 if (t.isCompound() || s.isCompound()) {
1439 return !t.isCompound() ?
1440 visitIntersectionType((IntersectionClassType)s.unannotatedType(), t, true) :
1441 visitIntersectionType((IntersectionClassType)t.unannotatedType(), s, false);
1442 }
1444 if (s.hasTag(CLASS) || s.hasTag(ARRAY)) {
1445 boolean upcast;
1446 if ((upcast = isSubtype(erasure(t), erasure(s)))
1447 || isSubtype(erasure(s), erasure(t))) {
1448 if (!upcast && s.hasTag(ARRAY)) {
1449 if (!isReifiable(s))
1450 warnStack.head.warn(LintCategory.UNCHECKED);
1451 return true;
1452 } else if (s.isRaw()) {
1453 return true;
1454 } else if (t.isRaw()) {
1455 if (!isUnbounded(s))
1456 warnStack.head.warn(LintCategory.UNCHECKED);
1457 return true;
1458 }
1459 // Assume |a| <: |b|
1460 final Type a = upcast ? t : s;
1461 final Type b = upcast ? s : t;
1462 final boolean HIGH = true;
1463 final boolean LOW = false;
1464 final boolean DONT_REWRITE_TYPEVARS = false;
1465 Type aHigh = rewriteQuantifiers(a, HIGH, DONT_REWRITE_TYPEVARS);
1466 Type aLow = rewriteQuantifiers(a, LOW, DONT_REWRITE_TYPEVARS);
1467 Type bHigh = rewriteQuantifiers(b, HIGH, DONT_REWRITE_TYPEVARS);
1468 Type bLow = rewriteQuantifiers(b, LOW, DONT_REWRITE_TYPEVARS);
1469 Type lowSub = asSub(bLow, aLow.tsym);
1470 Type highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);
1471 if (highSub == null) {
1472 final boolean REWRITE_TYPEVARS = true;
1473 aHigh = rewriteQuantifiers(a, HIGH, REWRITE_TYPEVARS);
1474 aLow = rewriteQuantifiers(a, LOW, REWRITE_TYPEVARS);
1475 bHigh = rewriteQuantifiers(b, HIGH, REWRITE_TYPEVARS);
1476 bLow = rewriteQuantifiers(b, LOW, REWRITE_TYPEVARS);
1477 lowSub = asSub(bLow, aLow.tsym);
1478 highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);
1479 }
1480 if (highSub != null) {
1481 if (!(a.tsym == highSub.tsym && a.tsym == lowSub.tsym)) {
1482 Assert.error(a.tsym + " != " + highSub.tsym + " != " + lowSub.tsym);
1483 }
1484 if (!disjointTypes(aHigh.allparams(), highSub.allparams())
1485 && !disjointTypes(aHigh.allparams(), lowSub.allparams())
1486 && !disjointTypes(aLow.allparams(), highSub.allparams())
1487 && !disjointTypes(aLow.allparams(), lowSub.allparams())) {
1488 if (upcast ? giveWarning(a, b) :
1489 giveWarning(b, a))
1490 warnStack.head.warn(LintCategory.UNCHECKED);
1491 return true;
1492 }
1493 }
1494 if (isReifiable(s))
1495 return isSubtypeUnchecked(a, b);
1496 else
1497 return isSubtypeUnchecked(a, b, warnStack.head);
1498 }
1500 // Sidecast
1501 if (s.hasTag(CLASS)) {
1502 if ((s.tsym.flags() & INTERFACE) != 0) {
1503 return ((t.tsym.flags() & FINAL) == 0)
1504 ? sideCast(t, s, warnStack.head)
1505 : sideCastFinal(t, s, warnStack.head);
1506 } else if ((t.tsym.flags() & INTERFACE) != 0) {
1507 return ((s.tsym.flags() & FINAL) == 0)
1508 ? sideCast(t, s, warnStack.head)
1509 : sideCastFinal(t, s, warnStack.head);
1510 } else {
1511 // unrelated class types
1512 return false;
1513 }
1514 }
1515 }
1516 return false;
1517 }
1519 boolean visitIntersectionType(IntersectionClassType ict, Type s, boolean reverse) {
1520 Warner warn = noWarnings;
1521 for (Type c : ict.getComponents()) {
1522 warn.clear();
1523 if (reverse ? !isCastable(s, c, warn) : !isCastable(c, s, warn))
1524 return false;
1525 }
1526 if (warn.hasLint(LintCategory.UNCHECKED))
1527 warnStack.head.warn(LintCategory.UNCHECKED);
1528 return true;
1529 }
1531 @Override
1532 public Boolean visitArrayType(ArrayType t, Type s) {
1533 switch (s.getTag()) {
1534 case ERROR:
1535 case BOT:
1536 return true;
1537 case TYPEVAR:
1538 if (isCastable(s, t, noWarnings)) {
1539 warnStack.head.warn(LintCategory.UNCHECKED);
1540 return true;
1541 } else {
1542 return false;
1543 }
1544 case CLASS:
1545 return isSubtype(t, s);
1546 case ARRAY:
1547 if (elemtype(t).isPrimitive() || elemtype(s).isPrimitive()) {
1548 return elemtype(t).hasTag(elemtype(s).getTag());
1549 } else {
1550 return visit(elemtype(t), elemtype(s));
1551 }
1552 default:
1553 return false;
1554 }
1555 }
1557 @Override
1558 public Boolean visitTypeVar(TypeVar t, Type s) {
1559 switch (s.getTag()) {
1560 case ERROR:
1561 case BOT:
1562 return true;
1563 case TYPEVAR:
1564 if (isSubtype(t, s)) {
1565 return true;
1566 } else if (isCastable(t.bound, s, noWarnings)) {
1567 warnStack.head.warn(LintCategory.UNCHECKED);
1568 return true;
1569 } else {
1570 return false;
1571 }
1572 default:
1573 return isCastable(t.bound, s, warnStack.head);
1574 }
1575 }
1577 @Override
1578 public Boolean visitErrorType(ErrorType t, Type s) {
1579 return true;
1580 }
1581 };
1582 // </editor-fold>
1584 // <editor-fold defaultstate="collapsed" desc="disjointTypes">
1585 public boolean disjointTypes(List<Type> ts, List<Type> ss) {
1586 while (ts.tail != null && ss.tail != null) {
1587 if (disjointType(ts.head, ss.head)) return true;
1588 ts = ts.tail;
1589 ss = ss.tail;
1590 }
1591 return false;
1592 }
1594 /**
1595 * Two types or wildcards are considered disjoint if it can be
1596 * proven that no type can be contained in both. It is
1597 * conservative in that it is allowed to say that two types are
1598 * not disjoint, even though they actually are.
1599 *
1600 * The type {@code C<X>} is castable to {@code C<Y>} exactly if
1601 * {@code X} and {@code Y} are not disjoint.
1602 */
1603 public boolean disjointType(Type t, Type s) {
1604 return disjointType.visit(t, s);
1605 }
1606 // where
1607 private TypeRelation disjointType = new TypeRelation() {
1609 private Set<TypePair> cache = new HashSet<TypePair>();
1611 @Override
1612 public Boolean visitType(Type t, Type s) {
1613 if (s.hasTag(WILDCARD))
1614 return visit(s, t);
1615 else
1616 return notSoftSubtypeRecursive(t, s) || notSoftSubtypeRecursive(s, t);
1617 }
1619 private boolean isCastableRecursive(Type t, Type s) {
1620 TypePair pair = new TypePair(t, s);
1621 if (cache.add(pair)) {
1622 try {
1623 return Types.this.isCastable(t, s);
1624 } finally {
1625 cache.remove(pair);
1626 }
1627 } else {
1628 return true;
1629 }
1630 }
1632 private boolean notSoftSubtypeRecursive(Type t, Type s) {
1633 TypePair pair = new TypePair(t, s);
1634 if (cache.add(pair)) {
1635 try {
1636 return Types.this.notSoftSubtype(t, s);
1637 } finally {
1638 cache.remove(pair);
1639 }
1640 } else {
1641 return false;
1642 }
1643 }
1645 @Override
1646 public Boolean visitWildcardType(WildcardType t, Type s) {
1647 if (t.isUnbound())
1648 return false;
1650 if (!s.hasTag(WILDCARD)) {
1651 if (t.isExtendsBound())
1652 return notSoftSubtypeRecursive(s, t.type);
1653 else
1654 return notSoftSubtypeRecursive(t.type, s);
1655 }
1657 if (s.isUnbound())
1658 return false;
1660 if (t.isExtendsBound()) {
1661 if (s.isExtendsBound())
1662 return !isCastableRecursive(t.type, upperBound(s));
1663 else if (s.isSuperBound())
1664 return notSoftSubtypeRecursive(lowerBound(s), t.type);
1665 } else if (t.isSuperBound()) {
1666 if (s.isExtendsBound())
1667 return notSoftSubtypeRecursive(t.type, upperBound(s));
1668 }
1669 return false;
1670 }
1671 };
1672 // </editor-fold>
1674 // <editor-fold defaultstate="collapsed" desc="lowerBoundArgtypes">
1675 /**
1676 * Returns the lower bounds of the formals of a method.
1677 */
1678 public List<Type> lowerBoundArgtypes(Type t) {
1679 return lowerBounds(t.getParameterTypes());
1680 }
1681 public List<Type> lowerBounds(List<Type> ts) {
1682 return map(ts, lowerBoundMapping);
1683 }
1684 private final Mapping lowerBoundMapping = new Mapping("lowerBound") {
1685 public Type apply(Type t) {
1686 return lowerBound(t);
1687 }
1688 };
1689 // </editor-fold>
1691 // <editor-fold defaultstate="collapsed" desc="notSoftSubtype">
1692 /**
1693 * This relation answers the question: is impossible that
1694 * something of type `t' can be a subtype of `s'? This is
1695 * different from the question "is `t' not a subtype of `s'?"
1696 * when type variables are involved: Integer is not a subtype of T
1697 * where {@code <T extends Number>} but it is not true that Integer cannot
1698 * possibly be a subtype of T.
1699 */
1700 public boolean notSoftSubtype(Type t, Type s) {
1701 if (t == s) return false;
1702 if (t.hasTag(TYPEVAR)) {
1703 TypeVar tv = (TypeVar) t;
1704 return !isCastable(tv.bound,
1705 relaxBound(s),
1706 noWarnings);
1707 }
1708 if (!s.hasTag(WILDCARD))
1709 s = upperBound(s);
1711 return !isSubtype(t, relaxBound(s));
1712 }
1714 private Type relaxBound(Type t) {
1715 if (t.hasTag(TYPEVAR)) {
1716 while (t.hasTag(TYPEVAR))
1717 t = t.getUpperBound();
1718 t = rewriteQuantifiers(t, true, true);
1719 }
1720 return t;
1721 }
1722 // </editor-fold>
1724 // <editor-fold defaultstate="collapsed" desc="isReifiable">
1725 public boolean isReifiable(Type t) {
1726 return isReifiable.visit(t);
1727 }
1728 // where
1729 private UnaryVisitor<Boolean> isReifiable = new UnaryVisitor<Boolean>() {
1731 public Boolean visitType(Type t, Void ignored) {
1732 return true;
1733 }
1735 @Override
1736 public Boolean visitClassType(ClassType t, Void ignored) {
1737 if (t.isCompound())
1738 return false;
1739 else {
1740 if (!t.isParameterized())
1741 return true;
1743 for (Type param : t.allparams()) {
1744 if (!param.isUnbound())
1745 return false;
1746 }
1747 return true;
1748 }
1749 }
1751 @Override
1752 public Boolean visitArrayType(ArrayType t, Void ignored) {
1753 return visit(t.elemtype);
1754 }
1756 @Override
1757 public Boolean visitTypeVar(TypeVar t, Void ignored) {
1758 return false;
1759 }
1760 };
1761 // </editor-fold>
1763 // <editor-fold defaultstate="collapsed" desc="Array Utils">
1764 public boolean isArray(Type t) {
1765 while (t.hasTag(WILDCARD))
1766 t = upperBound(t);
1767 return t.hasTag(ARRAY);
1768 }
1770 /**
1771 * The element type of an array.
1772 */
1773 public Type elemtype(Type t) {
1774 switch (t.getTag()) {
1775 case WILDCARD:
1776 return elemtype(upperBound(t));
1777 case ARRAY:
1778 t = t.unannotatedType();
1779 return ((ArrayType)t).elemtype;
1780 case FORALL:
1781 return elemtype(((ForAll)t).qtype);
1782 case ERROR:
1783 return t;
1784 default:
1785 return null;
1786 }
1787 }
1789 public Type elemtypeOrType(Type t) {
1790 Type elemtype = elemtype(t);
1791 return elemtype != null ?
1792 elemtype :
1793 t;
1794 }
1796 /**
1797 * Mapping to take element type of an arraytype
1798 */
1799 private Mapping elemTypeFun = new Mapping ("elemTypeFun") {
1800 public Type apply(Type t) { return elemtype(t); }
1801 };
1803 /**
1804 * The number of dimensions of an array type.
1805 */
1806 public int dimensions(Type t) {
1807 int result = 0;
1808 while (t.hasTag(ARRAY)) {
1809 result++;
1810 t = elemtype(t);
1811 }
1812 return result;
1813 }
1815 /**
1816 * Returns an ArrayType with the component type t
1817 *
1818 * @param t The component type of the ArrayType
1819 * @return the ArrayType for the given component
1820 */
1821 public ArrayType makeArrayType(Type t) {
1822 if (t.hasTag(VOID) || t.hasTag(PACKAGE)) {
1823 Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString());
1824 }
1825 return new ArrayType(t, syms.arrayClass);
1826 }
1827 // </editor-fold>
1829 // <editor-fold defaultstate="collapsed" desc="asSuper">
1830 /**
1831 * Return the (most specific) base type of t that starts with the
1832 * given symbol. If none exists, return null.
1833 *
1834 * @param t a type
1835 * @param sym a symbol
1836 */
1837 public Type asSuper(Type t, Symbol sym) {
1838 return asSuper.visit(t, sym);
1839 }
1840 // where
1841 private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() {
1843 public Type visitType(Type t, Symbol sym) {
1844 return null;
1845 }
1847 @Override
1848 public Type visitClassType(ClassType t, Symbol sym) {
1849 if (t.tsym == sym)
1850 return t;
1852 Type st = supertype(t);
1853 if (st.hasTag(CLASS) || st.hasTag(TYPEVAR) || st.hasTag(ERROR)) {
1854 Type x = asSuper(st, sym);
1855 if (x != null)
1856 return x;
1857 }
1858 if ((sym.flags() & INTERFACE) != 0) {
1859 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
1860 Type x = asSuper(l.head, sym);
1861 if (x != null)
1862 return x;
1863 }
1864 }
1865 return null;
1866 }
1868 @Override
1869 public Type visitArrayType(ArrayType t, Symbol sym) {
1870 return isSubtype(t, sym.type) ? sym.type : null;
1871 }
1873 @Override
1874 public Type visitTypeVar(TypeVar t, Symbol sym) {
1875 if (t.tsym == sym)
1876 return t;
1877 else
1878 return asSuper(t.bound, sym);
1879 }
1881 @Override
1882 public Type visitErrorType(ErrorType t, Symbol sym) {
1883 return t;
1884 }
1885 };
1887 /**
1888 * Return the base type of t or any of its outer types that starts
1889 * with the given symbol. If none exists, return null.
1890 *
1891 * @param t a type
1892 * @param sym a symbol
1893 */
1894 public Type asOuterSuper(Type t, Symbol sym) {
1895 switch (t.getTag()) {
1896 case CLASS:
1897 do {
1898 Type s = asSuper(t, sym);
1899 if (s != null) return s;
1900 t = t.getEnclosingType();
1901 } while (t.hasTag(CLASS));
1902 return null;
1903 case ARRAY:
1904 return isSubtype(t, sym.type) ? sym.type : null;
1905 case TYPEVAR:
1906 return asSuper(t, sym);
1907 case ERROR:
1908 return t;
1909 default:
1910 return null;
1911 }
1912 }
1914 /**
1915 * Return the base type of t or any of its enclosing types that
1916 * starts with the given symbol. If none exists, return null.
1917 *
1918 * @param t a type
1919 * @param sym a symbol
1920 */
1921 public Type asEnclosingSuper(Type t, Symbol sym) {
1922 switch (t.getTag()) {
1923 case CLASS:
1924 do {
1925 Type s = asSuper(t, sym);
1926 if (s != null) return s;
1927 Type outer = t.getEnclosingType();
1928 t = (outer.hasTag(CLASS)) ? outer :
1929 (t.tsym.owner.enclClass() != null) ? t.tsym.owner.enclClass().type :
1930 Type.noType;
1931 } while (t.hasTag(CLASS));
1932 return null;
1933 case ARRAY:
1934 return isSubtype(t, sym.type) ? sym.type : null;
1935 case TYPEVAR:
1936 return asSuper(t, sym);
1937 case ERROR:
1938 return t;
1939 default:
1940 return null;
1941 }
1942 }
1943 // </editor-fold>
1945 // <editor-fold defaultstate="collapsed" desc="memberType">
1946 /**
1947 * The type of given symbol, seen as a member of t.
1948 *
1949 * @param t a type
1950 * @param sym a symbol
1951 */
1952 public Type memberType(Type t, Symbol sym) {
1953 return (sym.flags() & STATIC) != 0
1954 ? sym.type
1955 : memberType.visit(t, sym);
1956 }
1957 // where
1958 private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
1960 public Type visitType(Type t, Symbol sym) {
1961 return sym.type;
1962 }
1964 @Override
1965 public Type visitWildcardType(WildcardType t, Symbol sym) {
1966 return memberType(upperBound(t), sym);
1967 }
1969 @Override
1970 public Type visitClassType(ClassType t, Symbol sym) {
1971 Symbol owner = sym.owner;
1972 long flags = sym.flags();
1973 if (((flags & STATIC) == 0) && owner.type.isParameterized()) {
1974 Type base = asOuterSuper(t, owner);
1975 //if t is an intersection type T = CT & I1 & I2 ... & In
1976 //its supertypes CT, I1, ... In might contain wildcards
1977 //so we need to go through capture conversion
1978 base = t.isCompound() ? capture(base) : base;
1979 if (base != null) {
1980 List<Type> ownerParams = owner.type.allparams();
1981 List<Type> baseParams = base.allparams();
1982 if (ownerParams.nonEmpty()) {
1983 if (baseParams.isEmpty()) {
1984 // then base is a raw type
1985 return erasure(sym.type);
1986 } else {
1987 return subst(sym.type, ownerParams, baseParams);
1988 }
1989 }
1990 }
1991 }
1992 return sym.type;
1993 }
1995 @Override
1996 public Type visitTypeVar(TypeVar t, Symbol sym) {
1997 return memberType(t.bound, sym);
1998 }
2000 @Override
2001 public Type visitErrorType(ErrorType t, Symbol sym) {
2002 return t;
2003 }
2004 };
2005 // </editor-fold>
2007 // <editor-fold defaultstate="collapsed" desc="isAssignable">
2008 public boolean isAssignable(Type t, Type s) {
2009 return isAssignable(t, s, noWarnings);
2010 }
2012 /**
2013 * Is t assignable to s?<br>
2014 * Equivalent to subtype except for constant values and raw
2015 * types.<br>
2016 * (not defined for Method and ForAll types)
2017 */
2018 public boolean isAssignable(Type t, Type s, Warner warn) {
2019 if (t.hasTag(ERROR))
2020 return true;
2021 if (t.getTag().isSubRangeOf(INT) && t.constValue() != null) {
2022 int value = ((Number)t.constValue()).intValue();
2023 switch (s.getTag()) {
2024 case BYTE:
2025 if (Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE)
2026 return true;
2027 break;
2028 case CHAR:
2029 if (Character.MIN_VALUE <= value && value <= Character.MAX_VALUE)
2030 return true;
2031 break;
2032 case SHORT:
2033 if (Short.MIN_VALUE <= value && value <= Short.MAX_VALUE)
2034 return true;
2035 break;
2036 case INT:
2037 return true;
2038 case CLASS:
2039 switch (unboxedType(s).getTag()) {
2040 case BYTE:
2041 case CHAR:
2042 case SHORT:
2043 return isAssignable(t, unboxedType(s), warn);
2044 }
2045 break;
2046 }
2047 }
2048 return isConvertible(t, s, warn);
2049 }
2050 // </editor-fold>
2052 // <editor-fold defaultstate="collapsed" desc="erasure">
2053 /**
2054 * The erasure of t {@code |t|} -- the type that results when all
2055 * type parameters in t are deleted.
2056 */
2057 public Type erasure(Type t) {
2058 return eraseNotNeeded(t)? t : erasure(t, false);
2059 }
2060 //where
2061 private boolean eraseNotNeeded(Type t) {
2062 // We don't want to erase primitive types and String type as that
2063 // operation is idempotent. Also, erasing these could result in loss
2064 // of information such as constant values attached to such types.
2065 return (t.isPrimitive()) || (syms.stringType.tsym == t.tsym);
2066 }
2068 private Type erasure(Type t, boolean recurse) {
2069 if (t.isPrimitive())
2070 return t; /* fast special case */
2071 else
2072 return erasure.visit(t, recurse);
2073 }
2074 // where
2075 private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() {
2076 public Type visitType(Type t, Boolean recurse) {
2077 if (t.isPrimitive())
2078 return t; /*fast special case*/
2079 else
2080 return t.map(recurse ? erasureRecFun : erasureFun);
2081 }
2083 @Override
2084 public Type visitWildcardType(WildcardType t, Boolean recurse) {
2085 return erasure(upperBound(t), recurse);
2086 }
2088 @Override
2089 public Type visitClassType(ClassType t, Boolean recurse) {
2090 Type erased = t.tsym.erasure(Types.this);
2091 if (recurse) {
2092 erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym);
2093 }
2094 return erased;
2095 }
2097 @Override
2098 public Type visitTypeVar(TypeVar t, Boolean recurse) {
2099 return erasure(t.bound, recurse);
2100 }
2102 @Override
2103 public Type visitErrorType(ErrorType t, Boolean recurse) {
2104 return t;
2105 }
2107 @Override
2108 public Type visitAnnotatedType(AnnotatedType t, Boolean recurse) {
2109 Type erased = erasure(t.underlyingType, recurse);
2110 if (erased.isAnnotated()) {
2111 // This can only happen when the underlying type is a
2112 // type variable and the upper bound of it is annotated.
2113 // The annotation on the type variable overrides the one
2114 // on the bound.
2115 erased = ((AnnotatedType)erased).underlyingType;
2116 }
2117 return new AnnotatedType(t.typeAnnotations, erased);
2118 }
2119 };
2121 private Mapping erasureFun = new Mapping ("erasure") {
2122 public Type apply(Type t) { return erasure(t); }
2123 };
2125 private Mapping erasureRecFun = new Mapping ("erasureRecursive") {
2126 public Type apply(Type t) { return erasureRecursive(t); }
2127 };
2129 public List<Type> erasure(List<Type> ts) {
2130 return Type.map(ts, erasureFun);
2131 }
2133 public Type erasureRecursive(Type t) {
2134 return erasure(t, true);
2135 }
2137 public List<Type> erasureRecursive(List<Type> ts) {
2138 return Type.map(ts, erasureRecFun);
2139 }
2140 // </editor-fold>
2142 // <editor-fold defaultstate="collapsed" desc="makeCompoundType">
2143 /**
2144 * Make a compound type from non-empty list of types
2145 *
2146 * @param bounds the types from which the compound type is formed
2147 * @param supertype is objectType if all bounds are interfaces,
2148 * null otherwise.
2149 */
2150 public Type makeCompoundType(List<Type> bounds) {
2151 return makeCompoundType(bounds, bounds.head.tsym.isInterface());
2152 }
2153 public Type makeCompoundType(List<Type> bounds, boolean allInterfaces) {
2154 Assert.check(bounds.nonEmpty());
2155 Type firstExplicitBound = bounds.head;
2156 if (allInterfaces) {
2157 bounds = bounds.prepend(syms.objectType);
2158 }
2159 ClassSymbol bc =
2160 new ClassSymbol(ABSTRACT|PUBLIC|SYNTHETIC|COMPOUND|ACYCLIC,
2161 Type.moreInfo
2162 ? names.fromString(bounds.toString())
2163 : names.empty,
2164 null,
2165 syms.noSymbol);
2166 bc.type = new IntersectionClassType(bounds, bc, allInterfaces);
2167 bc.erasure_field = (bounds.head.hasTag(TYPEVAR)) ?
2168 syms.objectType : // error condition, recover
2169 erasure(firstExplicitBound);
2170 bc.members_field = new Scope(bc);
2171 return bc.type;
2172 }
2174 /**
2175 * A convenience wrapper for {@link #makeCompoundType(List)}; the
2176 * arguments are converted to a list and passed to the other
2177 * method. Note that this might cause a symbol completion.
2178 * Hence, this version of makeCompoundType may not be called
2179 * during a classfile read.
2180 */
2181 public Type makeCompoundType(Type bound1, Type bound2) {
2182 return makeCompoundType(List.of(bound1, bound2));
2183 }
2184 // </editor-fold>
2186 // <editor-fold defaultstate="collapsed" desc="supertype">
2187 public Type supertype(Type t) {
2188 return supertype.visit(t);
2189 }
2190 // where
2191 private UnaryVisitor<Type> supertype = new UnaryVisitor<Type>() {
2193 public Type visitType(Type t, Void ignored) {
2194 // A note on wildcards: there is no good way to
2195 // determine a supertype for a super bounded wildcard.
2196 return null;
2197 }
2199 @Override
2200 public Type visitClassType(ClassType t, Void ignored) {
2201 if (t.supertype_field == null) {
2202 Type supertype = ((ClassSymbol)t.tsym).getSuperclass();
2203 // An interface has no superclass; its supertype is Object.
2204 if (t.isInterface())
2205 supertype = ((ClassType)t.tsym.type).supertype_field;
2206 if (t.supertype_field == null) {
2207 List<Type> actuals = classBound(t).allparams();
2208 List<Type> formals = t.tsym.type.allparams();
2209 if (t.hasErasedSupertypes()) {
2210 t.supertype_field = erasureRecursive(supertype);
2211 } else if (formals.nonEmpty()) {
2212 t.supertype_field = subst(supertype, formals, actuals);
2213 }
2214 else {
2215 t.supertype_field = supertype;
2216 }
2217 }
2218 }
2219 return t.supertype_field;
2220 }
2222 /**
2223 * The supertype is always a class type. If the type
2224 * variable's bounds start with a class type, this is also
2225 * the supertype. Otherwise, the supertype is
2226 * java.lang.Object.
2227 */
2228 @Override
2229 public Type visitTypeVar(TypeVar t, Void ignored) {
2230 if (t.bound.hasTag(TYPEVAR) ||
2231 (!t.bound.isCompound() && !t.bound.isInterface())) {
2232 return t.bound;
2233 } else {
2234 return supertype(t.bound);
2235 }
2236 }
2238 @Override
2239 public Type visitArrayType(ArrayType t, Void ignored) {
2240 if (t.elemtype.isPrimitive() || isSameType(t.elemtype, syms.objectType))
2241 return arraySuperType();
2242 else
2243 return new ArrayType(supertype(t.elemtype), t.tsym);
2244 }
2246 @Override
2247 public Type visitErrorType(ErrorType t, Void ignored) {
2248 return t;
2249 }
2250 };
2251 // </editor-fold>
2253 // <editor-fold defaultstate="collapsed" desc="interfaces">
2254 /**
2255 * Return the interfaces implemented by this class.
2256 */
2257 public List<Type> interfaces(Type t) {
2258 return interfaces.visit(t);
2259 }
2260 // where
2261 private UnaryVisitor<List<Type>> interfaces = new UnaryVisitor<List<Type>>() {
2263 public List<Type> visitType(Type t, Void ignored) {
2264 return List.nil();
2265 }
2267 @Override
2268 public List<Type> visitClassType(ClassType t, Void ignored) {
2269 if (t.interfaces_field == null) {
2270 List<Type> interfaces = ((ClassSymbol)t.tsym).getInterfaces();
2271 if (t.interfaces_field == null) {
2272 // If t.interfaces_field is null, then t must
2273 // be a parameterized type (not to be confused
2274 // with a generic type declaration).
2275 // Terminology:
2276 // Parameterized type: List<String>
2277 // Generic type declaration: class List<E> { ... }
2278 // So t corresponds to List<String> and
2279 // t.tsym.type corresponds to List<E>.
2280 // The reason t must be parameterized type is
2281 // that completion will happen as a side
2282 // effect of calling
2283 // ClassSymbol.getInterfaces. Since
2284 // t.interfaces_field is null after
2285 // completion, we can assume that t is not the
2286 // type of a class/interface declaration.
2287 Assert.check(t != t.tsym.type, t);
2288 List<Type> actuals = t.allparams();
2289 List<Type> formals = t.tsym.type.allparams();
2290 if (t.hasErasedSupertypes()) {
2291 t.interfaces_field = erasureRecursive(interfaces);
2292 } else if (formals.nonEmpty()) {
2293 t.interfaces_field =
2294 upperBounds(subst(interfaces, formals, actuals));
2295 }
2296 else {
2297 t.interfaces_field = interfaces;
2298 }
2299 }
2300 }
2301 return t.interfaces_field;
2302 }
2304 @Override
2305 public List<Type> visitTypeVar(TypeVar t, Void ignored) {
2306 if (t.bound.isCompound())
2307 return interfaces(t.bound);
2309 if (t.bound.isInterface())
2310 return List.of(t.bound);
2312 return List.nil();
2313 }
2314 };
2316 public boolean isDirectSuperInterface(TypeSymbol isym, TypeSymbol origin) {
2317 for (Type i2 : interfaces(origin.type)) {
2318 if (isym == i2.tsym) return true;
2319 }
2320 return false;
2321 }
2322 // </editor-fold>
2324 // <editor-fold defaultstate="collapsed" desc="isDerivedRaw">
2325 Map<Type,Boolean> isDerivedRawCache = new HashMap<Type,Boolean>();
2327 public boolean isDerivedRaw(Type t) {
2328 Boolean result = isDerivedRawCache.get(t);
2329 if (result == null) {
2330 result = isDerivedRawInternal(t);
2331 isDerivedRawCache.put(t, result);
2332 }
2333 return result;
2334 }
2336 public boolean isDerivedRawInternal(Type t) {
2337 if (t.isErroneous())
2338 return false;
2339 return
2340 t.isRaw() ||
2341 supertype(t) != null && isDerivedRaw(supertype(t)) ||
2342 isDerivedRaw(interfaces(t));
2343 }
2345 public boolean isDerivedRaw(List<Type> ts) {
2346 List<Type> l = ts;
2347 while (l.nonEmpty() && !isDerivedRaw(l.head)) l = l.tail;
2348 return l.nonEmpty();
2349 }
2350 // </editor-fold>
2352 // <editor-fold defaultstate="collapsed" desc="setBounds">
2353 /**
2354 * Set the bounds field of the given type variable to reflect a
2355 * (possibly multiple) list of bounds.
2356 * @param t a type variable
2357 * @param bounds the bounds, must be nonempty
2358 * @param supertype is objectType if all bounds are interfaces,
2359 * null otherwise.
2360 */
2361 public void setBounds(TypeVar t, List<Type> bounds) {
2362 setBounds(t, bounds, bounds.head.tsym.isInterface());
2363 }
2365 /**
2366 * Same as {@link #setBounds(Type.TypeVar,List,Type)}, except that
2367 * third parameter is computed directly, as follows: if all
2368 * all bounds are interface types, the computed supertype is Object,
2369 * otherwise the supertype is simply left null (in this case, the supertype
2370 * is assumed to be the head of the bound list passed as second argument).
2371 * Note that this check might cause a symbol completion. Hence, this version of
2372 * setBounds may not be called during a classfile read.
2373 */
2374 public void setBounds(TypeVar t, List<Type> bounds, boolean allInterfaces) {
2375 t.bound = bounds.tail.isEmpty() ?
2376 bounds.head :
2377 makeCompoundType(bounds, allInterfaces);
2378 t.rank_field = -1;
2379 }
2380 // </editor-fold>
2382 // <editor-fold defaultstate="collapsed" desc="getBounds">
2383 /**
2384 * Return list of bounds of the given type variable.
2385 */
2386 public List<Type> getBounds(TypeVar t) {
2387 if (t.bound.hasTag(NONE))
2388 return List.nil();
2389 else if (t.bound.isErroneous() || !t.bound.isCompound())
2390 return List.of(t.bound);
2391 else if ((erasure(t).tsym.flags() & INTERFACE) == 0)
2392 return interfaces(t).prepend(supertype(t));
2393 else
2394 // No superclass was given in bounds.
2395 // In this case, supertype is Object, erasure is first interface.
2396 return interfaces(t);
2397 }
2398 // </editor-fold>
2400 // <editor-fold defaultstate="collapsed" desc="classBound">
2401 /**
2402 * If the given type is a (possibly selected) type variable,
2403 * return the bounding class of this type, otherwise return the
2404 * type itself.
2405 */
2406 public Type classBound(Type t) {
2407 return classBound.visit(t);
2408 }
2409 // where
2410 private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() {
2412 public Type visitType(Type t, Void ignored) {
2413 return t;
2414 }
2416 @Override
2417 public Type visitClassType(ClassType t, Void ignored) {
2418 Type outer1 = classBound(t.getEnclosingType());
2419 if (outer1 != t.getEnclosingType())
2420 return new ClassType(outer1, t.getTypeArguments(), t.tsym);
2421 else
2422 return t;
2423 }
2425 @Override
2426 public Type visitTypeVar(TypeVar t, Void ignored) {
2427 return classBound(supertype(t));
2428 }
2430 @Override
2431 public Type visitErrorType(ErrorType t, Void ignored) {
2432 return t;
2433 }
2434 };
2435 // </editor-fold>
2437 // <editor-fold defaultstate="collapsed" desc="sub signature / override equivalence">
2438 /**
2439 * Returns true iff the first signature is a <em>sub
2440 * signature</em> of the other. This is <b>not</b> an equivalence
2441 * relation.
2442 *
2443 * @jls section 8.4.2.
2444 * @see #overrideEquivalent(Type t, Type s)
2445 * @param t first signature (possibly raw).
2446 * @param s second signature (could be subjected to erasure).
2447 * @return true if t is a sub signature of s.
2448 */
2449 public boolean isSubSignature(Type t, Type s) {
2450 return isSubSignature(t, s, true);
2451 }
2453 public boolean isSubSignature(Type t, Type s, boolean strict) {
2454 return hasSameArgs(t, s, strict) || hasSameArgs(t, erasure(s), strict);
2455 }
2457 /**
2458 * Returns true iff these signatures are related by <em>override
2459 * equivalence</em>. This is the natural extension of
2460 * isSubSignature to an equivalence relation.
2461 *
2462 * @jls section 8.4.2.
2463 * @see #isSubSignature(Type t, Type s)
2464 * @param t a signature (possible raw, could be subjected to
2465 * erasure).
2466 * @param s a signature (possible raw, could be subjected to
2467 * erasure).
2468 * @return true if either argument is a sub signature of the other.
2469 */
2470 public boolean overrideEquivalent(Type t, Type s) {
2471 return hasSameArgs(t, s) ||
2472 hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s);
2473 }
2475 public boolean overridesObjectMethod(TypeSymbol origin, Symbol msym) {
2476 for (Scope.Entry e = syms.objectType.tsym.members().lookup(msym.name) ; e.scope != null ; e = e.next()) {
2477 if (msym.overrides(e.sym, origin, Types.this, true)) {
2478 return true;
2479 }
2480 }
2481 return false;
2482 }
2484 // <editor-fold defaultstate="collapsed" desc="Determining method implementation in given site">
2485 class ImplementationCache {
2487 private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, Entry>>> _map =
2488 new WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, Entry>>>();
2490 class Entry {
2491 final MethodSymbol cachedImpl;
2492 final Filter<Symbol> implFilter;
2493 final boolean checkResult;
2494 final int prevMark;
2496 public Entry(MethodSymbol cachedImpl,
2497 Filter<Symbol> scopeFilter,
2498 boolean checkResult,
2499 int prevMark) {
2500 this.cachedImpl = cachedImpl;
2501 this.implFilter = scopeFilter;
2502 this.checkResult = checkResult;
2503 this.prevMark = prevMark;
2504 }
2506 boolean matches(Filter<Symbol> scopeFilter, boolean checkResult, int mark) {
2507 return this.implFilter == scopeFilter &&
2508 this.checkResult == checkResult &&
2509 this.prevMark == mark;
2510 }
2511 }
2513 MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
2514 SoftReference<Map<TypeSymbol, Entry>> ref_cache = _map.get(ms);
2515 Map<TypeSymbol, Entry> cache = ref_cache != null ? ref_cache.get() : null;
2516 if (cache == null) {
2517 cache = new HashMap<TypeSymbol, Entry>();
2518 _map.put(ms, new SoftReference<Map<TypeSymbol, Entry>>(cache));
2519 }
2520 Entry e = cache.get(origin);
2521 CompoundScope members = membersClosure(origin.type, true);
2522 if (e == null ||
2523 !e.matches(implFilter, checkResult, members.getMark())) {
2524 MethodSymbol impl = implementationInternal(ms, origin, checkResult, implFilter);
2525 cache.put(origin, new Entry(impl, implFilter, checkResult, members.getMark()));
2526 return impl;
2527 }
2528 else {
2529 return e.cachedImpl;
2530 }
2531 }
2533 private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
2534 for (Type t = origin.type; t.hasTag(CLASS) || t.hasTag(TYPEVAR); t = supertype(t)) {
2535 while (t.hasTag(TYPEVAR))
2536 t = t.getUpperBound();
2537 TypeSymbol c = t.tsym;
2538 for (Scope.Entry e = c.members().lookup(ms.name, implFilter);
2539 e.scope != null;
2540 e = e.next(implFilter)) {
2541 if (e.sym != null &&
2542 e.sym.overrides(ms, origin, Types.this, checkResult))
2543 return (MethodSymbol)e.sym;
2544 }
2545 }
2546 return null;
2547 }
2548 }
2550 private ImplementationCache implCache = new ImplementationCache();
2552 public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
2553 return implCache.get(ms, origin, checkResult, implFilter);
2554 }
2555 // </editor-fold>
2557 // <editor-fold defaultstate="collapsed" desc="compute transitive closure of all members in given site">
2558 class MembersClosureCache extends SimpleVisitor<CompoundScope, Boolean> {
2560 private WeakHashMap<TypeSymbol, Entry> _map =
2561 new WeakHashMap<TypeSymbol, Entry>();
2563 class Entry {
2564 final boolean skipInterfaces;
2565 final CompoundScope compoundScope;
2567 public Entry(boolean skipInterfaces, CompoundScope compoundScope) {
2568 this.skipInterfaces = skipInterfaces;
2569 this.compoundScope = compoundScope;
2570 }
2572 boolean matches(boolean skipInterfaces) {
2573 return this.skipInterfaces == skipInterfaces;
2574 }
2575 }
2577 List<TypeSymbol> seenTypes = List.nil();
2579 /** members closure visitor methods **/
2581 public CompoundScope visitType(Type t, Boolean skipInterface) {
2582 return null;
2583 }
2585 @Override
2586 public CompoundScope visitClassType(ClassType t, Boolean skipInterface) {
2587 if (seenTypes.contains(t.tsym)) {
2588 //this is possible when an interface is implemented in multiple
2589 //superclasses, or when a classs hierarchy is circular - in such
2590 //cases we don't need to recurse (empty scope is returned)
2591 return new CompoundScope(t.tsym);
2592 }
2593 try {
2594 seenTypes = seenTypes.prepend(t.tsym);
2595 ClassSymbol csym = (ClassSymbol)t.tsym;
2596 Entry e = _map.get(csym);
2597 if (e == null || !e.matches(skipInterface)) {
2598 CompoundScope membersClosure = new CompoundScope(csym);
2599 if (!skipInterface) {
2600 for (Type i : interfaces(t)) {
2601 membersClosure.addSubScope(visit(i, skipInterface));
2602 }
2603 }
2604 membersClosure.addSubScope(visit(supertype(t), skipInterface));
2605 membersClosure.addSubScope(csym.members());
2606 e = new Entry(skipInterface, membersClosure);
2607 _map.put(csym, e);
2608 }
2609 return e.compoundScope;
2610 }
2611 finally {
2612 seenTypes = seenTypes.tail;
2613 }
2614 }
2616 @Override
2617 public CompoundScope visitTypeVar(TypeVar t, Boolean skipInterface) {
2618 return visit(t.getUpperBound(), skipInterface);
2619 }
2620 }
2622 private MembersClosureCache membersCache = new MembersClosureCache();
2624 public CompoundScope membersClosure(Type site, boolean skipInterface) {
2625 return membersCache.visit(site, skipInterface);
2626 }
2627 // </editor-fold>
2630 //where
2631 public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms) {
2632 Filter<Symbol> filter = new MethodFilter(ms, site);
2633 List<MethodSymbol> candidates = List.nil();
2634 for (Symbol s : membersClosure(site, false).getElements(filter)) {
2635 if (!site.tsym.isInterface() && !s.owner.isInterface()) {
2636 return List.of((MethodSymbol)s);
2637 } else if (!candidates.contains(s)) {
2638 candidates = candidates.prepend((MethodSymbol)s);
2639 }
2640 }
2641 return prune(candidates);
2642 }
2644 public List<MethodSymbol> prune(List<MethodSymbol> methods) {
2645 ListBuffer<MethodSymbol> methodsMin = ListBuffer.lb();
2646 for (MethodSymbol m1 : methods) {
2647 boolean isMin_m1 = true;
2648 for (MethodSymbol m2 : methods) {
2649 if (m1 == m2) continue;
2650 if (m2.owner != m1.owner &&
2651 asSuper(m2.owner.type, m1.owner) != null) {
2652 isMin_m1 = false;
2653 break;
2654 }
2655 }
2656 if (isMin_m1)
2657 methodsMin.append(m1);
2658 }
2659 return methodsMin.toList();
2660 }
2661 // where
2662 private class MethodFilter implements Filter<Symbol> {
2664 Symbol msym;
2665 Type site;
2667 MethodFilter(Symbol msym, Type site) {
2668 this.msym = msym;
2669 this.site = site;
2670 }
2672 public boolean accepts(Symbol s) {
2673 return s.kind == Kinds.MTH &&
2674 s.name == msym.name &&
2675 s.isInheritedIn(site.tsym, Types.this) &&
2676 overrideEquivalent(memberType(site, s), memberType(site, msym));
2677 }
2678 };
2679 // </editor-fold>
2681 /**
2682 * Does t have the same arguments as s? It is assumed that both
2683 * types are (possibly polymorphic) method types. Monomorphic
2684 * method types "have the same arguments", if their argument lists
2685 * are equal. Polymorphic method types "have the same arguments",
2686 * if they have the same arguments after renaming all type
2687 * variables of one to corresponding type variables in the other,
2688 * where correspondence is by position in the type parameter list.
2689 */
2690 public boolean hasSameArgs(Type t, Type s) {
2691 return hasSameArgs(t, s, true);
2692 }
2694 public boolean hasSameArgs(Type t, Type s, boolean strict) {
2695 return hasSameArgs(t, s, strict ? hasSameArgs_strict : hasSameArgs_nonstrict);
2696 }
2698 private boolean hasSameArgs(Type t, Type s, TypeRelation hasSameArgs) {
2699 return hasSameArgs.visit(t, s);
2700 }
2701 // where
2702 private class HasSameArgs extends TypeRelation {
2704 boolean strict;
2706 public HasSameArgs(boolean strict) {
2707 this.strict = strict;
2708 }
2710 public Boolean visitType(Type t, Type s) {
2711 throw new AssertionError();
2712 }
2714 @Override
2715 public Boolean visitMethodType(MethodType t, Type s) {
2716 return s.hasTag(METHOD)
2717 && containsTypeEquivalent(t.argtypes, s.getParameterTypes());
2718 }
2720 @Override
2721 public Boolean visitForAll(ForAll t, Type s) {
2722 if (!s.hasTag(FORALL))
2723 return strict ? false : visitMethodType(t.asMethodType(), s);
2725 ForAll forAll = (ForAll)s;
2726 return hasSameBounds(t, forAll)
2727 && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
2728 }
2730 @Override
2731 public Boolean visitErrorType(ErrorType t, Type s) {
2732 return false;
2733 }
2734 };
2736 TypeRelation hasSameArgs_strict = new HasSameArgs(true);
2737 TypeRelation hasSameArgs_nonstrict = new HasSameArgs(false);
2739 // </editor-fold>
2741 // <editor-fold defaultstate="collapsed" desc="subst">
2742 public List<Type> subst(List<Type> ts,
2743 List<Type> from,
2744 List<Type> to) {
2745 return new Subst(from, to).subst(ts);
2746 }
2748 /**
2749 * Substitute all occurrences of a type in `from' with the
2750 * corresponding type in `to' in 't'. Match lists `from' and `to'
2751 * from the right: If lists have different length, discard leading
2752 * elements of the longer list.
2753 */
2754 public Type subst(Type t, List<Type> from, List<Type> to) {
2755 return new Subst(from, to).subst(t);
2756 }
2758 private class Subst extends UnaryVisitor<Type> {
2759 List<Type> from;
2760 List<Type> to;
2762 public Subst(List<Type> from, List<Type> to) {
2763 int fromLength = from.length();
2764 int toLength = to.length();
2765 while (fromLength > toLength) {
2766 fromLength--;
2767 from = from.tail;
2768 }
2769 while (fromLength < toLength) {
2770 toLength--;
2771 to = to.tail;
2772 }
2773 this.from = from;
2774 this.to = to;
2775 }
2777 Type subst(Type t) {
2778 if (from.tail == null)
2779 return t;
2780 else
2781 return visit(t);
2782 }
2784 List<Type> subst(List<Type> ts) {
2785 if (from.tail == null)
2786 return ts;
2787 boolean wild = false;
2788 if (ts.nonEmpty() && from.nonEmpty()) {
2789 Type head1 = subst(ts.head);
2790 List<Type> tail1 = subst(ts.tail);
2791 if (head1 != ts.head || tail1 != ts.tail)
2792 return tail1.prepend(head1);
2793 }
2794 return ts;
2795 }
2797 public Type visitType(Type t, Void ignored) {
2798 return t;
2799 }
2801 @Override
2802 public Type visitMethodType(MethodType t, Void ignored) {
2803 List<Type> argtypes = subst(t.argtypes);
2804 Type restype = subst(t.restype);
2805 List<Type> thrown = subst(t.thrown);
2806 if (argtypes == t.argtypes &&
2807 restype == t.restype &&
2808 thrown == t.thrown)
2809 return t;
2810 else
2811 return new MethodType(argtypes, restype, thrown, t.tsym);
2812 }
2814 @Override
2815 public Type visitTypeVar(TypeVar t, Void ignored) {
2816 for (List<Type> from = this.from, to = this.to;
2817 from.nonEmpty();
2818 from = from.tail, to = to.tail) {
2819 if (t == from.head) {
2820 return to.head.withTypeVar(t);
2821 }
2822 }
2823 return t;
2824 }
2826 @Override
2827 public Type visitClassType(ClassType t, Void ignored) {
2828 if (!t.isCompound()) {
2829 List<Type> typarams = t.getTypeArguments();
2830 List<Type> typarams1 = subst(typarams);
2831 Type outer = t.getEnclosingType();
2832 Type outer1 = subst(outer);
2833 if (typarams1 == typarams && outer1 == outer)
2834 return t;
2835 else
2836 return new ClassType(outer1, typarams1, t.tsym);
2837 } else {
2838 Type st = subst(supertype(t));
2839 List<Type> is = upperBounds(subst(interfaces(t)));
2840 if (st == supertype(t) && is == interfaces(t))
2841 return t;
2842 else
2843 return makeCompoundType(is.prepend(st));
2844 }
2845 }
2847 @Override
2848 public Type visitWildcardType(WildcardType t, Void ignored) {
2849 Type bound = t.type;
2850 if (t.kind != BoundKind.UNBOUND)
2851 bound = subst(bound);
2852 if (bound == t.type) {
2853 return t;
2854 } else {
2855 if (t.isExtendsBound() && bound.isExtendsBound())
2856 bound = upperBound(bound);
2857 return new WildcardType(bound, t.kind, syms.boundClass, t.bound);
2858 }
2859 }
2861 @Override
2862 public Type visitArrayType(ArrayType t, Void ignored) {
2863 Type elemtype = subst(t.elemtype);
2864 if (elemtype == t.elemtype)
2865 return t;
2866 else
2867 return new ArrayType(upperBound(elemtype), t.tsym);
2868 }
2870 @Override
2871 public Type visitForAll(ForAll t, Void ignored) {
2872 if (Type.containsAny(to, t.tvars)) {
2873 //perform alpha-renaming of free-variables in 't'
2874 //if 'to' types contain variables that are free in 't'
2875 List<Type> freevars = newInstances(t.tvars);
2876 t = new ForAll(freevars,
2877 Types.this.subst(t.qtype, t.tvars, freevars));
2878 }
2879 List<Type> tvars1 = substBounds(t.tvars, from, to);
2880 Type qtype1 = subst(t.qtype);
2881 if (tvars1 == t.tvars && qtype1 == t.qtype) {
2882 return t;
2883 } else if (tvars1 == t.tvars) {
2884 return new ForAll(tvars1, qtype1);
2885 } else {
2886 return new ForAll(tvars1, Types.this.subst(qtype1, t.tvars, tvars1));
2887 }
2888 }
2890 @Override
2891 public Type visitErrorType(ErrorType t, Void ignored) {
2892 return t;
2893 }
2894 }
2896 public List<Type> substBounds(List<Type> tvars,
2897 List<Type> from,
2898 List<Type> to) {
2899 if (tvars.isEmpty())
2900 return tvars;
2901 ListBuffer<Type> newBoundsBuf = lb();
2902 boolean changed = false;
2903 // calculate new bounds
2904 for (Type t : tvars) {
2905 TypeVar tv = (TypeVar) t;
2906 Type bound = subst(tv.bound, from, to);
2907 if (bound != tv.bound)
2908 changed = true;
2909 newBoundsBuf.append(bound);
2910 }
2911 if (!changed)
2912 return tvars;
2913 ListBuffer<Type> newTvars = lb();
2914 // create new type variables without bounds
2915 for (Type t : tvars) {
2916 newTvars.append(new TypeVar(t.tsym, null, syms.botType));
2917 }
2918 // the new bounds should use the new type variables in place
2919 // of the old
2920 List<Type> newBounds = newBoundsBuf.toList();
2921 from = tvars;
2922 to = newTvars.toList();
2923 for (; !newBounds.isEmpty(); newBounds = newBounds.tail) {
2924 newBounds.head = subst(newBounds.head, from, to);
2925 }
2926 newBounds = newBoundsBuf.toList();
2927 // set the bounds of new type variables to the new bounds
2928 for (Type t : newTvars.toList()) {
2929 TypeVar tv = (TypeVar) t;
2930 tv.bound = newBounds.head;
2931 newBounds = newBounds.tail;
2932 }
2933 return newTvars.toList();
2934 }
2936 public TypeVar substBound(TypeVar t, List<Type> from, List<Type> to) {
2937 Type bound1 = subst(t.bound, from, to);
2938 if (bound1 == t.bound)
2939 return t;
2940 else {
2941 // create new type variable without bounds
2942 TypeVar tv = new TypeVar(t.tsym, null, syms.botType);
2943 // the new bound should use the new type variable in place
2944 // of the old
2945 tv.bound = subst(bound1, List.<Type>of(t), List.<Type>of(tv));
2946 return tv;
2947 }
2948 }
2949 // </editor-fold>
2951 // <editor-fold defaultstate="collapsed" desc="hasSameBounds">
2952 /**
2953 * Does t have the same bounds for quantified variables as s?
2954 */
2955 boolean hasSameBounds(ForAll t, ForAll s) {
2956 List<Type> l1 = t.tvars;
2957 List<Type> l2 = s.tvars;
2958 while (l1.nonEmpty() && l2.nonEmpty() &&
2959 isSameType(l1.head.getUpperBound(),
2960 subst(l2.head.getUpperBound(),
2961 s.tvars,
2962 t.tvars))) {
2963 l1 = l1.tail;
2964 l2 = l2.tail;
2965 }
2966 return l1.isEmpty() && l2.isEmpty();
2967 }
2968 // </editor-fold>
2970 // <editor-fold defaultstate="collapsed" desc="newInstances">
2971 /** Create new vector of type variables from list of variables
2972 * changing all recursive bounds from old to new list.
2973 */
2974 public List<Type> newInstances(List<Type> tvars) {
2975 List<Type> tvars1 = Type.map(tvars, newInstanceFun);
2976 for (List<Type> l = tvars1; l.nonEmpty(); l = l.tail) {
2977 TypeVar tv = (TypeVar) l.head;
2978 tv.bound = subst(tv.bound, tvars, tvars1);
2979 }
2980 return tvars1;
2981 }
2982 private static final Mapping newInstanceFun = new Mapping("newInstanceFun") {
2983 public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound()); }
2984 };
2985 // </editor-fold>
2987 public Type createMethodTypeWithParameters(Type original, List<Type> newParams) {
2988 return original.accept(methodWithParameters, newParams);
2989 }
2990 // where
2991 private final MapVisitor<List<Type>> methodWithParameters = new MapVisitor<List<Type>>() {
2992 public Type visitType(Type t, List<Type> newParams) {
2993 throw new IllegalArgumentException("Not a method type: " + t);
2994 }
2995 public Type visitMethodType(MethodType t, List<Type> newParams) {
2996 return new MethodType(newParams, t.restype, t.thrown, t.tsym);
2997 }
2998 public Type visitForAll(ForAll t, List<Type> newParams) {
2999 return new ForAll(t.tvars, t.qtype.accept(this, newParams));
3000 }
3001 };
3003 public Type createMethodTypeWithThrown(Type original, List<Type> newThrown) {
3004 return original.accept(methodWithThrown, newThrown);
3005 }
3006 // where
3007 private final MapVisitor<List<Type>> methodWithThrown = new MapVisitor<List<Type>>() {
3008 public Type visitType(Type t, List<Type> newThrown) {
3009 throw new IllegalArgumentException("Not a method type: " + t);
3010 }
3011 public Type visitMethodType(MethodType t, List<Type> newThrown) {
3012 return new MethodType(t.argtypes, t.restype, newThrown, t.tsym);
3013 }
3014 public Type visitForAll(ForAll t, List<Type> newThrown) {
3015 return new ForAll(t.tvars, t.qtype.accept(this, newThrown));
3016 }
3017 };
3019 public Type createMethodTypeWithReturn(Type original, Type newReturn) {
3020 return original.accept(methodWithReturn, newReturn);
3021 }
3022 // where
3023 private final MapVisitor<Type> methodWithReturn = new MapVisitor<Type>() {
3024 public Type visitType(Type t, Type newReturn) {
3025 throw new IllegalArgumentException("Not a method type: " + t);
3026 }
3027 public Type visitMethodType(MethodType t, Type newReturn) {
3028 return new MethodType(t.argtypes, newReturn, t.thrown, t.tsym);
3029 }
3030 public Type visitForAll(ForAll t, Type newReturn) {
3031 return new ForAll(t.tvars, t.qtype.accept(this, newReturn));
3032 }
3033 };
3035 // <editor-fold defaultstate="collapsed" desc="createErrorType">
3036 public Type createErrorType(Type originalType) {
3037 return new ErrorType(originalType, syms.errSymbol);
3038 }
3040 public Type createErrorType(ClassSymbol c, Type originalType) {
3041 return new ErrorType(c, originalType);
3042 }
3044 public Type createErrorType(Name name, TypeSymbol container, Type originalType) {
3045 return new ErrorType(name, container, originalType);
3046 }
3047 // </editor-fold>
3049 // <editor-fold defaultstate="collapsed" desc="rank">
3050 /**
3051 * The rank of a class is the length of the longest path between
3052 * the class and java.lang.Object in the class inheritance
3053 * graph. Undefined for all but reference types.
3054 */
3055 public int rank(Type t) {
3056 t = t.unannotatedType();
3057 switch(t.getTag()) {
3058 case CLASS: {
3059 ClassType cls = (ClassType)t;
3060 if (cls.rank_field < 0) {
3061 Name fullname = cls.tsym.getQualifiedName();
3062 if (fullname == names.java_lang_Object)
3063 cls.rank_field = 0;
3064 else {
3065 int r = rank(supertype(cls));
3066 for (List<Type> l = interfaces(cls);
3067 l.nonEmpty();
3068 l = l.tail) {
3069 if (rank(l.head) > r)
3070 r = rank(l.head);
3071 }
3072 cls.rank_field = r + 1;
3073 }
3074 }
3075 return cls.rank_field;
3076 }
3077 case TYPEVAR: {
3078 TypeVar tvar = (TypeVar)t;
3079 if (tvar.rank_field < 0) {
3080 int r = rank(supertype(tvar));
3081 for (List<Type> l = interfaces(tvar);
3082 l.nonEmpty();
3083 l = l.tail) {
3084 if (rank(l.head) > r) r = rank(l.head);
3085 }
3086 tvar.rank_field = r + 1;
3087 }
3088 return tvar.rank_field;
3089 }
3090 case ERROR:
3091 return 0;
3092 default:
3093 throw new AssertionError();
3094 }
3095 }
3096 // </editor-fold>
3098 /**
3099 * Helper method for generating a string representation of a given type
3100 * accordingly to a given locale
3101 */
3102 public String toString(Type t, Locale locale) {
3103 return Printer.createStandardPrinter(messages).visit(t, locale);
3104 }
3106 /**
3107 * Helper method for generating a string representation of a given type
3108 * accordingly to a given locale
3109 */
3110 public String toString(Symbol t, Locale locale) {
3111 return Printer.createStandardPrinter(messages).visit(t, locale);
3112 }
3114 // <editor-fold defaultstate="collapsed" desc="toString">
3115 /**
3116 * This toString is slightly more descriptive than the one on Type.
3117 *
3118 * @deprecated Types.toString(Type t, Locale l) provides better support
3119 * for localization
3120 */
3121 @Deprecated
3122 public String toString(Type t) {
3123 if (t.hasTag(FORALL)) {
3124 ForAll forAll = (ForAll)t;
3125 return typaramsString(forAll.tvars) + forAll.qtype;
3126 }
3127 return "" + t;
3128 }
3129 // where
3130 private String typaramsString(List<Type> tvars) {
3131 StringBuilder s = new StringBuilder();
3132 s.append('<');
3133 boolean first = true;
3134 for (Type t : tvars) {
3135 if (!first) s.append(", ");
3136 first = false;
3137 appendTyparamString(((TypeVar)t.unannotatedType()), s);
3138 }
3139 s.append('>');
3140 return s.toString();
3141 }
3142 private void appendTyparamString(TypeVar t, StringBuilder buf) {
3143 buf.append(t);
3144 if (t.bound == null ||
3145 t.bound.tsym.getQualifiedName() == names.java_lang_Object)
3146 return;
3147 buf.append(" extends "); // Java syntax; no need for i18n
3148 Type bound = t.bound;
3149 if (!bound.isCompound()) {
3150 buf.append(bound);
3151 } else if ((erasure(t).tsym.flags() & INTERFACE) == 0) {
3152 buf.append(supertype(t));
3153 for (Type intf : interfaces(t)) {
3154 buf.append('&');
3155 buf.append(intf);
3156 }
3157 } else {
3158 // No superclass was given in bounds.
3159 // In this case, supertype is Object, erasure is first interface.
3160 boolean first = true;
3161 for (Type intf : interfaces(t)) {
3162 if (!first) buf.append('&');
3163 first = false;
3164 buf.append(intf);
3165 }
3166 }
3167 }
3168 // </editor-fold>
3170 // <editor-fold defaultstate="collapsed" desc="Determining least upper bounds of types">
3171 /**
3172 * A cache for closures.
3173 *
3174 * <p>A closure is a list of all the supertypes and interfaces of
3175 * a class or interface type, ordered by ClassSymbol.precedes
3176 * (that is, subclasses come first, arbitrary but fixed
3177 * otherwise).
3178 */
3179 private Map<Type,List<Type>> closureCache = new HashMap<Type,List<Type>>();
3181 /**
3182 * Returns the closure of a class or interface type.
3183 */
3184 public List<Type> closure(Type t) {
3185 List<Type> cl = closureCache.get(t);
3186 if (cl == null) {
3187 Type st = supertype(t);
3188 if (!t.isCompound()) {
3189 if (st.hasTag(CLASS)) {
3190 cl = insert(closure(st), t);
3191 } else if (st.hasTag(TYPEVAR)) {
3192 cl = closure(st).prepend(t);
3193 } else {
3194 cl = List.of(t);
3195 }
3196 } else {
3197 cl = closure(supertype(t));
3198 }
3199 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail)
3200 cl = union(cl, closure(l.head));
3201 closureCache.put(t, cl);
3202 }
3203 return cl;
3204 }
3206 /**
3207 * Insert a type in a closure
3208 */
3209 public List<Type> insert(List<Type> cl, Type t) {
3210 if (cl.isEmpty() || t.tsym.precedes(cl.head.tsym, this)) {
3211 return cl.prepend(t);
3212 } else if (cl.head.tsym.precedes(t.tsym, this)) {
3213 return insert(cl.tail, t).prepend(cl.head);
3214 } else {
3215 return cl;
3216 }
3217 }
3219 /**
3220 * Form the union of two closures
3221 */
3222 public List<Type> union(List<Type> cl1, List<Type> cl2) {
3223 if (cl1.isEmpty()) {
3224 return cl2;
3225 } else if (cl2.isEmpty()) {
3226 return cl1;
3227 } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) {
3228 return union(cl1.tail, cl2).prepend(cl1.head);
3229 } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) {
3230 return union(cl1, cl2.tail).prepend(cl2.head);
3231 } else {
3232 return union(cl1.tail, cl2.tail).prepend(cl1.head);
3233 }
3234 }
3236 /**
3237 * Intersect two closures
3238 */
3239 public List<Type> intersect(List<Type> cl1, List<Type> cl2) {
3240 if (cl1 == cl2)
3241 return cl1;
3242 if (cl1.isEmpty() || cl2.isEmpty())
3243 return List.nil();
3244 if (cl1.head.tsym.precedes(cl2.head.tsym, this))
3245 return intersect(cl1.tail, cl2);
3246 if (cl2.head.tsym.precedes(cl1.head.tsym, this))
3247 return intersect(cl1, cl2.tail);
3248 if (isSameType(cl1.head, cl2.head))
3249 return intersect(cl1.tail, cl2.tail).prepend(cl1.head);
3250 if (cl1.head.tsym == cl2.head.tsym &&
3251 cl1.head.hasTag(CLASS) && cl2.head.hasTag(CLASS)) {
3252 if (cl1.head.isParameterized() && cl2.head.isParameterized()) {
3253 Type merge = merge(cl1.head,cl2.head);
3254 return intersect(cl1.tail, cl2.tail).prepend(merge);
3255 }
3256 if (cl1.head.isRaw() || cl2.head.isRaw())
3257 return intersect(cl1.tail, cl2.tail).prepend(erasure(cl1.head));
3258 }
3259 return intersect(cl1.tail, cl2.tail);
3260 }
3261 // where
3262 class TypePair {
3263 final Type t1;
3264 final Type t2;
3265 TypePair(Type t1, Type t2) {
3266 this.t1 = t1;
3267 this.t2 = t2;
3268 }
3269 @Override
3270 public int hashCode() {
3271 return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2);
3272 }
3273 @Override
3274 public boolean equals(Object obj) {
3275 if (!(obj instanceof TypePair))
3276 return false;
3277 TypePair typePair = (TypePair)obj;
3278 return isSameType(t1, typePair.t1)
3279 && isSameType(t2, typePair.t2);
3280 }
3281 }
3282 Set<TypePair> mergeCache = new HashSet<TypePair>();
3283 private Type merge(Type c1, Type c2) {
3284 ClassType class1 = (ClassType) c1;
3285 List<Type> act1 = class1.getTypeArguments();
3286 ClassType class2 = (ClassType) c2;
3287 List<Type> act2 = class2.getTypeArguments();
3288 ListBuffer<Type> merged = new ListBuffer<Type>();
3289 List<Type> typarams = class1.tsym.type.getTypeArguments();
3291 while (act1.nonEmpty() && act2.nonEmpty() && typarams.nonEmpty()) {
3292 if (containsType(act1.head, act2.head)) {
3293 merged.append(act1.head);
3294 } else if (containsType(act2.head, act1.head)) {
3295 merged.append(act2.head);
3296 } else {
3297 TypePair pair = new TypePair(c1, c2);
3298 Type m;
3299 if (mergeCache.add(pair)) {
3300 m = new WildcardType(lub(upperBound(act1.head),
3301 upperBound(act2.head)),
3302 BoundKind.EXTENDS,
3303 syms.boundClass);
3304 mergeCache.remove(pair);
3305 } else {
3306 m = new WildcardType(syms.objectType,
3307 BoundKind.UNBOUND,
3308 syms.boundClass);
3309 }
3310 merged.append(m.withTypeVar(typarams.head));
3311 }
3312 act1 = act1.tail;
3313 act2 = act2.tail;
3314 typarams = typarams.tail;
3315 }
3316 Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
3317 return new ClassType(class1.getEnclosingType(), merged.toList(), class1.tsym);
3318 }
3320 /**
3321 * Return the minimum type of a closure, a compound type if no
3322 * unique minimum exists.
3323 */
3324 private Type compoundMin(List<Type> cl) {
3325 if (cl.isEmpty()) return syms.objectType;
3326 List<Type> compound = closureMin(cl);
3327 if (compound.isEmpty())
3328 return null;
3329 else if (compound.tail.isEmpty())
3330 return compound.head;
3331 else
3332 return makeCompoundType(compound);
3333 }
3335 /**
3336 * Return the minimum types of a closure, suitable for computing
3337 * compoundMin or glb.
3338 */
3339 private List<Type> closureMin(List<Type> cl) {
3340 ListBuffer<Type> classes = lb();
3341 ListBuffer<Type> interfaces = lb();
3342 while (!cl.isEmpty()) {
3343 Type current = cl.head;
3344 if (current.isInterface())
3345 interfaces.append(current);
3346 else
3347 classes.append(current);
3348 ListBuffer<Type> candidates = lb();
3349 for (Type t : cl.tail) {
3350 if (!isSubtypeNoCapture(current, t))
3351 candidates.append(t);
3352 }
3353 cl = candidates.toList();
3354 }
3355 return classes.appendList(interfaces).toList();
3356 }
3358 /**
3359 * Return the least upper bound of pair of types. if the lub does
3360 * not exist return null.
3361 */
3362 public Type lub(Type t1, Type t2) {
3363 return lub(List.of(t1, t2));
3364 }
3366 /**
3367 * Return the least upper bound (lub) of set of types. If the lub
3368 * does not exist return the type of null (bottom).
3369 */
3370 public Type lub(List<Type> ts) {
3371 final int ARRAY_BOUND = 1;
3372 final int CLASS_BOUND = 2;
3373 int boundkind = 0;
3374 for (Type t : ts) {
3375 switch (t.getTag()) {
3376 case CLASS:
3377 boundkind |= CLASS_BOUND;
3378 break;
3379 case ARRAY:
3380 boundkind |= ARRAY_BOUND;
3381 break;
3382 case TYPEVAR:
3383 do {
3384 t = t.getUpperBound();
3385 } while (t.hasTag(TYPEVAR));
3386 if (t.hasTag(ARRAY)) {
3387 boundkind |= ARRAY_BOUND;
3388 } else {
3389 boundkind |= CLASS_BOUND;
3390 }
3391 break;
3392 default:
3393 if (t.isPrimitive())
3394 return syms.errType;
3395 }
3396 }
3397 switch (boundkind) {
3398 case 0:
3399 return syms.botType;
3401 case ARRAY_BOUND:
3402 // calculate lub(A[], B[])
3403 List<Type> elements = Type.map(ts, elemTypeFun);
3404 for (Type t : elements) {
3405 if (t.isPrimitive()) {
3406 // if a primitive type is found, then return
3407 // arraySuperType unless all the types are the
3408 // same
3409 Type first = ts.head;
3410 for (Type s : ts.tail) {
3411 if (!isSameType(first, s)) {
3412 // lub(int[], B[]) is Cloneable & Serializable
3413 return arraySuperType();
3414 }
3415 }
3416 // all the array types are the same, return one
3417 // lub(int[], int[]) is int[]
3418 return first;
3419 }
3420 }
3421 // lub(A[], B[]) is lub(A, B)[]
3422 return new ArrayType(lub(elements), syms.arrayClass);
3424 case CLASS_BOUND:
3425 // calculate lub(A, B)
3426 while (!ts.head.hasTag(CLASS) && !ts.head.hasTag(TYPEVAR)) {
3427 ts = ts.tail;
3428 }
3429 Assert.check(!ts.isEmpty());
3430 //step 1 - compute erased candidate set (EC)
3431 List<Type> cl = erasedSupertypes(ts.head);
3432 for (Type t : ts.tail) {
3433 if (t.hasTag(CLASS) || t.hasTag(TYPEVAR))
3434 cl = intersect(cl, erasedSupertypes(t));
3435 }
3436 //step 2 - compute minimal erased candidate set (MEC)
3437 List<Type> mec = closureMin(cl);
3438 //step 3 - for each element G in MEC, compute lci(Inv(G))
3439 List<Type> candidates = List.nil();
3440 for (Type erasedSupertype : mec) {
3441 List<Type> lci = List.of(asSuper(ts.head, erasedSupertype.tsym));
3442 for (Type t : ts) {
3443 lci = intersect(lci, List.of(asSuper(t, erasedSupertype.tsym)));
3444 }
3445 candidates = candidates.appendList(lci);
3446 }
3447 //step 4 - let MEC be { G1, G2 ... Gn }, then we have that
3448 //lub = lci(Inv(G1)) & lci(Inv(G2)) & ... & lci(Inv(Gn))
3449 return compoundMin(candidates);
3451 default:
3452 // calculate lub(A, B[])
3453 List<Type> classes = List.of(arraySuperType());
3454 for (Type t : ts) {
3455 if (!t.hasTag(ARRAY)) // Filter out any arrays
3456 classes = classes.prepend(t);
3457 }
3458 // lub(A, B[]) is lub(A, arraySuperType)
3459 return lub(classes);
3460 }
3461 }
3462 // where
3463 List<Type> erasedSupertypes(Type t) {
3464 ListBuffer<Type> buf = lb();
3465 for (Type sup : closure(t)) {
3466 if (sup.hasTag(TYPEVAR)) {
3467 buf.append(sup);
3468 } else {
3469 buf.append(erasure(sup));
3470 }
3471 }
3472 return buf.toList();
3473 }
3475 private Type arraySuperType = null;
3476 private Type arraySuperType() {
3477 // initialized lazily to avoid problems during compiler startup
3478 if (arraySuperType == null) {
3479 synchronized (this) {
3480 if (arraySuperType == null) {
3481 // JLS 10.8: all arrays implement Cloneable and Serializable.
3482 arraySuperType = makeCompoundType(List.of(syms.serializableType,
3483 syms.cloneableType), true);
3484 }
3485 }
3486 }
3487 return arraySuperType;
3488 }
3489 // </editor-fold>
3491 // <editor-fold defaultstate="collapsed" desc="Greatest lower bound">
3492 public Type glb(List<Type> ts) {
3493 Type t1 = ts.head;
3494 for (Type t2 : ts.tail) {
3495 if (t1.isErroneous())
3496 return t1;
3497 t1 = glb(t1, t2);
3498 }
3499 return t1;
3500 }
3501 //where
3502 public Type glb(Type t, Type s) {
3503 if (s == null)
3504 return t;
3505 else if (t.isPrimitive() || s.isPrimitive())
3506 return syms.errType;
3507 else if (isSubtypeNoCapture(t, s))
3508 return t;
3509 else if (isSubtypeNoCapture(s, t))
3510 return s;
3512 List<Type> closure = union(closure(t), closure(s));
3513 List<Type> bounds = closureMin(closure);
3515 if (bounds.isEmpty()) { // length == 0
3516 return syms.objectType;
3517 } else if (bounds.tail.isEmpty()) { // length == 1
3518 return bounds.head;
3519 } else { // length > 1
3520 int classCount = 0;
3521 for (Type bound : bounds)
3522 if (!bound.isInterface())
3523 classCount++;
3524 if (classCount > 1)
3525 return createErrorType(t);
3526 }
3527 return makeCompoundType(bounds);
3528 }
3529 // </editor-fold>
3531 // <editor-fold defaultstate="collapsed" desc="hashCode">
3532 /**
3533 * Compute a hash code on a type.
3534 */
3535 public int hashCode(Type t) {
3536 return hashCode.visit(t);
3537 }
3538 // where
3539 private static final UnaryVisitor<Integer> hashCode = new UnaryVisitor<Integer>() {
3541 public Integer visitType(Type t, Void ignored) {
3542 return t.getTag().ordinal();
3543 }
3545 @Override
3546 public Integer visitClassType(ClassType t, Void ignored) {
3547 int result = visit(t.getEnclosingType());
3548 result *= 127;
3549 result += t.tsym.flatName().hashCode();
3550 for (Type s : t.getTypeArguments()) {
3551 result *= 127;
3552 result += visit(s);
3553 }
3554 return result;
3555 }
3557 @Override
3558 public Integer visitMethodType(MethodType t, Void ignored) {
3559 int h = METHOD.ordinal();
3560 for (List<Type> thisargs = t.argtypes;
3561 thisargs.tail != null;
3562 thisargs = thisargs.tail)
3563 h = (h << 5) + visit(thisargs.head);
3564 return (h << 5) + visit(t.restype);
3565 }
3567 @Override
3568 public Integer visitWildcardType(WildcardType t, Void ignored) {
3569 int result = t.kind.hashCode();
3570 if (t.type != null) {
3571 result *= 127;
3572 result += visit(t.type);
3573 }
3574 return result;
3575 }
3577 @Override
3578 public Integer visitArrayType(ArrayType t, Void ignored) {
3579 return visit(t.elemtype) + 12;
3580 }
3582 @Override
3583 public Integer visitTypeVar(TypeVar t, Void ignored) {
3584 return System.identityHashCode(t.tsym);
3585 }
3587 @Override
3588 public Integer visitUndetVar(UndetVar t, Void ignored) {
3589 return System.identityHashCode(t);
3590 }
3592 @Override
3593 public Integer visitErrorType(ErrorType t, Void ignored) {
3594 return 0;
3595 }
3596 };
3597 // </editor-fold>
3599 // <editor-fold defaultstate="collapsed" desc="Return-Type-Substitutable">
3600 /**
3601 * Does t have a result that is a subtype of the result type of s,
3602 * suitable for covariant returns? It is assumed that both types
3603 * are (possibly polymorphic) method types. Monomorphic method
3604 * types are handled in the obvious way. Polymorphic method types
3605 * require renaming all type variables of one to corresponding
3606 * type variables in the other, where correspondence is by
3607 * position in the type parameter list. */
3608 public boolean resultSubtype(Type t, Type s, Warner warner) {
3609 List<Type> tvars = t.getTypeArguments();
3610 List<Type> svars = s.getTypeArguments();
3611 Type tres = t.getReturnType();
3612 Type sres = subst(s.getReturnType(), svars, tvars);
3613 return covariantReturnType(tres, sres, warner);
3614 }
3616 /**
3617 * Return-Type-Substitutable.
3618 * @jls section 8.4.5
3619 */
3620 public boolean returnTypeSubstitutable(Type r1, Type r2) {
3621 if (hasSameArgs(r1, r2))
3622 return resultSubtype(r1, r2, noWarnings);
3623 else
3624 return covariantReturnType(r1.getReturnType(),
3625 erasure(r2.getReturnType()),
3626 noWarnings);
3627 }
3629 public boolean returnTypeSubstitutable(Type r1,
3630 Type r2, Type r2res,
3631 Warner warner) {
3632 if (isSameType(r1.getReturnType(), r2res))
3633 return true;
3634 if (r1.getReturnType().isPrimitive() || r2res.isPrimitive())
3635 return false;
3637 if (hasSameArgs(r1, r2))
3638 return covariantReturnType(r1.getReturnType(), r2res, warner);
3639 if (!allowCovariantReturns)
3640 return false;
3641 if (isSubtypeUnchecked(r1.getReturnType(), r2res, warner))
3642 return true;
3643 if (!isSubtype(r1.getReturnType(), erasure(r2res)))
3644 return false;
3645 warner.warn(LintCategory.UNCHECKED);
3646 return true;
3647 }
3649 /**
3650 * Is t an appropriate return type in an overrider for a
3651 * method that returns s?
3652 */
3653 public boolean covariantReturnType(Type t, Type s, Warner warner) {
3654 return
3655 isSameType(t, s) ||
3656 allowCovariantReturns &&
3657 !t.isPrimitive() &&
3658 !s.isPrimitive() &&
3659 isAssignable(t, s, warner);
3660 }
3661 // </editor-fold>
3663 // <editor-fold defaultstate="collapsed" desc="Box/unbox support">
3664 /**
3665 * Return the class that boxes the given primitive.
3666 */
3667 public ClassSymbol boxedClass(Type t) {
3668 return reader.enterClass(syms.boxedName[t.getTag().ordinal()]);
3669 }
3671 /**
3672 * Return the boxed type if 't' is primitive, otherwise return 't' itself.
3673 */
3674 public Type boxedTypeOrType(Type t) {
3675 return t.isPrimitive() ?
3676 boxedClass(t).type :
3677 t;
3678 }
3680 /**
3681 * Return the primitive type corresponding to a boxed type.
3682 */
3683 public Type unboxedType(Type t) {
3684 if (allowBoxing) {
3685 for (int i=0; i<syms.boxedName.length; i++) {
3686 Name box = syms.boxedName[i];
3687 if (box != null &&
3688 asSuper(t, reader.enterClass(box)) != null)
3689 return syms.typeOfTag[i];
3690 }
3691 }
3692 return Type.noType;
3693 }
3695 /**
3696 * Return the unboxed type if 't' is a boxed class, otherwise return 't' itself.
3697 */
3698 public Type unboxedTypeOrType(Type t) {
3699 Type unboxedType = unboxedType(t);
3700 return unboxedType.hasTag(NONE) ? t : unboxedType;
3701 }
3702 // </editor-fold>
3704 // <editor-fold defaultstate="collapsed" desc="Capture conversion">
3705 /*
3706 * JLS 5.1.10 Capture Conversion:
3707 *
3708 * Let G name a generic type declaration with n formal type
3709 * parameters A1 ... An with corresponding bounds U1 ... Un. There
3710 * exists a capture conversion from G<T1 ... Tn> to G<S1 ... Sn>,
3711 * where, for 1 <= i <= n:
3712 *
3713 * + If Ti is a wildcard type argument (4.5.1) of the form ? then
3714 * Si is a fresh type variable whose upper bound is
3715 * Ui[A1 := S1, ..., An := Sn] and whose lower bound is the null
3716 * type.
3717 *
3718 * + If Ti is a wildcard type argument of the form ? extends Bi,
3719 * then Si is a fresh type variable whose upper bound is
3720 * glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is
3721 * the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is
3722 * a compile-time error if for any two classes (not interfaces)
3723 * Vi and Vj,Vi is not a subclass of Vj or vice versa.
3724 *
3725 * + If Ti is a wildcard type argument of the form ? super Bi,
3726 * then Si is a fresh type variable whose upper bound is
3727 * Ui[A1 := S1, ..., An := Sn] and whose lower bound is Bi.
3728 *
3729 * + Otherwise, Si = Ti.
3730 *
3731 * Capture conversion on any type other than a parameterized type
3732 * (4.5) acts as an identity conversion (5.1.1). Capture
3733 * conversions never require a special action at run time and
3734 * therefore never throw an exception at run time.
3735 *
3736 * Capture conversion is not applied recursively.
3737 */
3738 /**
3739 * Capture conversion as specified by the JLS.
3740 */
3742 public List<Type> capture(List<Type> ts) {
3743 List<Type> buf = List.nil();
3744 for (Type t : ts) {
3745 buf = buf.prepend(capture(t));
3746 }
3747 return buf.reverse();
3748 }
3749 public Type capture(Type t) {
3750 if (!t.hasTag(CLASS))
3751 return t;
3752 if (t.getEnclosingType() != Type.noType) {
3753 Type capturedEncl = capture(t.getEnclosingType());
3754 if (capturedEncl != t.getEnclosingType()) {
3755 Type type1 = memberType(capturedEncl, t.tsym);
3756 t = subst(type1, t.tsym.type.getTypeArguments(), t.getTypeArguments());
3757 }
3758 }
3759 t = t.unannotatedType();
3760 ClassType cls = (ClassType)t;
3761 if (cls.isRaw() || !cls.isParameterized())
3762 return cls;
3764 ClassType G = (ClassType)cls.asElement().asType();
3765 List<Type> A = G.getTypeArguments();
3766 List<Type> T = cls.getTypeArguments();
3767 List<Type> S = freshTypeVariables(T);
3769 List<Type> currentA = A;
3770 List<Type> currentT = T;
3771 List<Type> currentS = S;
3772 boolean captured = false;
3773 while (!currentA.isEmpty() &&
3774 !currentT.isEmpty() &&
3775 !currentS.isEmpty()) {
3776 if (currentS.head != currentT.head) {
3777 captured = true;
3778 WildcardType Ti = (WildcardType)currentT.head.unannotatedType();
3779 Type Ui = currentA.head.getUpperBound();
3780 CapturedType Si = (CapturedType)currentS.head.unannotatedType();
3781 if (Ui == null)
3782 Ui = syms.objectType;
3783 switch (Ti.kind) {
3784 case UNBOUND:
3785 Si.bound = subst(Ui, A, S);
3786 Si.lower = syms.botType;
3787 break;
3788 case EXTENDS:
3789 Si.bound = glb(Ti.getExtendsBound(), subst(Ui, A, S));
3790 Si.lower = syms.botType;
3791 break;
3792 case SUPER:
3793 Si.bound = subst(Ui, A, S);
3794 Si.lower = Ti.getSuperBound();
3795 break;
3796 }
3797 if (Si.bound == Si.lower)
3798 currentS.head = Si.bound;
3799 }
3800 currentA = currentA.tail;
3801 currentT = currentT.tail;
3802 currentS = currentS.tail;
3803 }
3804 if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty())
3805 return erasure(t); // some "rare" type involved
3807 if (captured)
3808 return new ClassType(cls.getEnclosingType(), S, cls.tsym);
3809 else
3810 return t;
3811 }
3812 // where
3813 public List<Type> freshTypeVariables(List<Type> types) {
3814 ListBuffer<Type> result = lb();
3815 for (Type t : types) {
3816 if (t.hasTag(WILDCARD)) {
3817 t = t.unannotatedType();
3818 Type bound = ((WildcardType)t).getExtendsBound();
3819 if (bound == null)
3820 bound = syms.objectType;
3821 result.append(new CapturedType(capturedName,
3822 syms.noSymbol,
3823 bound,
3824 syms.botType,
3825 (WildcardType)t));
3826 } else {
3827 result.append(t);
3828 }
3829 }
3830 return result.toList();
3831 }
3832 // </editor-fold>
3834 // <editor-fold defaultstate="collapsed" desc="Internal utility methods">
3835 private List<Type> upperBounds(List<Type> ss) {
3836 if (ss.isEmpty()) return ss;
3837 Type head = upperBound(ss.head);
3838 List<Type> tail = upperBounds(ss.tail);
3839 if (head != ss.head || tail != ss.tail)
3840 return tail.prepend(head);
3841 else
3842 return ss;
3843 }
3845 private boolean sideCast(Type from, Type to, Warner warn) {
3846 // We are casting from type $from$ to type $to$, which are
3847 // non-final unrelated types. This method
3848 // tries to reject a cast by transferring type parameters
3849 // from $to$ to $from$ by common superinterfaces.
3850 boolean reverse = false;
3851 Type target = to;
3852 if ((to.tsym.flags() & INTERFACE) == 0) {
3853 Assert.check((from.tsym.flags() & INTERFACE) != 0);
3854 reverse = true;
3855 to = from;
3856 from = target;
3857 }
3858 List<Type> commonSupers = superClosure(to, erasure(from));
3859 boolean giveWarning = commonSupers.isEmpty();
3860 // The arguments to the supers could be unified here to
3861 // get a more accurate analysis
3862 while (commonSupers.nonEmpty()) {
3863 Type t1 = asSuper(from, commonSupers.head.tsym);
3864 Type t2 = commonSupers.head; // same as asSuper(to, commonSupers.head.tsym);
3865 if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
3866 return false;
3867 giveWarning = giveWarning || (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2));
3868 commonSupers = commonSupers.tail;
3869 }
3870 if (giveWarning && !isReifiable(reverse ? from : to))
3871 warn.warn(LintCategory.UNCHECKED);
3872 if (!allowCovariantReturns)
3873 // reject if there is a common method signature with
3874 // incompatible return types.
3875 chk.checkCompatibleAbstracts(warn.pos(), from, to);
3876 return true;
3877 }
3879 private boolean sideCastFinal(Type from, Type to, Warner warn) {
3880 // We are casting from type $from$ to type $to$, which are
3881 // unrelated types one of which is final and the other of
3882 // which is an interface. This method
3883 // tries to reject a cast by transferring type parameters
3884 // from the final class to the interface.
3885 boolean reverse = false;
3886 Type target = to;
3887 if ((to.tsym.flags() & INTERFACE) == 0) {
3888 Assert.check((from.tsym.flags() & INTERFACE) != 0);
3889 reverse = true;
3890 to = from;
3891 from = target;
3892 }
3893 Assert.check((from.tsym.flags() & FINAL) != 0);
3894 Type t1 = asSuper(from, to.tsym);
3895 if (t1 == null) return false;
3896 Type t2 = to;
3897 if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
3898 return false;
3899 if (!allowCovariantReturns)
3900 // reject if there is a common method signature with
3901 // incompatible return types.
3902 chk.checkCompatibleAbstracts(warn.pos(), from, to);
3903 if (!isReifiable(target) &&
3904 (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2)))
3905 warn.warn(LintCategory.UNCHECKED);
3906 return true;
3907 }
3909 private boolean giveWarning(Type from, Type to) {
3910 List<Type> bounds = to.isCompound() ?
3911 ((IntersectionClassType)to.unannotatedType()).getComponents() : List.of(to);
3912 for (Type b : bounds) {
3913 Type subFrom = asSub(from, b.tsym);
3914 if (b.isParameterized() &&
3915 (!(isUnbounded(b) ||
3916 isSubtype(from, b) ||
3917 ((subFrom != null) && containsType(b.allparams(), subFrom.allparams()))))) {
3918 return true;
3919 }
3920 }
3921 return false;
3922 }
3924 private List<Type> superClosure(Type t, Type s) {
3925 List<Type> cl = List.nil();
3926 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
3927 if (isSubtype(s, erasure(l.head))) {
3928 cl = insert(cl, l.head);
3929 } else {
3930 cl = union(cl, superClosure(l.head, s));
3931 }
3932 }
3933 return cl;
3934 }
3936 private boolean containsTypeEquivalent(Type t, Type s) {
3937 return
3938 isSameType(t, s) || // shortcut
3939 containsType(t, s) && containsType(s, t);
3940 }
3942 // <editor-fold defaultstate="collapsed" desc="adapt">
3943 /**
3944 * Adapt a type by computing a substitution which maps a source
3945 * type to a target type.
3946 *
3947 * @param source the source type
3948 * @param target the target type
3949 * @param from the type variables of the computed substitution
3950 * @param to the types of the computed substitution.
3951 */
3952 public void adapt(Type source,
3953 Type target,
3954 ListBuffer<Type> from,
3955 ListBuffer<Type> to) throws AdaptFailure {
3956 new Adapter(from, to).adapt(source, target);
3957 }
3959 class Adapter extends SimpleVisitor<Void, Type> {
3961 ListBuffer<Type> from;
3962 ListBuffer<Type> to;
3963 Map<Symbol,Type> mapping;
3965 Adapter(ListBuffer<Type> from, ListBuffer<Type> to) {
3966 this.from = from;
3967 this.to = to;
3968 mapping = new HashMap<Symbol,Type>();
3969 }
3971 public void adapt(Type source, Type target) throws AdaptFailure {
3972 visit(source, target);
3973 List<Type> fromList = from.toList();
3974 List<Type> toList = to.toList();
3975 while (!fromList.isEmpty()) {
3976 Type val = mapping.get(fromList.head.tsym);
3977 if (toList.head != val)
3978 toList.head = val;
3979 fromList = fromList.tail;
3980 toList = toList.tail;
3981 }
3982 }
3984 @Override
3985 public Void visitClassType(ClassType source, Type target) throws AdaptFailure {
3986 if (target.hasTag(CLASS))
3987 adaptRecursive(source.allparams(), target.allparams());
3988 return null;
3989 }
3991 @Override
3992 public Void visitArrayType(ArrayType source, Type target) throws AdaptFailure {
3993 if (target.hasTag(ARRAY))
3994 adaptRecursive(elemtype(source), elemtype(target));
3995 return null;
3996 }
3998 @Override
3999 public Void visitWildcardType(WildcardType source, Type target) throws AdaptFailure {
4000 if (source.isExtendsBound())
4001 adaptRecursive(upperBound(source), upperBound(target));
4002 else if (source.isSuperBound())
4003 adaptRecursive(lowerBound(source), lowerBound(target));
4004 return null;
4005 }
4007 @Override
4008 public Void visitTypeVar(TypeVar source, Type target) throws AdaptFailure {
4009 // Check to see if there is
4010 // already a mapping for $source$, in which case
4011 // the old mapping will be merged with the new
4012 Type val = mapping.get(source.tsym);
4013 if (val != null) {
4014 if (val.isSuperBound() && target.isSuperBound()) {
4015 val = isSubtype(lowerBound(val), lowerBound(target))
4016 ? target : val;
4017 } else if (val.isExtendsBound() && target.isExtendsBound()) {
4018 val = isSubtype(upperBound(val), upperBound(target))
4019 ? val : target;
4020 } else if (!isSameType(val, target)) {
4021 throw new AdaptFailure();
4022 }
4023 } else {
4024 val = target;
4025 from.append(source);
4026 to.append(target);
4027 }
4028 mapping.put(source.tsym, val);
4029 return null;
4030 }
4032 @Override
4033 public Void visitType(Type source, Type target) {
4034 return null;
4035 }
4037 private Set<TypePair> cache = new HashSet<TypePair>();
4039 private void adaptRecursive(Type source, Type target) {
4040 TypePair pair = new TypePair(source, target);
4041 if (cache.add(pair)) {
4042 try {
4043 visit(source, target);
4044 } finally {
4045 cache.remove(pair);
4046 }
4047 }
4048 }
4050 private void adaptRecursive(List<Type> source, List<Type> target) {
4051 if (source.length() == target.length()) {
4052 while (source.nonEmpty()) {
4053 adaptRecursive(source.head, target.head);
4054 source = source.tail;
4055 target = target.tail;
4056 }
4057 }
4058 }
4059 }
4061 public static class AdaptFailure extends RuntimeException {
4062 static final long serialVersionUID = -7490231548272701566L;
4063 }
4065 private void adaptSelf(Type t,
4066 ListBuffer<Type> from,
4067 ListBuffer<Type> to) {
4068 try {
4069 //if (t.tsym.type != t)
4070 adapt(t.tsym.type, t, from, to);
4071 } catch (AdaptFailure ex) {
4072 // Adapt should never fail calculating a mapping from
4073 // t.tsym.type to t as there can be no merge problem.
4074 throw new AssertionError(ex);
4075 }
4076 }
4077 // </editor-fold>
4079 /**
4080 * Rewrite all type variables (universal quantifiers) in the given
4081 * type to wildcards (existential quantifiers). This is used to
4082 * determine if a cast is allowed. For example, if high is true
4083 * and {@code T <: Number}, then {@code List<T>} is rewritten to
4084 * {@code List<? extends Number>}. Since {@code List<Integer> <:
4085 * List<? extends Number>} a {@code List<T>} can be cast to {@code
4086 * List<Integer>} with a warning.
4087 * @param t a type
4088 * @param high if true return an upper bound; otherwise a lower
4089 * bound
4090 * @param rewriteTypeVars only rewrite captured wildcards if false;
4091 * otherwise rewrite all type variables
4092 * @return the type rewritten with wildcards (existential
4093 * quantifiers) only
4094 */
4095 private Type rewriteQuantifiers(Type t, boolean high, boolean rewriteTypeVars) {
4096 return new Rewriter(high, rewriteTypeVars).visit(t);
4097 }
4099 class Rewriter extends UnaryVisitor<Type> {
4101 boolean high;
4102 boolean rewriteTypeVars;
4104 Rewriter(boolean high, boolean rewriteTypeVars) {
4105 this.high = high;
4106 this.rewriteTypeVars = rewriteTypeVars;
4107 }
4109 @Override
4110 public Type visitClassType(ClassType t, Void s) {
4111 ListBuffer<Type> rewritten = new ListBuffer<Type>();
4112 boolean changed = false;
4113 for (Type arg : t.allparams()) {
4114 Type bound = visit(arg);
4115 if (arg != bound) {
4116 changed = true;
4117 }
4118 rewritten.append(bound);
4119 }
4120 if (changed)
4121 return subst(t.tsym.type,
4122 t.tsym.type.allparams(),
4123 rewritten.toList());
4124 else
4125 return t;
4126 }
4128 public Type visitType(Type t, Void s) {
4129 return high ? upperBound(t) : lowerBound(t);
4130 }
4132 @Override
4133 public Type visitCapturedType(CapturedType t, Void s) {
4134 Type w_bound = t.wildcard.type;
4135 Type bound = w_bound.contains(t) ?
4136 erasure(w_bound) :
4137 visit(w_bound);
4138 return rewriteAsWildcardType(visit(bound), t.wildcard.bound, t.wildcard.kind);
4139 }
4141 @Override
4142 public Type visitTypeVar(TypeVar t, Void s) {
4143 if (rewriteTypeVars) {
4144 Type bound = t.bound.contains(t) ?
4145 erasure(t.bound) :
4146 visit(t.bound);
4147 return rewriteAsWildcardType(bound, t, EXTENDS);
4148 } else {
4149 return t;
4150 }
4151 }
4153 @Override
4154 public Type visitWildcardType(WildcardType t, Void s) {
4155 Type bound2 = visit(t.type);
4156 return t.type == bound2 ? t : rewriteAsWildcardType(bound2, t.bound, t.kind);
4157 }
4159 private Type rewriteAsWildcardType(Type bound, TypeVar formal, BoundKind bk) {
4160 switch (bk) {
4161 case EXTENDS: return high ?
4162 makeExtendsWildcard(B(bound), formal) :
4163 makeExtendsWildcard(syms.objectType, formal);
4164 case SUPER: return high ?
4165 makeSuperWildcard(syms.botType, formal) :
4166 makeSuperWildcard(B(bound), formal);
4167 case UNBOUND: return makeExtendsWildcard(syms.objectType, formal);
4168 default:
4169 Assert.error("Invalid bound kind " + bk);
4170 return null;
4171 }
4172 }
4174 Type B(Type t) {
4175 while (t.hasTag(WILDCARD)) {
4176 WildcardType w = (WildcardType)t.unannotatedType();
4177 t = high ?
4178 w.getExtendsBound() :
4179 w.getSuperBound();
4180 if (t == null) {
4181 t = high ? syms.objectType : syms.botType;
4182 }
4183 }
4184 return t;
4185 }
4186 }
4189 /**
4190 * Create a wildcard with the given upper (extends) bound; create
4191 * an unbounded wildcard if bound is Object.
4192 *
4193 * @param bound the upper bound
4194 * @param formal the formal type parameter that will be
4195 * substituted by the wildcard
4196 */
4197 private WildcardType makeExtendsWildcard(Type bound, TypeVar formal) {
4198 if (bound == syms.objectType) {
4199 return new WildcardType(syms.objectType,
4200 BoundKind.UNBOUND,
4201 syms.boundClass,
4202 formal);
4203 } else {
4204 return new WildcardType(bound,
4205 BoundKind.EXTENDS,
4206 syms.boundClass,
4207 formal);
4208 }
4209 }
4211 /**
4212 * Create a wildcard with the given lower (super) bound; create an
4213 * unbounded wildcard if bound is bottom (type of {@code null}).
4214 *
4215 * @param bound the lower bound
4216 * @param formal the formal type parameter that will be
4217 * substituted by the wildcard
4218 */
4219 private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
4220 if (bound.hasTag(BOT)) {
4221 return new WildcardType(syms.objectType,
4222 BoundKind.UNBOUND,
4223 syms.boundClass,
4224 formal);
4225 } else {
4226 return new WildcardType(bound,
4227 BoundKind.SUPER,
4228 syms.boundClass,
4229 formal);
4230 }
4231 }
4233 /**
4234 * A wrapper for a type that allows use in sets.
4235 */
4236 public static class UniqueType {
4237 public final Type type;
4238 final Types types;
4240 public UniqueType(Type type, Types types) {
4241 this.type = type;
4242 this.types = types;
4243 }
4245 public int hashCode() {
4246 return types.hashCode(type);
4247 }
4249 public boolean equals(Object obj) {
4250 return (obj instanceof UniqueType) &&
4251 types.isSameAnnotatedType(type, ((UniqueType)obj).type);
4252 }
4254 public String toString() {
4255 return type.toString();
4256 }
4258 }
4259 // </editor-fold>
4261 // <editor-fold defaultstate="collapsed" desc="Visitors">
4262 /**
4263 * A default visitor for types. All visitor methods except
4264 * visitType are implemented by delegating to visitType. Concrete
4265 * subclasses must provide an implementation of visitType and can
4266 * override other methods as needed.
4267 *
4268 * @param <R> the return type of the operation implemented by this
4269 * visitor; use Void if no return type is needed.
4270 * @param <S> the type of the second argument (the first being the
4271 * type itself) of the operation implemented by this visitor; use
4272 * Void if a second argument is not needed.
4273 */
4274 public static abstract class DefaultTypeVisitor<R,S> implements Type.Visitor<R,S> {
4275 final public R visit(Type t, S s) { return t.accept(this, s); }
4276 public R visitClassType(ClassType t, S s) { return visitType(t, s); }
4277 public R visitWildcardType(WildcardType t, S s) { return visitType(t, s); }
4278 public R visitArrayType(ArrayType t, S s) { return visitType(t, s); }
4279 public R visitMethodType(MethodType t, S s) { return visitType(t, s); }
4280 public R visitPackageType(PackageType t, S s) { return visitType(t, s); }
4281 public R visitTypeVar(TypeVar t, S s) { return visitType(t, s); }
4282 public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); }
4283 public R visitForAll(ForAll t, S s) { return visitType(t, s); }
4284 public R visitUndetVar(UndetVar t, S s) { return visitType(t, s); }
4285 public R visitErrorType(ErrorType t, S s) { return visitType(t, s); }
4286 // Pretend annotations don't exist
4287 public R visitAnnotatedType(AnnotatedType t, S s) { return visit(t.underlyingType, s); }
4288 }
4290 /**
4291 * A default visitor for symbols. All visitor methods except
4292 * visitSymbol are implemented by delegating to visitSymbol. Concrete
4293 * subclasses must provide an implementation of visitSymbol and can
4294 * override other methods as needed.
4295 *
4296 * @param <R> the return type of the operation implemented by this
4297 * visitor; use Void if no return type is needed.
4298 * @param <S> the type of the second argument (the first being the
4299 * symbol itself) of the operation implemented by this visitor; use
4300 * Void if a second argument is not needed.
4301 */
4302 public static abstract class DefaultSymbolVisitor<R,S> implements Symbol.Visitor<R,S> {
4303 final public R visit(Symbol s, S arg) { return s.accept(this, arg); }
4304 public R visitClassSymbol(ClassSymbol s, S arg) { return visitSymbol(s, arg); }
4305 public R visitMethodSymbol(MethodSymbol s, S arg) { return visitSymbol(s, arg); }
4306 public R visitOperatorSymbol(OperatorSymbol s, S arg) { return visitSymbol(s, arg); }
4307 public R visitPackageSymbol(PackageSymbol s, S arg) { return visitSymbol(s, arg); }
4308 public R visitTypeSymbol(TypeSymbol s, S arg) { return visitSymbol(s, arg); }
4309 public R visitVarSymbol(VarSymbol s, S arg) { return visitSymbol(s, arg); }
4310 }
4312 /**
4313 * A <em>simple</em> visitor for types. This visitor is simple as
4314 * captured wildcards, for-all types (generic methods), and
4315 * undetermined type variables (part of inference) are hidden.
4316 * Captured wildcards are hidden by treating them as type
4317 * variables and the rest are hidden by visiting their qtypes.
4318 *
4319 * @param <R> the return type of the operation implemented by this
4320 * visitor; use Void if no return type is needed.
4321 * @param <S> the type of the second argument (the first being the
4322 * type itself) of the operation implemented by this visitor; use
4323 * Void if a second argument is not needed.
4324 */
4325 public static abstract class SimpleVisitor<R,S> extends DefaultTypeVisitor<R,S> {
4326 @Override
4327 public R visitCapturedType(CapturedType t, S s) {
4328 return visitTypeVar(t, s);
4329 }
4330 @Override
4331 public R visitForAll(ForAll t, S s) {
4332 return visit(t.qtype, s);
4333 }
4334 @Override
4335 public R visitUndetVar(UndetVar t, S s) {
4336 return visit(t.qtype, s);
4337 }
4338 }
4340 /**
4341 * A plain relation on types. That is a 2-ary function on the
4342 * form Type × Type → Boolean.
4343 * <!-- In plain text: Type x Type -> Boolean -->
4344 */
4345 public static abstract class TypeRelation extends SimpleVisitor<Boolean,Type> {}
4347 /**
4348 * A convenience visitor for implementing operations that only
4349 * require one argument (the type itself), that is, unary
4350 * operations.
4351 *
4352 * @param <R> the return type of the operation implemented by this
4353 * visitor; use Void if no return type is needed.
4354 */
4355 public static abstract class UnaryVisitor<R> extends SimpleVisitor<R,Void> {
4356 final public R visit(Type t) { return t.accept(this, null); }
4357 }
4359 /**
4360 * A visitor for implementing a mapping from types to types. The
4361 * default behavior of this class is to implement the identity
4362 * mapping (mapping a type to itself). This can be overridden in
4363 * subclasses.
4364 *
4365 * @param <S> the type of the second argument (the first being the
4366 * type itself) of this mapping; use Void if a second argument is
4367 * not needed.
4368 */
4369 public static class MapVisitor<S> extends DefaultTypeVisitor<Type,S> {
4370 final public Type visit(Type t) { return t.accept(this, null); }
4371 public Type visitType(Type t, S s) { return t; }
4372 }
4373 // </editor-fold>
4376 // <editor-fold defaultstate="collapsed" desc="Annotation support">
4378 public RetentionPolicy getRetention(Attribute.Compound a) {
4379 return getRetention(a.type.tsym);
4380 }
4382 public RetentionPolicy getRetention(Symbol sym) {
4383 RetentionPolicy vis = RetentionPolicy.CLASS; // the default
4384 Attribute.Compound c = sym.attribute(syms.retentionType.tsym);
4385 if (c != null) {
4386 Attribute value = c.member(names.value);
4387 if (value != null && value instanceof Attribute.Enum) {
4388 Name levelName = ((Attribute.Enum)value).value.name;
4389 if (levelName == names.SOURCE) vis = RetentionPolicy.SOURCE;
4390 else if (levelName == names.CLASS) vis = RetentionPolicy.CLASS;
4391 else if (levelName == names.RUNTIME) vis = RetentionPolicy.RUNTIME;
4392 else ;// /* fail soft */ throw new AssertionError(levelName);
4393 }
4394 }
4395 return vis;
4396 }
4397 // </editor-fold>
4399 // <editor-fold defaultstate="collapsed" desc="Signature Generation">
4401 public static abstract class SignatureGenerator {
4403 private final Types types;
4405 protected abstract void append(char ch);
4406 protected abstract void append(byte[] ba);
4407 protected abstract void append(Name name);
4408 protected void classReference(ClassSymbol c) { /* by default: no-op */ }
4410 protected SignatureGenerator(Types types) {
4411 this.types = types;
4412 }
4414 /**
4415 * Assemble signature of given type in string buffer.
4416 */
4417 public void assembleSig(Type type) {
4418 type = type.unannotatedType();
4419 switch (type.getTag()) {
4420 case BYTE:
4421 append('B');
4422 break;
4423 case SHORT:
4424 append('S');
4425 break;
4426 case CHAR:
4427 append('C');
4428 break;
4429 case INT:
4430 append('I');
4431 break;
4432 case LONG:
4433 append('J');
4434 break;
4435 case FLOAT:
4436 append('F');
4437 break;
4438 case DOUBLE:
4439 append('D');
4440 break;
4441 case BOOLEAN:
4442 append('Z');
4443 break;
4444 case VOID:
4445 append('V');
4446 break;
4447 case CLASS:
4448 append('L');
4449 assembleClassSig(type);
4450 append(';');
4451 break;
4452 case ARRAY:
4453 ArrayType at = (ArrayType) type;
4454 append('[');
4455 assembleSig(at.elemtype);
4456 break;
4457 case METHOD:
4458 MethodType mt = (MethodType) type;
4459 append('(');
4460 assembleSig(mt.argtypes);
4461 append(')');
4462 assembleSig(mt.restype);
4463 if (hasTypeVar(mt.thrown)) {
4464 for (List<Type> l = mt.thrown; l.nonEmpty(); l = l.tail) {
4465 append('^');
4466 assembleSig(l.head);
4467 }
4468 }
4469 break;
4470 case WILDCARD: {
4471 Type.WildcardType ta = (Type.WildcardType) type;
4472 switch (ta.kind) {
4473 case SUPER:
4474 append('-');
4475 assembleSig(ta.type);
4476 break;
4477 case EXTENDS:
4478 append('+');
4479 assembleSig(ta.type);
4480 break;
4481 case UNBOUND:
4482 append('*');
4483 break;
4484 default:
4485 throw new AssertionError(ta.kind);
4486 }
4487 break;
4488 }
4489 case TYPEVAR:
4490 append('T');
4491 append(type.tsym.name);
4492 append(';');
4493 break;
4494 case FORALL:
4495 Type.ForAll ft = (Type.ForAll) type;
4496 assembleParamsSig(ft.tvars);
4497 assembleSig(ft.qtype);
4498 break;
4499 default:
4500 throw new AssertionError("typeSig " + type.getTag());
4501 }
4502 }
4504 public boolean hasTypeVar(List<Type> l) {
4505 while (l.nonEmpty()) {
4506 if (l.head.hasTag(TypeTag.TYPEVAR)) {
4507 return true;
4508 }
4509 l = l.tail;
4510 }
4511 return false;
4512 }
4514 public void assembleClassSig(Type type) {
4515 type = type.unannotatedType();
4516 ClassType ct = (ClassType) type;
4517 ClassSymbol c = (ClassSymbol) ct.tsym;
4518 classReference(c);
4519 Type outer = ct.getEnclosingType();
4520 if (outer.allparams().nonEmpty()) {
4521 boolean rawOuter =
4522 c.owner.kind == Kinds.MTH || // either a local class
4523 c.name == types.names.empty; // or anonymous
4524 assembleClassSig(rawOuter
4525 ? types.erasure(outer)
4526 : outer);
4527 append('.');
4528 Assert.check(c.flatname.startsWith(c.owner.enclClass().flatname));
4529 append(rawOuter
4530 ? c.flatname.subName(c.owner.enclClass().flatname.getByteLength() + 1, c.flatname.getByteLength())
4531 : c.name);
4532 } else {
4533 append(externalize(c.flatname));
4534 }
4535 if (ct.getTypeArguments().nonEmpty()) {
4536 append('<');
4537 assembleSig(ct.getTypeArguments());
4538 append('>');
4539 }
4540 }
4542 public void assembleParamsSig(List<Type> typarams) {
4543 append('<');
4544 for (List<Type> ts = typarams; ts.nonEmpty(); ts = ts.tail) {
4545 Type.TypeVar tvar = (Type.TypeVar) ts.head;
4546 append(tvar.tsym.name);
4547 List<Type> bounds = types.getBounds(tvar);
4548 if ((bounds.head.tsym.flags() & INTERFACE) != 0) {
4549 append(':');
4550 }
4551 for (List<Type> l = bounds; l.nonEmpty(); l = l.tail) {
4552 append(':');
4553 assembleSig(l.head);
4554 }
4555 }
4556 append('>');
4557 }
4559 private void assembleSig(List<Type> types) {
4560 for (List<Type> ts = types; ts.nonEmpty(); ts = ts.tail) {
4561 assembleSig(ts.head);
4562 }
4563 }
4564 }
4565 // </editor-fold>
4566 }