Wed, 16 Feb 2011 10:27:00 -0800
6990136: Cleanup use of Type.clone()
Summary: Introduced factory methods in class Types which can be used rather than clone().
Reviewed-by: jjg, mcimadamore
1 /*
2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.tools.javac.code;
28 import com.sun.tools.javac.util.*;
29 import com.sun.tools.javac.code.Symbol.*;
31 import javax.lang.model.type.*;
33 import static com.sun.tools.javac.code.Flags.*;
34 import static com.sun.tools.javac.code.Kinds.*;
35 import static com.sun.tools.javac.code.BoundKind.*;
36 import static com.sun.tools.javac.code.TypeTags.*;
38 /** This class represents Java types. The class itself defines the behavior of
39 * the following types:
40 * <pre>
41 * base types (tags: BYTE, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, BOOLEAN),
42 * type `void' (tag: VOID),
43 * the bottom type (tag: BOT),
44 * the missing type (tag: NONE).
45 * </pre>
46 * <p>The behavior of the following types is defined in subclasses, which are
47 * all static inner classes of this class:
48 * <pre>
49 * class types (tag: CLASS, class: ClassType),
50 * array types (tag: ARRAY, class: ArrayType),
51 * method types (tag: METHOD, class: MethodType),
52 * package types (tag: PACKAGE, class: PackageType),
53 * type variables (tag: TYPEVAR, class: TypeVar),
54 * type arguments (tag: WILDCARD, class: WildcardType),
55 * polymorphic types (tag: FORALL, class: ForAll),
56 * the error type (tag: ERROR, class: ErrorType).
57 * </pre>
58 *
59 * <p><b>This is NOT part of any supported API.
60 * If you write code that depends on this, you do so at your own risk.
61 * This code and its internal interfaces are subject to change or
62 * deletion without notice.</b>
63 *
64 * @see TypeTags
65 */
66 public class Type implements PrimitiveType {
68 /** Constant type: no type at all. */
69 public static final JCNoType noType = new JCNoType(NONE);
71 /** If this switch is turned on, the names of type variables
72 * and anonymous classes are printed with hashcodes appended.
73 */
74 public static boolean moreInfo = false;
76 /** The tag of this type.
77 *
78 * @see TypeTags
79 */
80 public int tag;
82 /** The defining class / interface / package / type variable
83 */
84 public TypeSymbol tsym;
86 /**
87 * The constant value of this type, null if this type does not
88 * have a constant value attribute. Only primitive types and
89 * strings (ClassType) can have a constant value attribute.
90 * @return the constant value attribute of this type
91 */
92 public Object constValue() {
93 return null;
94 }
96 public <R,S> R accept(Type.Visitor<R,S> v, S s) { return v.visitType(this, s); }
98 /** Define a type given its tag and type symbol
99 */
100 public Type(int tag, TypeSymbol tsym) {
101 this.tag = tag;
102 this.tsym = tsym;
103 }
105 /** An abstract class for mappings from types to types
106 */
107 public static abstract class Mapping {
108 private String name;
109 public Mapping(String name) {
110 this.name = name;
111 }
112 public abstract Type apply(Type t);
113 public String toString() {
114 return name;
115 }
116 }
118 /** map a type function over all immediate descendants of this type
119 */
120 public Type map(Mapping f) {
121 return this;
122 }
124 /** map a type function over a list of types
125 */
126 public static List<Type> map(List<Type> ts, Mapping f) {
127 if (ts.nonEmpty()) {
128 List<Type> tail1 = map(ts.tail, f);
129 Type t = f.apply(ts.head);
130 if (tail1 != ts.tail || t != ts.head)
131 return tail1.prepend(t);
132 }
133 return ts;
134 }
136 /** Define a constant type, of the same kind as this type
137 * and with given constant value
138 */
139 public Type constType(Object constValue) {
140 final Object value = constValue;
141 Assert.check(tag <= BOOLEAN);
142 return new Type(tag, tsym) {
143 @Override
144 public Object constValue() {
145 return value;
146 }
147 @Override
148 public Type baseType() {
149 return tsym.type;
150 }
151 };
152 }
154 /**
155 * If this is a constant type, return its underlying type.
156 * Otherwise, return the type itself.
157 */
158 public Type baseType() {
159 return this;
160 }
162 /** Return the base types of a list of types.
163 */
164 public static List<Type> baseTypes(List<Type> ts) {
165 if (ts.nonEmpty()) {
166 Type t = ts.head.baseType();
167 List<Type> baseTypes = baseTypes(ts.tail);
168 if (t != ts.head || baseTypes != ts.tail)
169 return baseTypes.prepend(t);
170 }
171 return ts;
172 }
174 /** The Java source which this type represents.
175 */
176 public String toString() {
177 String s = (tsym == null || tsym.name == null)
178 ? "<none>"
179 : tsym.name.toString();
180 if (moreInfo && tag == TYPEVAR) s = s + hashCode();
181 return s;
182 }
184 /**
185 * The Java source which this type list represents. A List is
186 * represented as a comma-spearated listing of the elements in
187 * that list.
188 */
189 public static String toString(List<Type> ts) {
190 if (ts.isEmpty()) {
191 return "";
192 } else {
193 StringBuffer buf = new StringBuffer();
194 buf.append(ts.head.toString());
195 for (List<Type> l = ts.tail; l.nonEmpty(); l = l.tail)
196 buf.append(",").append(l.head.toString());
197 return buf.toString();
198 }
199 }
201 /**
202 * The constant value of this type, converted to String
203 */
204 public String stringValue() {
205 Object cv = Assert.checkNonNull(constValue());
206 if (tag == BOOLEAN)
207 return ((Integer) cv).intValue() == 0 ? "false" : "true";
208 else if (tag == CHAR)
209 return String.valueOf((char) ((Integer) cv).intValue());
210 else
211 return cv.toString();
212 }
214 /**
215 * This method is analogous to isSameType, but weaker, since we
216 * never complete classes. Where isSameType would complete a
217 * class, equals assumes that the two types are different.
218 */
219 public boolean equals(Object t) {
220 return super.equals(t);
221 }
223 public int hashCode() {
224 return super.hashCode();
225 }
227 /** Is this a constant type whose value is false?
228 */
229 public boolean isFalse() {
230 return
231 tag == BOOLEAN &&
232 constValue() != null &&
233 ((Integer)constValue()).intValue() == 0;
234 }
236 /** Is this a constant type whose value is true?
237 */
238 public boolean isTrue() {
239 return
240 tag == BOOLEAN &&
241 constValue() != null &&
242 ((Integer)constValue()).intValue() != 0;
243 }
245 public String argtypes(boolean varargs) {
246 List<Type> args = getParameterTypes();
247 if (!varargs) return args.toString();
248 StringBuilder buf = new StringBuilder();
249 while (args.tail.nonEmpty()) {
250 buf.append(args.head);
251 args = args.tail;
252 buf.append(',');
253 }
254 if (args.head.tag == ARRAY) {
255 buf.append(((ArrayType)args.head).elemtype);
256 buf.append("...");
257 } else {
258 buf.append(args.head);
259 }
260 return buf.toString();
261 }
263 /** Access methods.
264 */
265 public List<Type> getTypeArguments() { return List.nil(); }
266 public Type getEnclosingType() { return null; }
267 public List<Type> getParameterTypes() { return List.nil(); }
268 public Type getReturnType() { return null; }
269 public List<Type> getThrownTypes() { return List.nil(); }
270 public Type getUpperBound() { return null; }
271 public Type getLowerBound() { return null; }
273 /** Navigation methods, these will work for classes, type variables,
274 * foralls, but will return null for arrays and methods.
275 */
277 /** Return all parameters of this type and all its outer types in order
278 * outer (first) to inner (last).
279 */
280 public List<Type> allparams() { return List.nil(); }
282 /** Does this type contain "error" elements?
283 */
284 public boolean isErroneous() {
285 return false;
286 }
288 public static boolean isErroneous(List<Type> ts) {
289 for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
290 if (l.head.isErroneous()) return true;
291 return false;
292 }
294 /** Is this type parameterized?
295 * A class type is parameterized if it has some parameters.
296 * An array type is parameterized if its element type is parameterized.
297 * All other types are not parameterized.
298 */
299 public boolean isParameterized() {
300 return false;
301 }
303 /** Is this type a raw type?
304 * A class type is a raw type if it misses some of its parameters.
305 * An array type is a raw type if its element type is raw.
306 * All other types are not raw.
307 * Type validation will ensure that the only raw types
308 * in a program are types that miss all their type variables.
309 */
310 public boolean isRaw() {
311 return false;
312 }
314 public boolean isCompound() {
315 return tsym.completer == null
316 // Compound types can't have a completer. Calling
317 // flags() will complete the symbol causing the
318 // compiler to load classes unnecessarily. This led
319 // to regression 6180021.
320 && (tsym.flags() & COMPOUND) != 0;
321 }
323 public boolean isInterface() {
324 return (tsym.flags() & INTERFACE) != 0;
325 }
327 public boolean isFinal() {
328 return (tsym.flags() & FINAL) != 0;
329 }
331 public boolean isPrimitive() {
332 return tag < VOID;
333 }
335 /**
336 * Does this type contain occurrences of type t?
337 */
338 public boolean contains(Type t) {
339 return t == this;
340 }
342 public static boolean contains(List<Type> ts, Type t) {
343 for (List<Type> l = ts;
344 l.tail != null /*inlined: l.nonEmpty()*/;
345 l = l.tail)
346 if (l.head.contains(t)) return true;
347 return false;
348 }
350 /** Does this type contain an occurrence of some type in 'ts'?
351 */
352 public boolean containsAny(List<Type> ts) {
353 for (Type t : ts)
354 if (this.contains(t)) return true;
355 return false;
356 }
358 public static boolean containsAny(List<Type> ts1, List<Type> ts2) {
359 for (Type t : ts1)
360 if (t.containsAny(ts2)) return true;
361 return false;
362 }
364 public static List<Type> filter(List<Type> ts, Filter<Type> tf) {
365 ListBuffer<Type> buf = ListBuffer.lb();
366 for (Type t : ts) {
367 if (tf.accepts(t)) {
368 buf.append(t);
369 }
370 }
371 return buf.toList();
372 }
374 public boolean isSuperBound() { return false; }
375 public boolean isExtendsBound() { return false; }
376 public boolean isUnbound() { return false; }
377 public Type withTypeVar(Type t) { return this; }
379 /** The underlying method type of this type.
380 */
381 public MethodType asMethodType() { throw new AssertionError(); }
383 /** Complete loading all classes in this type.
384 */
385 public void complete() {}
387 public TypeSymbol asElement() {
388 return tsym;
389 }
391 public TypeKind getKind() {
392 switch (tag) {
393 case BYTE: return TypeKind.BYTE;
394 case CHAR: return TypeKind.CHAR;
395 case SHORT: return TypeKind.SHORT;
396 case INT: return TypeKind.INT;
397 case LONG: return TypeKind.LONG;
398 case FLOAT: return TypeKind.FLOAT;
399 case DOUBLE: return TypeKind.DOUBLE;
400 case BOOLEAN: return TypeKind.BOOLEAN;
401 case VOID: return TypeKind.VOID;
402 case BOT: return TypeKind.NULL;
403 case NONE: return TypeKind.NONE;
404 default: return TypeKind.OTHER;
405 }
406 }
408 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
409 if (isPrimitive())
410 return v.visitPrimitive(this, p);
411 else
412 throw new AssertionError();
413 }
415 public static class WildcardType extends Type
416 implements javax.lang.model.type.WildcardType {
418 public Type type;
419 public BoundKind kind;
420 public TypeVar bound;
422 @Override
423 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
424 return v.visitWildcardType(this, s);
425 }
427 public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) {
428 super(WILDCARD, tsym);
429 this.type = Assert.checkNonNull(type);
430 this.kind = kind;
431 }
432 public WildcardType(WildcardType t, TypeVar bound) {
433 this(t.type, t.kind, t.tsym, bound);
434 }
436 public WildcardType(Type type, BoundKind kind, TypeSymbol tsym, TypeVar bound) {
437 this(type, kind, tsym);
438 this.bound = bound;
439 }
441 public boolean contains(Type t) {
442 return kind != UNBOUND && type.contains(t);
443 }
445 public boolean isSuperBound() {
446 return kind == SUPER ||
447 kind == UNBOUND;
448 }
449 public boolean isExtendsBound() {
450 return kind == EXTENDS ||
451 kind == UNBOUND;
452 }
453 public boolean isUnbound() {
454 return kind == UNBOUND;
455 }
457 public Type withTypeVar(Type t) {
458 //-System.err.println(this+".withTypeVar("+t+");");//DEBUG
459 if (bound == t)
460 return this;
461 bound = (TypeVar)t;
462 return this;
463 }
465 boolean isPrintingBound = false;
466 public String toString() {
467 StringBuffer s = new StringBuffer();
468 s.append(kind.toString());
469 if (kind != UNBOUND)
470 s.append(type);
471 if (moreInfo && bound != null && !isPrintingBound)
472 try {
473 isPrintingBound = true;
474 s.append("{:").append(bound.bound).append(":}");
475 } finally {
476 isPrintingBound = false;
477 }
478 return s.toString();
479 }
481 public Type map(Mapping f) {
482 //- System.err.println(" (" + this + ").map(" + f + ")");//DEBUG
483 Type t = type;
484 if (t != null)
485 t = f.apply(t);
486 if (t == type)
487 return this;
488 else
489 return new WildcardType(t, kind, tsym, bound);
490 }
492 public Type getExtendsBound() {
493 if (kind == EXTENDS)
494 return type;
495 else
496 return null;
497 }
499 public Type getSuperBound() {
500 if (kind == SUPER)
501 return type;
502 else
503 return null;
504 }
506 public TypeKind getKind() {
507 return TypeKind.WILDCARD;
508 }
510 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
511 return v.visitWildcard(this, p);
512 }
513 }
515 public static class ClassType extends Type implements DeclaredType {
517 /** The enclosing type of this type. If this is the type of an inner
518 * class, outer_field refers to the type of its enclosing
519 * instance class, in all other cases it referes to noType.
520 */
521 private Type outer_field;
523 /** The type parameters of this type (to be set once class is loaded).
524 */
525 public List<Type> typarams_field;
527 /** A cache variable for the type parameters of this type,
528 * appended to all parameters of its enclosing class.
529 * @see #allparams
530 */
531 public List<Type> allparams_field;
533 /** The supertype of this class (to be set once class is loaded).
534 */
535 public Type supertype_field;
537 /** The interfaces of this class (to be set once class is loaded).
538 */
539 public List<Type> interfaces_field;
541 public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
542 super(CLASS, tsym);
543 this.outer_field = outer;
544 this.typarams_field = typarams;
545 this.allparams_field = null;
546 this.supertype_field = null;
547 this.interfaces_field = null;
548 /*
549 // this can happen during error recovery
550 assert
551 outer.isParameterized() ?
552 typarams.length() == tsym.type.typarams().length() :
553 outer.isRaw() ?
554 typarams.length() == 0 :
555 true;
556 */
557 }
559 @Override
560 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
561 return v.visitClassType(this, s);
562 }
564 public Type constType(Object constValue) {
565 final Object value = constValue;
566 return new ClassType(getEnclosingType(), typarams_field, tsym) {
567 @Override
568 public Object constValue() {
569 return value;
570 }
571 @Override
572 public Type baseType() {
573 return tsym.type;
574 }
575 };
576 }
578 /** The Java source which this type represents.
579 */
580 public String toString() {
581 StringBuffer buf = new StringBuffer();
582 if (getEnclosingType().tag == CLASS && tsym.owner.kind == TYP) {
583 buf.append(getEnclosingType().toString());
584 buf.append(".");
585 buf.append(className(tsym, false));
586 } else {
587 buf.append(className(tsym, true));
588 }
589 if (getTypeArguments().nonEmpty()) {
590 buf.append('<');
591 buf.append(getTypeArguments().toString());
592 buf.append(">");
593 }
594 return buf.toString();
595 }
596 //where
597 private String className(Symbol sym, boolean longform) {
598 if (sym.name.isEmpty() && (sym.flags() & COMPOUND) != 0) {
599 StringBuffer s = new StringBuffer(supertype_field.toString());
600 for (List<Type> is=interfaces_field; is.nonEmpty(); is = is.tail) {
601 s.append("&");
602 s.append(is.head.toString());
603 }
604 return s.toString();
605 } else if (sym.name.isEmpty()) {
606 String s;
607 ClassType norm = (ClassType) tsym.type;
608 if (norm == null) {
609 s = Log.getLocalizedString("anonymous.class", (Object)null);
610 } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
611 s = Log.getLocalizedString("anonymous.class",
612 norm.interfaces_field.head);
613 } else {
614 s = Log.getLocalizedString("anonymous.class",
615 norm.supertype_field);
616 }
617 if (moreInfo)
618 s += String.valueOf(sym.hashCode());
619 return s;
620 } else if (longform) {
621 return sym.getQualifiedName().toString();
622 } else {
623 return sym.name.toString();
624 }
625 }
627 public List<Type> getTypeArguments() {
628 if (typarams_field == null) {
629 complete();
630 if (typarams_field == null)
631 typarams_field = List.nil();
632 }
633 return typarams_field;
634 }
636 public boolean hasErasedSupertypes() {
637 return isRaw();
638 }
640 public Type getEnclosingType() {
641 return outer_field;
642 }
644 public void setEnclosingType(Type outer) {
645 outer_field = outer;
646 }
648 public List<Type> allparams() {
649 if (allparams_field == null) {
650 allparams_field = getTypeArguments().prependList(getEnclosingType().allparams());
651 }
652 return allparams_field;
653 }
655 public boolean isErroneous() {
656 return
657 getEnclosingType().isErroneous() ||
658 isErroneous(getTypeArguments()) ||
659 this != tsym.type && tsym.type.isErroneous();
660 }
662 public boolean isParameterized() {
663 return allparams().tail != null;
664 // optimization, was: allparams().nonEmpty();
665 }
667 /** A cache for the rank. */
668 int rank_field = -1;
670 /** A class type is raw if it misses some
671 * of its type parameter sections.
672 * After validation, this is equivalent to:
673 * allparams.isEmpty() && tsym.type.allparams.nonEmpty();
674 */
675 public boolean isRaw() {
676 return
677 this != tsym.type && // necessary, but not sufficient condition
678 tsym.type.allparams().nonEmpty() &&
679 allparams().isEmpty();
680 }
682 public Type map(Mapping f) {
683 Type outer = getEnclosingType();
684 Type outer1 = f.apply(outer);
685 List<Type> typarams = getTypeArguments();
686 List<Type> typarams1 = map(typarams, f);
687 if (outer1 == outer && typarams1 == typarams) return this;
688 else return new ClassType(outer1, typarams1, tsym);
689 }
691 public boolean contains(Type elem) {
692 return
693 elem == this
694 || (isParameterized()
695 && (getEnclosingType().contains(elem) || contains(getTypeArguments(), elem)))
696 || (isCompound()
697 && (supertype_field.contains(elem) || contains(interfaces_field, elem)));
698 }
700 public void complete() {
701 if (tsym.completer != null) tsym.complete();
702 }
704 public TypeKind getKind() {
705 return TypeKind.DECLARED;
706 }
708 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
709 return v.visitDeclared(this, p);
710 }
711 }
713 public static class ErasedClassType extends ClassType {
714 public ErasedClassType(Type outer, TypeSymbol tsym) {
715 super(outer, List.<Type>nil(), tsym);
716 }
718 @Override
719 public boolean hasErasedSupertypes() {
720 return true;
721 }
722 }
724 public static class ArrayType extends Type
725 implements javax.lang.model.type.ArrayType {
727 public Type elemtype;
729 public ArrayType(Type elemtype, TypeSymbol arrayClass) {
730 super(ARRAY, arrayClass);
731 this.elemtype = elemtype;
732 }
734 @Override
735 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
736 return v.visitArrayType(this, s);
737 }
739 public String toString() {
740 return elemtype + "[]";
741 }
743 public boolean equals(Object obj) {
744 return
745 this == obj ||
746 (obj instanceof ArrayType &&
747 this.elemtype.equals(((ArrayType)obj).elemtype));
748 }
750 public int hashCode() {
751 return (ARRAY << 5) + elemtype.hashCode();
752 }
754 public boolean isVarargs() {
755 return false;
756 }
758 public List<Type> allparams() { return elemtype.allparams(); }
760 public boolean isErroneous() {
761 return elemtype.isErroneous();
762 }
764 public boolean isParameterized() {
765 return elemtype.isParameterized();
766 }
768 public boolean isRaw() {
769 return elemtype.isRaw();
770 }
772 public ArrayType makeVarargs() {
773 return new ArrayType(elemtype, tsym) {
774 @Override
775 public boolean isVarargs() {
776 return true;
777 }
778 };
779 }
781 public Type map(Mapping f) {
782 Type elemtype1 = f.apply(elemtype);
783 if (elemtype1 == elemtype) return this;
784 else return new ArrayType(elemtype1, tsym);
785 }
787 public boolean contains(Type elem) {
788 return elem == this || elemtype.contains(elem);
789 }
791 public void complete() {
792 elemtype.complete();
793 }
795 public Type getComponentType() {
796 return elemtype;
797 }
799 public TypeKind getKind() {
800 return TypeKind.ARRAY;
801 }
803 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
804 return v.visitArray(this, p);
805 }
806 }
808 public static class MethodType extends Type implements ExecutableType {
810 public List<Type> argtypes;
811 public Type restype;
812 public List<Type> thrown;
814 public MethodType(List<Type> argtypes,
815 Type restype,
816 List<Type> thrown,
817 TypeSymbol methodClass) {
818 super(METHOD, methodClass);
819 this.argtypes = argtypes;
820 this.restype = restype;
821 this.thrown = thrown;
822 }
824 @Override
825 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
826 return v.visitMethodType(this, s);
827 }
829 /** The Java source which this type represents.
830 *
831 * XXX 06/09/99 iris This isn't correct Java syntax, but it probably
832 * should be.
833 */
834 public String toString() {
835 return "(" + argtypes + ")" + restype;
836 }
838 public boolean equals(Object obj) {
839 if (this == obj)
840 return true;
841 if (!(obj instanceof MethodType))
842 return false;
843 MethodType m = (MethodType)obj;
844 List<Type> args1 = argtypes;
845 List<Type> args2 = m.argtypes;
846 while (!args1.isEmpty() && !args2.isEmpty()) {
847 if (!args1.head.equals(args2.head))
848 return false;
849 args1 = args1.tail;
850 args2 = args2.tail;
851 }
852 if (!args1.isEmpty() || !args2.isEmpty())
853 return false;
854 return restype.equals(m.restype);
855 }
857 public int hashCode() {
858 int h = METHOD;
859 for (List<Type> thisargs = this.argtypes;
860 thisargs.tail != null; /*inlined: thisargs.nonEmpty()*/
861 thisargs = thisargs.tail)
862 h = (h << 5) + thisargs.head.hashCode();
863 return (h << 5) + this.restype.hashCode();
864 }
866 public List<Type> getParameterTypes() { return argtypes; }
867 public Type getReturnType() { return restype; }
868 public List<Type> getThrownTypes() { return thrown; }
870 public boolean isErroneous() {
871 return
872 isErroneous(argtypes) ||
873 restype != null && restype.isErroneous();
874 }
876 public Type map(Mapping f) {
877 List<Type> argtypes1 = map(argtypes, f);
878 Type restype1 = f.apply(restype);
879 List<Type> thrown1 = map(thrown, f);
880 if (argtypes1 == argtypes &&
881 restype1 == restype &&
882 thrown1 == thrown) return this;
883 else return new MethodType(argtypes1, restype1, thrown1, tsym);
884 }
886 public boolean contains(Type elem) {
887 return elem == this || contains(argtypes, elem) || restype.contains(elem);
888 }
890 public MethodType asMethodType() { return this; }
892 public void complete() {
893 for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
894 l.head.complete();
895 restype.complete();
896 for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
897 l.head.complete();
898 }
900 public List<TypeVar> getTypeVariables() {
901 return List.nil();
902 }
904 public TypeSymbol asElement() {
905 return null;
906 }
908 public TypeKind getKind() {
909 return TypeKind.EXECUTABLE;
910 }
912 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
913 return v.visitExecutable(this, p);
914 }
915 }
917 public static class PackageType extends Type implements NoType {
919 PackageType(TypeSymbol tsym) {
920 super(PACKAGE, tsym);
921 }
923 @Override
924 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
925 return v.visitPackageType(this, s);
926 }
928 public String toString() {
929 return tsym.getQualifiedName().toString();
930 }
932 public TypeKind getKind() {
933 return TypeKind.PACKAGE;
934 }
936 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
937 return v.visitNoType(this, p);
938 }
939 }
941 public static class TypeVar extends Type implements TypeVariable {
943 /** The upper bound of this type variable; set from outside.
944 * Must be nonempty once it is set.
945 * For a bound, `bound' is the bound type itself.
946 * Multiple bounds are expressed as a single class type which has the
947 * individual bounds as superclass, respectively interfaces.
948 * The class type then has as `tsym' a compiler generated class `c',
949 * which has a flag COMPOUND and whose owner is the type variable
950 * itself. Furthermore, the erasure_field of the class
951 * points to the first class or interface bound.
952 */
953 public Type bound = null;
955 /** The lower bound of this type variable.
956 * TypeVars don't normally have a lower bound, so it is normally set
957 * to syms.botType.
958 * Subtypes, such as CapturedType, may provide a different value.
959 */
960 public Type lower;
962 public TypeVar(Name name, Symbol owner, Type lower) {
963 super(TYPEVAR, null);
964 tsym = new TypeSymbol(0, name, this, owner);
965 this.lower = lower;
966 }
968 public TypeVar(TypeSymbol tsym, Type bound, Type lower) {
969 super(TYPEVAR, tsym);
970 this.bound = bound;
971 this.lower = lower;
972 }
974 @Override
975 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
976 return v.visitTypeVar(this, s);
977 }
979 @Override
980 public Type getUpperBound() { return bound; }
982 int rank_field = -1;
984 @Override
985 public Type getLowerBound() {
986 return lower;
987 }
989 public TypeKind getKind() {
990 return TypeKind.TYPEVAR;
991 }
993 public boolean isCaptured() {
994 return false;
995 }
997 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
998 return v.visitTypeVariable(this, p);
999 }
1000 }
1002 /** A captured type variable comes from wildcards which can have
1003 * both upper and lower bound. CapturedType extends TypeVar with
1004 * a lower bound.
1005 */
1006 public static class CapturedType extends TypeVar {
1008 public WildcardType wildcard;
1010 public CapturedType(Name name,
1011 Symbol owner,
1012 Type upper,
1013 Type lower,
1014 WildcardType wildcard) {
1015 super(name, owner, lower);
1016 this.lower = Assert.checkNonNull(lower);
1017 this.bound = upper;
1018 this.wildcard = wildcard;
1019 }
1021 @Override
1022 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1023 return v.visitCapturedType(this, s);
1024 }
1026 @Override
1027 public boolean isCaptured() {
1028 return true;
1029 }
1031 @Override
1032 public String toString() {
1033 return "capture#"
1034 + (hashCode() & 0xFFFFFFFFL) % Printer.PRIME
1035 + " of "
1036 + wildcard;
1037 }
1038 }
1040 public static abstract class DelegatedType extends Type {
1041 public Type qtype;
1042 public DelegatedType(int tag, Type qtype) {
1043 super(tag, qtype.tsym);
1044 this.qtype = qtype;
1045 }
1046 public String toString() { return qtype.toString(); }
1047 public List<Type> getTypeArguments() { return qtype.getTypeArguments(); }
1048 public Type getEnclosingType() { return qtype.getEnclosingType(); }
1049 public List<Type> getParameterTypes() { return qtype.getParameterTypes(); }
1050 public Type getReturnType() { return qtype.getReturnType(); }
1051 public List<Type> getThrownTypes() { return qtype.getThrownTypes(); }
1052 public List<Type> allparams() { return qtype.allparams(); }
1053 public Type getUpperBound() { return qtype.getUpperBound(); }
1054 public boolean isErroneous() { return qtype.isErroneous(); }
1055 }
1057 public static class ForAll extends DelegatedType implements ExecutableType {
1058 public List<Type> tvars;
1060 public ForAll(List<Type> tvars, Type qtype) {
1061 super(FORALL, qtype);
1062 this.tvars = tvars;
1063 }
1065 @Override
1066 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1067 return v.visitForAll(this, s);
1068 }
1070 public String toString() {
1071 return "<" + tvars + ">" + qtype;
1072 }
1074 public List<Type> getTypeArguments() { return tvars; }
1076 public boolean isErroneous() {
1077 return qtype.isErroneous();
1078 }
1080 /**
1081 * Replaces this ForAll's typevars with a set of concrete Java types
1082 * and returns the instantiated generic type. Subclasses should override
1083 * in order to check that the list of types is a valid instantiation
1084 * of the ForAll's typevars.
1085 *
1086 * @param actuals list of actual types
1087 * @param types types instance
1088 * @return qtype where all occurrences of tvars are replaced
1089 * by types in actuals
1090 */
1091 public Type inst(List<Type> actuals, Types types) {
1092 return types.subst(qtype, tvars, actuals);
1093 }
1095 /**
1096 * Kind of type-constraint derived during type inference
1097 */
1098 public enum ConstraintKind {
1099 /**
1100 * upper bound constraint (a type variable must be instantiated
1101 * with a type T, where T is a subtype of all the types specified by
1102 * its EXTENDS constraints).
1103 */
1104 EXTENDS,
1105 /**
1106 * lower bound constraint (a type variable must be instantiated
1107 * with a type T, where T is a supertype of all the types specified by
1108 * its SUPER constraints).
1109 */
1110 SUPER,
1111 /**
1112 * equality constraint (a type variable must be instantiated to the type
1113 * specified by its EQUAL constraint.
1114 */
1115 EQUAL;
1116 }
1118 /**
1119 * Get the type-constraints of a given kind for a given type-variable of
1120 * this ForAll type. Subclasses should override in order to return more
1121 * accurate sets of constraints.
1122 *
1123 * @param tv the type-variable for which the constraint is to be retrieved
1124 * @param ck the constraint kind to be retrieved
1125 * @return the list of types specified by the selected constraint
1126 */
1127 public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
1128 return List.nil();
1129 }
1131 public Type map(Mapping f) {
1132 return f.apply(qtype);
1133 }
1135 public boolean contains(Type elem) {
1136 return qtype.contains(elem);
1137 }
1139 public MethodType asMethodType() {
1140 return qtype.asMethodType();
1141 }
1143 public void complete() {
1144 for (List<Type> l = tvars; l.nonEmpty(); l = l.tail) {
1145 ((TypeVar)l.head).bound.complete();
1146 }
1147 qtype.complete();
1148 }
1150 public List<TypeVar> getTypeVariables() {
1151 return List.convert(TypeVar.class, getTypeArguments());
1152 }
1154 public TypeKind getKind() {
1155 return TypeKind.EXECUTABLE;
1156 }
1158 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1159 return v.visitExecutable(this, p);
1160 }
1161 }
1163 /** A class for instantiatable variables, for use during type
1164 * inference.
1165 */
1166 public static class UndetVar extends DelegatedType {
1167 public List<Type> lobounds = List.nil();
1168 public List<Type> hibounds = List.nil();
1169 public Type inst = null;
1171 @Override
1172 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1173 return v.visitUndetVar(this, s);
1174 }
1176 public UndetVar(Type origin) {
1177 super(UNDETVAR, origin);
1178 }
1180 public String toString() {
1181 if (inst != null) return inst.toString();
1182 else return qtype + "?";
1183 }
1185 public Type baseType() {
1186 if (inst != null) return inst.baseType();
1187 else return this;
1188 }
1189 }
1191 /** Represents VOID or NONE.
1192 */
1193 static class JCNoType extends Type implements NoType {
1194 public JCNoType(int tag) {
1195 super(tag, null);
1196 }
1198 @Override
1199 public TypeKind getKind() {
1200 switch (tag) {
1201 case VOID: return TypeKind.VOID;
1202 case NONE: return TypeKind.NONE;
1203 default:
1204 throw new AssertionError("Unexpected tag: " + tag);
1205 }
1206 }
1208 @Override
1209 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1210 return v.visitNoType(this, p);
1211 }
1212 }
1214 static class BottomType extends Type implements NullType {
1215 public BottomType() {
1216 super(TypeTags.BOT, null);
1217 }
1219 @Override
1220 public TypeKind getKind() {
1221 return TypeKind.NULL;
1222 }
1224 @Override
1225 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1226 return v.visitNull(this, p);
1227 }
1229 @Override
1230 public Type constType(Object value) {
1231 return this;
1232 }
1234 @Override
1235 public String stringValue() {
1236 return "null";
1237 }
1238 }
1240 public static class ErrorType extends ClassType
1241 implements javax.lang.model.type.ErrorType {
1243 private Type originalType = null;
1245 public ErrorType(Type originalType, TypeSymbol tsym) {
1246 super(noType, List.<Type>nil(), null);
1247 tag = ERROR;
1248 this.tsym = tsym;
1249 this.originalType = (originalType == null ? noType : originalType);
1250 }
1252 public ErrorType(ClassSymbol c, Type originalType) {
1253 this(originalType, c);
1254 c.type = this;
1255 c.kind = ERR;
1256 c.members_field = new Scope.ErrorScope(c);
1257 }
1259 public ErrorType(Name name, TypeSymbol container, Type originalType) {
1260 this(new ClassSymbol(PUBLIC|STATIC|ACYCLIC, name, null, container), originalType);
1261 }
1263 @Override
1264 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1265 return v.visitErrorType(this, s);
1266 }
1268 public Type constType(Object constValue) { return this; }
1269 public Type getEnclosingType() { return this; }
1270 public Type getReturnType() { return this; }
1271 public Type asSub(Symbol sym) { return this; }
1272 public Type map(Mapping f) { return this; }
1274 public boolean isGenType(Type t) { return true; }
1275 public boolean isErroneous() { return true; }
1276 public boolean isCompound() { return false; }
1277 public boolean isInterface() { return false; }
1279 public List<Type> allparams() { return List.nil(); }
1280 public List<Type> getTypeArguments() { return List.nil(); }
1282 public TypeKind getKind() {
1283 return TypeKind.ERROR;
1284 }
1286 public Type getOriginalType() {
1287 return originalType;
1288 }
1290 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1291 return v.visitError(this, p);
1292 }
1293 }
1295 /**
1296 * A visitor for types. A visitor is used to implement operations
1297 * (or relations) on types. Most common operations on types are
1298 * binary relations and this interface is designed for binary
1299 * relations, that is, operations on the form
1300 * Type × S → R.
1301 * <!-- In plain text: Type x S -> R -->
1302 *
1303 * @param <R> the return type of the operation implemented by this
1304 * visitor; use Void if no return type is needed.
1305 * @param <S> the type of the second argument (the first being the
1306 * type itself) of the operation implemented by this visitor; use
1307 * Void if a second argument is not needed.
1308 */
1309 public interface Visitor<R,S> {
1310 R visitClassType(ClassType t, S s);
1311 R visitWildcardType(WildcardType t, S s);
1312 R visitArrayType(ArrayType t, S s);
1313 R visitMethodType(MethodType t, S s);
1314 R visitPackageType(PackageType t, S s);
1315 R visitTypeVar(TypeVar t, S s);
1316 R visitCapturedType(CapturedType t, S s);
1317 R visitForAll(ForAll t, S s);
1318 R visitUndetVar(UndetVar t, S s);
1319 R visitErrorType(ErrorType t, S s);
1320 R visitType(Type t, S s);
1321 }
1322 }