1 /*
2 * Copyright (c) 2003, 2019, 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 */
25
26 package com.sun.tools.javac.code;
27
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.Optional;
34 import java.util.Set;
35 import java.util.WeakHashMap;
36 import java.util.function.BiPredicate;
37 import java.util.function.Function;
38 import java.util.stream.Collector;
39
40 import javax.tools.JavaFileObject;
41
42 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
43 import com.sun.tools.javac.code.Lint.LintCategory;
44 import com.sun.tools.javac.code.Source.Feature;
45 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
46 import com.sun.tools.javac.code.TypeMetadata.Entry.Kind;
47 import com.sun.tools.javac.comp.AttrContext;
48 import com.sun.tools.javac.comp.Check;
49 import com.sun.tools.javac.comp.Enter;
50 import com.sun.tools.javac.comp.Env;
51 import com.sun.tools.javac.comp.LambdaToMethod;
52 import com.sun.tools.javac.jvm.ClassFile;
53 import com.sun.tools.javac.jvm.Target;
54 import com.sun.tools.javac.util.*;
55
56 import static com.sun.tools.javac.code.BoundKind.*;
57 import static com.sun.tools.javac.code.Flags.*;
58 import static com.sun.tools.javac.code.Kinds.Kind.*;
59 import static com.sun.tools.javac.code.Scope.*;
60 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
61 import static com.sun.tools.javac.code.Symbol.*;
62 import static com.sun.tools.javac.code.Type.*;
63 import static com.sun.tools.javac.code.TypeTag.*;
64 import static com.sun.tools.javac.jvm.ClassFile.externalize;
65 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
66
67 /**
68 * Utility class containing various operations on types.
69 *
70 * <p>Unless other names are more illustrative, the following naming
71 * conventions should be observed in this file:
72 *
73 * <dl>
74 * <dt>t</dt>
75 * <dd>If the first argument to an operation is a type, it should be named t.</dd>
76 * <dt>s</dt>
77 * <dd>Similarly, if the second argument to an operation is a type, it should be named s.</dd>
78 * <dt>ts</dt>
79 * <dd>If an operations takes a list of types, the first should be named ts.</dd>
80 * <dt>ss</dt>
81 * <dd>A second list of types should be named ss.</dd>
82 * </dl>
83 *
84 * <p><b>This is NOT part of any supported API.
85 * If you write code that depends on this, you do so at your own risk.
86 * This code and its internal interfaces are subject to change or
87 * deletion without notice.</b>
88 */
89 public class Types {
90 protected static final Context.Key<Types> typesKey = new Context.Key<>();
91
92 final Symtab syms;
93 final JavacMessages messages;
94 final Names names;
95 final boolean allowDefaultMethods;
96 final boolean mapCapturesToBounds;
97 final boolean allowValueBasedClasses;
98 final boolean injectTopInterfaceTypes;
99 final Check chk;
100 final Enter enter;
101 JCDiagnostic.Factory diags;
102 List<Warner> warnStack = List.nil();
103 final Name capturedName;
104
105 public final Warner noWarnings;
106
107 // <editor-fold defaultstate="collapsed" desc="Instantiating">
108 public static Types instance(Context context) {
109 Types instance = context.get(typesKey);
110 if (instance == null)
111 instance = new Types(context);
112 return instance;
113 }
114
115 protected Types(Context context) {
116 context.put(typesKey, this);
117 syms = Symtab.instance(context);
118 names = Names.instance(context);
119 Source source = Source.instance(context);
120 allowDefaultMethods = Feature.DEFAULT_METHODS.allowedInSource(source);
121 mapCapturesToBounds = Feature.MAP_CAPTURES_TO_BOUNDS.allowedInSource(source);
122 chk = Check.instance(context);
123 enter = Enter.instance(context);
124 capturedName = names.fromString("<captured wildcard>");
125 messages = JavacMessages.instance(context);
126 diags = JCDiagnostic.Factory.instance(context);
127 noWarnings = new Warner(null);
128 Options options = Options.instance(context);
129 allowValueBasedClasses = options.isSet("allowValueBasedClasses");
130 injectTopInterfaceTypes = Options.instance(context).isUnset("noTopInterfaceInjection") &&
131 Feature.INLINE_TYPES.allowedInSource(source) &&
132 Target.instance(context).hasTopInterfaces();
133 }
134 // </editor-fold>
135
136 // <editor-fold defaultstate="collapsed" desc="bounds">
137 /**
138 * Get a wildcard's upper bound, returning non-wildcards unchanged.
139 * @param t a type argument, either a wildcard or a type
140 */
141 public Type wildUpperBound(Type t) {
142 if (t.hasTag(WILDCARD)) {
143 WildcardType w = (WildcardType) t;
144 if (w.isSuperBound())
145 return w.bound == null ? syms.objectType : w.bound.getUpperBound();
146 else
147 return wildUpperBound(w.type);
148 }
149 else return t;
150 }
151
152 /**
153 * Get a capture variable's upper bound, returning other types unchanged.
154 * @param t a type
155 */
156 public Type cvarUpperBound(Type t) {
157 if (t.hasTag(TYPEVAR)) {
158 TypeVar v = (TypeVar) t;
159 return v.isCaptured() ? cvarUpperBound(v.getUpperBound()) : v;
160 }
161 else return t;
162 }
163
164 /**
165 * Get a wildcard's lower bound, returning non-wildcards unchanged.
166 * @param t a type argument, either a wildcard or a type
167 */
168 public Type wildLowerBound(Type t) {
169 if (t.hasTag(WILDCARD)) {
170 WildcardType w = (WildcardType) t;
171 return w.isExtendsBound() ? syms.botType : wildLowerBound(w.type);
172 }
173 else return t;
174 }
175
176 /**
177 * Get a capture variable's lower bound, returning other types unchanged.
178 * @param t a type
179 */
180 public Type cvarLowerBound(Type t) {
181 if (t.hasTag(TYPEVAR) && ((TypeVar) t).isCaptured()) {
182 return cvarLowerBound(t.getLowerBound());
183 }
184 else return t;
185 }
186
187 /**
188 * Recursively skip type-variables until a class/array type is found; capture conversion is then
189 * (optionally) applied to the resulting type. This is useful for i.e. computing a site that is
190 * suitable for a method lookup.
191 */
192 public Type skipTypeVars(Type site, boolean capture) {
193 while (site.hasTag(TYPEVAR)) {
194 site = site.getUpperBound();
195 }
196 return capture ? capture(site) : site;
197 }
198 // </editor-fold>
199
200 // <editor-fold defaultstate="collapsed" desc="projections">
201
202 /**
203 * A projection kind. See {@link TypeProjection}
204 */
205 enum ProjectionKind {
206 UPWARDS() {
207 @Override
208 ProjectionKind complement() {
209 return DOWNWARDS;
210 }
211 },
212 DOWNWARDS() {
213 @Override
214 ProjectionKind complement() {
215 return UPWARDS;
216 }
217 };
218
219 abstract ProjectionKind complement();
220 }
221
222 /**
223 * This visitor performs upwards and downwards projections on types.
224 *
225 * A projection is defined as a function that takes a type T, a set of type variables V and that
226 * produces another type S.
227 *
228 * An upwards projection maps a type T into a type S such that (i) T has no variables in V,
229 * and (ii) S is an upper bound of T.
230 *
231 * A downwards projection maps a type T into a type S such that (i) T has no variables in V,
232 * and (ii) S is a lower bound of T.
233 *
234 * Note that projections are only allowed to touch variables in V. Therefore, it is possible for
235 * a projection to leave its input type unchanged if it does not contain any variables in V.
236 *
237 * Moreover, note that while an upwards projection is always defined (every type as an upper bound),
238 * a downwards projection is not always defined.
239 *
240 * Examples:
241 *
242 * {@code upwards(List<#CAP1>, [#CAP1]) = List<? extends String>, where #CAP1 <: String }
243 * {@code downwards(List<#CAP2>, [#CAP2]) = List<? super String>, where #CAP2 :> String }
244 * {@code upwards(List<#CAP1>, [#CAP2]) = List<#CAP1> }
245 * {@code downwards(List<#CAP1>, [#CAP1]) = not defined }
246 */
247 class TypeProjection extends TypeMapping<ProjectionKind> {
248
249 List<Type> vars;
250 Set<Type> seen = new HashSet<>();
251
252 public TypeProjection(List<Type> vars) {
253 this.vars = vars;
254 }
255
256 @Override
257 public Type visitClassType(ClassType t, ProjectionKind pkind) {
258 if (t.isCompound()) {
259 List<Type> components = directSupertypes(t);
260 List<Type> components1 = components.map(c -> c.map(this, pkind));
261 if (components == components1) return t;
262 else return makeIntersectionType(components1);
263 } else {
264 Type outer = t.getEnclosingType();
265 Type outer1 = visit(outer, pkind);
266 List<Type> typarams = t.getTypeArguments();
267 List<Type> formals = t.tsym.type.getTypeArguments();
268 ListBuffer<Type> typarams1 = new ListBuffer<>();
269 boolean changed = false;
270 for (Type actual : typarams) {
271 Type t2 = mapTypeArgument(t, formals.head.getUpperBound(), actual, pkind);
272 if (t2.hasTag(BOT)) {
273 //not defined
274 return syms.botType;
275 }
276 typarams1.add(t2);
277 changed |= actual != t2;
278 formals = formals.tail;
279 }
280 if (outer1 == outer && !changed) return t;
281 else return new ClassType(outer1, typarams1.toList(), t.tsym, t.getMetadata()) {
282 @Override
283 protected boolean needsStripping() {
284 return true;
285 }
286 };
287 }
288 }
289
290 @Override
291 public Type visitArrayType(ArrayType t, ProjectionKind s) {
292 Type elemtype = t.elemtype;
293 Type elemtype1 = visit(elemtype, s);
294 if (elemtype1 == elemtype) {
295 return t;
296 } else if (elemtype1.hasTag(BOT)) {
297 //undefined
298 return syms.botType;
299 } else {
300 return new ArrayType(elemtype1, t.tsym, t.metadata) {
301 @Override
302 protected boolean needsStripping() {
303 return true;
304 }
305 };
306 }
307 }
308
309 @Override
310 public Type visitTypeVar(TypeVar t, ProjectionKind pkind) {
311 if (vars.contains(t)) {
312 if (seen.add(t)) {
313 try {
314 final Type bound;
315 switch (pkind) {
316 case UPWARDS:
317 bound = t.getUpperBound();
318 break;
319 case DOWNWARDS:
320 bound = (t.getLowerBound() == null) ?
321 syms.botType :
322 t.getLowerBound();
323 break;
324 default:
325 Assert.error();
326 return null;
327 }
328 return bound.map(this, pkind);
329 } finally {
330 seen.remove(t);
331 }
332 } else {
333 //cycle
334 return pkind == ProjectionKind.UPWARDS ?
335 syms.objectType : syms.botType;
336 }
337 } else {
338 return t;
339 }
340 }
341
342 private Type mapTypeArgument(Type site, Type declaredBound, Type t, ProjectionKind pkind) {
343 return t.containsAny(vars) ?
344 t.map(new TypeArgumentProjection(site, declaredBound), pkind) :
345 t;
346 }
347
348 class TypeArgumentProjection extends TypeMapping<ProjectionKind> {
349
350 Type site;
351 Type declaredBound;
352
353 TypeArgumentProjection(Type site, Type declaredBound) {
354 this.site = site;
355 this.declaredBound = declaredBound;
356 }
357
358 @Override
359 public Type visitType(Type t, ProjectionKind pkind) {
360 //type argument is some type containing restricted vars
361 if (pkind == ProjectionKind.DOWNWARDS) {
362 //not defined
363 return syms.botType;
364 }
365 Type upper = t.map(TypeProjection.this, ProjectionKind.UPWARDS);
366 Type lower = t.map(TypeProjection.this, ProjectionKind.DOWNWARDS);
367 List<Type> formals = site.tsym.type.getTypeArguments();
368 BoundKind bk;
369 Type bound;
370 if (!isSameType(upper, syms.objectType) &&
371 (declaredBound.containsAny(formals) ||
372 !isSubtype(declaredBound, upper))) {
373 bound = upper;
374 bk = EXTENDS;
375 } else if (!lower.hasTag(BOT)) {
376 bound = lower;
377 bk = SUPER;
378 } else {
379 bound = syms.objectType;
380 bk = UNBOUND;
381 }
382 return makeWildcard(bound, bk);
383 }
384
385 @Override
386 public Type visitWildcardType(WildcardType wt, ProjectionKind pkind) {
387 //type argument is some wildcard whose bound contains restricted vars
388 Type bound = syms.botType;
389 BoundKind bk = wt.kind;
390 switch (wt.kind) {
391 case EXTENDS:
392 bound = wt.type.map(TypeProjection.this, pkind);
393 if (bound.hasTag(BOT)) {
394 return syms.botType;
395 }
396 break;
397 case SUPER:
398 bound = wt.type.map(TypeProjection.this, pkind.complement());
399 if (bound.hasTag(BOT)) {
400 bound = syms.objectType;
401 bk = UNBOUND;
402 }
403 break;
404 }
405 return makeWildcard(bound, bk);
406 }
407
408 private Type makeWildcard(Type bound, BoundKind bk) {
409 return new WildcardType(bound, bk, syms.boundClass) {
410 @Override
411 protected boolean needsStripping() {
412 return true;
413 }
414 };
415 }
416 }
417 }
418
419 /**
420 * Computes an upward projection of given type, and vars. See {@link TypeProjection}.
421 *
422 * @param t the type to be projected
423 * @param vars the set of type variables to be mapped
424 * @return the type obtained as result of the projection
425 */
426 public Type upward(Type t, List<Type> vars) {
427 return t.map(new TypeProjection(vars), ProjectionKind.UPWARDS);
428 }
429
430 /**
431 * Computes the set of captured variables mentioned in a given type. See {@link CaptureScanner}.
432 * This routine is typically used to computed the input set of variables to be used during
433 * an upwards projection (see {@link Types#upward(Type, List)}).
434 *
435 * @param t the type where occurrences of captured variables have to be found
436 * @return the set of captured variables found in t
437 */
438 public List<Type> captures(Type t) {
439 CaptureScanner cs = new CaptureScanner();
440 Set<Type> captures = new HashSet<>();
441 cs.visit(t, captures);
442 return List.from(captures);
443 }
444
445 /**
446 * This visitor scans a type recursively looking for occurrences of captured type variables.
447 */
448 class CaptureScanner extends SimpleVisitor<Void, Set<Type>> {
449
450 @Override
451 public Void visitType(Type t, Set<Type> types) {
452 return null;
453 }
454
455 @Override
456 public Void visitClassType(ClassType t, Set<Type> seen) {
457 if (t.isCompound()) {
458 directSupertypes(t).forEach(s -> visit(s, seen));
459 } else {
460 t.allparams().forEach(ta -> visit(ta, seen));
461 }
462 return null;
463 }
464
465 @Override
466 public Void visitArrayType(ArrayType t, Set<Type> seen) {
467 return visit(t.elemtype, seen);
468 }
469
470 @Override
471 public Void visitWildcardType(WildcardType t, Set<Type> seen) {
472 visit(t.type, seen);
473 return null;
474 }
475
476 @Override
477 public Void visitTypeVar(TypeVar t, Set<Type> seen) {
478 if ((t.tsym.flags() & Flags.SYNTHETIC) != 0 && seen.add(t)) {
479 visit(t.getUpperBound(), seen);
480 }
481 return null;
482 }
483
484 @Override
485 public Void visitCapturedType(CapturedType t, Set<Type> seen) {
486 if (seen.add(t)) {
487 visit(t.getUpperBound(), seen);
488 visit(t.getLowerBound(), seen);
489 }
490 return null;
491 }
492 }
493
494 // </editor-fold>
495
496 // <editor-fold defaultstate="collapsed" desc="isUnbounded">
497 /**
498 * Checks that all the arguments to a class are unbounded
499 * wildcards or something else that doesn't make any restrictions
500 * on the arguments. If a class isUnbounded, a raw super- or
501 * subclass can be cast to it without a warning.
502 * @param t a type
503 * @return true iff the given type is unbounded or raw
504 */
505 public boolean isUnbounded(Type t) {
506 return isUnbounded.visit(t);
507 }
508 // where
509 private final UnaryVisitor<Boolean> isUnbounded = new UnaryVisitor<Boolean>() {
510
511 public Boolean visitType(Type t, Void ignored) {
512 return true;
513 }
514
515 @Override
516 public Boolean visitClassType(ClassType t, Void ignored) {
517 List<Type> parms = t.tsym.type.allparams();
518 List<Type> args = t.allparams();
519 while (parms.nonEmpty()) {
520 WildcardType unb = new WildcardType(syms.objectType,
521 BoundKind.UNBOUND,
522 syms.boundClass,
523 (TypeVar)parms.head);
524 if (!containsType(args.head, unb))
525 return false;
526 parms = parms.tail;
527 args = args.tail;
528 }
529 return true;
530 }
531 };
532 // </editor-fold>
533
534 // <editor-fold defaultstate="collapsed" desc="asSub">
535 /**
536 * Return the least specific subtype of t that starts with symbol
537 * sym. If none exists, return null. The least specific subtype
538 * is determined as follows:
539 *
540 * <p>If there is exactly one parameterized instance of sym that is a
541 * subtype of t, that parameterized instance is returned.<br>
542 * Otherwise, if the plain type or raw type `sym' is a subtype of
543 * type t, the type `sym' itself is returned. Otherwise, null is
544 * returned.
545 */
546 public Type asSub(Type t, Symbol sym) {
547 return asSub.visit(t, sym);
548 }
549 // where
550 private final SimpleVisitor<Type,Symbol> asSub = new SimpleVisitor<Type,Symbol>() {
551
552 public Type visitType(Type t, Symbol sym) {
553 return null;
554 }
555
556 @Override
557 public Type visitClassType(ClassType t, Symbol sym) {
558 if (t.tsym == sym)
559 return t;
560 Type base = asSuper(sym.type, t.tsym);
561 if (base == null)
562 return null;
563 ListBuffer<Type> from = new ListBuffer<>();
564 ListBuffer<Type> to = new ListBuffer<>();
565 try {
566 adapt(base, t, from, to);
567 } catch (AdaptFailure ex) {
568 return null;
569 }
570 Type res = subst(sym.type, from.toList(), to.toList());
571 if (!isSubtype(res, t))
572 return null;
573 ListBuffer<Type> openVars = new ListBuffer<>();
574 for (List<Type> l = sym.type.allparams();
575 l.nonEmpty(); l = l.tail)
576 if (res.contains(l.head) && !t.contains(l.head))
577 openVars.append(l.head);
578 if (openVars.nonEmpty()) {
579 if (t.isRaw()) {
580 // The subtype of a raw type is raw
581 res = erasure(res);
582 } else {
583 // Unbound type arguments default to ?
584 List<Type> opens = openVars.toList();
585 ListBuffer<Type> qs = new ListBuffer<>();
586 for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) {
587 qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND,
588 syms.boundClass, (TypeVar) iter.head));
589 }
590 res = subst(res, opens, qs.toList());
591 }
592 }
593 return res;
594 }
595
596 @Override
597 public Type visitErrorType(ErrorType t, Symbol sym) {
598 return t;
599 }
600 };
601 // </editor-fold>
602
603 // <editor-fold defaultstate="collapsed" desc="isConvertible">
604 /**
605 * Is t a subtype of or convertible via boxing/unboxing
606 * conversion to s?
607 */
608 public boolean isConvertible(Type t, Type s, Warner warn) {
609 if (t.hasTag(ERROR)) {
610 return true;
611 }
612
613 boolean tValue = t.isValue();
614 boolean sValue = s.isValue();
615 if (tValue != sValue) {
616 return tValue ?
617 isSubtype(t.referenceProjection(), s) :
618 (!t.hasTag(BOT) || isValueBased(s)) && isSubtype(t, s.referenceProjection());
619 }
620
621 boolean tPrimitive = t.isPrimitive();
622 boolean sPrimitive = s.isPrimitive();
623 if (tPrimitive == sPrimitive) {
624 return isSubtypeUnchecked(t, s, warn);
625 }
626 boolean tUndet = t.hasTag(UNDETVAR);
627 boolean sUndet = s.hasTag(UNDETVAR);
628
629 if (tUndet || sUndet) {
630 return tUndet ?
631 isSubtype(t, boxedTypeOrType(s)) :
632 isSubtype(boxedTypeOrType(t), s);
633 }
634
635 return tPrimitive
636 ? isSubtype(boxedClass(t).type, s)
637 : isSubtype(unboxedType(t), s);
638 }
639
640 /**
641 * Is t a subtype of or convertible via boxing/unboxing
642 * conversions to s?
643 */
644 public boolean isConvertible(Type t, Type s) {
645 return isConvertible(t, s, noWarnings);
646 }
647 // </editor-fold>
648
649 // <editor-fold defaultstate="collapsed" desc="findSam">
650
651 /**
652 * Exception used to report a function descriptor lookup failure. The exception
653 * wraps a diagnostic that can be used to generate more details error
654 * messages.
655 */
656 public static class FunctionDescriptorLookupError extends RuntimeException {
657 private static final long serialVersionUID = 0;
658
659 transient JCDiagnostic diagnostic;
660
661 FunctionDescriptorLookupError() {
662 this.diagnostic = null;
663 }
664
665 FunctionDescriptorLookupError setMessage(JCDiagnostic diag) {
666 this.diagnostic = diag;
667 return this;
668 }
669
670 public JCDiagnostic getDiagnostic() {
671 return diagnostic;
672 }
673 }
674
675 /**
676 * A cache that keeps track of function descriptors associated with given
677 * functional interfaces.
678 */
679 class DescriptorCache {
680
681 private WeakHashMap<TypeSymbol, Entry> _map = new WeakHashMap<>();
682
683 class FunctionDescriptor {
684 Symbol descSym;
685
686 FunctionDescriptor(Symbol descSym) {
687 this.descSym = descSym;
688 }
689
690 public Symbol getSymbol() {
691 return descSym;
692 }
693
694 public Type getType(Type site) {
695 site = removeWildcards(site);
696 if (site.isIntersection()) {
697 IntersectionClassType ict = (IntersectionClassType)site;
698 for (Type component : ict.getExplicitComponents()) {
699 if (!chk.checkValidGenericType(component)) {
700 //if the inferred functional interface type is not well-formed,
701 //or if it's not a subtype of the original target, issue an error
702 throw failure(diags.fragment(Fragments.NoSuitableFunctionalIntfInst(site)));
703 }
704 }
705 } else {
706 if (!chk.checkValidGenericType(site)) {
707 //if the inferred functional interface type is not well-formed,
708 //or if it's not a subtype of the original target, issue an error
709 throw failure(diags.fragment(Fragments.NoSuitableFunctionalIntfInst(site)));
710 }
711 }
712 return memberType(site, descSym);
713 }
714 }
715
716 class Entry {
717 final FunctionDescriptor cachedDescRes;
718 final int prevMark;
719
720 public Entry(FunctionDescriptor cachedDescRes,
721 int prevMark) {
722 this.cachedDescRes = cachedDescRes;
723 this.prevMark = prevMark;
724 }
725
726 boolean matches(int mark) {
727 return this.prevMark == mark;
728 }
729 }
730
731 FunctionDescriptor get(TypeSymbol origin) throws FunctionDescriptorLookupError {
732 Entry e = _map.get(origin);
733 CompoundScope members = membersClosure(origin.type, false);
734 if (e == null ||
735 !e.matches(members.getMark())) {
736 FunctionDescriptor descRes = findDescriptorInternal(origin, members);
737 _map.put(origin, new Entry(descRes, members.getMark()));
738 return descRes;
739 }
740 else {
741 return e.cachedDescRes;
742 }
743 }
744
745 /**
746 * Compute the function descriptor associated with a given functional interface
747 */
748 public FunctionDescriptor findDescriptorInternal(TypeSymbol origin,
749 CompoundScope membersCache) throws FunctionDescriptorLookupError {
750 if (!origin.isInterface() || (origin.flags() & ANNOTATION) != 0) {
751 //t must be an interface
752 throw failure("not.a.functional.intf", origin);
753 }
754
755 final ListBuffer<Symbol> abstracts = new ListBuffer<>();
756 for (Symbol sym : membersCache.getSymbols(new DescriptorFilter(origin))) {
757 Type mtype = memberType(origin.type, sym);
758 if (abstracts.isEmpty()) {
759 abstracts.append(sym);
760 } else if ((sym.name == abstracts.first().name &&
761 overrideEquivalent(mtype, memberType(origin.type, abstracts.first())))) {
762 if (!abstracts.stream().filter(msym -> msym.owner.isSubClass(sym.enclClass(), Types.this))
763 .map(msym -> memberType(origin.type, msym))
764 .anyMatch(abstractMType -> isSubSignature(abstractMType, mtype))) {
765 abstracts.append(sym);
766 }
767 } else {
768 //the target method(s) should be the only abstract members of t
769 throw failure("not.a.functional.intf.1", origin,
770 diags.fragment(Fragments.IncompatibleAbstracts(Kinds.kindName(origin), origin)));
771 }
772 }
773 if (abstracts.isEmpty()) {
774 //t must define a suitable non-generic method
775 throw failure("not.a.functional.intf.1", origin,
776 diags.fragment(Fragments.NoAbstracts(Kinds.kindName(origin), origin)));
777 } else if (abstracts.size() == 1) {
778 return new FunctionDescriptor(abstracts.first());
779 } else { // size > 1
780 FunctionDescriptor descRes = mergeDescriptors(origin, abstracts.toList());
781 if (descRes == null) {
782 //we can get here if the functional interface is ill-formed
783 ListBuffer<JCDiagnostic> descriptors = new ListBuffer<>();
784 for (Symbol desc : abstracts) {
785 String key = desc.type.getThrownTypes().nonEmpty() ?
786 "descriptor.throws" : "descriptor";
787 descriptors.append(diags.fragment(key, desc.name,
788 desc.type.getParameterTypes(),
789 desc.type.getReturnType(),
790 desc.type.getThrownTypes()));
791 }
792 JCDiagnostic msg =
793 diags.fragment(Fragments.IncompatibleDescsInFunctionalIntf(Kinds.kindName(origin),
794 origin));
795 JCDiagnostic.MultilineDiagnostic incompatibleDescriptors =
796 new JCDiagnostic.MultilineDiagnostic(msg, descriptors.toList());
797 throw failure(incompatibleDescriptors);
798 }
799 return descRes;
800 }
801 }
802
803 /**
804 * Compute a synthetic type for the target descriptor given a list
805 * of override-equivalent methods in the functional interface type.
806 * The resulting method type is a method type that is override-equivalent
807 * and return-type substitutable with each method in the original list.
808 */
809 private FunctionDescriptor mergeDescriptors(TypeSymbol origin, List<Symbol> methodSyms) {
810 return mergeAbstracts(methodSyms, origin.type, false)
811 .map(bestSoFar -> new FunctionDescriptor(bestSoFar.baseSymbol()) {
812 @Override
813 public Type getType(Type origin) {
814 Type mt = memberType(origin, getSymbol());
815 return createMethodTypeWithThrown(mt, bestSoFar.type.getThrownTypes());
816 }
817 }).orElse(null);
818 }
819
820 FunctionDescriptorLookupError failure(String msg, Object... args) {
821 return failure(diags.fragment(msg, args));
822 }
823
824 FunctionDescriptorLookupError failure(JCDiagnostic diag) {
825 return new FunctionDescriptorLookupError().setMessage(diag);
826 }
827 }
828
829 private DescriptorCache descCache = new DescriptorCache();
830
831 /**
832 * Find the method descriptor associated to this class symbol - if the
833 * symbol 'origin' is not a functional interface, an exception is thrown.
834 */
835 public Symbol findDescriptorSymbol(TypeSymbol origin) throws FunctionDescriptorLookupError {
836 return descCache.get(origin).getSymbol();
837 }
838
839 /**
840 * Find the type of the method descriptor associated to this class symbol -
841 * if the symbol 'origin' is not a functional interface, an exception is thrown.
842 */
843 public Type findDescriptorType(Type origin) throws FunctionDescriptorLookupError {
844 return descCache.get(origin.tsym).getType(origin);
845 }
846
847 /**
848 * Is given type a functional interface?
849 */
850 public boolean isFunctionalInterface(TypeSymbol tsym) {
851 try {
852 findDescriptorSymbol(tsym);
853 return true;
854 } catch (FunctionDescriptorLookupError ex) {
855 return false;
856 }
857 }
858
859 public boolean isFunctionalInterface(Type site) {
860 try {
861 findDescriptorType(site);
862 return true;
863 } catch (FunctionDescriptorLookupError ex) {
864 return false;
865 }
866 }
867
868 public Type removeWildcards(Type site) {
869 if (site.getTypeArguments().stream().anyMatch(t -> t.hasTag(WILDCARD))) {
870 //compute non-wildcard parameterization - JLS 9.9
871 List<Type> actuals = site.getTypeArguments();
872 List<Type> formals = site.tsym.type.getTypeArguments();
873 ListBuffer<Type> targs = new ListBuffer<>();
874 for (Type formal : formals) {
875 Type actual = actuals.head;
876 Type bound = formal.getUpperBound();
877 if (actuals.head.hasTag(WILDCARD)) {
878 WildcardType wt = (WildcardType)actual;
879 //check that bound does not contain other formals
880 if (bound.containsAny(formals)) {
881 targs.add(wt.type);
882 } else {
883 //compute new type-argument based on declared bound and wildcard bound
884 switch (wt.kind) {
885 case UNBOUND:
886 targs.add(bound);
887 break;
888 case EXTENDS:
889 targs.add(glb(bound, wt.type));
890 break;
891 case SUPER:
892 targs.add(wt.type);
893 break;
894 default:
895 Assert.error("Cannot get here!");
896 }
897 }
898 } else {
899 //not a wildcard - the new type argument remains unchanged
900 targs.add(actual);
901 }
902 actuals = actuals.tail;
903 }
904 return subst(site.tsym.type, formals, targs.toList());
905 } else {
906 return site;
907 }
908 }
909
910 /**
911 * Create a symbol for a class that implements a given functional interface
912 * and overrides its functional descriptor. This routine is used for two
913 * main purposes: (i) checking well-formedness of a functional interface;
914 * (ii) perform functional interface bridge calculation.
915 */
916 public ClassSymbol makeFunctionalInterfaceClass(Env<AttrContext> env, Name name, Type target, long cflags) {
917 if (target == null || target == syms.unknownType) {
918 return null;
919 }
920 Symbol descSym = findDescriptorSymbol(target.tsym);
921 Type descType = findDescriptorType(target);
922 ClassSymbol csym = new ClassSymbol(cflags, name, env.enclClass.sym.outermostClass());
923 csym.completer = Completer.NULL_COMPLETER;
924 csym.members_field = WriteableScope.create(csym);
925 MethodSymbol instDescSym = new MethodSymbol(descSym.flags(), descSym.name, descType, csym);
926 csym.members_field.enter(instDescSym);
927 Type.ClassType ctype = new Type.ClassType(Type.noType, List.nil(), csym);
928 ctype.supertype_field = syms.objectType;
929 ctype.interfaces_field = target.isIntersection() ?
930 directSupertypes(target) :
931 List.of(target);
932 csym.type = ctype;
933 csym.sourcefile = ((ClassSymbol)csym.owner).sourcefile;
934 return csym;
935 }
936
937 /**
938 * Find the minimal set of methods that are overridden by the functional
939 * descriptor in 'origin'. All returned methods are assumed to have different
940 * erased signatures.
941 */
942 public List<Symbol> functionalInterfaceBridges(TypeSymbol origin) {
943 Assert.check(isFunctionalInterface(origin));
944 Symbol descSym = findDescriptorSymbol(origin);
945 CompoundScope members = membersClosure(origin.type, false);
946 ListBuffer<Symbol> overridden = new ListBuffer<>();
947 outer: for (Symbol m2 : members.getSymbolsByName(descSym.name, bridgeFilter)) {
948 if (m2 == descSym) continue;
949 else if (descSym.overrides(m2, origin, Types.this, false)) {
950 for (Symbol m3 : overridden) {
951 if (isSameType(m3.erasure(Types.this), m2.erasure(Types.this)) ||
952 (m3.overrides(m2, origin, Types.this, false) &&
953 (pendingBridges((ClassSymbol)origin, m3.enclClass()) ||
954 (((MethodSymbol)m2).binaryImplementation((ClassSymbol)m3.owner, Types.this) != null)))) {
955 continue outer;
956 }
957 }
958 overridden.add(m2);
959 }
960 }
961 return overridden.toList();
962 }
963 //where
964 private Filter<Symbol> bridgeFilter = new Filter<Symbol>() {
965 public boolean accepts(Symbol t) {
966 return t.kind == MTH &&
967 t.name != names.init &&
968 t.name != names.clinit &&
969 (t.flags() & SYNTHETIC) == 0;
970 }
971 };
972 private boolean pendingBridges(ClassSymbol origin, TypeSymbol s) {
973 //a symbol will be completed from a classfile if (a) symbol has
974 //an associated file object with CLASS kind and (b) the symbol has
975 //not been entered
976 if (origin.classfile != null &&
977 origin.classfile.getKind() == JavaFileObject.Kind.CLASS &&
978 enter.getEnv(origin) == null) {
979 return false;
980 }
981 if (origin == s) {
982 return true;
983 }
984 for (Type t : interfaces(origin.type)) {
985 if (pendingBridges((ClassSymbol)t.tsym, s)) {
986 return true;
987 }
988 }
989 return false;
990 }
991 // </editor-fold>
992
993 /**
994 * Scope filter used to skip methods that should be ignored (such as methods
995 * overridden by j.l.Object) during function interface conversion interface check
996 */
997 class DescriptorFilter implements Filter<Symbol> {
998
999 TypeSymbol origin;
1000
1001 DescriptorFilter(TypeSymbol origin) {
1002 this.origin = origin;
1003 }
1004
1005 @Override
1006 public boolean accepts(Symbol sym) {
1007 return sym.kind == MTH &&
1008 (sym.flags() & (ABSTRACT | DEFAULT)) == ABSTRACT &&
1009 !overridesObjectMethod(origin, sym) &&
1010 (interfaceCandidates(origin.type, (MethodSymbol)sym).head.flags() & DEFAULT) == 0;
1011 }
1012 }
1013
1014 public boolean isValue(Type t) {
1015 return t != null && t.tsym != null && (t.tsym.flags_field & Flags.VALUE) != 0;
1016 }
1017
1018 public boolean isValueBased(Type t) {
1019 return allowValueBasedClasses && t != null && t.tsym != null && (t.tsym.flags() & Flags.VALUEBASED) != 0;
1020 }
1021
1022 // <editor-fold defaultstate="collapsed" desc="isSubtype">
1023 /**
1024 * Is t an unchecked subtype of s?
1025 */
1026 public boolean isSubtypeUnchecked(Type t, Type s) {
1027 return isSubtypeUnchecked(t, s, noWarnings);
1028 }
1029 /**
1030 * Is t an unchecked subtype of s?
1031 */
1032 public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
1033 boolean result = isSubtypeUncheckedInternal(t, s, true, warn);
1034 if (result) {
1035 checkUnsafeVarargsConversion(t, s, warn);
1036 }
1037 return result;
1038 }
1039 //where
1040 private boolean isSubtypeUncheckedInternal(Type t, Type s, boolean capture, Warner warn) {
1041 if (t.hasTag(ARRAY) && s.hasTag(ARRAY)) {
1042 if (((ArrayType)t).elemtype.isPrimitive()) {
1043 return isSameType(elemtype(t), elemtype(s));
1044 } else {
1045 // if T.ref <: S, then T[] <: S[]
1046 Type es = elemtype(s);
1047 Type et = elemtype(t);
1048 if (isValue(et)) {
1049 et = et.referenceProjection();
1050 if (isValue(es))
1051 es = es.referenceProjection(); // V <: V, surely
1052 }
1053 if (!isSubtypeUncheckedInternal(et, es, false, warn))
1054 return false;
1055 return true;
1056 }
1057 } else if (isSubtype(t, s, capture)) {
1058 return true;
1059 } else if (t.hasTag(TYPEVAR)) {
1060 return isSubtypeUncheckedInternal(t.getUpperBound(), s, false, warn);
1061 } else if (!s.isRaw()) {
1062 Type t2 = asSuper(t, s.tsym);
1063 if (t2 != null && t2.isRaw()) {
1064 if (isReifiable(s)) {
1065 warn.silentWarn(LintCategory.UNCHECKED);
1066 } else {
1067 warn.warn(LintCategory.UNCHECKED);
1068 }
1069 return true;
1070 }
1071 }
1072 return false;
1073 }
1074
1075 private void checkUnsafeVarargsConversion(Type t, Type s, Warner warn) {
1076 if (!t.hasTag(ARRAY) || isReifiable(t)) {
1077 return;
1078 }
1079 ArrayType from = (ArrayType)t;
1080 boolean shouldWarn = false;
1081 switch (s.getTag()) {
1082 case ARRAY:
1083 ArrayType to = (ArrayType)s;
1084 shouldWarn = from.isVarargs() &&
1085 !to.isVarargs() &&
1086 !isReifiable(from);
1087 break;
1088 case CLASS:
1089 shouldWarn = from.isVarargs();
1090 break;
1091 }
1092 if (shouldWarn) {
1093 warn.warn(LintCategory.VARARGS);
1094 }
1095 }
1096
1097 /**
1098 * Is t a subtype of s?<br>
1099 * (not defined for Method and ForAll types)
1100 */
1101 final public boolean isSubtype(Type t, Type s) {
1102 return isSubtype(t, s, true);
1103 }
1104 final public boolean isSubtypeNoCapture(Type t, Type s) {
1105 return isSubtype(t, s, false);
1106 }
1107 public boolean isSubtype(Type t, Type s, boolean capture) {
1108 if (t.equalsIgnoreMetadata(s))
1109 return true;
1110 if (s.isPartial())
1111 return isSuperType(s, t);
1112
1113 if (s.isCompound()) {
1114 for (Type s2 : interfaces(s).prepend(supertype(s))) {
1115 if (!isSubtype(t, s2, capture))
1116 return false;
1117 }
1118 return true;
1119 }
1120
1121 // Generally, if 's' is a lower-bounded type variable, recur on lower bound; but
1122 // for inference variables and intersections, we need to keep 's'
1123 // (see JLS 4.10.2 for intersections and 18.2.3 for inference vars)
1124 if (!t.hasTag(UNDETVAR) && !t.isCompound()) {
1125 // TODO: JDK-8039198, bounds checking sometimes passes in a wildcard as s
1126 Type lower = cvarLowerBound(wildLowerBound(s));
1127 if (s != lower && !lower.hasTag(BOT))
1128 return isSubtype(capture ? capture(t) : t, lower, false);
1129 }
1130
1131 return isSubtype.visit(capture ? capture(t) : t, s);
1132 }
1133 // where
1134 private TypeRelation isSubtype = new TypeRelation()
1135 {
1136 @Override
1137 public Boolean visitType(Type t, Type s) {
1138 switch (t.getTag()) {
1139 case BYTE:
1140 return (!s.hasTag(CHAR) && t.getTag().isSubRangeOf(s.getTag()));
1141 case CHAR:
1142 return (!s.hasTag(SHORT) && t.getTag().isSubRangeOf(s.getTag()));
1143 case SHORT: case INT: case LONG:
1144 case FLOAT: case DOUBLE:
1145 return t.getTag().isSubRangeOf(s.getTag());
1146 case BOOLEAN: case VOID:
1147 return t.hasTag(s.getTag());
1148 case TYPEVAR:
1149 return isSubtypeNoCapture(t.getUpperBound(), s);
1150 case BOT:
1151 return
1152 s.hasTag(BOT) || (s.hasTag(CLASS) && (!isValue(s) || isValueBased(s))) ||
1153 s.hasTag(ARRAY) || s.hasTag(TYPEVAR);
1154 case WILDCARD: //we shouldn't be here - avoids crash (see 7034495)
1155 case NONE:
1156 return false;
1157 default:
1158 throw new AssertionError("isSubtype " + t.getTag());
1159 }
1160 }
1161
1162 private Set<TypePair> cache = new HashSet<>();
1163
1164 private boolean containsTypeRecursive(Type t, Type s) {
1165 TypePair pair = new TypePair(t, s);
1166 if (cache.add(pair)) {
1167 try {
1168 return containsType(t.getTypeArguments(),
1169 s.getTypeArguments());
1170 } finally {
1171 cache.remove(pair);
1172 }
1173 } else {
1174 return containsType(t.getTypeArguments(),
1175 rewriteSupers(s).getTypeArguments());
1176 }
1177 }
1178
1179 private Type rewriteSupers(Type t) {
1180 if (!t.isParameterized())
1181 return t;
1182 ListBuffer<Type> from = new ListBuffer<>();
1183 ListBuffer<Type> to = new ListBuffer<>();
1184 adaptSelf(t, from, to);
1185 if (from.isEmpty())
1186 return t;
1187 ListBuffer<Type> rewrite = new ListBuffer<>();
1188 boolean changed = false;
1189 for (Type orig : to.toList()) {
1190 Type s = rewriteSupers(orig);
1191 if (s.isSuperBound() && !s.isExtendsBound()) {
1192 s = new WildcardType(syms.objectType,
1193 BoundKind.UNBOUND,
1194 syms.boundClass,
1195 s.getMetadata());
1196 changed = true;
1197 } else if (s != orig) {
1198 s = new WildcardType(wildUpperBound(s),
1199 BoundKind.EXTENDS,
1200 syms.boundClass,
1201 s.getMetadata());
1202 changed = true;
1203 }
1204 rewrite.append(s);
1205 }
1206 if (changed)
1207 return subst(t.tsym.type, from.toList(), rewrite.toList());
1208 else
1209 return t;
1210 }
1211
1212 @Override
1213 public Boolean visitClassType(ClassType t, Type s) {
1214 Type sup = asSuper(t, s.tsym);
1215 if (sup == null) return false;
1216 // If t is an intersection, sup might not be a class type
1217 if (!sup.hasTag(CLASS)) return isSubtypeNoCapture(sup, s);
1218 return sup.tsym == s.tsym
1219 // Check type variable containment
1220 && (!s.isParameterized() || containsTypeRecursive(s, sup))
1221 && isSubtypeNoCapture(sup.getEnclosingType(),
1222 s.getEnclosingType());
1223 }
1224
1225 @Override
1226 public Boolean visitArrayType(ArrayType t, Type s) {
1227 if (s.hasTag(ARRAY)) {
1228 if (t.elemtype.isPrimitive())
1229 return isSameType(t.elemtype, elemtype(s));
1230 else {
1231 // if T.ref <: S, then T[] <: S[]
1232 Type es = elemtype(s);
1233 Type et = elemtype(t);
1234 if (isValue(et)) {
1235 et = et.referenceProjection();
1236 if (isValue(es))
1237 es = es.referenceProjection(); // V <: V, surely
1238 }
1239 return isSubtypeNoCapture(et, es);
1240 }
1241 }
1242
1243 if (s.hasTag(CLASS)) {
1244 Name sname = s.tsym.getQualifiedName();
1245 return sname == names.java_lang_Object
1246 || sname == names.java_lang_Cloneable
1247 || sname == names.java_io_Serializable
1248 || (injectTopInterfaceTypes && sname == names.java_lang_IdentityObject);
1249 }
1250
1251 return false;
1252 }
1253
1254 @Override
1255 public Boolean visitUndetVar(UndetVar t, Type s) {
1256 //todo: test against origin needed? or replace with substitution?
1257 if (t == s || t.qtype == s || s.hasTag(ERROR) || s.hasTag(UNKNOWN)) {
1258 return true;
1259 } else if (s.hasTag(BOT)) {
1260 //if 's' is 'null' there's no instantiated type U for which
1261 //U <: s (but 'null' itself, which is not a valid type)
1262 return false;
1263 }
1264
1265 t.addBound(InferenceBound.UPPER, s, Types.this);
1266 return true;
1267 }
1268
1269 @Override
1270 public Boolean visitErrorType(ErrorType t, Type s) {
1271 return true;
1272 }
1273 };
1274
1275 /**
1276 * Is t a subtype of every type in given list `ts'?<br>
1277 * (not defined for Method and ForAll types)<br>
1278 * Allows unchecked conversions.
1279 */
1280 public boolean isSubtypeUnchecked(Type t, List<Type> ts, Warner warn) {
1281 for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
1282 if (!isSubtypeUnchecked(t, l.head, warn))
1283 return false;
1284 return true;
1285 }
1286
1287 /**
1288 * Are corresponding elements of ts subtypes of ss? If lists are
1289 * of different length, return false.
1290 */
1291 public boolean isSubtypes(List<Type> ts, List<Type> ss) {
1292 while (ts.tail != null && ss.tail != null
1293 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
1294 isSubtype(ts.head, ss.head)) {
1295 ts = ts.tail;
1296 ss = ss.tail;
1297 }
1298 return ts.tail == null && ss.tail == null;
1299 /*inlined: ts.isEmpty() && ss.isEmpty();*/
1300 }
1301
1302 /**
1303 * Are corresponding elements of ts subtypes of ss, allowing
1304 * unchecked conversions? If lists are of different length,
1305 * return false.
1306 **/
1307 public boolean isSubtypesUnchecked(List<Type> ts, List<Type> ss, Warner warn) {
1308 while (ts.tail != null && ss.tail != null
1309 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
1310 isSubtypeUnchecked(ts.head, ss.head, warn)) {
1311 ts = ts.tail;
1312 ss = ss.tail;
1313 }
1314 return ts.tail == null && ss.tail == null;
1315 /*inlined: ts.isEmpty() && ss.isEmpty();*/
1316 }
1317 // </editor-fold>
1318
1319 // <editor-fold defaultstate="collapsed" desc="isSuperType">
1320 /**
1321 * Is t a supertype of s?
1322 */
1323 public boolean isSuperType(Type t, Type s) {
1324 switch (t.getTag()) {
1325 case ERROR:
1326 return true;
1327 case UNDETVAR: {
1328 UndetVar undet = (UndetVar)t;
1329 if (t == s ||
1330 undet.qtype == s ||
1331 s.hasTag(ERROR) ||
1332 s.hasTag(BOT)) {
1333 return true;
1334 }
1335 undet.addBound(InferenceBound.LOWER, s, this);
1336 return true;
1337 }
1338 default:
1339 return isSubtype(s, t);
1340 }
1341 }
1342 // </editor-fold>
1343
1344 // <editor-fold defaultstate="collapsed" desc="isSameType">
1345 /**
1346 * Are corresponding elements of the lists the same type? If
1347 * lists are of different length, return false.
1348 */
1349 public boolean isSameTypes(List<Type> ts, List<Type> ss) {
1350 while (ts.tail != null && ss.tail != null
1351 /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
1352 isSameType(ts.head, ss.head)) {
1353 ts = ts.tail;
1354 ss = ss.tail;
1355 }
1356 return ts.tail == null && ss.tail == null;
1357 /*inlined: ts.isEmpty() && ss.isEmpty();*/
1358 }
1359
1360 /**
1361 * A polymorphic signature method (JLS 15.12.3) is a method that
1362 * (i) is declared in the java.lang.invoke.MethodHandle/VarHandle classes;
1363 * (ii) takes a single variable arity parameter;
1364 * (iii) whose declared type is Object[];
1365 * (iv) has any return type, Object signifying a polymorphic return type; and
1366 * (v) is native.
1367 */
1368 public boolean isSignaturePolymorphic(MethodSymbol msym) {
1369 List<Type> argtypes = msym.type.getParameterTypes();
1370 return (msym.flags_field & NATIVE) != 0 &&
1371 (msym.owner == syms.methodHandleType.tsym || msym.owner == syms.varHandleType.tsym) &&
1372 argtypes.length() == 1 &&
1373 argtypes.head.hasTag(TypeTag.ARRAY) &&
1374 ((ArrayType)argtypes.head).elemtype.tsym == syms.objectType.tsym;
1375 }
1376
1377 /**
1378 * Is t the same type as s?
1379 */
1380 public boolean isSameType(Type t, Type s) {
1381 return isSameTypeVisitor.visit(t, s);
1382 }
1383 // where
1384
1385 /**
1386 * Type-equality relation - type variables are considered
1387 * equals if they share the same object identity.
1388 */
1389 TypeRelation isSameTypeVisitor = new TypeRelation() {
1390
1391 public Boolean visitType(Type t, Type s) {
1392 if (t.equalsIgnoreMetadata(s))
1393 return true;
1394
1395 if (s.isPartial())
1396 return visit(s, t);
1397
1398 switch (t.getTag()) {
1399 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
1400 case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE:
1401 return t.hasTag(s.getTag());
1402 case TYPEVAR: {
1403 if (s.hasTag(TYPEVAR)) {
1404 //type-substitution does not preserve type-var types
1405 //check that type var symbols and bounds are indeed the same
1406 return t == s;
1407 }
1408 else {
1409 //special case for s == ? super X, where upper(s) = u
1410 //check that u == t, where u has been set by Type.withTypeVar
1411 return s.isSuperBound() &&
1412 !s.isExtendsBound() &&
1413 visit(t, wildUpperBound(s));
1414 }
1415 }
1416 default:
1417 throw new AssertionError("isSameType " + t.getTag());
1418 }
1419 }
1420
1421 @Override
1422 public Boolean visitWildcardType(WildcardType t, Type s) {
1423 if (!s.hasTag(WILDCARD)) {
1424 return false;
1425 } else {
1426 WildcardType t2 = (WildcardType)s;
1427 return (t.kind == t2.kind || (t.isExtendsBound() && s.isExtendsBound())) &&
1428 isSameType(t.type, t2.type);
1429 }
1430 }
1431
1432 @Override
1433 public Boolean visitClassType(ClassType t, Type s) {
1434 if (t == s)
1435 return true;
1436
1437 if (s.isPartial())
1438 return visit(s, t);
1439
1440 if (s.isSuperBound() && !s.isExtendsBound())
1441 return visit(t, wildUpperBound(s)) && visit(t, wildLowerBound(s));
1442
1443 if (t.isCompound() && s.isCompound()) {
1444 if (!visit(supertype(t), supertype(s)))
1445 return false;
1446
1447 Map<Symbol,Type> tMap = new HashMap<>();
1448 for (Type ti : interfaces(t)) {
1449 if (tMap.containsKey(ti)) {
1450 throw new AssertionError("Malformed intersection");
1451 }
1452 tMap.put(ti.tsym, ti);
1453 }
1454 for (Type si : interfaces(s)) {
1455 if (!tMap.containsKey(si.tsym))
1456 return false;
1457 Type ti = tMap.remove(si.tsym);
1458 if (!visit(ti, si))
1459 return false;
1460 }
1461 return tMap.isEmpty();
1462 }
1463 return t.tsym == s.tsym
1464 && visit(t.getEnclosingType(), s.getEnclosingType())
1465 && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments());
1466 }
1467
1468 @Override
1469 public Boolean visitArrayType(ArrayType t, Type s) {
1470 if (t == s)
1471 return true;
1472
1473 if (s.isPartial())
1474 return visit(s, t);
1475
1476 return s.hasTag(ARRAY)
1477 && containsTypeEquivalent(t.elemtype, elemtype(s));
1478 }
1479
1480 @Override
1481 public Boolean visitMethodType(MethodType t, Type s) {
1482 // isSameType for methods does not take thrown
1483 // exceptions into account!
1484 return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType());
1485 }
1486
1487 @Override
1488 public Boolean visitPackageType(PackageType t, Type s) {
1489 return t == s;
1490 }
1491
1492 @Override
1493 public Boolean visitForAll(ForAll t, Type s) {
1494 if (!s.hasTag(FORALL)) {
1495 return false;
1496 }
1497
1498 ForAll forAll = (ForAll)s;
1499 return hasSameBounds(t, forAll)
1500 && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
1501 }
1502
1503 @Override
1504 public Boolean visitUndetVar(UndetVar t, Type s) {
1505 if (s.hasTag(WILDCARD)) {
1506 // FIXME, this might be leftovers from before capture conversion
1507 return false;
1508 }
1509
1510 if (t == s || t.qtype == s || s.hasTag(ERROR) || s.hasTag(UNKNOWN)) {
1511 return true;
1512 }
1513
1514 t.addBound(InferenceBound.EQ, s, Types.this);
1515
1516 return true;
1517 }
1518
1519 @Override
1520 public Boolean visitErrorType(ErrorType t, Type s) {
1521 return true;
1522 }
1523 };
1524
1525 // </editor-fold>
1526
1527 // <editor-fold defaultstate="collapsed" desc="Contains Type">
1528 public boolean containedBy(Type t, Type s) {
1529 switch (t.getTag()) {
1530 case UNDETVAR:
1531 if (s.hasTag(WILDCARD)) {
1532 UndetVar undetvar = (UndetVar)t;
1533 WildcardType wt = (WildcardType)s;
1534 switch(wt.kind) {
1535 case UNBOUND:
1536 break;
1537 case EXTENDS: {
1538 Type bound = wildUpperBound(s);
1539 undetvar.addBound(InferenceBound.UPPER, bound, this);
1540 break;
1541 }
1542 case SUPER: {
1543 Type bound = wildLowerBound(s);
1544 undetvar.addBound(InferenceBound.LOWER, bound, this);
1545 break;
1546 }
1547 }
1548 return true;
1549 } else {
1550 return isSameType(t, s);
1551 }
1552 case ERROR:
1553 return true;
1554 default:
1555 return containsType(s, t);
1556 }
1557 }
1558
1559 boolean containsType(List<Type> ts, List<Type> ss) {
1560 while (ts.nonEmpty() && ss.nonEmpty()
1561 && containsType(ts.head, ss.head)) {
1562 ts = ts.tail;
1563 ss = ss.tail;
1564 }
1565 return ts.isEmpty() && ss.isEmpty();
1566 }
1567
1568 /**
1569 * Check if t contains s.
1570 *
1571 * <p>T contains S if:
1572 *
1573 * <p>{@code L(T) <: L(S) && U(S) <: U(T)}
1574 *
1575 * <p>This relation is only used by ClassType.isSubtype(), that
1576 * is,
1577 *
1578 * <p>{@code C<S> <: C<T> if T contains S.}
1579 *
1580 * <p>Because of F-bounds, this relation can lead to infinite
1581 * recursion. Thus we must somehow break that recursion. Notice
1582 * that containsType() is only called from ClassType.isSubtype().
1583 * Since the arguments have already been checked against their
1584 * bounds, we know:
1585 *
1586 * <p>{@code U(S) <: U(T) if T is "super" bound (U(T) *is* the bound)}
1587 *
1588 * <p>{@code L(T) <: L(S) if T is "extends" bound (L(T) is bottom)}
1589 *
1590 * @param t a type
1591 * @param s a type
1592 */
1593 public boolean containsType(Type t, Type s) {
1594 return containsType.visit(t, s);
1595 }
1596 // where
1597 private TypeRelation containsType = new TypeRelation() {
1598
1599 public Boolean visitType(Type t, Type s) {
1600 if (s.isPartial())
1601 return containedBy(s, t);
1602 else
1603 return isSameType(t, s);
1604 }
1605
1606 // void debugContainsType(WildcardType t, Type s) {
1607 // System.err.println();
1608 // System.err.format(" does %s contain %s?%n", t, s);
1609 // System.err.format(" %s U(%s) <: U(%s) %s = %s%n",
1610 // wildUpperBound(s), s, t, wildUpperBound(t),
1611 // t.isSuperBound()
1612 // || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t)));
1613 // System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
1614 // wildLowerBound(t), t, s, wildLowerBound(s),
1615 // t.isExtendsBound()
1616 // || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s)));
1617 // System.err.println();
1618 // }
1619
1620 @Override
1621 public Boolean visitWildcardType(WildcardType t, Type s) {
1622 if (s.isPartial())
1623 return containedBy(s, t);
1624 else {
1625 // debugContainsType(t, s);
1626
1627 // ----------------------------------- Unspecified behavior ----------------
1628
1629 /* If a value class V implements an interface I, then does "? extends I" contain V?
1630 It seems widening must be applied here to answer yes to compile some common code
1631 patterns.
1632 */
1633
1634 // ---------------------------------------------------------------------------
1635 return isSameWildcard(t, s)
1636 || isCaptureOf(s, t)
1637 || ((t.isExtendsBound() || isSubtypeNoCapture(wildLowerBound(t), wildLowerBound(s))) &&
1638 (t.isSuperBound() || isSubtypeNoCapture(wildUpperBound(s), wildUpperBound(t))));
1639 }
1640 }
1641
1642 @Override
1643 public Boolean visitUndetVar(UndetVar t, Type s) {
1644 if (!s.hasTag(WILDCARD)) {
1645 return isSameType(t, s);
1646 } else {
1647 return false;
1648 }
1649 }
1650
1651 @Override
1652 public Boolean visitErrorType(ErrorType t, Type s) {
1653 return true;
1654 }
1655 };
1656
1657 public boolean isCaptureOf(Type s, WildcardType t) {
1658 if (!s.hasTag(TYPEVAR) || !((TypeVar)s).isCaptured())
1659 return false;
1660 return isSameWildcard(t, ((CapturedType)s).wildcard);
1661 }
1662
1663 public boolean isSameWildcard(WildcardType t, Type s) {
1664 if (!s.hasTag(WILDCARD))
1665 return false;
1666 WildcardType w = (WildcardType)s;
1667 return w.kind == t.kind && w.type == t.type;
1668 }
1669
1670 public boolean containsTypeEquivalent(List<Type> ts, List<Type> ss) {
1671 while (ts.nonEmpty() && ss.nonEmpty()
1672 && containsTypeEquivalent(ts.head, ss.head)) {
1673 ts = ts.tail;
1674 ss = ss.tail;
1675 }
1676 return ts.isEmpty() && ss.isEmpty();
1677 }
1678 // </editor-fold>
1679
1680 // <editor-fold defaultstate="collapsed" desc="isCastable">
1681 public boolean isCastable(Type t, Type s) {
1682 return isCastable(t, s, noWarnings);
1683 }
1684
1685 /**
1686 * Is t is castable to s?<br>
1687 * s is assumed to be an erased type.<br>
1688 * (not defined for Method and ForAll types).
1689 */
1690 public boolean isCastable(Type t, Type s, Warner warn) {
1691 if (t == s)
1692 return true;
1693 if (t.isPrimitive() != s.isPrimitive()) {
1694 t = skipTypeVars(t, false);
1695 return (isConvertible(t, s, warn)
1696 || (s.isPrimitive() &&
1697 isSubtype(boxedClass(s).type, t)));
1698 }
1699 if (warn != warnStack.head) {
1700 try {
1701 warnStack = warnStack.prepend(warn);
1702 checkUnsafeVarargsConversion(t, s, warn);
1703 return isCastable.visit(t,s);
1704 } finally {
1705 warnStack = warnStack.tail;
1706 }
1707 } else {
1708 return isCastable.visit(t,s);
1709 }
1710 }
1711 // where
1712 private TypeRelation isCastable = new TypeRelation() {
1713
1714 public Boolean visitType(Type t, Type s) {
1715 if (s.hasTag(ERROR) || t.hasTag(NONE))
1716 return true;
1717
1718 switch (t.getTag()) {
1719 case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
1720 case DOUBLE:
1721 return s.isNumeric();
1722 case BOOLEAN:
1723 return s.hasTag(BOOLEAN);
1724 case VOID:
1725 return false;
1726 case BOT:
1727 return isSubtype(t, s);
1728 default:
1729 throw new AssertionError();
1730 }
1731 }
1732
1733 @Override
1734 public Boolean visitWildcardType(WildcardType t, Type s) {
1735 return isCastable(wildUpperBound(t), s, warnStack.head);
1736 }
1737
1738 @Override
1739 public Boolean visitClassType(ClassType t, Type s) {
1740 if (s.hasTag(ERROR) || (s.hasTag(BOT) && !isValue(t)))
1741 return true;
1742
1743 if (s.hasTag(TYPEVAR)) {
1744 if (isCastable(t, s.getUpperBound(), noWarnings)) {
1745 warnStack.head.warn(LintCategory.UNCHECKED);
1746 return true;
1747 } else {
1748 return false;
1749 }
1750 }
1751
1752 if (t.isCompound() || s.isCompound()) {
1753 return !t.isCompound() ?
1754 visitCompoundType((ClassType)s, t, true) :
1755 visitCompoundType(t, s, false);
1756 }
1757
1758 if (s.hasTag(CLASS) || s.hasTag(ARRAY)) {
1759 if (isValue(t)) {
1760 // (s) Value ? == (s) Value.ref
1761 t = t.referenceProjection();
1762 }
1763 if (isValue(s)) {
1764 // (Value) t ? == (Value.ref) t
1765 s = s.referenceProjection();
1766 }
1767 boolean upcast;
1768 if ((upcast = isSubtype(erasure(t), erasure(s)))
1769 || isSubtype(erasure(s), erasure(t))) {
1770 if (!upcast && s.hasTag(ARRAY)) {
1771 if (!isReifiable(s))
1772 warnStack.head.warn(LintCategory.UNCHECKED);
1773 return true;
1774 } else if (s.isRaw()) {
1775 return true;
1776 } else if (t.isRaw()) {
1777 if (!isUnbounded(s))
1778 warnStack.head.warn(LintCategory.UNCHECKED);
1779 return true;
1780 }
1781 // Assume |a| <: |b|
1782 final Type a = upcast ? t : s;
1783 final Type b = upcast ? s : t;
1784 final boolean HIGH = true;
1785 final boolean LOW = false;
1786 final boolean DONT_REWRITE_TYPEVARS = false;
1787 Type aHigh = rewriteQuantifiers(a, HIGH, DONT_REWRITE_TYPEVARS);
1788 Type aLow = rewriteQuantifiers(a, LOW, DONT_REWRITE_TYPEVARS);
1789 Type bHigh = rewriteQuantifiers(b, HIGH, DONT_REWRITE_TYPEVARS);
1790 Type bLow = rewriteQuantifiers(b, LOW, DONT_REWRITE_TYPEVARS);
1791 Type lowSub = asSub(bLow, aLow.tsym);
1792 Type highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);
1793 if (highSub == null) {
1794 final boolean REWRITE_TYPEVARS = true;
1795 aHigh = rewriteQuantifiers(a, HIGH, REWRITE_TYPEVARS);
1796 aLow = rewriteQuantifiers(a, LOW, REWRITE_TYPEVARS);
1797 bHigh = rewriteQuantifiers(b, HIGH, REWRITE_TYPEVARS);
1798 bLow = rewriteQuantifiers(b, LOW, REWRITE_TYPEVARS);
1799 lowSub = asSub(bLow, aLow.tsym);
1800 highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);
1801 }
1802 if (highSub != null) {
1803 if (!(a.tsym == highSub.tsym && a.tsym == lowSub.tsym)) {
1804 Assert.error(a.tsym + " != " + highSub.tsym + " != " + lowSub.tsym);
1805 }
1806 if (!disjointTypes(aHigh.allparams(), highSub.allparams())
1807 && !disjointTypes(aHigh.allparams(), lowSub.allparams())
1808 && !disjointTypes(aLow.allparams(), highSub.allparams())
1809 && !disjointTypes(aLow.allparams(), lowSub.allparams())) {
1810 if (upcast ? giveWarning(a, b) :
1811 giveWarning(b, a))
1812 warnStack.head.warn(LintCategory.UNCHECKED);
1813 return true;
1814 }
1815 }
1816 if (isReifiable(s))
1817 return isSubtypeUnchecked(a, b);
1818 else
1819 return isSubtypeUnchecked(a, b, warnStack.head);
1820 }
1821
1822 // Sidecast
1823 if (s.hasTag(CLASS)) {
1824 if ((s.tsym.flags() & INTERFACE) != 0) {
1825 return ((t.tsym.flags() & FINAL) == 0)
1826 ? sideCast(t, s, warnStack.head)
1827 : sideCastFinal(t, s, warnStack.head);
1828 } else if ((t.tsym.flags() & INTERFACE) != 0) {
1829 return ((s.tsym.flags() & FINAL) == 0)
1830 ? sideCast(t, s, warnStack.head)
1831 : sideCastFinal(t, s, warnStack.head);
1832 } else {
1833 // unrelated class types
1834 return false;
1835 }
1836 }
1837 }
1838 return false;
1839 }
1840
1841 boolean visitCompoundType(ClassType ct, Type s, boolean reverse) {
1842 Warner warn = noWarnings;
1843 for (Type c : directSupertypes(ct)) {
1844 warn.clear();
1845 if (reverse ? !isCastable(s, c, warn) : !isCastable(c, s, warn))
1846 return false;
1847 }
1848 if (warn.hasLint(LintCategory.UNCHECKED))
1849 warnStack.head.warn(LintCategory.UNCHECKED);
1850 return true;
1851 }
1852
1853 @Override
1854 public Boolean visitArrayType(ArrayType t, Type s) {
1855 switch (s.getTag()) {
1856 case ERROR:
1857 case BOT:
1858 return true;
1859 case TYPEVAR:
1860 if (isCastable(s, t, noWarnings)) {
1861 warnStack.head.warn(LintCategory.UNCHECKED);
1862 return true;
1863 } else {
1864 return false;
1865 }
1866 case CLASS:
1867 return isSubtype(t, s);
1868 case ARRAY:
1869 if (elemtype(t).isPrimitive() || elemtype(s).isPrimitive()) {
1870 return elemtype(t).hasTag(elemtype(s).getTag());
1871 } else {
1872 Type et = elemtype(t);
1873 Type es = elemtype(s);
1874 if (!visit(et, es))
1875 return false;
1876 return true;
1877 }
1878 default:
1879 return false;
1880 }
1881 }
1882
1883 @Override
1884 public Boolean visitTypeVar(TypeVar t, Type s) {
1885 switch (s.getTag()) {
1886 case ERROR:
1887 case BOT:
1888 return true;
1889 case TYPEVAR:
1890 if (isSubtype(t, s)) {
1891 return true;
1892 } else if (isCastable(t.getUpperBound(), s, noWarnings)) {
1893 warnStack.head.warn(LintCategory.UNCHECKED);
1894 return true;
1895 } else {
1896 return false;
1897 }
1898 default:
1899 return isCastable(t.getUpperBound(), s, warnStack.head);
1900 }
1901 }
1902
1903 @Override
1904 public Boolean visitErrorType(ErrorType t, Type s) {
1905 return true;
1906 }
1907 };
1908 // </editor-fold>
1909
1910 // <editor-fold defaultstate="collapsed" desc="disjointTypes">
1911 public boolean disjointTypes(List<Type> ts, List<Type> ss) {
1912 while (ts.tail != null && ss.tail != null) {
1913 if (disjointType(ts.head, ss.head)) return true;
1914 ts = ts.tail;
1915 ss = ss.tail;
1916 }
1917 return false;
1918 }
1919
1920 /**
1921 * Two types or wildcards are considered disjoint if it can be
1922 * proven that no type can be contained in both. It is
1923 * conservative in that it is allowed to say that two types are
1924 * not disjoint, even though they actually are.
1925 *
1926 * The type {@code C<X>} is castable to {@code C<Y>} exactly if
1927 * {@code X} and {@code Y} are not disjoint.
1928 */
1929 public boolean disjointType(Type t, Type s) {
1930 return disjointType.visit(t, s);
1931 }
1932 // where
1933 private TypeRelation disjointType = new TypeRelation() {
1934
1935 private Set<TypePair> cache = new HashSet<>();
1936
1937 @Override
1938 public Boolean visitType(Type t, Type s) {
1939 if (s.hasTag(WILDCARD))
1940 return visit(s, t);
1941 else
1942 return notSoftSubtypeRecursive(t, s) || notSoftSubtypeRecursive(s, t);
1943 }
1944
1945 private boolean isCastableRecursive(Type t, Type s) {
1946 TypePair pair = new TypePair(t, s);
1947 if (cache.add(pair)) {
1948 try {
1949 return Types.this.isCastable(t, s);
1950 } finally {
1951 cache.remove(pair);
1952 }
1953 } else {
1954 return true;
1955 }
1956 }
1957
1958 private boolean notSoftSubtypeRecursive(Type t, Type s) {
1959 TypePair pair = new TypePair(t, s);
1960 if (cache.add(pair)) {
1961 try {
1962 return Types.this.notSoftSubtype(t, s);
1963 } finally {
1964 cache.remove(pair);
1965 }
1966 } else {
1967 return false;
1968 }
1969 }
1970
1971 @Override
1972 public Boolean visitWildcardType(WildcardType t, Type s) {
1973 if (t.isUnbound())
1974 return false;
1975
1976 if (!s.hasTag(WILDCARD)) {
1977 if (t.isExtendsBound())
1978 return notSoftSubtypeRecursive(s, t.type);
1979 else
1980 return notSoftSubtypeRecursive(t.type, s);
1981 }
1982
1983 if (s.isUnbound())
1984 return false;
1985
1986 if (t.isExtendsBound()) {
1987 if (s.isExtendsBound())
1988 return !isCastableRecursive(t.type, wildUpperBound(s));
1989 else if (s.isSuperBound())
1990 return notSoftSubtypeRecursive(wildLowerBound(s), t.type);
1991 } else if (t.isSuperBound()) {
1992 if (s.isExtendsBound())
1993 return notSoftSubtypeRecursive(t.type, wildUpperBound(s));
1994 }
1995 return false;
1996 }
1997 };
1998 // </editor-fold>
1999
2000 // <editor-fold defaultstate="collapsed" desc="cvarLowerBounds">
2001 public List<Type> cvarLowerBounds(List<Type> ts) {
2002 return ts.map(cvarLowerBoundMapping);
2003 }
2004 private final TypeMapping<Void> cvarLowerBoundMapping = new TypeMapping<Void>() {
2005 @Override
2006 public Type visitCapturedType(CapturedType t, Void _unused) {
2007 return cvarLowerBound(t);
2008 }
2009 };
2010 // </editor-fold>
2011
2012 // <editor-fold defaultstate="collapsed" desc="notSoftSubtype">
2013 /**
2014 * This relation answers the question: is impossible that
2015 * something of type `t' can be a subtype of `s'? This is
2016 * different from the question "is `t' not a subtype of `s'?"
2017 * when type variables are involved: Integer is not a subtype of T
2018 * where {@code <T extends Number>} but it is not true that Integer cannot
2019 * possibly be a subtype of T.
2020 */
2021 public boolean notSoftSubtype(Type t, Type s) {
2022 if (t == s) return false;
2023 if (t.hasTag(TYPEVAR)) {
2024 TypeVar tv = (TypeVar) t;
2025 return !isCastable(tv.getUpperBound(),
2026 relaxBound(s),
2027 noWarnings);
2028 }
2029 if (!s.hasTag(WILDCARD))
2030 s = cvarUpperBound(s);
2031
2032 return !isSubtype(t, relaxBound(s));
2033 }
2034
2035 private Type relaxBound(Type t) {
2036 return (t.hasTag(TYPEVAR)) ?
2037 rewriteQuantifiers(skipTypeVars(t, false), true, true) :
2038 t;
2039 }
2040 // </editor-fold>
2041
2042 // <editor-fold defaultstate="collapsed" desc="isReifiable">
2043 public boolean isReifiable(Type t) {
2044 return isReifiable.visit(t);
2045 }
2046 // where
2047 private UnaryVisitor<Boolean> isReifiable = new UnaryVisitor<Boolean>() {
2048
2049 public Boolean visitType(Type t, Void ignored) {
2050 return true;
2051 }
2052
2053 @Override
2054 public Boolean visitClassType(ClassType t, Void ignored) {
2055 if (t.isCompound())
2056 return false;
2057 else {
2058 if (!t.isParameterized())
2059 return true;
2060
2061 for (Type param : t.allparams()) {
2062 if (!param.isUnbound())
2063 return false;
2064 }
2065 return true;
2066 }
2067 }
2068
2069 @Override
2070 public Boolean visitArrayType(ArrayType t, Void ignored) {
2071 return visit(t.elemtype);
2072 }
2073
2074 @Override
2075 public Boolean visitTypeVar(TypeVar t, Void ignored) {
2076 return false;
2077 }
2078 };
2079 // </editor-fold>
2080
2081 // <editor-fold defaultstate="collapsed" desc="Array Utils">
2082 public boolean isArray(Type t) {
2083 while (t.hasTag(WILDCARD))
2084 t = wildUpperBound(t);
2085 return t.hasTag(ARRAY);
2086 }
2087
2088 /**
2089 * The element type of an array.
2090 */
2091 public Type elemtype(Type t) {
2092 switch (t.getTag()) {
2093 case WILDCARD:
2094 return elemtype(wildUpperBound(t));
2095 case ARRAY:
2096 return ((ArrayType)t).elemtype;
2097 case FORALL:
2098 return elemtype(((ForAll)t).qtype);
2099 case ERROR:
2100 return t;
2101 default:
2102 return null;
2103 }
2104 }
2105
2106 public Type elemtypeOrType(Type t) {
2107 Type elemtype = elemtype(t);
2108 return elemtype != null ?
2109 elemtype :
2110 t;
2111 }
2112
2113 /**
2114 * Mapping to take element type of an arraytype
2115 */
2116 private TypeMapping<Void> elemTypeFun = new TypeMapping<Void>() {
2117 @Override
2118 public Type visitArrayType(ArrayType t, Void _unused) {
2119 return t.elemtype;
2120 }
2121
2122 @Override
2123 public Type visitTypeVar(TypeVar t, Void _unused) {
2124 return visit(skipTypeVars(t, false));
2125 }
2126 };
2127
2128 /**
2129 * The number of dimensions of an array type.
2130 */
2131 public int dimensions(Type t) {
2132 int result = 0;
2133 while (t.hasTag(ARRAY)) {
2134 result++;
2135 t = elemtype(t);
2136 }
2137 return result;
2138 }
2139
2140 /**
2141 * Returns an ArrayType with the component type t
2142 *
2143 * @param t The component type of the ArrayType
2144 * @return the ArrayType for the given component
2145 */
2146 public ArrayType makeArrayType(Type t) {
2147 if (t.hasTag(VOID) || t.hasTag(PACKAGE)) {
2148 Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString());
2149 }
2150 return new ArrayType(t, syms.arrayClass);
2151 }
2152 // </editor-fold>
2153
2154 // <editor-fold defaultstate="collapsed" desc="asSuper">
2155 /**
2156 * Return the (most specific) base type of t that starts with the
2157 * given symbol. If none exists, return null.
2158 *
2159 * Caveat Emptor: Since javac represents the class of all arrays with a singleton
2160 * symbol Symtab.arrayClass, which by being a singleton cannot hold any discriminant,
2161 * this method could yield surprising answers when invoked on arrays. For example when
2162 * invoked with t being byte [] and sym being t.sym itself, asSuper would answer null.
2163 *
2164 * @param t a type
2165 * @param sym a symbol
2166 */
2167 public Type asSuper(Type t, Symbol sym) {
2168 /* Some examples:
2169 *
2170 * (Enum<E>, Comparable) => Comparable<E>
2171 * (c.s.s.d.AttributeTree.ValueKind, Enum) => Enum<c.s.s.d.AttributeTree.ValueKind>
2172 * (c.s.s.t.ExpressionTree, c.s.s.t.Tree) => c.s.s.t.Tree
2173 * (j.u.List<capture#160 of ? extends c.s.s.d.DocTree>, Iterable) =>
2174 * Iterable<capture#160 of ? extends c.s.s.d.DocTree>
2175 */
2176 if (sym.type == syms.objectType) { //optimization
2177 if (!isValue(t))
2178 return syms.objectType;
2179 }
2180 return asSuper.visit(t, sym);
2181 }
2182 // where
2183 private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() {
2184
2185 public Type visitType(Type t, Symbol sym) {
2186 return null;
2187 }
2188
2189 @Override
2190 public Type visitClassType(ClassType t, Symbol sym) {
2191 if (t.tsym == sym)
2192 return t;
2193
2194 // No man may be an island, but the bell tolls for a value.
2195 if (isValue(t))
2196 return null;
2197
2198 Type st = supertype(t);
2199 if (st.hasTag(CLASS) || st.hasTag(TYPEVAR)) {
2200 Type x = asSuper(st, sym);
2201 if (x != null)
2202 return x;
2203 }
2204 if ((sym.flags() & INTERFACE) != 0) {
2205 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
2206 if (!l.head.hasTag(ERROR)) {
2207 Type x = asSuper(l.head, sym);
2208 if (x != null)
2209 return x;
2210 }
2211 }
2212 }
2213 return null;
2214 }
2215
2216 @Override
2217 public Type visitArrayType(ArrayType t, Symbol sym) {
2218 return isSubtype(t, sym.type) ? sym.type : null;
2219 }
2220
2221 @Override
2222 public Type visitTypeVar(TypeVar t, Symbol sym) {
2223 if (t.tsym == sym)
2224 return t;
2225 else
2226 return asSuper(t.getUpperBound(), sym);
2227 }
2228
2229 @Override
2230 public Type visitErrorType(ErrorType t, Symbol sym) {
2231 return t;
2232 }
2233 };
2234
2235 /**
2236 * Return the base type of t or any of its outer types that starts
2237 * with the given symbol. If none exists, return null.
2238 *
2239 * @param t a type
2240 * @param sym a symbol
2241 */
2242 public Type asOuterSuper(Type t, Symbol sym) {
2243 switch (t.getTag()) {
2244 case CLASS:
2245 do {
2246 Type s = asSuper(t, sym);
2247 if (s != null) return s;
2248 t = t.getEnclosingType();
2249 } while (t.hasTag(CLASS));
2250 return null;
2251 case ARRAY:
2252 return isSubtype(t, sym.type) ? sym.type : null;
2253 case TYPEVAR:
2254 return asSuper(t, sym);
2255 case ERROR:
2256 return t;
2257 default:
2258 return null;
2259 }
2260 }
2261
2262 /**
2263 * Return the base type of t or any of its enclosing types that
2264 * starts with the given symbol. If none exists, return null.
2265 *
2266 * @param t a type
2267 * @param sym a symbol
2268 */
2269 public Type asEnclosingSuper(Type t, Symbol sym) {
2270 switch (t.getTag()) {
2271 case CLASS:
2272 do {
2273 Type s = asSuper(t, sym);
2274 if (s != null) return s;
2275 Type outer = t.getEnclosingType();
2276 t = (outer.hasTag(CLASS)) ? outer :
2277 (t.tsym.owner.enclClass() != null) ? t.tsym.owner.enclClass().type :
2278 Type.noType;
2279 } while (t.hasTag(CLASS));
2280 return null;
2281 case ARRAY:
2282 return isSubtype(t, sym.type) ? sym.type : null;
2283 case TYPEVAR:
2284 return asSuper(t, sym);
2285 case ERROR:
2286 return t;
2287 default:
2288 return null;
2289 }
2290 }
2291 // </editor-fold>
2292
2293 // <editor-fold defaultstate="collapsed" desc="memberType">
2294 /**
2295 * The type of given symbol, seen as a member of t.
2296 *
2297 * @param t a type
2298 * @param sym a symbol
2299 */
2300 public Type memberType(Type t, Symbol sym) {
2301
2302 if ((sym.flags() & STATIC) != 0)
2303 return sym.type;
2304
2305 /* If any inline types are involved, switch over to the reference universe,
2306 where the hierarchy is navigable. V and V.ref have identical membership
2307 with no bridging needs.
2308 */
2309 if (t.isValue())
2310 t = t.referenceProjection();
2311
2312 if (sym.owner.isValue())
2313 sym = sym.referenceProjection();
2314
2315 return memberType.visit(t, sym);
2316 }
2317 // where
2318 private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
2319
2320 public Type visitType(Type t, Symbol sym) {
2321 return sym.type;
2322 }
2323
2324 @Override
2325 public Type visitWildcardType(WildcardType t, Symbol sym) {
2326 return memberType(wildUpperBound(t), sym);
2327 }
2328
2329 @Override
2330 public Type visitClassType(ClassType t, Symbol sym) {
2331 Symbol owner = sym.owner;
2332 long flags = sym.flags();
2333 if (((flags & STATIC) == 0) && owner.type.isParameterized()) {
2334 Type base = asOuterSuper(t, owner);
2335 //if t is an intersection type T = CT & I1 & I2 ... & In
2336 //its supertypes CT, I1, ... In might contain wildcards
2337 //so we need to go through capture conversion
2338 base = t.isCompound() ? capture(base) : base;
2339 if (base != null) {
2340 List<Type> ownerParams = owner.type.allparams();
2341 List<Type> baseParams = base.allparams();
2342 if (ownerParams.nonEmpty()) {
2343 if (baseParams.isEmpty()) {
2344 // then base is a raw type
2345 return erasure(sym.type);
2346 } else {
2347 return subst(sym.type, ownerParams, baseParams);
2348 }
2349 }
2350 }
2351 }
2352 return sym.type;
2353 }
2354
2355 @Override
2356 public Type visitTypeVar(TypeVar t, Symbol sym) {
2357 return memberType(t.getUpperBound(), sym);
2358 }
2359
2360 @Override
2361 public Type visitErrorType(ErrorType t, Symbol sym) {
2362 return t;
2363 }
2364 };
2365 // </editor-fold>
2366
2367 // <editor-fold defaultstate="collapsed" desc="isAssignable">
2368 public boolean isAssignable(Type t, Type s) {
2369 return isAssignable(t, s, noWarnings);
2370 }
2371
2372 /**
2373 * Is t assignable to s?<br>
2374 * Equivalent to subtype except for constant values and raw
2375 * types.<br>
2376 * (not defined for Method and ForAll types)
2377 */
2378 public boolean isAssignable(Type t, Type s, Warner warn) {
2379 if (t.hasTag(ERROR))
2380 return true;
2381 if (t.getTag().isSubRangeOf(INT) && t.constValue() != null) {
2382 int value = ((Number)t.constValue()).intValue();
2383 switch (s.getTag()) {
2384 case BYTE:
2385 case CHAR:
2386 case SHORT:
2387 case INT:
2388 if (s.getTag().checkRange(value))
2389 return true;
2390 break;
2391 case CLASS:
2392 switch (unboxedType(s).getTag()) {
2393 case BYTE:
2394 case CHAR:
2395 case SHORT:
2396 return isAssignable(t, unboxedType(s), warn);
2397 }
2398 break;
2399 }
2400 }
2401 return isConvertible(t, s, warn);
2402 }
2403 // </editor-fold>
2404
2405 // <editor-fold defaultstate="collapsed" desc="erasure">
2406 /**
2407 * The erasure of t {@code |t|} -- the type that results when all
2408 * type parameters in t are deleted.
2409 */
2410 public Type erasure(Type t) {
2411 return eraseNotNeeded(t) ? t : erasure(t, false);
2412 }
2413 //where
2414 private boolean eraseNotNeeded(Type t) {
2415 // We don't want to erase primitive types and String type as that
2416 // operation is idempotent. Also, erasing these could result in loss
2417 // of information such as constant values attached to such types.
2418 return (t.isPrimitive()) || (syms.stringType.tsym == t.tsym);
2419 }
2420
2421 private Type erasure(Type t, boolean recurse) {
2422 if (t.isPrimitive()) {
2423 return t; /* fast special case */
2424 } else {
2425 Type out = erasure.visit(t, recurse);
2426 return out;
2427 }
2428 }
2429 // where
2430 private TypeMapping<Boolean> erasure = new StructuralTypeMapping<Boolean>() {
2431 private Type combineMetadata(final Type s,
2432 final Type t) {
2433 if (t.getMetadata() != TypeMetadata.EMPTY) {
2434 switch (s.getKind()) {
2435 case OTHER:
2436 case UNION:
2437 case INTERSECTION:
2438 case PACKAGE:
2439 case EXECUTABLE:
2440 case NONE:
2441 case VOID:
2442 case ERROR:
2443 return s;
2444 default: return s.cloneWithMetadata(s.getMetadata().without(Kind.ANNOTATIONS));
2445 }
2446 } else {
2447 return s;
2448 }
2449 }
2450
2451 public Type visitType(Type t, Boolean recurse) {
2452 if (t.isPrimitive())
2453 return t; /*fast special case*/
2454 else {
2455 //other cases already handled
2456 return combineMetadata(t, t);
2457 }
2458 }
2459
2460 @Override
2461 public Type visitWildcardType(WildcardType t, Boolean recurse) {
2462 Type erased = erasure(wildUpperBound(t), recurse);
2463 return combineMetadata(erased, t);
2464 }
2465
2466 @Override
2467 public Type visitClassType(ClassType t, Boolean recurse) {
2468 Type erased = t.tsym.erasure(Types.this);
2469 if (recurse) {
2470 erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym,
2471 t.getMetadata().without(Kind.ANNOTATIONS));
2472 return erased;
2473 } else {
2474 return combineMetadata(erased, t);
2475 }
2476 }
2477
2478 @Override
2479 public Type visitTypeVar(TypeVar t, Boolean recurse) {
2480 Type erased = erasure(t.getUpperBound(), recurse);
2481 return combineMetadata(erased, t);
2482 }
2483 };
2484
2485 public List<Type> erasure(List<Type> ts) {
2486 return erasure.visit(ts, false);
2487 }
2488
2489 public Type erasureRecursive(Type t) {
2490 return erasure(t, true);
2491 }
2492
2493 public List<Type> erasureRecursive(List<Type> ts) {
2494 return erasure.visit(ts, true);
2495 }
2496 // </editor-fold>
2497
2498 // <editor-fold defaultstate="collapsed" desc="makeIntersectionType">
2499 /**
2500 * Make an intersection type from non-empty list of types. The list should be ordered according to
2501 * {@link TypeSymbol#precedes(TypeSymbol, Types)}. Note that this might cause a symbol completion.
2502 * Hence, this version of makeIntersectionType may not be called during a classfile read.
2503 *
2504 * @param bounds the types from which the intersection type is formed
2505 */
2506 public IntersectionClassType makeIntersectionType(List<Type> bounds) {
2507 return makeIntersectionType(bounds, bounds.head.tsym.isInterface());
2508 }
2509
2510 /**
2511 * Make an intersection type from non-empty list of types. The list should be ordered according to
2512 * {@link TypeSymbol#precedes(TypeSymbol, Types)}. This does not cause symbol completion as
2513 * an extra parameter indicates as to whether all bounds are interfaces - in which case the
2514 * supertype is implicitly assumed to be 'Object'.
2515 *
2516 * @param bounds the types from which the intersection type is formed
2517 * @param allInterfaces are all bounds interface types?
2518 */
2519 public IntersectionClassType makeIntersectionType(List<Type> bounds, boolean allInterfaces) {
2520 Assert.check(bounds.nonEmpty());
2521 Type firstExplicitBound = bounds.head;
2522 if (allInterfaces) {
2523 bounds = bounds.prepend(syms.objectType);
2524 }
2525 long flags = ABSTRACT | PUBLIC | SYNTHETIC | COMPOUND | ACYCLIC;
2526 if (isValue(bounds.head))
2527 flags |= VALUE;
2528 ClassSymbol bc =
2529 new ClassSymbol(flags,
2530 Type.moreInfo
2531 ? names.fromString(bounds.toString())
2532 : names.empty,
2533 null,
2534 syms.noSymbol);
2535 IntersectionClassType intersectionType = new IntersectionClassType(bounds, bc, allInterfaces);
2536 bc.type = intersectionType;
2537 bc.erasure_field = (bounds.head.hasTag(TYPEVAR)) ?
2538 syms.objectType : // error condition, recover
2539 erasure(firstExplicitBound);
2540 bc.members_field = WriteableScope.create(bc);
2541 return intersectionType;
2542 }
2543 // </editor-fold>
2544
2545 // <editor-fold defaultstate="collapsed" desc="supertype">
2546 public Type supertype(Type t) {
2547 return supertype.visit(t);
2548 }
2549 // where
2550 private UnaryVisitor<Type> supertype = new UnaryVisitor<Type>() {
2551
2552 public Type visitType(Type t, Void ignored) {
2553 // A note on wildcards: there is no good way to
2554 // determine a supertype for a super bounded wildcard.
2555 return Type.noType;
2556 }
2557
2558 @Override
2559 public Type visitClassType(ClassType t, Void ignored) {
2560 if (t.supertype_field == null) {
2561 Type supertype = ((ClassSymbol)t.tsym).getSuperclass();
2562 // An interface has no superclass; its supertype is Object.
2563 if (t.isInterface())
2564 supertype = ((ClassType)t.tsym.type).supertype_field;
2565 if (t.supertype_field == null) {
2566 List<Type> actuals = classBound(t).allparams();
2567 List<Type> formals = t.tsym.type.allparams();
2568 if (t.hasErasedSupertypes()) {
2569 t.supertype_field = erasureRecursive(supertype);
2570 } else if (formals.nonEmpty()) {
2571 t.supertype_field = subst(supertype, formals, actuals);
2572 }
2573 else {
2574 t.supertype_field = supertype;
2575 }
2576 }
2577 }
2578 return t.supertype_field;
2579 }
2580
2581 /**
2582 * The supertype is always a class type. If the type
2583 * variable's bounds start with a class type, this is also
2584 * the supertype. Otherwise, the supertype is
2585 * java.lang.Object.
2586 */
2587 @Override
2588 public Type visitTypeVar(TypeVar t, Void ignored) {
2589 if (t.getUpperBound().hasTag(TYPEVAR) ||
2590 (!t.getUpperBound().isCompound() && !t.getUpperBound().isInterface())) {
2591 return t.getUpperBound();
2592 } else {
2593 return supertype(t.getUpperBound());
2594 }
2595 }
2596
2597 @Override
2598 public Type visitArrayType(ArrayType t, Void ignored) {
2599 if (t.elemtype.isPrimitive() || isSameType(t.elemtype, syms.objectType))
2600 return arraySuperType();
2601 else
2602 return new ArrayType(supertype(t.elemtype), t.tsym);
2603 }
2604
2605 @Override
2606 public Type visitErrorType(ErrorType t, Void ignored) {
2607 return Type.noType;
2608 }
2609 };
2610 // </editor-fold>
2611
2612 // <editor-fold defaultstate="collapsed" desc="interfaces">
2613 /**
2614 * Return the interfaces implemented by this class.
2615 */
2616 public List<Type> interfaces(Type t) {
2617 return interfaces.visit(t);
2618 }
2619 // where
2620 private UnaryVisitor<List<Type>> interfaces = new UnaryVisitor<List<Type>>() {
2621
2622 public List<Type> visitType(Type t, Void ignored) {
2623 return List.nil();
2624 }
2625
2626 @Override
2627 public List<Type> visitClassType(ClassType t, Void ignored) {
2628 if (t.interfaces_field == null) {
2629 List<Type> interfaces = ((ClassSymbol)t.tsym).getInterfaces();
2630 if (t.interfaces_field == null) {
2631 // If t.interfaces_field is null, then t must
2632 // be a parameterized type (not to be confused
2633 // with a generic type declaration).
2634 // Terminology:
2635 // Parameterized type: List<String>
2636 // Generic type declaration: class List<E> { ... }
2637 // So t corresponds to List<String> and
2638 // t.tsym.type corresponds to List<E>.
2639 // The reason t must be parameterized type is
2640 // that completion will happen as a side
2641 // effect of calling
2642 // ClassSymbol.getInterfaces. Since
2643 // t.interfaces_field is null after
2644 // completion, we can assume that t is not the
2645 // type of a class/interface declaration.
2646 Assert.check(t != t.tsym.type, t);
2647 List<Type> actuals = t.allparams();
2648 List<Type> formals = t.tsym.type.allparams();
2649 if (t.hasErasedSupertypes()) {
2650 t.interfaces_field = erasureRecursive(interfaces);
2651 } else if (formals.nonEmpty()) {
2652 t.interfaces_field = subst(interfaces, formals, actuals);
2653 }
2654 else {
2655 t.interfaces_field = interfaces;
2656 }
2657 }
2658 }
2659 return t.interfaces_field;
2660 }
2661
2662 @Override
2663 public List<Type> visitTypeVar(TypeVar t, Void ignored) {
2664 if (t.getUpperBound().isCompound())
2665 return interfaces(t.getUpperBound());
2666
2667 if (t.getUpperBound().isInterface())
2668 return List.of(t.getUpperBound());
2669
2670 return List.nil();
2671 }
2672 };
2673
2674 public List<Type> directSupertypes(Type t) {
2675 return directSupertypes.visit(t);
2676 }
2677 // where
2678 private final UnaryVisitor<List<Type>> directSupertypes = new UnaryVisitor<List<Type>>() {
2679
2680 public List<Type> visitType(final Type type, final Void ignored) {
2681 if (!type.isIntersection()) {
2682 final Type sup = supertype(type);
2683 return (sup == Type.noType || sup == type || sup == null)
2684 ? interfaces(type)
2685 : interfaces(type).prepend(sup);
2686 } else {
2687 return ((IntersectionClassType)type).getExplicitComponents();
2688 }
2689 }
2690 };
2691
2692 public boolean isDirectSuperInterface(TypeSymbol isym, TypeSymbol origin) {
2693 for (Type i2 : interfaces(origin.type)) {
2694 if (isym == i2.tsym) return true;
2695 }
2696 return false;
2697 }
2698 // </editor-fold>
2699
2700 // <editor-fold defaultstate="collapsed" desc="isDerivedRaw">
2701 Map<Type,Boolean> isDerivedRawCache = new HashMap<>();
2702
2703 public boolean isDerivedRaw(Type t) {
2704 Boolean result = isDerivedRawCache.get(t);
2705 if (result == null) {
2706 result = isDerivedRawInternal(t);
2707 isDerivedRawCache.put(t, result);
2708 }
2709 return result;
2710 }
2711
2712 public boolean isDerivedRawInternal(Type t) {
2713 if (t.isErroneous())
2714 return false;
2715 return
2716 t.isRaw() ||
2717 supertype(t) != Type.noType && isDerivedRaw(supertype(t)) ||
2718 isDerivedRaw(interfaces(t));
2719 }
2720
2721 public boolean isDerivedRaw(List<Type> ts) {
2722 List<Type> l = ts;
2723 while (l.nonEmpty() && !isDerivedRaw(l.head)) l = l.tail;
2724 return l.nonEmpty();
2725 }
2726 // </editor-fold>
2727
2728 // <editor-fold defaultstate="collapsed" desc="setBounds">
2729 /**
2730 * Same as {@link Types#setBounds(TypeVar, List, boolean)}, except that third parameter is computed directly,
2731 * as follows: if all all bounds are interface types, the computed supertype is Object,otherwise
2732 * the supertype is simply left null (in this case, the supertype is assumed to be the head of
2733 * the bound list passed as second argument). Note that this check might cause a symbol completion.
2734 * Hence, this version of setBounds may not be called during a classfile read.
2735 *
2736 * @param t a type variable
2737 * @param bounds the bounds, must be nonempty
2738 */
2739 public void setBounds(TypeVar t, List<Type> bounds) {
2740 setBounds(t, bounds, bounds.head.tsym.isInterface());
2741 }
2742
2743 /**
2744 * Set the bounds field of the given type variable to reflect a (possibly multiple) list of bounds.
2745 * This does not cause symbol completion as an extra parameter indicates as to whether all bounds
2746 * are interfaces - in which case the supertype is implicitly assumed to be 'Object'.
2747 *
2748 * @param t a type variable
2749 * @param bounds the bounds, must be nonempty
2750 * @param allInterfaces are all bounds interface types?
2751 */
2752 public void setBounds(TypeVar t, List<Type> bounds, boolean allInterfaces) {
2753 t.setUpperBound( bounds.tail.isEmpty() ?
2754 bounds.head :
2755 makeIntersectionType(bounds, allInterfaces) );
2756 t.rank_field = -1;
2757 }
2758 // </editor-fold>
2759
2760 // <editor-fold defaultstate="collapsed" desc="getBounds">
2761 /**
2762 * Return list of bounds of the given type variable.
2763 */
2764 public List<Type> getBounds(TypeVar t) {
2765 if (t.getUpperBound().hasTag(NONE))
2766 return List.nil();
2767 else if (t.getUpperBound().isErroneous() || !t.getUpperBound().isCompound())
2768 return List.of(t.getUpperBound());
2769 else if ((erasure(t).tsym.flags() & INTERFACE) == 0)
2770 return interfaces(t).prepend(supertype(t));
2771 else
2772 // No superclass was given in bounds.
2773 // In this case, supertype is Object, erasure is first interface.
2774 return interfaces(t);
2775 }
2776 // </editor-fold>
2777
2778 // <editor-fold defaultstate="collapsed" desc="classBound">
2779 /**
2780 * If the given type is a (possibly selected) type variable,
2781 * return the bounding class of this type, otherwise return the
2782 * type itself.
2783 */
2784 public Type classBound(Type t) {
2785 return classBound.visit(t);
2786 }
2787 // where
2788 private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() {
2789
2790 public Type visitType(Type t, Void ignored) {
2791 return t;
2792 }
2793
2794 @Override
2795 public Type visitClassType(ClassType t, Void ignored) {
2796 Type outer1 = classBound(t.getEnclosingType());
2797 if (outer1 != t.getEnclosingType())
2798 return new ClassType(outer1, t.getTypeArguments(), t.tsym,
2799 t.getMetadata());
2800 else
2801 return t;
2802 }
2803
2804 @Override
2805 public Type visitTypeVar(TypeVar t, Void ignored) {
2806 return classBound(supertype(t));
2807 }
2808
2809 @Override
2810 public Type visitErrorType(ErrorType t, Void ignored) {
2811 return t;
2812 }
2813 };
2814 // </editor-fold>
2815
2816 // <editor-fold defaultstate="collapsed" desc="sub signature / override equivalence">
2817 /**
2818 * Returns true iff the first signature is a <em>sub
2819 * signature</em> of the other. This is <b>not</b> an equivalence
2820 * relation.
2821 *
2822 * @jls 8.4.2 Method Signature
2823 * @see #overrideEquivalent(Type t, Type s)
2824 * @param t first signature (possibly raw).
2825 * @param s second signature (could be subjected to erasure).
2826 * @return true if t is a sub signature of s.
2827 */
2828 public boolean isSubSignature(Type t, Type s) {
2829 return isSubSignature(t, s, true);
2830 }
2831
2832 public boolean isSubSignature(Type t, Type s, boolean strict) {
2833 return hasSameArgs(t, s, strict) || hasSameArgs(t, erasure(s), strict);
2834 }
2835
2836 /**
2837 * Returns true iff these signatures are related by <em>override
2838 * equivalence</em>. This is the natural extension of
2839 * isSubSignature to an equivalence relation.
2840 *
2841 * @jls 8.4.2 Method Signature
2842 * @see #isSubSignature(Type t, Type s)
2843 * @param t a signature (possible raw, could be subjected to
2844 * erasure).
2845 * @param s a signature (possible raw, could be subjected to
2846 * erasure).
2847 * @return true if either argument is a sub signature of the other.
2848 */
2849 public boolean overrideEquivalent(Type t, Type s) {
2850 return hasSameArgs(t, s) ||
2851 hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s);
2852 }
2853
2854 public boolean overridesObjectMethod(TypeSymbol origin, Symbol msym) {
2855 for (Symbol sym : syms.objectType.tsym.members().getSymbolsByName(msym.name)) {
2856 if (msym.overrides(sym, origin, Types.this, true)) {
2857 return true;
2858 }
2859 }
2860 return false;
2861 }
2862
2863 /**
2864 * This enum defines the strategy for implementing most specific return type check
2865 * during the most specific and functional interface checks.
2866 */
2867 public enum MostSpecificReturnCheck {
2868 /**
2869 * Return r1 is more specific than r2 if {@code r1 <: r2}. Extra care required for (i) handling
2870 * method type variables (if either method is generic) and (ii) subtyping should be replaced
2871 * by type-equivalence for primitives. This is essentially an inlined version of
2872 * {@link Types#resultSubtype(Type, Type, Warner)}, where the assignability check has been
2873 * replaced with a strict subtyping check.
2874 */
2875 BASIC() {
2876 @Override
2877 public boolean test(Type mt1, Type mt2, Types types) {
2878 List<Type> tvars = mt1.getTypeArguments();
2879 List<Type> svars = mt2.getTypeArguments();
2880 Type t = mt1.getReturnType();
2881 Type s = types.subst(mt2.getReturnType(), svars, tvars);
2882 return types.isSameType(t, s) ||
2883 !t.isPrimitive() &&
2884 !s.isPrimitive() &&
2885 types.isSubtype(t, s);
2886 }
2887 },
2888 /**
2889 * Return r1 is more specific than r2 if r1 is return-type-substitutable for r2.
2890 */
2891 RTS() {
2892 @Override
2893 public boolean test(Type mt1, Type mt2, Types types) {
2894 return types.returnTypeSubstitutable(mt1, mt2);
2895 }
2896 };
2897
2898 public abstract boolean test(Type mt1, Type mt2, Types types);
2899 }
2900
2901 /**
2902 * Merge multiple abstract methods. The preferred method is a method that is a subsignature
2903 * of all the other signatures and whose return type is more specific {@see MostSpecificReturnCheck}.
2904 * The resulting preferred method has a thrown clause that is the intersection of the merged
2905 * methods' clauses.
2906 */
2907 public Optional<Symbol> mergeAbstracts(List<Symbol> ambiguousInOrder, Type site, boolean sigCheck) {
2908 //first check for preconditions
2909 boolean shouldErase = false;
2910 List<Type> erasedParams = ambiguousInOrder.head.erasure(this).getParameterTypes();
2911 for (Symbol s : ambiguousInOrder) {
2912 if ((s.flags() & ABSTRACT) == 0 ||
2913 (sigCheck && !isSameTypes(erasedParams, s.erasure(this).getParameterTypes()))) {
2914 return Optional.empty();
2915 } else if (s.type.hasTag(FORALL)) {
2916 shouldErase = true;
2917 }
2918 }
2919 //then merge abstracts
2920 for (MostSpecificReturnCheck mostSpecificReturnCheck : MostSpecificReturnCheck.values()) {
2921 outer: for (Symbol s : ambiguousInOrder) {
2922 Type mt = memberType(site, s);
2923 List<Type> allThrown = mt.getThrownTypes();
2924 for (Symbol s2 : ambiguousInOrder) {
2925 if (s != s2) {
2926 Type mt2 = memberType(site, s2);
2927 if (!isSubSignature(mt, mt2) ||
2928 !mostSpecificReturnCheck.test(mt, mt2, this)) {
2929 //ambiguity cannot be resolved
2930 continue outer;
2931 } else {
2932 List<Type> thrownTypes2 = mt2.getThrownTypes();
2933 if (!mt.hasTag(FORALL) && shouldErase) {
2934 thrownTypes2 = erasure(thrownTypes2);
2935 } else if (mt.hasTag(FORALL)) {
2936 //subsignature implies that if most specific is generic, then all other
2937 //methods are too
2938 Assert.check(mt2.hasTag(FORALL));
2939 // if both are generic methods, adjust thrown types ahead of intersection computation
2940 thrownTypes2 = subst(thrownTypes2, mt2.getTypeArguments(), mt.getTypeArguments());
2941 }
2942 allThrown = chk.intersect(allThrown, thrownTypes2);
2943 }
2944 }
2945 }
2946 return (allThrown == mt.getThrownTypes()) ?
2947 Optional.of(s) :
2948 Optional.of(new MethodSymbol(
2949 s.flags(),
2950 s.name,
2951 createMethodTypeWithThrown(s.type, allThrown),
2952 s.owner) {
2953 @Override
2954 public Symbol baseSymbol() {
2955 return s;
2956 }
2957 });
2958 }
2959 }
2960 return Optional.empty();
2961 }
2962
2963 // <editor-fold defaultstate="collapsed" desc="Determining method implementation in given site">
2964 class ImplementationCache {
2965
2966 private WeakHashMap<MethodSymbol, SoftReference<Map<TypeSymbol, Entry>>> _map = new WeakHashMap<>();
2967
2968 class Entry {
2969 final MethodSymbol cachedImpl;
2970 final Filter<Symbol> implFilter;
2971 final boolean checkResult;
2972 final int prevMark;
2973
2974 public Entry(MethodSymbol cachedImpl,
2975 Filter<Symbol> scopeFilter,
2976 boolean checkResult,
2977 int prevMark) {
2978 this.cachedImpl = cachedImpl;
2979 this.implFilter = scopeFilter;
2980 this.checkResult = checkResult;
2981 this.prevMark = prevMark;
2982 }
2983
2984 boolean matches(Filter<Symbol> scopeFilter, boolean checkResult, int mark) {
2985 return this.implFilter == scopeFilter &&
2986 this.checkResult == checkResult &&
2987 this.prevMark == mark;
2988 }
2989 }
2990
2991 MethodSymbol get(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
2992 SoftReference<Map<TypeSymbol, Entry>> ref_cache = _map.get(ms);
2993 Map<TypeSymbol, Entry> cache = ref_cache != null ? ref_cache.get() : null;
2994 if (cache == null) {
2995 cache = new HashMap<>();
2996 _map.put(ms, new SoftReference<>(cache));
2997 }
2998 Entry e = cache.get(origin);
2999 CompoundScope members = membersClosure(origin.type, true);
3000 if (e == null ||
3001 !e.matches(implFilter, checkResult, members.getMark())) {
3002 MethodSymbol impl = implementationInternal(ms, origin, checkResult, implFilter);
3003 cache.put(origin, new Entry(impl, implFilter, checkResult, members.getMark()));
3004 return impl;
3005 }
3006 else {
3007 return e.cachedImpl;
3008 }
3009 }
3010
3011 private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
3012 for (Type t = origin.type; t.hasTag(CLASS) || t.hasTag(TYPEVAR); t = supertype(t)) {
3013 t = skipTypeVars(t, false);
3014 TypeSymbol c = t.tsym;
3015 Symbol bestSoFar = null;
3016 for (Symbol sym : c.members().getSymbolsByName(ms.name, implFilter)) {
3017 if (sym != null && sym.overrides(ms, origin, Types.this, checkResult)) {
3018 bestSoFar = sym;
3019 if ((sym.flags() & ABSTRACT) == 0) {
3020 //if concrete impl is found, exit immediately
3021 break;
3022 }
3023 }
3024 }
3025 if (bestSoFar != null) {
3026 //return either the (only) concrete implementation or the first abstract one
3027 return (MethodSymbol)bestSoFar;
3028 }
3029 }
3030 return null;
3031 }
3032 }
3033
3034 private ImplementationCache implCache = new ImplementationCache();
3035
3036 public MethodSymbol implementation(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
3037 return implCache.get(ms, origin, checkResult, implFilter);
3038 }
3039 // </editor-fold>
3040
3041 // <editor-fold defaultstate="collapsed" desc="compute transitive closure of all members in given site">
3042 class MembersClosureCache extends SimpleVisitor<Scope.CompoundScope, Void> {
3043
3044 private Map<TypeSymbol, CompoundScope> _map = new HashMap<>();
3045
3046 Set<TypeSymbol> seenTypes = new HashSet<>();
3047
3048 class MembersScope extends CompoundScope {
3049
3050 CompoundScope scope;
3051
3052 public MembersScope(CompoundScope scope) {
3053 super(scope.owner);
3054 this.scope = scope;
3055 }
3056
3057 Filter<Symbol> combine(Filter<Symbol> sf) {
3058 return s -> !s.owner.isInterface() && (sf == null || sf.accepts(s));
3059 }
3060
3061 @Override
3062 public Iterable<Symbol> getSymbols(Filter<Symbol> sf, LookupKind lookupKind) {
3063 return scope.getSymbols(combine(sf), lookupKind);
3064 }
3065
3066 @Override
3067 public Iterable<Symbol> getSymbolsByName(Name name, Filter<Symbol> sf, LookupKind lookupKind) {
3068 return scope.getSymbolsByName(name, combine(sf), lookupKind);
3069 }
3070
3071 @Override
3072 public int getMark() {
3073 return scope.getMark();
3074 }
3075 }
3076
3077 CompoundScope nilScope;
3078
3079 /** members closure visitor methods **/
3080
3081 public CompoundScope visitType(Type t, Void _unused) {
3082 if (nilScope == null) {
3083 nilScope = new CompoundScope(syms.noSymbol);
3084 }
3085 return nilScope;
3086 }
3087
3088 @Override
3089 public CompoundScope visitClassType(ClassType t, Void _unused) {
3090 if (!seenTypes.add(t.tsym)) {
3091 //this is possible when an interface is implemented in multiple
3092 //superclasses, or when a class hierarchy is circular - in such
3093 //cases we don't need to recurse (empty scope is returned)
3094 return new CompoundScope(t.tsym);
3095 }
3096 try {
3097 seenTypes.add(t.tsym);
3098 ClassSymbol csym = (ClassSymbol)t.tsym;
3099 CompoundScope membersClosure = _map.get(csym);
3100 if (membersClosure == null) {
3101 membersClosure = new CompoundScope(csym);
3102 for (Type i : interfaces(t)) {
3103 membersClosure.prependSubScope(visit(i, null));
3104 }
3105 membersClosure.prependSubScope(visit(supertype(t), null));
3106 membersClosure.prependSubScope(csym.members());
3107 _map.put(csym, membersClosure);
3108 }
3109 return membersClosure;
3110 }
3111 finally {
3112 seenTypes.remove(t.tsym);
3113 }
3114 }
3115
3116 @Override
3117 public CompoundScope visitTypeVar(TypeVar t, Void _unused) {
3118 return visit(t.getUpperBound(), null);
3119 }
3120 }
3121
3122 private MembersClosureCache membersCache = new MembersClosureCache();
3123
3124 public CompoundScope membersClosure(Type site, boolean skipInterface) {
3125 CompoundScope cs = membersCache.visit(site, null);
3126 Assert.checkNonNull(cs, () -> "type " + site);
3127 return skipInterface ? membersCache.new MembersScope(cs) : cs;
3128 }
3129 // </editor-fold>
3130
3131
3132 /** Return first abstract member of class `sym'.
3133 */
3134 public MethodSymbol firstUnimplementedAbstract(ClassSymbol sym) {
3135 try {
3136 return firstUnimplementedAbstractImpl(sym, sym);
3137 } catch (CompletionFailure ex) {
3138 chk.completionError(enter.getEnv(sym).tree.pos(), ex);
3139 return null;
3140 }
3141 }
3142 //where:
3143 private MethodSymbol firstUnimplementedAbstractImpl(ClassSymbol impl, ClassSymbol c) {
3144 MethodSymbol undef = null;
3145 // Do not bother to search in classes that are not abstract,
3146 // since they cannot have abstract members.
3147 if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) {
3148 Scope s = c.members();
3149 for (Symbol sym : s.getSymbols(NON_RECURSIVE)) {
3150 if (sym.kind == MTH &&
3151 (sym.flags() & (ABSTRACT|DEFAULT|PRIVATE)) == ABSTRACT) {
3152 MethodSymbol absmeth = (MethodSymbol)sym;
3153 MethodSymbol implmeth = absmeth.implementation(impl, this, true);
3154 if (implmeth == null || implmeth == absmeth) {
3155 //look for default implementations
3156 if (allowDefaultMethods) {
3157 MethodSymbol prov = interfaceCandidates(impl.type, absmeth).head;
3158 if (prov != null && prov.overrides(absmeth, impl, this, true)) {
3159 implmeth = prov;
3160 }
3161 }
3162 }
3163 if (implmeth == null || implmeth == absmeth) {
3164 undef = absmeth;
3165 break;
3166 }
3167 }
3168 }
3169 if (undef == null) {
3170 Type st = supertype(c.type);
3171 if (st.hasTag(CLASS))
3172 undef = firstUnimplementedAbstractImpl(impl, (ClassSymbol)st.tsym);
3173 }
3174 for (List<Type> l = interfaces(c.type);
3175 undef == null && l.nonEmpty();
3176 l = l.tail) {
3177 undef = firstUnimplementedAbstractImpl(impl, (ClassSymbol)l.head.tsym);
3178 }
3179 }
3180 return undef;
3181 }
3182
3183 public class CandidatesCache {
3184 public Map<Entry, List<MethodSymbol>> cache = new WeakHashMap<>();
3185
3186 class Entry {
3187 Type site;
3188 MethodSymbol msym;
3189
3190 Entry(Type site, MethodSymbol msym) {
3191 this.site = site;
3192 this.msym = msym;
3193 }
3194
3195 @Override
3196 public boolean equals(Object obj) {
3197 if (obj instanceof Entry) {
3198 Entry e = (Entry)obj;
3199 return e.msym == msym && isSameType(site, e.site);
3200 } else {
3201 return false;
3202 }
3203 }
3204
3205 @Override
3206 public int hashCode() {
3207 return Types.this.hashCode(site) & ~msym.hashCode();
3208 }
3209 }
3210
3211 public List<MethodSymbol> get(Entry e) {
3212 return cache.get(e);
3213 }
3214
3215 public void put(Entry e, List<MethodSymbol> msymbols) {
3216 cache.put(e, msymbols);
3217 }
3218 }
3219
3220 public CandidatesCache candidatesCache = new CandidatesCache();
3221
3222 //where
3223 public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms) {
3224 CandidatesCache.Entry e = candidatesCache.new Entry(site, ms);
3225 List<MethodSymbol> candidates = candidatesCache.get(e);
3226 if (candidates == null) {
3227 Filter<Symbol> filter = new MethodFilter(ms, site);
3228 List<MethodSymbol> candidates2 = List.nil();
3229 for (Symbol s : membersClosure(site, false).getSymbols(filter)) {
3230 if (!site.tsym.isInterface() && !s.owner.isInterface()) {
3231 return List.of((MethodSymbol)s);
3232 } else if (!candidates2.contains(s)) {
3233 candidates2 = candidates2.prepend((MethodSymbol)s);
3234 }
3235 }
3236 candidates = prune(candidates2);
3237 candidatesCache.put(e, candidates);
3238 }
3239 return candidates;
3240 }
3241
3242 public List<MethodSymbol> prune(List<MethodSymbol> methods) {
3243 ListBuffer<MethodSymbol> methodsMin = new ListBuffer<>();
3244 for (MethodSymbol m1 : methods) {
3245 boolean isMin_m1 = true;
3246 for (MethodSymbol m2 : methods) {
3247 if (m1 == m2) continue;
3248 if (m2.owner != m1.owner &&
3249 asSuper(m2.owner.type, m1.owner) != null) {
3250 isMin_m1 = false;
3251 break;
3252 }
3253 }
3254 if (isMin_m1)
3255 methodsMin.append(m1);
3256 }
3257 return methodsMin.toList();
3258 }
3259 // where
3260 private class MethodFilter implements Filter<Symbol> {
3261
3262 Symbol msym;
3263 Type site;
3264
3265 MethodFilter(Symbol msym, Type site) {
3266 this.msym = msym;
3267 this.site = site;
3268 }
3269
3270 public boolean accepts(Symbol s) {
3271 return s.kind == MTH &&
3272 s.name == msym.name &&
3273 (s.flags() & SYNTHETIC) == 0 &&
3274 s.isInheritedIn(site.tsym, Types.this) &&
3275 overrideEquivalent(memberType(site, s), memberType(site, msym));
3276 }
3277 }
3278 // </editor-fold>
3279
3280 /**
3281 * Does t have the same arguments as s? It is assumed that both
3282 * types are (possibly polymorphic) method types. Monomorphic
3283 * method types "have the same arguments", if their argument lists
3284 * are equal. Polymorphic method types "have the same arguments",
3285 * if they have the same arguments after renaming all type
3286 * variables of one to corresponding type variables in the other,
3287 * where correspondence is by position in the type parameter list.
3288 */
3289 public boolean hasSameArgs(Type t, Type s) {
3290 return hasSameArgs(t, s, true);
3291 }
3292
3293 public boolean hasSameArgs(Type t, Type s, boolean strict) {
3294 return hasSameArgs(t, s, strict ? hasSameArgs_strict : hasSameArgs_nonstrict);
3295 }
3296
3297 private boolean hasSameArgs(Type t, Type s, TypeRelation hasSameArgs) {
3298 return hasSameArgs.visit(t, s);
3299 }
3300 // where
3301 private class HasSameArgs extends TypeRelation {
3302
3303 boolean strict;
3304
3305 public HasSameArgs(boolean strict) {
3306 this.strict = strict;
3307 }
3308
3309 public Boolean visitType(Type t, Type s) {
3310 throw new AssertionError();
3311 }
3312
3313 @Override
3314 public Boolean visitMethodType(MethodType t, Type s) {
3315 return s.hasTag(METHOD)
3316 && containsTypeEquivalent(t.argtypes, s.getParameterTypes());
3317 }
3318
3319 @Override
3320 public Boolean visitForAll(ForAll t, Type s) {
3321 if (!s.hasTag(FORALL))
3322 return strict ? false : visitMethodType(t.asMethodType(), s);
3323
3324 ForAll forAll = (ForAll)s;
3325 return hasSameBounds(t, forAll)
3326 && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
3327 }
3328
3329 @Override
3330 public Boolean visitErrorType(ErrorType t, Type s) {
3331 return false;
3332 }
3333 }
3334
3335 TypeRelation hasSameArgs_strict = new HasSameArgs(true);
3336 TypeRelation hasSameArgs_nonstrict = new HasSameArgs(false);
3337
3338 // </editor-fold>
3339
3340 // <editor-fold defaultstate="collapsed" desc="subst">
3341 public List<Type> subst(List<Type> ts,
3342 List<Type> from,
3343 List<Type> to) {
3344 return ts.map(new Subst(from, to));
3345 }
3346
3347 /**
3348 * Substitute all occurrences of a type in `from' with the
3349 * corresponding type in `to' in 't'. Match lists `from' and `to'
3350 * from the right: If lists have different length, discard leading
3351 * elements of the longer list.
3352 */
3353 public Type subst(Type t, List<Type> from, List<Type> to) {
3354 return t.map(new Subst(from, to));
3355 }
3356
3357 private class Subst extends StructuralTypeMapping<Void> {
3358 List<Type> from;
3359 List<Type> to;
3360
3361 public Subst(List<Type> from, List<Type> to) {
3362 int fromLength = from.length();
3363 int toLength = to.length();
3364 while (fromLength > toLength) {
3365 fromLength--;
3366 from = from.tail;
3367 }
3368 while (fromLength < toLength) {
3369 toLength--;
3370 to = to.tail;
3371 }
3372 this.from = from;
3373 this.to = to;
3374 }
3375
3376 @Override
3377 public Type visitTypeVar(TypeVar t, Void ignored) {
3378 for (List<Type> from = this.from, to = this.to;
3379 from.nonEmpty();
3380 from = from.tail, to = to.tail) {
3381 if (t.equalsIgnoreMetadata(from.head)) {
3382 return to.head.withTypeVar(t);
3383 }
3384 }
3385 return t;
3386 }
3387
3388 @Override
3389 public Type visitClassType(ClassType t, Void ignored) {
3390 if (!t.isCompound()) {
3391 return super.visitClassType(t, ignored);
3392 } else {
3393 Type st = visit(supertype(t));
3394 List<Type> is = visit(interfaces(t), ignored);
3395 if (st == supertype(t) && is == interfaces(t))
3396 return t;
3397 else
3398 return makeIntersectionType(is.prepend(st));
3399 }
3400 }
3401
3402 @Override
3403 public Type visitWildcardType(WildcardType t, Void ignored) {
3404 WildcardType t2 = (WildcardType)super.visitWildcardType(t, ignored);
3405 if (t2 != t && t.isExtendsBound() && t2.type.isExtendsBound()) {
3406 t2.type = wildUpperBound(t2.type);
3407 }
3408 return t2;
3409 }
3410
3411 @Override
3412 public Type visitForAll(ForAll t, Void ignored) {
3413 if (Type.containsAny(to, t.tvars)) {
3414 //perform alpha-renaming of free-variables in 't'
3415 //if 'to' types contain variables that are free in 't'
3416 List<Type> freevars = newInstances(t.tvars);
3417 t = new ForAll(freevars,
3418 Types.this.subst(t.qtype, t.tvars, freevars));
3419 }
3420 List<Type> tvars1 = substBounds(t.tvars, from, to);
3421 Type qtype1 = visit(t.qtype);
3422 if (tvars1 == t.tvars && qtype1 == t.qtype) {
3423 return t;
3424 } else if (tvars1 == t.tvars) {
3425 return new ForAll(tvars1, qtype1) {
3426 @Override
3427 public boolean needsStripping() {
3428 return true;
3429 }
3430 };
3431 } else {
3432 return new ForAll(tvars1, Types.this.subst(qtype1, t.tvars, tvars1)) {
3433 @Override
3434 public boolean needsStripping() {
3435 return true;
3436 }
3437 };
3438 }
3439 }
3440 }
3441
3442 public List<Type> substBounds(List<Type> tvars,
3443 List<Type> from,
3444 List<Type> to) {
3445 if (tvars.isEmpty())
3446 return tvars;
3447 ListBuffer<Type> newBoundsBuf = new ListBuffer<>();
3448 boolean changed = false;
3449 // calculate new bounds
3450 for (Type t : tvars) {
3451 TypeVar tv = (TypeVar) t;
3452 Type bound = subst(tv.getUpperBound(), from, to);
3453 if (bound != tv.getUpperBound())
3454 changed = true;
3455 newBoundsBuf.append(bound);
3456 }
3457 if (!changed)
3458 return tvars;
3459 ListBuffer<Type> newTvars = new ListBuffer<>();
3460 // create new type variables without bounds
3461 for (Type t : tvars) {
3462 newTvars.append(new TypeVar(t.tsym, null, syms.botType,
3463 t.getMetadata()));
3464 }
3465 // the new bounds should use the new type variables in place
3466 // of the old
3467 List<Type> newBounds = newBoundsBuf.toList();
3468 from = tvars;
3469 to = newTvars.toList();
3470 for (; !newBounds.isEmpty(); newBounds = newBounds.tail) {
3471 newBounds.head = subst(newBounds.head, from, to);
3472 }
3473 newBounds = newBoundsBuf.toList();
3474 // set the bounds of new type variables to the new bounds
3475 for (Type t : newTvars.toList()) {
3476 TypeVar tv = (TypeVar) t;
3477 tv.setUpperBound( newBounds.head );
3478 newBounds = newBounds.tail;
3479 }
3480 return newTvars.toList();
3481 }
3482
3483 public TypeVar substBound(TypeVar t, List<Type> from, List<Type> to) {
3484 Type bound1 = subst(t.getUpperBound(), from, to);
3485 if (bound1 == t.getUpperBound())
3486 return t;
3487 else {
3488 // create new type variable without bounds
3489 TypeVar tv = new TypeVar(t.tsym, null, syms.botType,
3490 t.getMetadata());
3491 // the new bound should use the new type variable in place
3492 // of the old
3493 tv.setUpperBound( subst(bound1, List.of(t), List.of(tv)) );
3494 return tv;
3495 }
3496 }
3497 // </editor-fold>
3498
3499 // <editor-fold defaultstate="collapsed" desc="hasSameBounds">
3500 /**
3501 * Does t have the same bounds for quantified variables as s?
3502 */
3503 public boolean hasSameBounds(ForAll t, ForAll s) {
3504 List<Type> l1 = t.tvars;
3505 List<Type> l2 = s.tvars;
3506 while (l1.nonEmpty() && l2.nonEmpty() &&
3507 isSameType(l1.head.getUpperBound(),
3508 subst(l2.head.getUpperBound(),
3509 s.tvars,
3510 t.tvars))) {
3511 l1 = l1.tail;
3512 l2 = l2.tail;
3513 }
3514 return l1.isEmpty() && l2.isEmpty();
3515 }
3516 // </editor-fold>
3517
3518 // <editor-fold defaultstate="collapsed" desc="newInstances">
3519 /** Create new vector of type variables from list of variables
3520 * changing all recursive bounds from old to new list.
3521 */
3522 public List<Type> newInstances(List<Type> tvars) {
3523 List<Type> tvars1 = tvars.map(newInstanceFun);
3524 for (List<Type> l = tvars1; l.nonEmpty(); l = l.tail) {
3525 TypeVar tv = (TypeVar) l.head;
3526 tv.setUpperBound( subst(tv.getUpperBound(), tvars, tvars1) );
3527 }
3528 return tvars1;
3529 }
3530 private static final TypeMapping<Void> newInstanceFun = new TypeMapping<Void>() {
3531 @Override
3532 public TypeVar visitTypeVar(TypeVar t, Void _unused) {
3533 return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound(), t.getMetadata());
3534 }
3535 };
3536 // </editor-fold>
3537
3538 public Type createMethodTypeWithParameters(Type original, List<Type> newParams) {
3539 return original.accept(methodWithParameters, newParams);
3540 }
3541 // where
3542 private final MapVisitor<List<Type>> methodWithParameters = new MapVisitor<List<Type>>() {
3543 public Type visitType(Type t, List<Type> newParams) {
3544 throw new IllegalArgumentException("Not a method type: " + t);
3545 }
3546 public Type visitMethodType(MethodType t, List<Type> newParams) {
3547 return new MethodType(newParams, t.restype, t.thrown, t.tsym);
3548 }
3549 public Type visitForAll(ForAll t, List<Type> newParams) {
3550 return new ForAll(t.tvars, t.qtype.accept(this, newParams));
3551 }
3552 };
3553
3554 public Type createMethodTypeWithThrown(Type original, List<Type> newThrown) {
3555 return original.accept(methodWithThrown, newThrown);
3556 }
3557 // where
3558 private final MapVisitor<List<Type>> methodWithThrown = new MapVisitor<List<Type>>() {
3559 public Type visitType(Type t, List<Type> newThrown) {
3560 throw new IllegalArgumentException("Not a method type: " + t);
3561 }
3562 public Type visitMethodType(MethodType t, List<Type> newThrown) {
3563 return new MethodType(t.argtypes, t.restype, newThrown, t.tsym);
3564 }
3565 public Type visitForAll(ForAll t, List<Type> newThrown) {
3566 return new ForAll(t.tvars, t.qtype.accept(this, newThrown));
3567 }
3568 };
3569
3570 public Type createMethodTypeWithReturn(Type original, Type newReturn) {
3571 return original.accept(methodWithReturn, newReturn);
3572 }
3573 // where
3574 private final MapVisitor<Type> methodWithReturn = new MapVisitor<Type>() {
3575 public Type visitType(Type t, Type newReturn) {
3576 throw new IllegalArgumentException("Not a method type: " + t);
3577 }
3578 public Type visitMethodType(MethodType t, Type newReturn) {
3579 return new MethodType(t.argtypes, newReturn, t.thrown, t.tsym) {
3580 @Override
3581 public Type baseType() {
3582 return t;
3583 }
3584 };
3585 }
3586 public Type visitForAll(ForAll t, Type newReturn) {
3587 return new ForAll(t.tvars, t.qtype.accept(this, newReturn)) {
3588 @Override
3589 public Type baseType() {
3590 return t;
3591 }
3592 };
3593 }
3594 };
3595
3596 // <editor-fold defaultstate="collapsed" desc="createErrorType">
3597 public Type createErrorType(Type originalType) {
3598 return new ErrorType(originalType, syms.errSymbol);
3599 }
3600
3601 public Type createErrorType(ClassSymbol c, Type originalType) {
3602 return new ErrorType(c, originalType);
3603 }
3604
3605 public Type createErrorType(Name name, TypeSymbol container, Type originalType) {
3606 return new ErrorType(name, container, originalType);
3607 }
3608 // </editor-fold>
3609
3610 // <editor-fold defaultstate="collapsed" desc="rank">
3611 /**
3612 * The rank of a class is the length of the longest path between
3613 * the class and java.lang.Object in the class inheritance
3614 * graph. Undefined for all but reference types.
3615 */
3616 public int rank(Type t) {
3617 switch(t.getTag()) {
3618 case CLASS: {
3619 ClassType cls = (ClassType)t;
3620 if (cls.rank_field < 0) {
3621 Name fullname = cls.tsym.getQualifiedName();
3622 if (fullname == names.java_lang_Object)
3623 cls.rank_field = 0;
3624 else {
3625 int r = rank(supertype(cls));
3626 for (List<Type> l = interfaces(cls);
3627 l.nonEmpty();
3628 l = l.tail) {
3629 if (rank(l.head) > r)
3630 r = rank(l.head);
3631 }
3632 cls.rank_field = r + 1;
3633 }
3634 }
3635 return cls.rank_field;
3636 }
3637 case TYPEVAR: {
3638 TypeVar tvar = (TypeVar)t;
3639 if (tvar.rank_field < 0) {
3640 int r = rank(supertype(tvar));
3641 for (List<Type> l = interfaces(tvar);
3642 l.nonEmpty();
3643 l = l.tail) {
3644 if (rank(l.head) > r) r = rank(l.head);
3645 }
3646 tvar.rank_field = r + 1;
3647 }
3648 return tvar.rank_field;
3649 }
3650 case ERROR:
3651 case NONE:
3652 return 0;
3653 default:
3654 throw new AssertionError();
3655 }
3656 }
3657 // </editor-fold>
3658
3659 /**
3660 * Helper method for generating a string representation of a given type
3661 * accordingly to a given locale
3662 */
3663 public String toString(Type t, Locale locale) {
3664 return Printer.createStandardPrinter(messages).visit(t, locale);
3665 }
3666
3667 /**
3668 * Helper method for generating a string representation of a given type
3669 * accordingly to a given locale
3670 */
3671 public String toString(Symbol t, Locale locale) {
3672 return Printer.createStandardPrinter(messages).visit(t, locale);
3673 }
3674
3675 // <editor-fold defaultstate="collapsed" desc="toString">
3676 /**
3677 * This toString is slightly more descriptive than the one on Type.
3678 *
3679 * @deprecated Types.toString(Type t, Locale l) provides better support
3680 * for localization
3681 */
3682 @Deprecated
3683 public String toString(Type t) {
3684 if (t.hasTag(FORALL)) {
3685 ForAll forAll = (ForAll)t;
3686 return typaramsString(forAll.tvars) + forAll.qtype;
3687 }
3688 return "" + t;
3689 }
3690 // where
3691 private String typaramsString(List<Type> tvars) {
3692 StringBuilder s = new StringBuilder();
3693 s.append('<');
3694 boolean first = true;
3695 for (Type t : tvars) {
3696 if (!first) s.append(", ");
3697 first = false;
3698 appendTyparamString(((TypeVar)t), s);
3699 }
3700 s.append('>');
3701 return s.toString();
3702 }
3703 private void appendTyparamString(TypeVar t, StringBuilder buf) {
3704 buf.append(t);
3705 if (t.getUpperBound() == null ||
3706 t.getUpperBound().tsym.getQualifiedName() == names.java_lang_Object)
3707 return;
3708 buf.append(" extends "); // Java syntax; no need for i18n
3709 Type bound = t.getUpperBound();
3710 if (!bound.isCompound()) {
3711 buf.append(bound);
3712 } else if ((erasure(t).tsym.flags() & INTERFACE) == 0) {
3713 buf.append(supertype(t));
3714 for (Type intf : interfaces(t)) {
3715 buf.append('&');
3716 buf.append(intf);
3717 }
3718 } else {
3719 // No superclass was given in bounds.
3720 // In this case, supertype is Object, erasure is first interface.
3721 boolean first = true;
3722 for (Type intf : interfaces(t)) {
3723 if (!first) buf.append('&');
3724 first = false;
3725 buf.append(intf);
3726 }
3727 }
3728 }
3729 // </editor-fold>
3730
3731 // <editor-fold defaultstate="collapsed" desc="Determining least upper bounds of types">
3732 /**
3733 * A cache for closures.
3734 *
3735 * <p>A closure is a list of all the supertypes and interfaces of
3736 * a class or interface type, ordered by ClassSymbol.precedes
3737 * (that is, subclasses come first, arbitrary but fixed
3738 * otherwise).
3739 */
3740 private Map<Type,List<Type>> closureCache = new HashMap<>();
3741
3742 /**
3743 * Returns the closure of a class or interface type.
3744 */
3745 public List<Type> closure(Type t) {
3746 List<Type> cl = closureCache.get(t);
3747 if (cl == null) {
3748 Type st = supertype(t);
3749 if (!t.isCompound()) {
3750 if (st.hasTag(CLASS)) {
3751 cl = insert(closure(st), t);
3752 } else if (st.hasTag(TYPEVAR)) {
3753 cl = closure(st).prepend(t);
3754 } else {
3755 cl = List.of(t);
3756 }
3757 } else {
3758 cl = closure(supertype(t));
3759 }
3760 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail)
3761 cl = union(cl, closure(l.head));
3762 closureCache.put(t, cl);
3763 }
3764 return cl;
3765 }
3766
3767 /**
3768 * Collect types into a new closure (using a @code{ClosureHolder})
3769 */
3770 public Collector<Type, ClosureHolder, List<Type>> closureCollector(boolean minClosure, BiPredicate<Type, Type> shouldSkip) {
3771 return Collector.of(() -> new ClosureHolder(minClosure, shouldSkip),
3772 ClosureHolder::add,
3773 ClosureHolder::merge,
3774 ClosureHolder::closure);
3775 }
3776 //where
3777 class ClosureHolder {
3778 List<Type> closure;
3779 final boolean minClosure;
3780 final BiPredicate<Type, Type> shouldSkip;
3781
3782 ClosureHolder(boolean minClosure, BiPredicate<Type, Type> shouldSkip) {
3783 this.closure = List.nil();
3784 this.minClosure = minClosure;
3785 this.shouldSkip = shouldSkip;
3786 }
3787
3788 void add(Type type) {
3789 closure = insert(closure, type, shouldSkip);
3790 }
3791
3792 ClosureHolder merge(ClosureHolder other) {
3793 closure = union(closure, other.closure, shouldSkip);
3794 return this;
3795 }
3796
3797 List<Type> closure() {
3798 return minClosure ? closureMin(closure) : closure;
3799 }
3800 }
3801
3802 BiPredicate<Type, Type> basicClosureSkip = (t1, t2) -> t1.tsym == t2.tsym;
3803
3804 /**
3805 * Insert a type in a closure
3806 */
3807 public List<Type> insert(List<Type> cl, Type t, BiPredicate<Type, Type> shouldSkip) {
3808 if (cl.isEmpty()) {
3809 return cl.prepend(t);
3810 } else if (shouldSkip.test(t, cl.head)) {
3811 return cl;
3812 } else if (t.tsym.precedes(cl.head.tsym, this)) {
3813 return cl.prepend(t);
3814 } else {
3815 // t comes after head, or the two are unrelated
3816 return insert(cl.tail, t, shouldSkip).prepend(cl.head);
3817 }
3818 }
3819
3820 public List<Type> insert(List<Type> cl, Type t) {
3821 return insert(cl, t, basicClosureSkip);
3822 }
3823
3824 /**
3825 * Form the union of two closures
3826 */
3827 public List<Type> union(List<Type> cl1, List<Type> cl2, BiPredicate<Type, Type> shouldSkip) {
3828 if (cl1.isEmpty()) {
3829 return cl2;
3830 } else if (cl2.isEmpty()) {
3831 return cl1;
3832 } else if (shouldSkip.test(cl1.head, cl2.head)) {
3833 return union(cl1.tail, cl2.tail, shouldSkip).prepend(cl1.head);
3834 } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) {
3835 return union(cl1, cl2.tail, shouldSkip).prepend(cl2.head);
3836 } else {
3837 return union(cl1.tail, cl2, shouldSkip).prepend(cl1.head);
3838 }
3839 }
3840
3841 public List<Type> union(List<Type> cl1, List<Type> cl2) {
3842 return union(cl1, cl2, basicClosureSkip);
3843 }
3844
3845 /**
3846 * Intersect two closures
3847 */
3848 public List<Type> intersect(List<Type> cl1, List<Type> cl2) {
3849 if (cl1 == cl2)
3850 return cl1;
3851 if (cl1.isEmpty() || cl2.isEmpty())
3852 return List.nil();
3853 if (cl1.head.tsym.precedes(cl2.head.tsym, this))
3854 return intersect(cl1.tail, cl2);
3855 if (cl2.head.tsym.precedes(cl1.head.tsym, this))
3856 return intersect(cl1, cl2.tail);
3857 if (isSameType(cl1.head, cl2.head))
3858 return intersect(cl1.tail, cl2.tail).prepend(cl1.head);
3859 if (cl1.head.tsym == cl2.head.tsym &&
3860 cl1.head.hasTag(CLASS) && cl2.head.hasTag(CLASS)) {
3861 if (cl1.head.isParameterized() && cl2.head.isParameterized()) {
3862 Type merge = merge(cl1.head,cl2.head);
3863 return intersect(cl1.tail, cl2.tail).prepend(merge);
3864 }
3865 if (cl1.head.isRaw() || cl2.head.isRaw())
3866 return intersect(cl1.tail, cl2.tail).prepend(erasure(cl1.head));
3867 }
3868 return intersect(cl1.tail, cl2.tail);
3869 }
3870 // where
3871 class TypePair {
3872 final Type t1;
3873 final Type t2;;
3874
3875 TypePair(Type t1, Type t2) {
3876 this.t1 = t1;
3877 this.t2 = t2;
3878 }
3879 @Override
3880 public int hashCode() {
3881 return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2);
3882 }
3883 @Override
3884 public boolean equals(Object obj) {
3885 if (!(obj instanceof TypePair))
3886 return false;
3887 TypePair typePair = (TypePair)obj;
3888 return isSameType(t1, typePair.t1)
3889 && isSameType(t2, typePair.t2);
3890 }
3891 }
3892 Set<TypePair> mergeCache = new HashSet<>();
3893 private Type merge(Type c1, Type c2) {
3894 ClassType class1 = (ClassType) c1;
3895 List<Type> act1 = class1.getTypeArguments();
3896 ClassType class2 = (ClassType) c2;
3897 List<Type> act2 = class2.getTypeArguments();
3898 ListBuffer<Type> merged = new ListBuffer<>();
3899 List<Type> typarams = class1.tsym.type.getTypeArguments();
3900
3901 while (act1.nonEmpty() && act2.nonEmpty() && typarams.nonEmpty()) {
3902 if (containsType(act1.head, act2.head)) {
3903 merged.append(act1.head);
3904 } else if (containsType(act2.head, act1.head)) {
3905 merged.append(act2.head);
3906 } else {
3907 TypePair pair = new TypePair(c1, c2);
3908 Type m;
3909 if (mergeCache.add(pair)) {
3910 m = new WildcardType(lub(wildUpperBound(act1.head),
3911 wildUpperBound(act2.head)),
3912 BoundKind.EXTENDS,
3913 syms.boundClass);
3914 mergeCache.remove(pair);
3915 } else {
3916 m = new WildcardType(syms.objectType,
3917 BoundKind.UNBOUND,
3918 syms.boundClass);
3919 }
3920 merged.append(m.withTypeVar(typarams.head));
3921 }
3922 act1 = act1.tail;
3923 act2 = act2.tail;
3924 typarams = typarams.tail;
3925 }
3926 Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
3927 // There is no spec detailing how type annotations are to
3928 // be inherited. So set it to noAnnotations for now
3929 return new ClassType(class1.getEnclosingType(), merged.toList(),
3930 class1.tsym);
3931 }
3932
3933 /**
3934 * Return the minimum type of a closure, a compound type if no
3935 * unique minimum exists.
3936 */
3937 private Type compoundMin(List<Type> cl) {
3938 if (cl.isEmpty()) return syms.objectType;
3939 List<Type> compound = closureMin(cl);
3940 if (compound.isEmpty())
3941 return null;
3942 else if (compound.tail.isEmpty())
3943 return compound.head;
3944 else
3945 return makeIntersectionType(compound);
3946 }
3947
3948 /**
3949 * Return the minimum types of a closure, suitable for computing
3950 * compoundMin or glb.
3951 */
3952 private List<Type> closureMin(List<Type> cl) {
3953 ListBuffer<Type> classes = new ListBuffer<>();
3954 ListBuffer<Type> interfaces = new ListBuffer<>();
3955 Set<Type> toSkip = new HashSet<>();
3956 while (!cl.isEmpty()) {
3957 Type current = cl.head;
3958 boolean keep = !toSkip.contains(current);
3959 if (keep && current.hasTag(TYPEVAR)) {
3960 // skip lower-bounded variables with a subtype in cl.tail
3961 for (Type t : cl.tail) {
3962 if (isSubtypeNoCapture(t, current)) {
3963 keep = false;
3964 break;
3965 }
3966 }
3967 }
3968 if (keep) {
3969 if (current.isInterface())
3970 interfaces.append(current);
3971 else
3972 classes.append(current);
3973 for (Type t : cl.tail) {
3974 // skip supertypes of 'current' in cl.tail
3975 if (isSubtypeNoCapture(current, t))
3976 toSkip.add(t);
3977 }
3978 }
3979 cl = cl.tail;
3980 }
3981 return classes.appendList(interfaces).toList();
3982 }
3983
3984 /**
3985 * Return the least upper bound of list of types. if the lub does
3986 * not exist return null.
3987 */
3988 public Type lub(List<Type> ts) {
3989 return lub(ts.toArray(new Type[ts.length()]));
3990 }
3991
3992 /**
3993 * Return the least upper bound (lub) of set of types. If the lub
3994 * does not exist return the type of null (bottom).
3995 */
3996 public Type lub(Type... ts) {
3997 final int UNKNOWN_BOUND = 0;
3998 final int ARRAY_BOUND = 1;
3999 final int CLASS_BOUND = 2;
4000
4001 int[] kinds = new int[ts.length];
4002
4003 int boundkind = UNKNOWN_BOUND;
4004 for (int i = 0 ; i < ts.length ; i++) {
4005 Type t = ts[i];
4006 switch (t.getTag()) {
4007 case CLASS:
4008 boundkind |= kinds[i] = CLASS_BOUND;
4009 break;
4010 case ARRAY:
4011 boundkind |= kinds[i] = ARRAY_BOUND;
4012 break;
4013 case TYPEVAR:
4014 do {
4015 t = t.getUpperBound();
4016 } while (t.hasTag(TYPEVAR));
4017 if (t.hasTag(ARRAY)) {
4018 boundkind |= kinds[i] = ARRAY_BOUND;
4019 } else {
4020 boundkind |= kinds[i] = CLASS_BOUND;
4021 }
4022 break;
4023 default:
4024 kinds[i] = UNKNOWN_BOUND;
4025 if (t.isPrimitive())
4026 return syms.errType;
4027 }
4028 }
4029 switch (boundkind) {
4030 case 0:
4031 return syms.botType;
4032
4033 case ARRAY_BOUND:
4034 // calculate lub(A[], B[])
4035 Type[] elements = new Type[ts.length];
4036 for (int i = 0 ; i < ts.length ; i++) {
4037 Type elem = elements[i] = elemTypeFun.apply(ts[i]);
4038 if (elem.isPrimitive()) {
4039 // if a primitive type is found, then return
4040 // arraySuperType unless all the types are the
4041 // same
4042 Type first = ts[0];
4043 for (int j = 1 ; j < ts.length ; j++) {
4044 if (!isSameType(first, ts[j])) {
4045 // lub(int[], B[]) is Cloneable & Serializable
4046 return arraySuperType();
4047 }
4048 }
4049 // all the array types are the same, return one
4050 // lub(int[], int[]) is int[]
4051 return first;
4052 }
4053 }
4054 // lub(A[], B[]) is lub(A, B)[]
4055 return new ArrayType(lub(elements), syms.arrayClass);
4056
4057 case CLASS_BOUND:
4058 // calculate lub(A, B)
4059 int startIdx = 0;
4060 for (int i = 0; i < ts.length ; i++) {
4061 Type t = ts[i];
4062 if (t.hasTag(CLASS) || t.hasTag(TYPEVAR)) {
4063 break;
4064 } else {
4065 startIdx++;
4066 }
4067 }
4068 Assert.check(startIdx < ts.length);
4069 //step 1 - compute erased candidate set (EC)
4070 List<Type> cl = erasedSupertypes(ts[startIdx]);
4071 for (int i = startIdx + 1 ; i < ts.length ; i++) {
4072 Type t = ts[i];
4073 if (t.hasTag(CLASS) || t.hasTag(TYPEVAR))
4074 cl = intersect(cl, erasedSupertypes(t));
4075 }
4076 //step 2 - compute minimal erased candidate set (MEC)
4077 List<Type> mec = closureMin(cl);
4078 //step 3 - for each element G in MEC, compute lci(Inv(G))
4079 List<Type> candidates = List.nil();
4080 for (Type erasedSupertype : mec) {
4081 List<Type> lci = List.of(asSuper(ts[startIdx], erasedSupertype.tsym));
4082 for (int i = startIdx + 1 ; i < ts.length ; i++) {
4083 Type superType = asSuper(ts[i], erasedSupertype.tsym);
4084 lci = intersect(lci, superType != null ? List.of(superType) : List.nil());
4085 }
4086 candidates = candidates.appendList(lci);
4087 }
4088 //step 4 - let MEC be { G1, G2 ... Gn }, then we have that
4089 //lub = lci(Inv(G1)) & lci(Inv(G2)) & ... & lci(Inv(Gn))
4090 return compoundMin(candidates);
4091
4092 default:
4093 // calculate lub(A, B[])
4094 List<Type> classes = List.of(arraySuperType());
4095 for (int i = 0 ; i < ts.length ; i++) {
4096 if (kinds[i] != ARRAY_BOUND) // Filter out any arrays
4097 classes = classes.prepend(ts[i]);
4098 }
4099 // lub(A, B[]) is lub(A, arraySuperType)
4100 return lub(classes);
4101 }
4102 }
4103 // where
4104 List<Type> erasedSupertypes(Type t) {
4105 ListBuffer<Type> buf = new ListBuffer<>();
4106 for (Type sup : closure(t)) {
4107 if (sup.hasTag(TYPEVAR)) {
4108 buf.append(sup);
4109 } else {
4110 buf.append(erasure(sup));
4111 }
4112 }
4113 return buf.toList();
4114 }
4115
4116 private Type arraySuperType = null;
4117 private Type arraySuperType() {
4118 // initialized lazily to avoid problems during compiler startup
4119 if (arraySuperType == null) {
4120 synchronized (this) {
4121 if (arraySuperType == null) {
4122 // JLS 10.8: all arrays implement Cloneable and Serializable.
4123 List<Type> ifaces = injectTopInterfaceTypes ?
4124 List.of(syms.serializableType, syms.cloneableType, syms.identityObjectType):
4125 List.of(syms.serializableType, syms.cloneableType);
4126 arraySuperType = makeIntersectionType(ifaces, true);
4127 }
4128 }
4129 }
4130 return arraySuperType;
4131 }
4132 // </editor-fold>
4133
4134 // <editor-fold defaultstate="collapsed" desc="Greatest lower bound">
4135 public Type glb(List<Type> ts) {
4136 Type t1 = ts.head;
4137 for (Type t2 : ts.tail) {
4138 if (t1.isErroneous())
4139 return t1;
4140 t1 = glb(t1, t2);
4141 }
4142 return t1;
4143 }
4144 //where
4145 public Type glb(Type t, Type s) {
4146 if (s == null)
4147 return t;
4148 else if (t.isPrimitive() || s.isPrimitive())
4149 return syms.errType;
4150 else if (isSubtypeNoCapture(t, s))
4151 return t;
4152 else if (isSubtypeNoCapture(s, t))
4153 return s;
4154
4155 List<Type> closure = union(closure(t), closure(s));
4156 return glbFlattened(closure, t);
4157 }
4158 //where
4159 /**
4160 * Perform glb for a list of non-primitive, non-error, non-compound types;
4161 * redundant elements are removed. Bounds should be ordered according to
4162 * {@link Symbol#precedes(TypeSymbol,Types)}.
4163 *
4164 * @param flatBounds List of type to glb
4165 * @param errT Original type to use if the result is an error type
4166 */
4167 private Type glbFlattened(List<Type> flatBounds, Type errT) {
4168 List<Type> bounds = closureMin(flatBounds);
4169
4170 if (bounds.isEmpty()) { // length == 0
4171 return syms.objectType;
4172 } else if (bounds.tail.isEmpty()) { // length == 1
4173 return bounds.head;
4174 } else { // length > 1
4175 int classCount = 0;
4176 List<Type> cvars = List.nil();
4177 List<Type> lowers = List.nil();
4178 for (Type bound : bounds) {
4179 if (!bound.isInterface()) {
4180 classCount++;
4181 Type lower = cvarLowerBound(bound);
4182 if (bound != lower && !lower.hasTag(BOT)) {
4183 cvars = cvars.append(bound);
4184 lowers = lowers.append(lower);
4185 }
4186 }
4187 }
4188 if (classCount > 1) {
4189 if (lowers.isEmpty()) {
4190 return createErrorType(errT);
4191 } else {
4192 // try again with lower bounds included instead of capture variables
4193 List<Type> newBounds = bounds.diff(cvars).appendList(lowers);
4194 return glb(newBounds);
4195 }
4196 }
4197 }
4198 return makeIntersectionType(bounds);
4199 }
4200 // </editor-fold>
4201
4202 // <editor-fold defaultstate="collapsed" desc="hashCode">
4203 /**
4204 * Compute a hash code on a type.
4205 */
4206 public int hashCode(Type t) {
4207 return hashCode(t, false);
4208 }
4209
4210 public int hashCode(Type t, boolean strict) {
4211 return strict ?
4212 hashCodeStrictVisitor.visit(t) :
4213 hashCodeVisitor.visit(t);
4214 }
4215 // where
4216 private static final HashCodeVisitor hashCodeVisitor = new HashCodeVisitor();
4217 private static final HashCodeVisitor hashCodeStrictVisitor = new HashCodeVisitor() {
4218 @Override
4219 public Integer visitTypeVar(TypeVar t, Void ignored) {
4220 return System.identityHashCode(t);
4221 }
4222 };
4223
4224 private static class HashCodeVisitor extends UnaryVisitor<Integer> {
4225 public Integer visitType(Type t, Void ignored) {
4226 return t.getTag().ordinal();
4227 }
4228
4229 @Override
4230 public Integer visitClassType(ClassType t, Void ignored) {
4231 int result = visit(t.getEnclosingType());
4232 result *= 127;
4233 result += t.tsym.flatName().hashCode();
4234 for (Type s : t.getTypeArguments()) {
4235 result *= 127;
4236 result += visit(s);
4237 }
4238 return result;
4239 }
4240
4241 @Override
4242 public Integer visitMethodType(MethodType t, Void ignored) {
4243 int h = METHOD.ordinal();
4244 for (List<Type> thisargs = t.argtypes;
4245 thisargs.tail != null;
4246 thisargs = thisargs.tail)
4247 h = (h << 5) + visit(thisargs.head);
4248 return (h << 5) + visit(t.restype);
4249 }
4250
4251 @Override
4252 public Integer visitWildcardType(WildcardType t, Void ignored) {
4253 int result = t.kind.hashCode();
4254 if (t.type != null) {
4255 result *= 127;
4256 result += visit(t.type);
4257 }
4258 return result;
4259 }
4260
4261 @Override
4262 public Integer visitArrayType(ArrayType t, Void ignored) {
4263 return visit(t.elemtype) + 12;
4264 }
4265
4266 @Override
4267 public Integer visitTypeVar(TypeVar t, Void ignored) {
4268 return System.identityHashCode(t);
4269 }
4270
4271 @Override
4272 public Integer visitUndetVar(UndetVar t, Void ignored) {
4273 return System.identityHashCode(t);
4274 }
4275
4276 @Override
4277 public Integer visitErrorType(ErrorType t, Void ignored) {
4278 return 0;
4279 }
4280 }
4281 // </editor-fold>
4282
4283 // <editor-fold defaultstate="collapsed" desc="Return-Type-Substitutable">
4284 /**
4285 * Does t have a result that is a subtype of the result type of s,
4286 * suitable for covariant returns? It is assumed that both types
4287 * are (possibly polymorphic) method types. Monomorphic method
4288 * types are handled in the obvious way. Polymorphic method types
4289 * require renaming all type variables of one to corresponding
4290 * type variables in the other, where correspondence is by
4291 * position in the type parameter list. */
4292 public boolean resultSubtype(Type t, Type s, Warner warner) {
4293 List<Type> tvars = t.getTypeArguments();
4294 List<Type> svars = s.getTypeArguments();
4295 Type tres = t.getReturnType();
4296 Type sres = subst(s.getReturnType(), svars, tvars);
4297 return covariantReturnType(tres, sres, warner);
4298 }
4299
4300 /**
4301 * Return-Type-Substitutable.
4302 * @jls 8.4.5 Method Result
4303 */
4304 public boolean returnTypeSubstitutable(Type r1, Type r2) {
4305 if (hasSameArgs(r1, r2))
4306 return resultSubtype(r1, r2, noWarnings);
4307 else
4308 return covariantReturnType(r1.getReturnType(),
4309 erasure(r2.getReturnType()),
4310 noWarnings);
4311 }
4312
4313 public boolean returnTypeSubstitutable(Type r1,
4314 Type r2, Type r2res,
4315 Warner warner) {
4316 if (isSameType(r1.getReturnType(), r2res))
4317 return true;
4318 if (r1.getReturnType().isPrimitive() || r2res.isPrimitive())
4319 return false;
4320
4321 if (hasSameArgs(r1, r2))
4322 return covariantReturnType(r1.getReturnType(), r2res, warner);
4323 if (isSubtypeUnchecked(r1.getReturnType(), r2res, warner))
4324 return true;
4325 if (!isSubtype(r1.getReturnType(), erasure(r2res)))
4326 return false;
4327 warner.warn(LintCategory.UNCHECKED);
4328 return true;
4329 }
4330
4331 /**
4332 * Is t an appropriate return type in an overrider for a
4333 * method that returns s?
4334 */
4335 public boolean covariantReturnType(Type t, Type s, Warner warner) {
4336 return
4337 isSameType(t, s) ||
4338 !t.isPrimitive() &&
4339 !s.isPrimitive() &&
4340 isAssignable(t, s, warner);
4341 }
4342 // </editor-fold>
4343
4344 // <editor-fold defaultstate="collapsed" desc="Box/unbox support">
4345 /**
4346 * Return the class that boxes the given primitive.
4347 */
4348 public ClassSymbol boxedClass(Type t) {
4349 return syms.enterClass(syms.java_base, syms.boxedName[t.getTag().ordinal()]);
4350 }
4351
4352 /**
4353 * Return the boxed type if 't' is primitive, otherwise return 't' itself.
4354 */
4355 public Type boxedTypeOrType(Type t) {
4356 return t.isPrimitive() ?
4357 boxedClass(t).type :
4358 t;
4359 }
4360
4361 /**
4362 * Return the primitive type corresponding to a boxed type.
4363 */
4364 public Type unboxedType(Type t) {
4365 for (int i=0; i<syms.boxedName.length; i++) {
4366 Name box = syms.boxedName[i];
4367 if (box != null &&
4368 asSuper(t, syms.enterClass(syms.java_base, box)) != null)
4369 return syms.typeOfTag[i];
4370 }
4371 return Type.noType;
4372 }
4373
4374 /**
4375 * Return the unboxed type if 't' is a boxed class, otherwise return 't' itself.
4376 */
4377 public Type unboxedTypeOrType(Type t) {
4378 Type unboxedType = unboxedType(t);
4379 return unboxedType.hasTag(NONE) ? t : unboxedType;
4380 }
4381 // </editor-fold>
4382
4383 // <editor-fold defaultstate="collapsed" desc="Capture conversion">
4384 /*
4385 * JLS 5.1.10 Capture Conversion:
4386 *
4387 * Let G name a generic type declaration with n formal type
4388 * parameters A1 ... An with corresponding bounds U1 ... Un. There
4389 * exists a capture conversion from G<T1 ... Tn> to G<S1 ... Sn>,
4390 * where, for 1 <= i <= n:
4391 *
4392 * + If Ti is a wildcard type argument (4.5.1) of the form ? then
4393 * Si is a fresh type variable whose upper bound is
4394 * Ui[A1 := S1, ..., An := Sn] and whose lower bound is the null
4395 * type.
4396 *
4397 * + If Ti is a wildcard type argument of the form ? extends Bi,
4398 * then Si is a fresh type variable whose upper bound is
4399 * glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is
4400 * the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is
4401 * a compile-time error if for any two classes (not interfaces)
4402 * Vi and Vj,Vi is not a subclass of Vj or vice versa.
4403 *
4404 * + If Ti is a wildcard type argument of the form ? super Bi,
4405 * then Si is a fresh type variable whose upper bound is
4406 * Ui[A1 := S1, ..., An := Sn] and whose lower bound is Bi.
4407 *
4408 * + Otherwise, Si = Ti.
4409 *
4410 * Capture conversion on any type other than a parameterized type
4411 * (4.5) acts as an identity conversion (5.1.1). Capture
4412 * conversions never require a special action at run time and
4413 * therefore never throw an exception at run time.
4414 *
4415 * Capture conversion is not applied recursively.
4416 */
4417 /**
4418 * Capture conversion as specified by the JLS.
4419 */
4420
4421 public List<Type> capture(List<Type> ts) {
4422 List<Type> buf = List.nil();
4423 for (Type t : ts) {
4424 buf = buf.prepend(capture(t));
4425 }
4426 return buf.reverse();
4427 }
4428
4429 public Type capture(Type t) {
4430 if (!t.hasTag(CLASS)) {
4431 return t;
4432 }
4433 if (t.getEnclosingType() != Type.noType) {
4434 Type capturedEncl = capture(t.getEnclosingType());
4435 if (capturedEncl != t.getEnclosingType()) {
4436 Type type1 = memberType(capturedEncl, t.tsym);
4437 t = subst(type1, t.tsym.type.getTypeArguments(), t.getTypeArguments());
4438 }
4439 }
4440 ClassType cls = (ClassType)t;
4441 if (cls.isRaw() || !cls.isParameterized())
4442 return cls;
4443
4444 ClassType G = (ClassType)cls.asElement().asType();
4445 List<Type> A = G.getTypeArguments();
4446 List<Type> T = cls.getTypeArguments();
4447 List<Type> S = freshTypeVariables(T);
4448
4449 List<Type> currentA = A;
4450 List<Type> currentT = T;
4451 List<Type> currentS = S;
4452 boolean captured = false;
4453 while (!currentA.isEmpty() &&
4454 !currentT.isEmpty() &&
4455 !currentS.isEmpty()) {
4456 if (currentS.head != currentT.head) {
4457 captured = true;
4458 WildcardType Ti = (WildcardType)currentT.head;
4459 Type Ui = currentA.head.getUpperBound();
4460 CapturedType Si = (CapturedType)currentS.head;
4461 if (Ui == null)
4462 Ui = syms.objectType;
4463 switch (Ti.kind) {
4464 case UNBOUND:
4465 Si.setUpperBound( subst(Ui, A, S) );
4466 Si.lower = syms.botType;
4467 break;
4468 case EXTENDS:
4469 Si.setUpperBound( glb(Ti.getExtendsBound(), subst(Ui, A, S)) );
4470 Si.lower = syms.botType;
4471 break;
4472 case SUPER:
4473 Si.setUpperBound( subst(Ui, A, S) );
4474 Si.lower = Ti.getSuperBound();
4475 break;
4476 }
4477 Type tmpBound = Si.getUpperBound().hasTag(UNDETVAR) ? ((UndetVar)Si.getUpperBound()).qtype : Si.getUpperBound();
4478 Type tmpLower = Si.lower.hasTag(UNDETVAR) ? ((UndetVar)Si.lower).qtype : Si.lower;
4479 if (!Si.getUpperBound().hasTag(ERROR) &&
4480 !Si.lower.hasTag(ERROR) &&
4481 isSameType(tmpBound, tmpLower)) {
4482 currentS.head = Si.getUpperBound();
4483 }
4484 }
4485 currentA = currentA.tail;
4486 currentT = currentT.tail;
4487 currentS = currentS.tail;
4488 }
4489 if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty())
4490 return erasure(t); // some "rare" type involved
4491
4492 if (captured)
4493 return new ClassType(cls.getEnclosingType(), S, cls.tsym,
4494 cls.getMetadata());
4495 else
4496 return t;
4497 }
4498 // where
4499 public List<Type> freshTypeVariables(List<Type> types) {
4500 ListBuffer<Type> result = new ListBuffer<>();
4501 for (Type t : types) {
4502 if (t.hasTag(WILDCARD)) {
4503 Type bound = ((WildcardType)t).getExtendsBound();
4504 if (bound == null)
4505 bound = syms.objectType;
4506 result.append(new CapturedType(capturedName,
4507 syms.noSymbol,
4508 bound,
4509 syms.botType,
4510 (WildcardType)t));
4511 } else {
4512 result.append(t);
4513 }
4514 }
4515 return result.toList();
4516 }
4517 // </editor-fold>
4518
4519 // <editor-fold defaultstate="collapsed" desc="Internal utility methods">
4520 private boolean sideCast(Type from, Type to, Warner warn) {
4521 // We are casting from type $from$ to type $to$, which are
4522 // non-final unrelated types. This method
4523 // tries to reject a cast by transferring type parameters
4524 // from $to$ to $from$ by common superinterfaces.
4525 boolean reverse = false;
4526 Type target = to;
4527 if ((to.tsym.flags() & INTERFACE) == 0) {
4528 Assert.check((from.tsym.flags() & INTERFACE) != 0);
4529 reverse = true;
4530 to = from;
4531 from = target;
4532 }
4533 List<Type> commonSupers = superClosure(to, erasure(from));
4534 boolean giveWarning = commonSupers.isEmpty();
4535 // The arguments to the supers could be unified here to
4536 // get a more accurate analysis
4537 while (commonSupers.nonEmpty()) {
4538 Type t1 = asSuper(from, commonSupers.head.tsym);
4539 Type t2 = commonSupers.head; // same as asSuper(to, commonSupers.head.tsym);
4540 if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
4541 return false;
4542 giveWarning = giveWarning || (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2));
4543 commonSupers = commonSupers.tail;
4544 }
4545 if (giveWarning && !isReifiable(reverse ? from : to))
4546 warn.warn(LintCategory.UNCHECKED);
4547 return true;
4548 }
4549
4550 private boolean sideCastFinal(Type from, Type to, Warner warn) {
4551 // We are casting from type $from$ to type $to$, which are
4552 // unrelated types one of which is final and the other of
4553 // which is an interface. This method
4554 // tries to reject a cast by transferring type parameters
4555 // from the final class to the interface.
4556 boolean reverse = false;
4557 Type target = to;
4558 if ((to.tsym.flags() & INTERFACE) == 0) {
4559 Assert.check((from.tsym.flags() & INTERFACE) != 0);
4560 reverse = true;
4561 to = from;
4562 from = target;
4563 }
4564 Assert.check((from.tsym.flags() & FINAL) != 0);
4565 Type t1 = asSuper(from, to.tsym);
4566 if (t1 == null) return false;
4567 Type t2 = to;
4568 if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
4569 return false;
4570 if (!isReifiable(target) &&
4571 (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2)))
4572 warn.warn(LintCategory.UNCHECKED);
4573 return true;
4574 }
4575
4576 private boolean giveWarning(Type from, Type to) {
4577 List<Type> bounds = to.isCompound() ?
4578 directSupertypes(to) : List.of(to);
4579 for (Type b : bounds) {
4580 Type subFrom = asSub(from, b.tsym);
4581 if (b.isParameterized() &&
4582 (!(isUnbounded(b) ||
4583 isSubtype(from, b) ||
4584 ((subFrom != null) && containsType(b.allparams(), subFrom.allparams()))))) {
4585 return true;
4586 }
4587 }
4588 return false;
4589 }
4590
4591 private List<Type> superClosure(Type t, Type s) {
4592 List<Type> cl = List.nil();
4593 for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
4594 if (isSubtype(s, erasure(l.head))) {
4595 cl = insert(cl, l.head);
4596 } else {
4597 cl = union(cl, superClosure(l.head, s));
4598 }
4599 }
4600 return cl;
4601 }
4602
4603 private boolean containsTypeEquivalent(Type t, Type s) {
4604 return isSameType(t, s) || // shortcut
4605 containsType(t, s) && containsType(s, t);
4606 }
4607
4608 // <editor-fold defaultstate="collapsed" desc="adapt">
4609 /**
4610 * Adapt a type by computing a substitution which maps a source
4611 * type to a target type.
4612 *
4613 * @param source the source type
4614 * @param target the target type
4615 * @param from the type variables of the computed substitution
4616 * @param to the types of the computed substitution.
4617 */
4618 public void adapt(Type source,
4619 Type target,
4620 ListBuffer<Type> from,
4621 ListBuffer<Type> to) throws AdaptFailure {
4622 new Adapter(from, to).adapt(source, target);
4623 }
4624
4625 class Adapter extends SimpleVisitor<Void, Type> {
4626
4627 ListBuffer<Type> from;
4628 ListBuffer<Type> to;
4629 Map<Symbol,Type> mapping;
4630
4631 Adapter(ListBuffer<Type> from, ListBuffer<Type> to) {
4632 this.from = from;
4633 this.to = to;
4634 mapping = new HashMap<>();
4635 }
4636
4637 public void adapt(Type source, Type target) throws AdaptFailure {
4638 visit(source, target);
4639 List<Type> fromList = from.toList();
4640 List<Type> toList = to.toList();
4641 while (!fromList.isEmpty()) {
4642 Type val = mapping.get(fromList.head.tsym);
4643 if (toList.head != val)
4644 toList.head = val;
4645 fromList = fromList.tail;
4646 toList = toList.tail;
4647 }
4648 }
4649
4650 @Override
4651 public Void visitClassType(ClassType source, Type target) throws AdaptFailure {
4652 if (target.hasTag(CLASS))
4653 adaptRecursive(source.allparams(), target.allparams());
4654 return null;
4655 }
4656
4657 @Override
4658 public Void visitArrayType(ArrayType source, Type target) throws AdaptFailure {
4659 if (target.hasTag(ARRAY))
4660 adaptRecursive(elemtype(source), elemtype(target));
4661 return null;
4662 }
4663
4664 @Override
4665 public Void visitWildcardType(WildcardType source, Type target) throws AdaptFailure {
4666 if (source.isExtendsBound())
4667 adaptRecursive(wildUpperBound(source), wildUpperBound(target));
4668 else if (source.isSuperBound())
4669 adaptRecursive(wildLowerBound(source), wildLowerBound(target));
4670 return null;
4671 }
4672
4673 @Override
4674 public Void visitTypeVar(TypeVar source, Type target) throws AdaptFailure {
4675 // Check to see if there is
4676 // already a mapping for $source$, in which case
4677 // the old mapping will be merged with the new
4678 Type val = mapping.get(source.tsym);
4679 if (val != null) {
4680 if (val.isSuperBound() && target.isSuperBound()) {
4681 val = isSubtype(wildLowerBound(val), wildLowerBound(target))
4682 ? target : val;
4683 } else if (val.isExtendsBound() && target.isExtendsBound()) {
4684 val = isSubtype(wildUpperBound(val), wildUpperBound(target))
4685 ? val : target;
4686 } else if (!isSameType(val, target)) {
4687 throw new AdaptFailure();
4688 }
4689 } else {
4690 val = target;
4691 from.append(source);
4692 to.append(target);
4693 }
4694 mapping.put(source.tsym, val);
4695 return null;
4696 }
4697
4698 @Override
4699 public Void visitType(Type source, Type target) {
4700 return null;
4701 }
4702
4703 private Set<TypePair> cache = new HashSet<>();
4704
4705 private void adaptRecursive(Type source, Type target) {
4706 TypePair pair = new TypePair(source, target);
4707 if (cache.add(pair)) {
4708 try {
4709 visit(source, target);
4710 } finally {
4711 cache.remove(pair);
4712 }
4713 }
4714 }
4715
4716 private void adaptRecursive(List<Type> source, List<Type> target) {
4717 if (source.length() == target.length()) {
4718 while (source.nonEmpty()) {
4719 adaptRecursive(source.head, target.head);
4720 source = source.tail;
4721 target = target.tail;
4722 }
4723 }
4724 }
4725 }
4726
4727 public static class AdaptFailure extends RuntimeException {
4728 static final long serialVersionUID = -7490231548272701566L;
4729 }
4730
4731 private void adaptSelf(Type t,
4732 ListBuffer<Type> from,
4733 ListBuffer<Type> to) {
4734 try {
4735 //if (t.tsym.type != t)
4736 adapt(t.tsym.type, t, from, to);
4737 } catch (AdaptFailure ex) {
4738 // Adapt should never fail calculating a mapping from
4739 // t.tsym.type to t as there can be no merge problem.
4740 throw new AssertionError(ex);
4741 }
4742 }
4743 // </editor-fold>
4744
4745 /**
4746 * Rewrite all type variables (universal quantifiers) in the given
4747 * type to wildcards (existential quantifiers). This is used to
4748 * determine if a cast is allowed. For example, if high is true
4749 * and {@code T <: Number}, then {@code List<T>} is rewritten to
4750 * {@code List<? extends Number>}. Since {@code List<Integer> <:
4751 * List<? extends Number>} a {@code List<T>} can be cast to {@code
4752 * List<Integer>} with a warning.
4753 * @param t a type
4754 * @param high if true return an upper bound; otherwise a lower
4755 * bound
4756 * @param rewriteTypeVars only rewrite captured wildcards if false;
4757 * otherwise rewrite all type variables
4758 * @return the type rewritten with wildcards (existential
4759 * quantifiers) only
4760 */
4761 private Type rewriteQuantifiers(Type t, boolean high, boolean rewriteTypeVars) {
4762 return new Rewriter(high, rewriteTypeVars).visit(t);
4763 }
4764
4765 class Rewriter extends UnaryVisitor<Type> {
4766
4767 boolean high;
4768 boolean rewriteTypeVars;
4769
4770 Rewriter(boolean high, boolean rewriteTypeVars) {
4771 this.high = high;
4772 this.rewriteTypeVars = rewriteTypeVars;
4773 }
4774
4775 @Override
4776 public Type visitClassType(ClassType t, Void s) {
4777 ListBuffer<Type> rewritten = new ListBuffer<>();
4778 boolean changed = false;
4779 for (Type arg : t.allparams()) {
4780 Type bound = visit(arg);
4781 if (arg != bound) {
4782 changed = true;
4783 }
4784 rewritten.append(bound);
4785 }
4786 if (changed)
4787 return subst(t.tsym.type,
4788 t.tsym.type.allparams(),
4789 rewritten.toList());
4790 else
4791 return t;
4792 }
4793
4794 public Type visitType(Type t, Void s) {
4795 return t;
4796 }
4797
4798 @Override
4799 public Type visitCapturedType(CapturedType t, Void s) {
4800 Type w_bound = t.wildcard.type;
4801 Type bound = w_bound.contains(t) ?
4802 erasure(w_bound) :
4803 visit(w_bound);
4804 return rewriteAsWildcardType(visit(bound), t.wildcard.bound, t.wildcard.kind);
4805 }
4806
4807 @Override
4808 public Type visitTypeVar(TypeVar t, Void s) {
4809 if (rewriteTypeVars) {
4810 Type bound = t.getUpperBound().contains(t) ?
4811 erasure(t.getUpperBound()) :
4812 visit(t.getUpperBound());
4813 return rewriteAsWildcardType(bound, t, EXTENDS);
4814 } else {
4815 return t;
4816 }
4817 }
4818
4819 @Override
4820 public Type visitWildcardType(WildcardType t, Void s) {
4821 Type bound2 = visit(t.type);
4822 return t.type == bound2 ? t : rewriteAsWildcardType(bound2, t.bound, t.kind);
4823 }
4824
4825 private Type rewriteAsWildcardType(Type bound, TypeVar formal, BoundKind bk) {
4826 switch (bk) {
4827 case EXTENDS: return high ?
4828 makeExtendsWildcard(B(bound), formal) :
4829 makeExtendsWildcard(syms.objectType, formal);
4830 case SUPER: return high ?
4831 makeSuperWildcard(syms.botType, formal) :
4832 makeSuperWildcard(B(bound), formal);
4833 case UNBOUND: return makeExtendsWildcard(syms.objectType, formal);
4834 default:
4835 Assert.error("Invalid bound kind " + bk);
4836 return null;
4837 }
4838 }
4839
4840 Type B(Type t) {
4841 while (t.hasTag(WILDCARD)) {
4842 WildcardType w = (WildcardType)t;
4843 t = high ?
4844 w.getExtendsBound() :
4845 w.getSuperBound();
4846 if (t == null) {
4847 t = high ? syms.objectType : syms.botType;
4848 }
4849 }
4850 return t;
4851 }
4852 }
4853
4854
4855 /**
4856 * Create a wildcard with the given upper (extends) bound; create
4857 * an unbounded wildcard if bound is Object.
4858 *
4859 * @param bound the upper bound
4860 * @param formal the formal type parameter that will be
4861 * substituted by the wildcard
4862 */
4863 private WildcardType makeExtendsWildcard(Type bound, TypeVar formal) {
4864 if (bound == syms.objectType) {
4865 return new WildcardType(syms.objectType,
4866 BoundKind.UNBOUND,
4867 syms.boundClass,
4868 formal);
4869 } else {
4870 return new WildcardType(bound,
4871 BoundKind.EXTENDS,
4872 syms.boundClass,
4873 formal);
4874 }
4875 }
4876
4877 /**
4878 * Create a wildcard with the given lower (super) bound; create an
4879 * unbounded wildcard if bound is bottom (type of {@code null}).
4880 *
4881 * @param bound the lower bound
4882 * @param formal the formal type parameter that will be
4883 * substituted by the wildcard
4884 */
4885 private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
4886 if (bound.hasTag(BOT)) {
4887 return new WildcardType(syms.objectType,
4888 BoundKind.UNBOUND,
4889 syms.boundClass,
4890 formal);
4891 } else {
4892 return new WildcardType(bound,
4893 BoundKind.SUPER,
4894 syms.boundClass,
4895 formal);
4896 }
4897 }
4898
4899 /**
4900 * A wrapper for a type that allows use in sets.
4901 */
4902 public static class UniqueType {
4903 public final Type type;
4904 final Types types;
4905 private boolean encodeTypeSig;
4906
4907 public UniqueType(Type type, Types types, boolean encodeTypeSig) {
4908 this.type = type;
4909 this.types = types;
4910 this.encodeTypeSig = encodeTypeSig;
4911 }
4912
4913 public UniqueType(Type type, Types types) {
4914 this(type, types, true);
4915 }
4916
4917 public int hashCode() {
4918 return types.hashCode(type);
4919 }
4920
4921 public boolean equals(Object obj) {
4922 return (obj instanceof UniqueType) &&
4923 types.isSameType(type, ((UniqueType)obj).type);
4924 }
4925
4926 public boolean encodeTypeSig() {
4927 return encodeTypeSig;
4928 }
4929
4930 public String toString() {
4931 return type.toString();
4932 }
4933
4934 }
4935 // </editor-fold>
4936
4937 // <editor-fold defaultstate="collapsed" desc="Visitors">
4938 /**
4939 * A default visitor for types. All visitor methods except
4940 * visitType are implemented by delegating to visitType. Concrete
4941 * subclasses must provide an implementation of visitType and can
4942 * override other methods as needed.
4943 *
4944 * @param <R> the return type of the operation implemented by this
4945 * visitor; use Void if no return type is needed.
4946 * @param <S> the type of the second argument (the first being the
4947 * type itself) of the operation implemented by this visitor; use
4948 * Void if a second argument is not needed.
4949 */
4950 public static abstract class DefaultTypeVisitor<R,S> implements Type.Visitor<R,S> {
4951 final public R visit(Type t, S s) { return t.accept(this, s); }
4952 public R visitClassType(ClassType t, S s) { return visitType(t, s); }
4953 public R visitWildcardType(WildcardType t, S s) { return visitType(t, s); }
4954 public R visitArrayType(ArrayType t, S s) { return visitType(t, s); }
4955 public R visitMethodType(MethodType t, S s) { return visitType(t, s); }
4956 public R visitPackageType(PackageType t, S s) { return visitType(t, s); }
4957 public R visitModuleType(ModuleType t, S s) { return visitType(t, s); }
4958 public R visitTypeVar(TypeVar t, S s) { return visitType(t, s); }
4959 public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); }
4960 public R visitForAll(ForAll t, S s) { return visitType(t, s); }
4961 public R visitUndetVar(UndetVar t, S s) { return visitType(t, s); }
4962 public R visitErrorType(ErrorType t, S s) { return visitType(t, s); }
4963 }
4964
4965 /**
4966 * A default visitor for symbols. All visitor methods except
4967 * visitSymbol are implemented by delegating to visitSymbol. Concrete
4968 * subclasses must provide an implementation of visitSymbol and can
4969 * override other methods as needed.
4970 *
4971 * @param <R> the return type of the operation implemented by this
4972 * visitor; use Void if no return type is needed.
4973 * @param <S> the type of the second argument (the first being the
4974 * symbol itself) of the operation implemented by this visitor; use
4975 * Void if a second argument is not needed.
4976 */
4977 public static abstract class DefaultSymbolVisitor<R,S> implements Symbol.Visitor<R,S> {
4978 final public R visit(Symbol s, S arg) { return s.accept(this, arg); }
4979 public R visitClassSymbol(ClassSymbol s, S arg) { return visitSymbol(s, arg); }
4980 public R visitMethodSymbol(MethodSymbol s, S arg) { return visitSymbol(s, arg); }
4981 public R visitOperatorSymbol(OperatorSymbol s, S arg) { return visitSymbol(s, arg); }
4982 public R visitPackageSymbol(PackageSymbol s, S arg) { return visitSymbol(s, arg); }
4983 public R visitTypeSymbol(TypeSymbol s, S arg) { return visitSymbol(s, arg); }
4984 public R visitVarSymbol(VarSymbol s, S arg) { return visitSymbol(s, arg); }
4985 }
4986
4987 /**
4988 * A <em>simple</em> visitor for types. This visitor is simple as
4989 * captured wildcards, for-all types (generic methods), and
4990 * undetermined type variables (part of inference) are hidden.
4991 * Captured wildcards are hidden by treating them as type
4992 * variables and the rest are hidden by visiting their qtypes.
4993 *
4994 * @param <R> the return type of the operation implemented by this
4995 * visitor; use Void if no return type is needed.
4996 * @param <S> the type of the second argument (the first being the
4997 * type itself) of the operation implemented by this visitor; use
4998 * Void if a second argument is not needed.
4999 */
5000 public static abstract class SimpleVisitor<R,S> extends DefaultTypeVisitor<R,S> {
5001 @Override
5002 public R visitCapturedType(CapturedType t, S s) {
5003 return visitTypeVar(t, s);
5004 }
5005 @Override
5006 public R visitForAll(ForAll t, S s) {
5007 return visit(t.qtype, s);
5008 }
5009 @Override
5010 public R visitUndetVar(UndetVar t, S s) {
5011 return visit(t.qtype, s);
5012 }
5013 }
5014
5015 /**
5016 * A plain relation on types. That is a 2-ary function on the
5017 * form Type × Type → Boolean.
5018 * <!-- In plain text: Type x Type -> Boolean -->
5019 */
5020 public static abstract class TypeRelation extends SimpleVisitor<Boolean,Type> {}
5021
5022 /**
5023 * A convenience visitor for implementing operations that only
5024 * require one argument (the type itself), that is, unary
5025 * operations.
5026 *
5027 * @param <R> the return type of the operation implemented by this
5028 * visitor; use Void if no return type is needed.
5029 */
5030 public static abstract class UnaryVisitor<R> extends SimpleVisitor<R,Void> {
5031 final public R visit(Type t) { return t.accept(this, null); }
5032 }
5033
5034 /**
5035 * A visitor for implementing a mapping from types to types. The
5036 * default behavior of this class is to implement the identity
5037 * mapping (mapping a type to itself). This can be overridden in
5038 * subclasses.
5039 *
5040 * @param <S> the type of the second argument (the first being the
5041 * type itself) of this mapping; use Void if a second argument is
5042 * not needed.
5043 */
5044 public static class MapVisitor<S> extends DefaultTypeVisitor<Type,S> {
5045 final public Type visit(Type t) { return t.accept(this, null); }
5046 public Type visitType(Type t, S s) { return t; }
5047 }
5048
5049 /**
5050 * An abstract class for mappings from types to types (see {@link Type#map(TypeMapping)}.
5051 * This class implements the functional interface {@code Function}, that allows it to be used
5052 * fluently in stream-like processing.
5053 */
5054 public static class TypeMapping<S> extends MapVisitor<S> implements Function<Type, Type> {
5055 @Override
5056 public Type apply(Type type) { return visit(type); }
5057
5058 List<Type> visit(List<Type> ts, S s) {
5059 return ts.map(t -> visit(t, s));
5060 }
5061
5062 @Override
5063 public Type visitCapturedType(CapturedType t, S s) {
5064 return visitTypeVar(t, s);
5065 }
5066 }
5067 // </editor-fold>
5068
5069
5070 // <editor-fold defaultstate="collapsed" desc="Annotation support">
5071
5072 public RetentionPolicy getRetention(Attribute.Compound a) {
5073 return getRetention(a.type.tsym);
5074 }
5075
5076 public RetentionPolicy getRetention(TypeSymbol sym) {
5077 RetentionPolicy vis = RetentionPolicy.CLASS; // the default
5078 Attribute.Compound c = sym.attribute(syms.retentionType.tsym);
5079 if (c != null) {
5080 Attribute value = c.member(names.value);
5081 if (value != null && value instanceof Attribute.Enum) {
5082 Name levelName = ((Attribute.Enum)value).value.name;
5083 if (levelName == names.SOURCE) vis = RetentionPolicy.SOURCE;
5084 else if (levelName == names.CLASS) vis = RetentionPolicy.CLASS;
5085 else if (levelName == names.RUNTIME) vis = RetentionPolicy.RUNTIME;
5086 else ;// /* fail soft */ throw new AssertionError(levelName);
5087 }
5088 }
5089 return vis;
5090 }
5091 // </editor-fold>
5092
5093 // <editor-fold defaultstate="collapsed" desc="Signature Generation">
5094
5095 public static abstract class SignatureGenerator {
5096
5097 public static class InvalidSignatureException extends RuntimeException {
5098 private static final long serialVersionUID = 0;
5099
5100 private final transient Type type;
5101
5102 InvalidSignatureException(Type type) {
5103 this.type = type;
5104 }
5105
5106 public Type type() {
5107 return type;
5108 }
5109 }
5110
5111 private final Types types;
5112
5113 protected abstract void append(char ch);
5114 protected abstract void append(byte[] ba);
5115 protected abstract void append(Name name);
5116 protected void classReference(ClassSymbol c) { /* by default: no-op */ }
5117
5118 protected SignatureGenerator(Types types) {
5119 this.types = types;
5120 }
5121
5122 protected void reportIllegalSignature(Type t) {
5123 throw new InvalidSignatureException(t);
5124 }
5125
5126 /**
5127 * Assemble signature of given type in string buffer.
5128 */
5129 public void assembleSig(Type type) {
5130 switch (type.getTag()) {
5131 case BYTE:
5132 append('B');
5133 break;
5134 case SHORT:
5135 append('S');
5136 break;
5137 case CHAR:
5138 append('C');
5139 break;
5140 case INT:
5141 append('I');
5142 break;
5143 case LONG:
5144 append('J');
5145 break;
5146 case FLOAT:
5147 append('F');
5148 break;
5149 case DOUBLE:
5150 append('D');
5151 break;
5152 case BOOLEAN:
5153 append('Z');
5154 break;
5155 case VOID:
5156 append('V');
5157 break;
5158 case CLASS:
5159 if (type.isCompound()) {
5160 reportIllegalSignature(type);
5161 }
5162 if (types.isValue(type))
5163 append('Q');
5164 else
5165 append('L');
5166 assembleClassSig(type);
5167 append(';');
5168 break;
5169 case ARRAY:
5170 ArrayType at = (ArrayType) type;
5171 append('[');
5172 assembleSig(at.elemtype);
5173 break;
5174 case METHOD:
5175 MethodType mt = (MethodType) type;
5176 append('(');
5177 assembleSig(mt.argtypes);
5178 append(')');
5179 assembleSig(mt.restype);
5180 if (hasTypeVar(mt.thrown)) {
5181 for (List<Type> l = mt.thrown; l.nonEmpty(); l = l.tail) {
5182 append('^');
5183 assembleSig(l.head);
5184 }
5185 }
5186 break;
5187 case WILDCARD: {
5188 Type.WildcardType ta = (Type.WildcardType) type;
5189 switch (ta.kind) {
5190 case SUPER:
5191 append('-');
5192 assembleSig(ta.type);
5193 break;
5194 case EXTENDS:
5195 append('+');
5196 assembleSig(ta.type);
5197 break;
5198 case UNBOUND:
5199 append('*');
5200 break;
5201 default:
5202 throw new AssertionError(ta.kind);
5203 }
5204 break;
5205 }
5206 case TYPEVAR:
5207 if (((TypeVar)type).isCaptured()) {
5208 reportIllegalSignature(type);
5209 }
5210 append('T');
5211 append(type.tsym.name);
5212 append(';');
5213 break;
5214 case FORALL:
5215 Type.ForAll ft = (Type.ForAll) type;
5216 assembleParamsSig(ft.tvars);
5217 assembleSig(ft.qtype);
5218 break;
5219 default:
5220 throw new AssertionError("typeSig " + type.getTag());
5221 }
5222 }
5223
5224 public boolean hasTypeVar(List<Type> l) {
5225 while (l.nonEmpty()) {
5226 if (l.head.hasTag(TypeTag.TYPEVAR)) {
5227 return true;
5228 }
5229 l = l.tail;
5230 }
5231 return false;
5232 }
5233
5234 public void assembleClassSig(Type type) {
5235 ClassType ct = (ClassType) type;
5236 ClassSymbol c = (ClassSymbol) ct.tsym;
5237 classReference(c);
5238 Type outer = ct.getEnclosingType();
5239 if (outer.allparams().nonEmpty()) {
5240 boolean rawOuter =
5241 c.owner.kind == MTH || // either a local class
5242 c.name == types.names.empty; // or anonymous
5243 assembleClassSig(rawOuter
5244 ? types.erasure(outer)
5245 : outer);
5246 append(rawOuter ? '$' : '.');
5247 Assert.check(c.flatname.startsWith(c.owner.enclClass().flatname));
5248 append(rawOuter
5249 ? c.flatname.subName(c.owner.enclClass().flatname.getByteLength() + 1, c.flatname.getByteLength())
5250 : c.name);
5251 } else {
5252 append(externalize(c.flatname));
5253 }
5254 if (ct.getTypeArguments().nonEmpty()) {
5255 append('<');
5256 assembleSig(ct.getTypeArguments());
5257 append('>');
5258 }
5259 }
5260
5261 public void assembleParamsSig(List<Type> typarams) {
5262 append('<');
5263 for (List<Type> ts = typarams; ts.nonEmpty(); ts = ts.tail) {
5264 Type.TypeVar tvar = (Type.TypeVar) ts.head;
5265 append(tvar.tsym.name);
5266 List<Type> bounds = types.getBounds(tvar);
5267 if ((bounds.head.tsym.flags() & INTERFACE) != 0) {
5268 append(':');
5269 }
5270 for (List<Type> l = bounds; l.nonEmpty(); l = l.tail) {
5271 append(':');
5272 assembleSig(l.head);
5273 }
5274 }
5275 append('>');
5276 }
5277
5278 public void assembleSig(List<Type> types) {
5279 for (List<Type> ts = types; ts.nonEmpty(); ts = ts.tail) {
5280 assembleSig(ts.head);
5281 }
5282 }
5283 }
5284
5285 public Type constantType(LoadableConstant c) {
5286 switch (c.poolTag()) {
5287 case ClassFile.CONSTANT_Class:
5288 return syms.classType;
5289 case ClassFile.CONSTANT_String:
5290 return syms.stringType;
5291 case ClassFile.CONSTANT_Integer:
5292 return syms.intType;
5293 case ClassFile.CONSTANT_Float:
5294 return syms.floatType;
5295 case ClassFile.CONSTANT_Long:
5296 return syms.longType;
5297 case ClassFile.CONSTANT_Double:
5298 return syms.doubleType;
5299 case ClassFile.CONSTANT_MethodHandle:
5300 return syms.methodHandleType;
5301 case ClassFile.CONSTANT_MethodType:
5302 return syms.methodTypeType;
5303 case ClassFile.CONSTANT_Dynamic:
5304 return ((DynamicVarSymbol)c).type;
5305 default:
5306 throw new AssertionError("Not a loadable constant: " + c.poolTag());
5307 }
5308 }
5309 // </editor-fold>
5310
5311 public void newRound() {
5312 descCache._map.clear();
5313 isDerivedRawCache.clear();
5314 implCache._map.clear();
5315 membersCache._map.clear();
5316 closureCache.clear();
5317 }
5318 }