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