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