Fri, 28 Sep 2012 16:56:53 +0100
8000233: Fix issues in recent push
Summary: Forgot to incorporate review comments in pushed changesets
Reviewed-by: jjg
1 /*
2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.tools.javac.code;
28 import java.util.Collections;
30 import com.sun.tools.javac.code.Symbol.*;
31 import com.sun.tools.javac.util.*;
33 import java.util.EnumMap;
34 import java.util.EnumSet;
35 import java.util.Map;
36 import java.util.Set;
38 import javax.lang.model.type.*;
40 import static com.sun.tools.javac.code.BoundKind.*;
41 import static com.sun.tools.javac.code.Flags.*;
42 import static com.sun.tools.javac.code.Kinds.*;
43 import static com.sun.tools.javac.code.TypeTags.*;
45 /** This class represents Java types. The class itself defines the behavior of
46 * the following types:
47 * <pre>
48 * base types (tags: BYTE, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, BOOLEAN),
49 * type `void' (tag: VOID),
50 * the bottom type (tag: BOT),
51 * the missing type (tag: NONE).
52 * </pre>
53 * <p>The behavior of the following types is defined in subclasses, which are
54 * all static inner classes of this class:
55 * <pre>
56 * class types (tag: CLASS, class: ClassType),
57 * array types (tag: ARRAY, class: ArrayType),
58 * method types (tag: METHOD, class: MethodType),
59 * package types (tag: PACKAGE, class: PackageType),
60 * type variables (tag: TYPEVAR, class: TypeVar),
61 * type arguments (tag: WILDCARD, class: WildcardType),
62 * generic method types (tag: FORALL, class: ForAll),
63 * the error type (tag: ERROR, class: ErrorType).
64 * </pre>
65 *
66 * <p><b>This is NOT part of any supported API.
67 * If you write code that depends on this, you do so at your own risk.
68 * This code and its internal interfaces are subject to change or
69 * deletion without notice.</b>
70 *
71 * @see TypeTags
72 */
73 public class Type implements PrimitiveType {
75 /** Constant type: no type at all. */
76 public static final JCNoType noType = new JCNoType(NONE);
78 /** If this switch is turned on, the names of type variables
79 * and anonymous classes are printed with hashcodes appended.
80 */
81 public static boolean moreInfo = false;
83 /** The tag of this type.
84 *
85 * @see TypeTags
86 */
87 public int tag;
89 /** The defining class / interface / package / type variable
90 */
91 public TypeSymbol tsym;
93 /**
94 * The constant value of this type, null if this type does not
95 * have a constant value attribute. Only primitive types and
96 * strings (ClassType) can have a constant value attribute.
97 * @return the constant value attribute of this type
98 */
99 public Object constValue() {
100 return null;
101 }
103 /**
104 * Get the representation of this type used for modelling purposes.
105 * By default, this is itself. For ErrorType, a different value
106 * may be provided,
107 */
108 public Type getModelType() {
109 return this;
110 }
112 public static List<Type> getModelTypes(List<Type> ts) {
113 ListBuffer<Type> lb = new ListBuffer<Type>();
114 for (Type t: ts)
115 lb.append(t.getModelType());
116 return lb.toList();
117 }
119 public <R,S> R accept(Type.Visitor<R,S> v, S s) { return v.visitType(this, s); }
121 /** Define a type given its tag and type symbol
122 */
123 public Type(int tag, TypeSymbol tsym) {
124 this.tag = tag;
125 this.tsym = tsym;
126 }
128 /** An abstract class for mappings from types to types
129 */
130 public static abstract class Mapping {
131 private String name;
132 public Mapping(String name) {
133 this.name = name;
134 }
135 public abstract Type apply(Type t);
136 public String toString() {
137 return name;
138 }
139 }
141 /** map a type function over all immediate descendants of this type
142 */
143 public Type map(Mapping f) {
144 return this;
145 }
147 /** map a type function over a list of types
148 */
149 public static List<Type> map(List<Type> ts, Mapping f) {
150 if (ts.nonEmpty()) {
151 List<Type> tail1 = map(ts.tail, f);
152 Type t = f.apply(ts.head);
153 if (tail1 != ts.tail || t != ts.head)
154 return tail1.prepend(t);
155 }
156 return ts;
157 }
159 /** Define a constant type, of the same kind as this type
160 * and with given constant value
161 */
162 public Type constType(Object constValue) {
163 final Object value = constValue;
164 Assert.check(tag <= BOOLEAN);
165 return new Type(tag, tsym) {
166 @Override
167 public Object constValue() {
168 return value;
169 }
170 @Override
171 public Type baseType() {
172 return tsym.type;
173 }
174 };
175 }
177 /**
178 * If this is a constant type, return its underlying type.
179 * Otherwise, return the type itself.
180 */
181 public Type baseType() {
182 return this;
183 }
185 /** Return the base types of a list of types.
186 */
187 public static List<Type> baseTypes(List<Type> ts) {
188 if (ts.nonEmpty()) {
189 Type t = ts.head.baseType();
190 List<Type> baseTypes = baseTypes(ts.tail);
191 if (t != ts.head || baseTypes != ts.tail)
192 return baseTypes.prepend(t);
193 }
194 return ts;
195 }
197 /** The Java source which this type represents.
198 */
199 public String toString() {
200 String s = (tsym == null || tsym.name == null)
201 ? "<none>"
202 : tsym.name.toString();
203 if (moreInfo && tag == TYPEVAR) s = s + hashCode();
204 return s;
205 }
207 /**
208 * The Java source which this type list represents. A List is
209 * represented as a comma-spearated listing of the elements in
210 * that list.
211 */
212 public static String toString(List<Type> ts) {
213 if (ts.isEmpty()) {
214 return "";
215 } else {
216 StringBuilder buf = new StringBuilder();
217 buf.append(ts.head.toString());
218 for (List<Type> l = ts.tail; l.nonEmpty(); l = l.tail)
219 buf.append(",").append(l.head.toString());
220 return buf.toString();
221 }
222 }
224 /**
225 * The constant value of this type, converted to String
226 */
227 public String stringValue() {
228 Object cv = Assert.checkNonNull(constValue());
229 if (tag == BOOLEAN)
230 return ((Integer) cv).intValue() == 0 ? "false" : "true";
231 else if (tag == CHAR)
232 return String.valueOf((char) ((Integer) cv).intValue());
233 else
234 return cv.toString();
235 }
237 /**
238 * This method is analogous to isSameType, but weaker, since we
239 * never complete classes. Where isSameType would complete a
240 * class, equals assumes that the two types are different.
241 */
242 public boolean equals(Object t) {
243 return super.equals(t);
244 }
246 public int hashCode() {
247 return super.hashCode();
248 }
250 /** Is this a constant type whose value is false?
251 */
252 public boolean isFalse() {
253 return
254 tag == BOOLEAN &&
255 constValue() != null &&
256 ((Integer)constValue()).intValue() == 0;
257 }
259 /** Is this a constant type whose value is true?
260 */
261 public boolean isTrue() {
262 return
263 tag == BOOLEAN &&
264 constValue() != null &&
265 ((Integer)constValue()).intValue() != 0;
266 }
268 public String argtypes(boolean varargs) {
269 List<Type> args = getParameterTypes();
270 if (!varargs) return args.toString();
271 StringBuilder buf = new StringBuilder();
272 while (args.tail.nonEmpty()) {
273 buf.append(args.head);
274 args = args.tail;
275 buf.append(',');
276 }
277 if (args.head.tag == ARRAY) {
278 buf.append(((ArrayType)args.head).elemtype);
279 buf.append("...");
280 } else {
281 buf.append(args.head);
282 }
283 return buf.toString();
284 }
286 /** Access methods.
287 */
288 public List<Type> getTypeArguments() { return List.nil(); }
289 public Type getEnclosingType() { return null; }
290 public List<Type> getParameterTypes() { return List.nil(); }
291 public Type getReturnType() { return null; }
292 public List<Type> getThrownTypes() { return List.nil(); }
293 public Type getUpperBound() { return null; }
294 public Type getLowerBound() { return null; }
296 /** Navigation methods, these will work for classes, type variables,
297 * foralls, but will return null for arrays and methods.
298 */
300 /** Return all parameters of this type and all its outer types in order
301 * outer (first) to inner (last).
302 */
303 public List<Type> allparams() { return List.nil(); }
305 /** Does this type contain "error" elements?
306 */
307 public boolean isErroneous() {
308 return false;
309 }
311 public static boolean isErroneous(List<Type> ts) {
312 for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
313 if (l.head.isErroneous()) return true;
314 return false;
315 }
317 /** Is this type parameterized?
318 * A class type is parameterized if it has some parameters.
319 * An array type is parameterized if its element type is parameterized.
320 * All other types are not parameterized.
321 */
322 public boolean isParameterized() {
323 return false;
324 }
326 /** Is this type a raw type?
327 * A class type is a raw type if it misses some of its parameters.
328 * An array type is a raw type if its element type is raw.
329 * All other types are not raw.
330 * Type validation will ensure that the only raw types
331 * in a program are types that miss all their type variables.
332 */
333 public boolean isRaw() {
334 return false;
335 }
337 public boolean isCompound() {
338 return tsym.completer == null
339 // Compound types can't have a completer. Calling
340 // flags() will complete the symbol causing the
341 // compiler to load classes unnecessarily. This led
342 // to regression 6180021.
343 && (tsym.flags() & COMPOUND) != 0;
344 }
346 public boolean isInterface() {
347 return (tsym.flags() & INTERFACE) != 0;
348 }
350 public boolean isFinal() {
351 return (tsym.flags() & FINAL) != 0;
352 }
354 public boolean isPrimitive() {
355 return tag < VOID;
356 }
358 /**
359 * Does this type contain occurrences of type t?
360 */
361 public boolean contains(Type t) {
362 return t == this;
363 }
365 public static boolean contains(List<Type> ts, Type t) {
366 for (List<Type> l = ts;
367 l.tail != null /*inlined: l.nonEmpty()*/;
368 l = l.tail)
369 if (l.head.contains(t)) return true;
370 return false;
371 }
373 /** Does this type contain an occurrence of some type in 'ts'?
374 */
375 public boolean containsAny(List<Type> ts) {
376 for (Type t : ts)
377 if (this.contains(t)) return true;
378 return false;
379 }
381 public static boolean containsAny(List<Type> ts1, List<Type> ts2) {
382 for (Type t : ts1)
383 if (t.containsAny(ts2)) return true;
384 return false;
385 }
387 public static List<Type> filter(List<Type> ts, Filter<Type> tf) {
388 ListBuffer<Type> buf = ListBuffer.lb();
389 for (Type t : ts) {
390 if (tf.accepts(t)) {
391 buf.append(t);
392 }
393 }
394 return buf.toList();
395 }
397 public boolean isSuperBound() { return false; }
398 public boolean isExtendsBound() { return false; }
399 public boolean isUnbound() { return false; }
400 public Type withTypeVar(Type t) { return this; }
402 /** The underlying method type of this type.
403 */
404 public MethodType asMethodType() { throw new AssertionError(); }
406 /** Complete loading all classes in this type.
407 */
408 public void complete() {}
410 public TypeSymbol asElement() {
411 return tsym;
412 }
414 public TypeKind getKind() {
415 switch (tag) {
416 case BYTE: return TypeKind.BYTE;
417 case CHAR: return TypeKind.CHAR;
418 case SHORT: return TypeKind.SHORT;
419 case INT: return TypeKind.INT;
420 case LONG: return TypeKind.LONG;
421 case FLOAT: return TypeKind.FLOAT;
422 case DOUBLE: return TypeKind.DOUBLE;
423 case BOOLEAN: return TypeKind.BOOLEAN;
424 case VOID: return TypeKind.VOID;
425 case BOT: return TypeKind.NULL;
426 case NONE: return TypeKind.NONE;
427 default: return TypeKind.OTHER;
428 }
429 }
431 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
432 if (isPrimitive())
433 return v.visitPrimitive(this, p);
434 else
435 throw new AssertionError();
436 }
438 public static class WildcardType extends Type
439 implements javax.lang.model.type.WildcardType {
441 public Type type;
442 public BoundKind kind;
443 public TypeVar bound;
445 @Override
446 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
447 return v.visitWildcardType(this, s);
448 }
450 public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) {
451 super(WILDCARD, tsym);
452 this.type = Assert.checkNonNull(type);
453 this.kind = kind;
454 }
455 public WildcardType(WildcardType t, TypeVar bound) {
456 this(t.type, t.kind, t.tsym, bound);
457 }
459 public WildcardType(Type type, BoundKind kind, TypeSymbol tsym, TypeVar bound) {
460 this(type, kind, tsym);
461 this.bound = bound;
462 }
464 public boolean contains(Type t) {
465 return kind != UNBOUND && type.contains(t);
466 }
468 public boolean isSuperBound() {
469 return kind == SUPER ||
470 kind == UNBOUND;
471 }
472 public boolean isExtendsBound() {
473 return kind == EXTENDS ||
474 kind == UNBOUND;
475 }
476 public boolean isUnbound() {
477 return kind == UNBOUND;
478 }
480 public Type withTypeVar(Type t) {
481 //-System.err.println(this+".withTypeVar("+t+");");//DEBUG
482 if (bound == t)
483 return this;
484 bound = (TypeVar)t;
485 return this;
486 }
488 boolean isPrintingBound = false;
489 public String toString() {
490 StringBuilder s = new StringBuilder();
491 s.append(kind.toString());
492 if (kind != UNBOUND)
493 s.append(type);
494 if (moreInfo && bound != null && !isPrintingBound)
495 try {
496 isPrintingBound = true;
497 s.append("{:").append(bound.bound).append(":}");
498 } finally {
499 isPrintingBound = false;
500 }
501 return s.toString();
502 }
504 public Type map(Mapping f) {
505 //- System.err.println(" (" + this + ").map(" + f + ")");//DEBUG
506 Type t = type;
507 if (t != null)
508 t = f.apply(t);
509 if (t == type)
510 return this;
511 else
512 return new WildcardType(t, kind, tsym, bound);
513 }
515 public Type getExtendsBound() {
516 if (kind == EXTENDS)
517 return type;
518 else
519 return null;
520 }
522 public Type getSuperBound() {
523 if (kind == SUPER)
524 return type;
525 else
526 return null;
527 }
529 public TypeKind getKind() {
530 return TypeKind.WILDCARD;
531 }
533 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
534 return v.visitWildcard(this, p);
535 }
536 }
538 public static class ClassType extends Type implements DeclaredType {
540 /** The enclosing type of this type. If this is the type of an inner
541 * class, outer_field refers to the type of its enclosing
542 * instance class, in all other cases it referes to noType.
543 */
544 private Type outer_field;
546 /** The type parameters of this type (to be set once class is loaded).
547 */
548 public List<Type> typarams_field;
550 /** A cache variable for the type parameters of this type,
551 * appended to all parameters of its enclosing class.
552 * @see #allparams
553 */
554 public List<Type> allparams_field;
556 /** The supertype of this class (to be set once class is loaded).
557 */
558 public Type supertype_field;
560 /** The interfaces of this class (to be set once class is loaded).
561 */
562 public List<Type> interfaces_field;
564 /** All the interfaces of this class, including missing ones.
565 */
566 public List<Type> all_interfaces_field;
568 public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
569 super(CLASS, tsym);
570 this.outer_field = outer;
571 this.typarams_field = typarams;
572 this.allparams_field = null;
573 this.supertype_field = null;
574 this.interfaces_field = null;
575 /*
576 // this can happen during error recovery
577 assert
578 outer.isParameterized() ?
579 typarams.length() == tsym.type.typarams().length() :
580 outer.isRaw() ?
581 typarams.length() == 0 :
582 true;
583 */
584 }
586 @Override
587 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
588 return v.visitClassType(this, s);
589 }
591 public Type constType(Object constValue) {
592 final Object value = constValue;
593 return new ClassType(getEnclosingType(), typarams_field, tsym) {
594 @Override
595 public Object constValue() {
596 return value;
597 }
598 @Override
599 public Type baseType() {
600 return tsym.type;
601 }
602 };
603 }
605 /** The Java source which this type represents.
606 */
607 public String toString() {
608 StringBuilder buf = new StringBuilder();
609 if (getEnclosingType().tag == CLASS && tsym.owner.kind == TYP) {
610 buf.append(getEnclosingType().toString());
611 buf.append(".");
612 buf.append(className(tsym, false));
613 } else {
614 buf.append(className(tsym, true));
615 }
616 if (getTypeArguments().nonEmpty()) {
617 buf.append('<');
618 buf.append(getTypeArguments().toString());
619 buf.append(">");
620 }
621 return buf.toString();
622 }
623 //where
624 private String className(Symbol sym, boolean longform) {
625 if (sym.name.isEmpty() && (sym.flags() & COMPOUND) != 0) {
626 StringBuilder s = new StringBuilder(supertype_field.toString());
627 for (List<Type> is=interfaces_field; is.nonEmpty(); is = is.tail) {
628 s.append("&");
629 s.append(is.head.toString());
630 }
631 return s.toString();
632 } else if (sym.name.isEmpty()) {
633 String s;
634 ClassType norm = (ClassType) tsym.type;
635 if (norm == null) {
636 s = Log.getLocalizedString("anonymous.class", (Object)null);
637 } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
638 s = Log.getLocalizedString("anonymous.class",
639 norm.interfaces_field.head);
640 } else {
641 s = Log.getLocalizedString("anonymous.class",
642 norm.supertype_field);
643 }
644 if (moreInfo)
645 s += String.valueOf(sym.hashCode());
646 return s;
647 } else if (longform) {
648 return sym.getQualifiedName().toString();
649 } else {
650 return sym.name.toString();
651 }
652 }
654 public List<Type> getTypeArguments() {
655 if (typarams_field == null) {
656 complete();
657 if (typarams_field == null)
658 typarams_field = List.nil();
659 }
660 return typarams_field;
661 }
663 public boolean hasErasedSupertypes() {
664 return isRaw();
665 }
667 public Type getEnclosingType() {
668 return outer_field;
669 }
671 public void setEnclosingType(Type outer) {
672 outer_field = outer;
673 }
675 public List<Type> allparams() {
676 if (allparams_field == null) {
677 allparams_field = getTypeArguments().prependList(getEnclosingType().allparams());
678 }
679 return allparams_field;
680 }
682 public boolean isErroneous() {
683 return
684 getEnclosingType().isErroneous() ||
685 isErroneous(getTypeArguments()) ||
686 this != tsym.type && tsym.type.isErroneous();
687 }
689 public boolean isParameterized() {
690 return allparams().tail != null;
691 // optimization, was: allparams().nonEmpty();
692 }
694 /** A cache for the rank. */
695 int rank_field = -1;
697 /** A class type is raw if it misses some
698 * of its type parameter sections.
699 * After validation, this is equivalent to:
700 * {@code allparams.isEmpty() && tsym.type.allparams.nonEmpty(); }
701 */
702 public boolean isRaw() {
703 return
704 this != tsym.type && // necessary, but not sufficient condition
705 tsym.type.allparams().nonEmpty() &&
706 allparams().isEmpty();
707 }
709 public Type map(Mapping f) {
710 Type outer = getEnclosingType();
711 Type outer1 = f.apply(outer);
712 List<Type> typarams = getTypeArguments();
713 List<Type> typarams1 = map(typarams, f);
714 if (outer1 == outer && typarams1 == typarams) return this;
715 else return new ClassType(outer1, typarams1, tsym);
716 }
718 public boolean contains(Type elem) {
719 return
720 elem == this
721 || (isParameterized()
722 && (getEnclosingType().contains(elem) || contains(getTypeArguments(), elem)))
723 || (isCompound()
724 && (supertype_field.contains(elem) || contains(interfaces_field, elem)));
725 }
727 public void complete() {
728 if (tsym.completer != null) tsym.complete();
729 }
731 public TypeKind getKind() {
732 return TypeKind.DECLARED;
733 }
735 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
736 return v.visitDeclared(this, p);
737 }
738 }
740 public static class ErasedClassType extends ClassType {
741 public ErasedClassType(Type outer, TypeSymbol tsym) {
742 super(outer, List.<Type>nil(), tsym);
743 }
745 @Override
746 public boolean hasErasedSupertypes() {
747 return true;
748 }
749 }
751 // a clone of a ClassType that knows about the alternatives of a union type.
752 public static class UnionClassType extends ClassType implements UnionType {
753 final List<? extends Type> alternatives_field;
755 public UnionClassType(ClassType ct, List<? extends Type> alternatives) {
756 super(ct.outer_field, ct.typarams_field, ct.tsym);
757 allparams_field = ct.allparams_field;
758 supertype_field = ct.supertype_field;
759 interfaces_field = ct.interfaces_field;
760 all_interfaces_field = ct.interfaces_field;
761 alternatives_field = alternatives;
762 }
764 public Type getLub() {
765 return tsym.type;
766 }
768 public java.util.List<? extends TypeMirror> getAlternatives() {
769 return Collections.unmodifiableList(alternatives_field);
770 }
772 @Override
773 public TypeKind getKind() {
774 return TypeKind.UNION;
775 }
777 @Override
778 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
779 return v.visitUnion(this, p);
780 }
781 }
783 public static class ArrayType extends Type
784 implements javax.lang.model.type.ArrayType {
786 public Type elemtype;
788 public ArrayType(Type elemtype, TypeSymbol arrayClass) {
789 super(ARRAY, arrayClass);
790 this.elemtype = elemtype;
791 }
793 @Override
794 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
795 return v.visitArrayType(this, s);
796 }
798 public String toString() {
799 return elemtype + "[]";
800 }
802 public boolean equals(Object obj) {
803 return
804 this == obj ||
805 (obj instanceof ArrayType &&
806 this.elemtype.equals(((ArrayType)obj).elemtype));
807 }
809 public int hashCode() {
810 return (ARRAY << 5) + elemtype.hashCode();
811 }
813 public boolean isVarargs() {
814 return false;
815 }
817 public List<Type> allparams() { return elemtype.allparams(); }
819 public boolean isErroneous() {
820 return elemtype.isErroneous();
821 }
823 public boolean isParameterized() {
824 return elemtype.isParameterized();
825 }
827 public boolean isRaw() {
828 return elemtype.isRaw();
829 }
831 public ArrayType makeVarargs() {
832 return new ArrayType(elemtype, tsym) {
833 @Override
834 public boolean isVarargs() {
835 return true;
836 }
837 };
838 }
840 public Type map(Mapping f) {
841 Type elemtype1 = f.apply(elemtype);
842 if (elemtype1 == elemtype) return this;
843 else return new ArrayType(elemtype1, tsym);
844 }
846 public boolean contains(Type elem) {
847 return elem == this || elemtype.contains(elem);
848 }
850 public void complete() {
851 elemtype.complete();
852 }
854 public Type getComponentType() {
855 return elemtype;
856 }
858 public TypeKind getKind() {
859 return TypeKind.ARRAY;
860 }
862 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
863 return v.visitArray(this, p);
864 }
865 }
867 public static class MethodType extends Type implements ExecutableType {
869 public List<Type> argtypes;
870 public Type restype;
871 public List<Type> thrown;
873 public MethodType(List<Type> argtypes,
874 Type restype,
875 List<Type> thrown,
876 TypeSymbol methodClass) {
877 super(METHOD, methodClass);
878 this.argtypes = argtypes;
879 this.restype = restype;
880 this.thrown = thrown;
881 }
883 @Override
884 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
885 return v.visitMethodType(this, s);
886 }
888 /** The Java source which this type represents.
889 *
890 * XXX 06/09/99 iris This isn't correct Java syntax, but it probably
891 * should be.
892 */
893 public String toString() {
894 return "(" + argtypes + ")" + restype;
895 }
897 public boolean equals(Object obj) {
898 if (this == obj)
899 return true;
900 if (!(obj instanceof MethodType))
901 return false;
902 MethodType m = (MethodType)obj;
903 List<Type> args1 = argtypes;
904 List<Type> args2 = m.argtypes;
905 while (!args1.isEmpty() && !args2.isEmpty()) {
906 if (!args1.head.equals(args2.head))
907 return false;
908 args1 = args1.tail;
909 args2 = args2.tail;
910 }
911 if (!args1.isEmpty() || !args2.isEmpty())
912 return false;
913 return restype.equals(m.restype);
914 }
916 public int hashCode() {
917 int h = METHOD;
918 for (List<Type> thisargs = this.argtypes;
919 thisargs.tail != null; /*inlined: thisargs.nonEmpty()*/
920 thisargs = thisargs.tail)
921 h = (h << 5) + thisargs.head.hashCode();
922 return (h << 5) + this.restype.hashCode();
923 }
925 public List<Type> getParameterTypes() { return argtypes; }
926 public Type getReturnType() { return restype; }
927 public List<Type> getThrownTypes() { return thrown; }
929 public boolean isErroneous() {
930 return
931 isErroneous(argtypes) ||
932 restype != null && restype.isErroneous();
933 }
935 public Type map(Mapping f) {
936 List<Type> argtypes1 = map(argtypes, f);
937 Type restype1 = f.apply(restype);
938 List<Type> thrown1 = map(thrown, f);
939 if (argtypes1 == argtypes &&
940 restype1 == restype &&
941 thrown1 == thrown) return this;
942 else return new MethodType(argtypes1, restype1, thrown1, tsym);
943 }
945 public boolean contains(Type elem) {
946 return elem == this || contains(argtypes, elem) || restype.contains(elem);
947 }
949 public MethodType asMethodType() { return this; }
951 public void complete() {
952 for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
953 l.head.complete();
954 restype.complete();
955 for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
956 l.head.complete();
957 }
959 public List<TypeVar> getTypeVariables() {
960 return List.nil();
961 }
963 public TypeSymbol asElement() {
964 return null;
965 }
967 public TypeKind getKind() {
968 return TypeKind.EXECUTABLE;
969 }
971 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
972 return v.visitExecutable(this, p);
973 }
974 }
976 public static class PackageType extends Type implements NoType {
978 PackageType(TypeSymbol tsym) {
979 super(PACKAGE, tsym);
980 }
982 @Override
983 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
984 return v.visitPackageType(this, s);
985 }
987 public String toString() {
988 return tsym.getQualifiedName().toString();
989 }
991 public TypeKind getKind() {
992 return TypeKind.PACKAGE;
993 }
995 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
996 return v.visitNoType(this, p);
997 }
998 }
1000 public static class TypeVar extends Type implements TypeVariable {
1002 /** The upper bound of this type variable; set from outside.
1003 * Must be nonempty once it is set.
1004 * For a bound, `bound' is the bound type itself.
1005 * Multiple bounds are expressed as a single class type which has the
1006 * individual bounds as superclass, respectively interfaces.
1007 * The class type then has as `tsym' a compiler generated class `c',
1008 * which has a flag COMPOUND and whose owner is the type variable
1009 * itself. Furthermore, the erasure_field of the class
1010 * points to the first class or interface bound.
1011 */
1012 public Type bound = null;
1014 /** The lower bound of this type variable.
1015 * TypeVars don't normally have a lower bound, so it is normally set
1016 * to syms.botType.
1017 * Subtypes, such as CapturedType, may provide a different value.
1018 */
1019 public Type lower;
1021 public TypeVar(Name name, Symbol owner, Type lower) {
1022 super(TYPEVAR, null);
1023 tsym = new TypeSymbol(0, name, this, owner);
1024 this.lower = lower;
1025 }
1027 public TypeVar(TypeSymbol tsym, Type bound, Type lower) {
1028 super(TYPEVAR, tsym);
1029 this.bound = bound;
1030 this.lower = lower;
1031 }
1033 @Override
1034 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1035 return v.visitTypeVar(this, s);
1036 }
1038 @Override
1039 public Type getUpperBound() { return bound; }
1041 int rank_field = -1;
1043 @Override
1044 public Type getLowerBound() {
1045 return lower;
1046 }
1048 public TypeKind getKind() {
1049 return TypeKind.TYPEVAR;
1050 }
1052 public boolean isCaptured() {
1053 return false;
1054 }
1056 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1057 return v.visitTypeVariable(this, p);
1058 }
1059 }
1061 /** A captured type variable comes from wildcards which can have
1062 * both upper and lower bound. CapturedType extends TypeVar with
1063 * a lower bound.
1064 */
1065 public static class CapturedType extends TypeVar {
1067 public WildcardType wildcard;
1069 public CapturedType(Name name,
1070 Symbol owner,
1071 Type upper,
1072 Type lower,
1073 WildcardType wildcard) {
1074 super(name, owner, lower);
1075 this.lower = Assert.checkNonNull(lower);
1076 this.bound = upper;
1077 this.wildcard = wildcard;
1078 }
1080 @Override
1081 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1082 return v.visitCapturedType(this, s);
1083 }
1085 @Override
1086 public boolean isCaptured() {
1087 return true;
1088 }
1090 @Override
1091 public String toString() {
1092 return "capture#"
1093 + (hashCode() & 0xFFFFFFFFL) % Printer.PRIME
1094 + " of "
1095 + wildcard;
1096 }
1097 }
1099 public static abstract class DelegatedType extends Type {
1100 public Type qtype;
1101 public DelegatedType(int tag, Type qtype) {
1102 super(tag, qtype.tsym);
1103 this.qtype = qtype;
1104 }
1105 public String toString() { return qtype.toString(); }
1106 public List<Type> getTypeArguments() { return qtype.getTypeArguments(); }
1107 public Type getEnclosingType() { return qtype.getEnclosingType(); }
1108 public List<Type> getParameterTypes() { return qtype.getParameterTypes(); }
1109 public Type getReturnType() { return qtype.getReturnType(); }
1110 public List<Type> getThrownTypes() { return qtype.getThrownTypes(); }
1111 public List<Type> allparams() { return qtype.allparams(); }
1112 public Type getUpperBound() { return qtype.getUpperBound(); }
1113 public boolean isErroneous() { return qtype.isErroneous(); }
1114 }
1116 /**
1117 * The type of a generic method type. It consists of a method type and
1118 * a list of method type-parameters that are used within the method
1119 * type.
1120 */
1121 public static class ForAll extends DelegatedType implements ExecutableType {
1122 public List<Type> tvars;
1124 public ForAll(List<Type> tvars, Type qtype) {
1125 super(FORALL, (MethodType)qtype);
1126 this.tvars = tvars;
1127 }
1129 @Override
1130 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1131 return v.visitForAll(this, s);
1132 }
1134 public String toString() {
1135 return "<" + tvars + ">" + qtype;
1136 }
1138 public List<Type> getTypeArguments() { return tvars; }
1140 public boolean isErroneous() {
1141 return qtype.isErroneous();
1142 }
1144 public Type map(Mapping f) {
1145 return f.apply(qtype);
1146 }
1148 public boolean contains(Type elem) {
1149 return qtype.contains(elem);
1150 }
1152 public MethodType asMethodType() {
1153 return (MethodType)qtype;
1154 }
1156 public void complete() {
1157 for (List<Type> l = tvars; l.nonEmpty(); l = l.tail) {
1158 ((TypeVar)l.head).bound.complete();
1159 }
1160 qtype.complete();
1161 }
1163 public List<TypeVar> getTypeVariables() {
1164 return List.convert(TypeVar.class, getTypeArguments());
1165 }
1167 public TypeKind getKind() {
1168 return TypeKind.EXECUTABLE;
1169 }
1171 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1172 return v.visitExecutable(this, p);
1173 }
1174 }
1176 /** A class for inference variables, for use during method/diamond type
1177 * inference. An inference variable has upper/lower bounds and a set
1178 * of equality constraints. Such bounds are set during subtyping, type-containment,
1179 * type-equality checks, when the types being tested contain inference variables.
1180 * A change listener can be attached to an inference variable, to receive notifications
1181 * whenever the bounds of an inference variable change.
1182 */
1183 public static class UndetVar extends DelegatedType {
1185 /** Inference variable change listener. The listener method is called
1186 * whenever a change to the inference variable's bounds occurs
1187 */
1188 public interface UndetVarListener {
1189 /** called when some inference variable bounds (of given kinds ibs) change */
1190 void varChanged(UndetVar uv, Set<InferenceBound> ibs);
1191 }
1193 /**
1194 * Inference variable bound kinds
1195 */
1196 public enum InferenceBound {
1197 /** upper bounds */
1198 UPPER,
1199 /** lower bounds */
1200 LOWER,
1201 /** equality constraints */
1202 EQ;
1203 }
1205 /** inference variable bounds */
1206 private Map<InferenceBound, List<Type>> bounds;
1208 /** inference variable's inferred type (set from Infer.java) */
1209 public Type inst = null;
1211 /** inference variable's change listener */
1212 public UndetVarListener listener = null;
1214 @Override
1215 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1216 return v.visitUndetVar(this, s);
1217 }
1219 public UndetVar(TypeVar origin, Types types) {
1220 super(UNDETVAR, origin);
1221 bounds = new EnumMap<InferenceBound, List<Type>>(InferenceBound.class);
1222 bounds.put(InferenceBound.UPPER, types.getBounds(origin));
1223 bounds.put(InferenceBound.LOWER, List.<Type>nil());
1224 bounds.put(InferenceBound.EQ, List.<Type>nil());
1225 }
1227 public String toString() {
1228 if (inst != null) return inst.toString();
1229 else return qtype + "?";
1230 }
1232 public Type baseType() {
1233 if (inst != null) return inst.baseType();
1234 else return this;
1235 }
1237 /** get all bounds of a given kind */
1238 public List<Type> getBounds(InferenceBound ib) {
1239 return bounds.get(ib);
1240 }
1242 /** add a bound of a given kind - this might trigger listener notification */
1243 public void addBound(InferenceBound ib, Type bound, Types types) {
1244 List<Type> prevBounds = bounds.get(ib);
1245 for (Type b : prevBounds) {
1246 if (types.isSameType(b, bound)) {
1247 return;
1248 }
1249 }
1250 bounds.put(ib, prevBounds.prepend(bound));
1251 notifyChange(EnumSet.of(ib));
1252 }
1254 /** replace types in all bounds - this might trigger listener notification */
1255 public void substBounds(List<Type> from, List<Type> to, Types types) {
1256 EnumSet<InferenceBound> changed = EnumSet.noneOf(InferenceBound.class);
1257 Map<InferenceBound, List<Type>> bounds2 = new EnumMap<InferenceBound, List<Type>>(InferenceBound.class);
1258 for (Map.Entry<InferenceBound, List<Type>> _entry : bounds.entrySet()) {
1259 InferenceBound ib = _entry.getKey();
1260 List<Type> prevBounds = _entry.getValue();
1261 List<Type> newBounds = types.subst(prevBounds, from, to);
1262 bounds2.put(ib, newBounds);
1263 if (prevBounds != newBounds) {
1264 changed.add(ib);
1265 }
1266 }
1267 if (!changed.isEmpty()) {
1268 bounds = bounds2;
1269 notifyChange(changed);
1270 }
1271 }
1273 private void notifyChange(EnumSet<InferenceBound> ibs) {
1274 if (listener != null) {
1275 listener.varChanged(this, ibs);
1276 }
1277 }
1278 }
1280 /** Represents VOID or NONE.
1281 */
1282 static class JCNoType extends Type implements NoType {
1283 public JCNoType(int tag) {
1284 super(tag, null);
1285 }
1287 @Override
1288 public TypeKind getKind() {
1289 switch (tag) {
1290 case VOID: return TypeKind.VOID;
1291 case NONE: return TypeKind.NONE;
1292 default:
1293 throw new AssertionError("Unexpected tag: " + tag);
1294 }
1295 }
1297 @Override
1298 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1299 return v.visitNoType(this, p);
1300 }
1301 }
1303 static class BottomType extends Type implements NullType {
1304 public BottomType() {
1305 super(TypeTags.BOT, null);
1306 }
1308 @Override
1309 public TypeKind getKind() {
1310 return TypeKind.NULL;
1311 }
1313 @Override
1314 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1315 return v.visitNull(this, p);
1316 }
1318 @Override
1319 public Type constType(Object value) {
1320 return this;
1321 }
1323 @Override
1324 public String stringValue() {
1325 return "null";
1326 }
1327 }
1329 public static class ErrorType extends ClassType
1330 implements javax.lang.model.type.ErrorType {
1332 private Type originalType = null;
1334 public ErrorType(Type originalType, TypeSymbol tsym) {
1335 super(noType, List.<Type>nil(), null);
1336 tag = ERROR;
1337 this.tsym = tsym;
1338 this.originalType = (originalType == null ? noType : originalType);
1339 }
1341 public ErrorType(ClassSymbol c, Type originalType) {
1342 this(originalType, c);
1343 c.type = this;
1344 c.kind = ERR;
1345 c.members_field = new Scope.ErrorScope(c);
1346 }
1348 public ErrorType(Name name, TypeSymbol container, Type originalType) {
1349 this(new ClassSymbol(PUBLIC|STATIC|ACYCLIC, name, null, container), originalType);
1350 }
1352 @Override
1353 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1354 return v.visitErrorType(this, s);
1355 }
1357 public Type constType(Object constValue) { return this; }
1358 public Type getEnclosingType() { return this; }
1359 public Type getReturnType() { return this; }
1360 public Type asSub(Symbol sym) { return this; }
1361 public Type map(Mapping f) { return this; }
1363 public boolean isGenType(Type t) { return true; }
1364 public boolean isErroneous() { return true; }
1365 public boolean isCompound() { return false; }
1366 public boolean isInterface() { return false; }
1368 public List<Type> allparams() { return List.nil(); }
1369 public List<Type> getTypeArguments() { return List.nil(); }
1371 public TypeKind getKind() {
1372 return TypeKind.ERROR;
1373 }
1375 public Type getOriginalType() {
1376 return originalType;
1377 }
1379 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1380 return v.visitError(this, p);
1381 }
1382 }
1384 /**
1385 * A visitor for types. A visitor is used to implement operations
1386 * (or relations) on types. Most common operations on types are
1387 * binary relations and this interface is designed for binary
1388 * relations, that is, operations on the form
1389 * Type × S → R.
1390 * <!-- In plain text: Type x S -> R -->
1391 *
1392 * @param <R> the return type of the operation implemented by this
1393 * visitor; use Void if no return type is needed.
1394 * @param <S> the type of the second argument (the first being the
1395 * type itself) of the operation implemented by this visitor; use
1396 * Void if a second argument is not needed.
1397 */
1398 public interface Visitor<R,S> {
1399 R visitClassType(ClassType t, S s);
1400 R visitWildcardType(WildcardType t, S s);
1401 R visitArrayType(ArrayType t, S s);
1402 R visitMethodType(MethodType t, S s);
1403 R visitPackageType(PackageType t, S s);
1404 R visitTypeVar(TypeVar t, S s);
1405 R visitCapturedType(CapturedType t, S s);
1406 R visitForAll(ForAll t, S s);
1407 R visitUndetVar(UndetVar t, S s);
1408 R visitErrorType(ErrorType t, S s);
1409 R visitType(Type t, S s);
1410 }
1411 }