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