Tue, 09 Oct 2012 19:10:00 -0700
8000663: clean up langtools imports
Reviewed-by: darcy
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;
29 import java.util.EnumMap;
30 import java.util.EnumSet;
31 import java.util.Map;
32 import java.util.Set;
34 import javax.lang.model.type.*;
36 import com.sun.tools.javac.code.Symbol.*;
37 import com.sun.tools.javac.util.*;
38 import static com.sun.tools.javac.code.BoundKind.*;
39 import static com.sun.tools.javac.code.Flags.*;
40 import static com.sun.tools.javac.code.Kinds.*;
41 import static com.sun.tools.javac.code.TypeTags.*;
43 /** This class represents Java types. The class itself defines the behavior of
44 * the following types:
45 * <pre>
46 * base types (tags: BYTE, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, BOOLEAN),
47 * type `void' (tag: VOID),
48 * the bottom type (tag: BOT),
49 * the missing type (tag: NONE).
50 * </pre>
51 * <p>The behavior of the following types is defined in subclasses, which are
52 * all static inner classes of this class:
53 * <pre>
54 * class types (tag: CLASS, class: ClassType),
55 * array types (tag: ARRAY, class: ArrayType),
56 * method types (tag: METHOD, class: MethodType),
57 * package types (tag: PACKAGE, class: PackageType),
58 * type variables (tag: TYPEVAR, class: TypeVar),
59 * type arguments (tag: WILDCARD, class: WildcardType),
60 * generic method types (tag: FORALL, class: ForAll),
61 * the error type (tag: ERROR, class: ErrorType).
62 * </pre>
63 *
64 * <p><b>This is NOT part of any supported API.
65 * If you write code that depends on this, you do so at your own risk.
66 * This code and its internal interfaces are subject to change or
67 * deletion without notice.</b>
68 *
69 * @see TypeTags
70 */
71 public class Type implements PrimitiveType {
73 /** Constant type: no type at all. */
74 public static final JCNoType noType = new JCNoType(NONE);
76 /** Constant type: special type to be used during recovery of deferred expressions. */
77 public static final JCNoType recoveryType = new JCNoType(NONE);
79 /** If this switch is turned on, the names of type variables
80 * and anonymous classes are printed with hashcodes appended.
81 */
82 public static boolean moreInfo = false;
84 /** The tag of this type.
85 *
86 * @see TypeTags
87 */
88 public int tag;
90 /** The defining class / interface / package / type variable
91 */
92 public TypeSymbol tsym;
94 /**
95 * The constant value of this type, null if this type does not
96 * have a constant value attribute. Only primitive types and
97 * strings (ClassType) can have a constant value attribute.
98 * @return the constant value attribute of this type
99 */
100 public Object constValue() {
101 return null;
102 }
104 /**
105 * Get the representation of this type used for modelling purposes.
106 * By default, this is itself. For ErrorType, a different value
107 * may be provided,
108 */
109 public Type getModelType() {
110 return this;
111 }
113 public static List<Type> getModelTypes(List<Type> ts) {
114 ListBuffer<Type> lb = new ListBuffer<Type>();
115 for (Type t: ts)
116 lb.append(t.getModelType());
117 return lb.toList();
118 }
120 public <R,S> R accept(Type.Visitor<R,S> v, S s) { return v.visitType(this, s); }
122 /** Define a type given its tag and type symbol
123 */
124 public Type(int tag, TypeSymbol tsym) {
125 this.tag = tag;
126 this.tsym = tsym;
127 }
129 /** An abstract class for mappings from types to types
130 */
131 public static abstract class Mapping {
132 private String name;
133 public Mapping(String name) {
134 this.name = name;
135 }
136 public abstract Type apply(Type t);
137 public String toString() {
138 return name;
139 }
140 }
142 /** map a type function over all immediate descendants of this type
143 */
144 public Type map(Mapping f) {
145 return this;
146 }
148 /** map a type function over a list of types
149 */
150 public static List<Type> map(List<Type> ts, Mapping f) {
151 if (ts.nonEmpty()) {
152 List<Type> tail1 = map(ts.tail, f);
153 Type t = f.apply(ts.head);
154 if (tail1 != ts.tail || t != ts.head)
155 return tail1.prepend(t);
156 }
157 return ts;
158 }
160 /** Define a constant type, of the same kind as this type
161 * and with given constant value
162 */
163 public Type constType(Object constValue) {
164 final Object value = constValue;
165 Assert.check(tag <= BOOLEAN);
166 return new Type(tag, tsym) {
167 @Override
168 public Object constValue() {
169 return value;
170 }
171 @Override
172 public Type baseType() {
173 return tsym.type;
174 }
175 };
176 }
178 /**
179 * If this is a constant type, return its underlying type.
180 * Otherwise, return the type itself.
181 */
182 public Type baseType() {
183 return this;
184 }
186 /** Return the base types of a list of types.
187 */
188 public static List<Type> baseTypes(List<Type> ts) {
189 if (ts.nonEmpty()) {
190 Type t = ts.head.baseType();
191 List<Type> baseTypes = baseTypes(ts.tail);
192 if (t != ts.head || baseTypes != ts.tail)
193 return baseTypes.prepend(t);
194 }
195 return ts;
196 }
198 /** The Java source which this type represents.
199 */
200 public String toString() {
201 String s = (tsym == null || tsym.name == null)
202 ? "<none>"
203 : tsym.name.toString();
204 if (moreInfo && tag == TYPEVAR) s = s + hashCode();
205 return s;
206 }
208 /**
209 * The Java source which this type list represents. A List is
210 * represented as a comma-spearated listing of the elements in
211 * that list.
212 */
213 public static String toString(List<Type> ts) {
214 if (ts.isEmpty()) {
215 return "";
216 } else {
217 StringBuilder buf = new StringBuilder();
218 buf.append(ts.head.toString());
219 for (List<Type> l = ts.tail; l.nonEmpty(); l = l.tail)
220 buf.append(",").append(l.head.toString());
221 return buf.toString();
222 }
223 }
225 /**
226 * The constant value of this type, converted to String
227 */
228 public String stringValue() {
229 Object cv = Assert.checkNonNull(constValue());
230 if (tag == BOOLEAN)
231 return ((Integer) cv).intValue() == 0 ? "false" : "true";
232 else if (tag == CHAR)
233 return String.valueOf((char) ((Integer) cv).intValue());
234 else
235 return cv.toString();
236 }
238 /**
239 * This method is analogous to isSameType, but weaker, since we
240 * never complete classes. Where isSameType would complete a
241 * class, equals assumes that the two types are different.
242 */
243 public boolean equals(Object t) {
244 return super.equals(t);
245 }
247 public int hashCode() {
248 return super.hashCode();
249 }
251 /** Is this a constant type whose value is false?
252 */
253 public boolean isFalse() {
254 return
255 tag == BOOLEAN &&
256 constValue() != null &&
257 ((Integer)constValue()).intValue() == 0;
258 }
260 /** Is this a constant type whose value is true?
261 */
262 public boolean isTrue() {
263 return
264 tag == BOOLEAN &&
265 constValue() != null &&
266 ((Integer)constValue()).intValue() != 0;
267 }
269 public String argtypes(boolean varargs) {
270 List<Type> args = getParameterTypes();
271 if (!varargs) return args.toString();
272 StringBuilder buf = new StringBuilder();
273 while (args.tail.nonEmpty()) {
274 buf.append(args.head);
275 args = args.tail;
276 buf.append(',');
277 }
278 if (args.head.tag == ARRAY) {
279 buf.append(((ArrayType)args.head).elemtype);
280 buf.append("...");
281 } else {
282 buf.append(args.head);
283 }
284 return buf.toString();
285 }
287 /** Access methods.
288 */
289 public List<Type> getTypeArguments() { return List.nil(); }
290 public Type getEnclosingType() { return null; }
291 public List<Type> getParameterTypes() { return List.nil(); }
292 public Type getReturnType() { return null; }
293 public List<Type> getThrownTypes() { return List.nil(); }
294 public Type getUpperBound() { return null; }
295 public Type getLowerBound() { return null; }
297 /** Navigation methods, these will work for classes, type variables,
298 * foralls, but will return null for arrays and methods.
299 */
301 /** Return all parameters of this type and all its outer types in order
302 * outer (first) to inner (last).
303 */
304 public List<Type> allparams() { return List.nil(); }
306 /** Does this type contain "error" elements?
307 */
308 public boolean isErroneous() {
309 return false;
310 }
312 public static boolean isErroneous(List<Type> ts) {
313 for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
314 if (l.head.isErroneous()) return true;
315 return false;
316 }
318 /** Is this type parameterized?
319 * A class type is parameterized if it has some parameters.
320 * An array type is parameterized if its element type is parameterized.
321 * All other types are not parameterized.
322 */
323 public boolean isParameterized() {
324 return false;
325 }
327 /** Is this type a raw type?
328 * A class type is a raw type if it misses some of its parameters.
329 * An array type is a raw type if its element type is raw.
330 * All other types are not raw.
331 * Type validation will ensure that the only raw types
332 * in a program are types that miss all their type variables.
333 */
334 public boolean isRaw() {
335 return false;
336 }
338 public boolean isCompound() {
339 return tsym.completer == null
340 // Compound types can't have a completer. Calling
341 // flags() will complete the symbol causing the
342 // compiler to load classes unnecessarily. This led
343 // to regression 6180021.
344 && (tsym.flags() & COMPOUND) != 0;
345 }
347 public boolean isInterface() {
348 return (tsym.flags() & INTERFACE) != 0;
349 }
351 public boolean isFinal() {
352 return (tsym.flags() & FINAL) != 0;
353 }
355 public boolean isPrimitive() {
356 return tag < VOID;
357 }
359 /**
360 * Does this type contain occurrences of type t?
361 */
362 public boolean contains(Type t) {
363 return t == this;
364 }
366 public static boolean contains(List<Type> ts, Type t) {
367 for (List<Type> l = ts;
368 l.tail != null /*inlined: l.nonEmpty()*/;
369 l = l.tail)
370 if (l.head.contains(t)) return true;
371 return false;
372 }
374 /** Does this type contain an occurrence of some type in 'ts'?
375 */
376 public boolean containsAny(List<Type> ts) {
377 for (Type t : ts)
378 if (this.contains(t)) return true;
379 return false;
380 }
382 public static boolean containsAny(List<Type> ts1, List<Type> ts2) {
383 for (Type t : ts1)
384 if (t.containsAny(ts2)) return true;
385 return false;
386 }
388 public static List<Type> filter(List<Type> ts, Filter<Type> tf) {
389 ListBuffer<Type> buf = ListBuffer.lb();
390 for (Type t : ts) {
391 if (tf.accepts(t)) {
392 buf.append(t);
393 }
394 }
395 return buf.toList();
396 }
398 public boolean isSuperBound() { return false; }
399 public boolean isExtendsBound() { return false; }
400 public boolean isUnbound() { return false; }
401 public Type withTypeVar(Type t) { return this; }
403 /** The underlying method type of this type.
404 */
405 public MethodType asMethodType() { throw new AssertionError(); }
407 /** Complete loading all classes in this type.
408 */
409 public void complete() {}
411 public TypeSymbol asElement() {
412 return tsym;
413 }
415 public TypeKind getKind() {
416 switch (tag) {
417 case BYTE: return TypeKind.BYTE;
418 case CHAR: return TypeKind.CHAR;
419 case SHORT: return TypeKind.SHORT;
420 case INT: return TypeKind.INT;
421 case LONG: return TypeKind.LONG;
422 case FLOAT: return TypeKind.FLOAT;
423 case DOUBLE: return TypeKind.DOUBLE;
424 case BOOLEAN: return TypeKind.BOOLEAN;
425 case VOID: return TypeKind.VOID;
426 case BOT: return TypeKind.NULL;
427 case NONE: return TypeKind.NONE;
428 default: return TypeKind.OTHER;
429 }
430 }
432 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
433 if (isPrimitive())
434 return v.visitPrimitive(this, p);
435 else
436 throw new AssertionError();
437 }
439 public static class WildcardType extends Type
440 implements javax.lang.model.type.WildcardType {
442 public Type type;
443 public BoundKind kind;
444 public TypeVar bound;
446 @Override
447 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
448 return v.visitWildcardType(this, s);
449 }
451 public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) {
452 super(WILDCARD, tsym);
453 this.type = Assert.checkNonNull(type);
454 this.kind = kind;
455 }
456 public WildcardType(WildcardType t, TypeVar bound) {
457 this(t.type, t.kind, t.tsym, bound);
458 }
460 public WildcardType(Type type, BoundKind kind, TypeSymbol tsym, TypeVar bound) {
461 this(type, kind, tsym);
462 this.bound = bound;
463 }
465 public boolean contains(Type t) {
466 return kind != UNBOUND && type.contains(t);
467 }
469 public boolean isSuperBound() {
470 return kind == SUPER ||
471 kind == UNBOUND;
472 }
473 public boolean isExtendsBound() {
474 return kind == EXTENDS ||
475 kind == UNBOUND;
476 }
477 public boolean isUnbound() {
478 return kind == UNBOUND;
479 }
481 public Type withTypeVar(Type t) {
482 //-System.err.println(this+".withTypeVar("+t+");");//DEBUG
483 if (bound == t)
484 return this;
485 bound = (TypeVar)t;
486 return this;
487 }
489 boolean isPrintingBound = false;
490 public String toString() {
491 StringBuilder s = new StringBuilder();
492 s.append(kind.toString());
493 if (kind != UNBOUND)
494 s.append(type);
495 if (moreInfo && bound != null && !isPrintingBound)
496 try {
497 isPrintingBound = true;
498 s.append("{:").append(bound.bound).append(":}");
499 } finally {
500 isPrintingBound = false;
501 }
502 return s.toString();
503 }
505 public Type map(Mapping f) {
506 //- System.err.println(" (" + this + ").map(" + f + ")");//DEBUG
507 Type t = type;
508 if (t != null)
509 t = f.apply(t);
510 if (t == type)
511 return this;
512 else
513 return new WildcardType(t, kind, tsym, bound);
514 }
516 public Type getExtendsBound() {
517 if (kind == EXTENDS)
518 return type;
519 else
520 return null;
521 }
523 public Type getSuperBound() {
524 if (kind == SUPER)
525 return type;
526 else
527 return null;
528 }
530 public TypeKind getKind() {
531 return TypeKind.WILDCARD;
532 }
534 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
535 return v.visitWildcard(this, p);
536 }
537 }
539 public static class ClassType extends Type implements DeclaredType {
541 /** The enclosing type of this type. If this is the type of an inner
542 * class, outer_field refers to the type of its enclosing
543 * instance class, in all other cases it referes to noType.
544 */
545 private Type outer_field;
547 /** The type parameters of this type (to be set once class is loaded).
548 */
549 public List<Type> typarams_field;
551 /** A cache variable for the type parameters of this type,
552 * appended to all parameters of its enclosing class.
553 * @see #allparams
554 */
555 public List<Type> allparams_field;
557 /** The supertype of this class (to be set once class is loaded).
558 */
559 public Type supertype_field;
561 /** The interfaces of this class (to be set once class is loaded).
562 */
563 public List<Type> interfaces_field;
565 /** All the interfaces of this class, including missing ones.
566 */
567 public List<Type> all_interfaces_field;
569 public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
570 super(CLASS, tsym);
571 this.outer_field = outer;
572 this.typarams_field = typarams;
573 this.allparams_field = null;
574 this.supertype_field = null;
575 this.interfaces_field = null;
576 /*
577 // this can happen during error recovery
578 assert
579 outer.isParameterized() ?
580 typarams.length() == tsym.type.typarams().length() :
581 outer.isRaw() ?
582 typarams.length() == 0 :
583 true;
584 */
585 }
587 @Override
588 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
589 return v.visitClassType(this, s);
590 }
592 public Type constType(Object constValue) {
593 final Object value = constValue;
594 return new ClassType(getEnclosingType(), typarams_field, tsym) {
595 @Override
596 public Object constValue() {
597 return value;
598 }
599 @Override
600 public Type baseType() {
601 return tsym.type;
602 }
603 };
604 }
606 /** The Java source which this type represents.
607 */
608 public String toString() {
609 StringBuilder buf = new StringBuilder();
610 if (getEnclosingType().tag == CLASS && tsym.owner.kind == TYP) {
611 buf.append(getEnclosingType().toString());
612 buf.append(".");
613 buf.append(className(tsym, false));
614 } else {
615 buf.append(className(tsym, true));
616 }
617 if (getTypeArguments().nonEmpty()) {
618 buf.append('<');
619 buf.append(getTypeArguments().toString());
620 buf.append(">");
621 }
622 return buf.toString();
623 }
624 //where
625 private String className(Symbol sym, boolean longform) {
626 if (sym.name.isEmpty() && (sym.flags() & COMPOUND) != 0) {
627 StringBuilder s = new StringBuilder(supertype_field.toString());
628 for (List<Type> is=interfaces_field; is.nonEmpty(); is = is.tail) {
629 s.append("&");
630 s.append(is.head.toString());
631 }
632 return s.toString();
633 } else if (sym.name.isEmpty()) {
634 String s;
635 ClassType norm = (ClassType) tsym.type;
636 if (norm == null) {
637 s = Log.getLocalizedString("anonymous.class", (Object)null);
638 } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
639 s = Log.getLocalizedString("anonymous.class",
640 norm.interfaces_field.head);
641 } else {
642 s = Log.getLocalizedString("anonymous.class",
643 norm.supertype_field);
644 }
645 if (moreInfo)
646 s += String.valueOf(sym.hashCode());
647 return s;
648 } else if (longform) {
649 return sym.getQualifiedName().toString();
650 } else {
651 return sym.name.toString();
652 }
653 }
655 public List<Type> getTypeArguments() {
656 if (typarams_field == null) {
657 complete();
658 if (typarams_field == null)
659 typarams_field = List.nil();
660 }
661 return typarams_field;
662 }
664 public boolean hasErasedSupertypes() {
665 return isRaw();
666 }
668 public Type getEnclosingType() {
669 return outer_field;
670 }
672 public void setEnclosingType(Type outer) {
673 outer_field = outer;
674 }
676 public List<Type> allparams() {
677 if (allparams_field == null) {
678 allparams_field = getTypeArguments().prependList(getEnclosingType().allparams());
679 }
680 return allparams_field;
681 }
683 public boolean isErroneous() {
684 return
685 getEnclosingType().isErroneous() ||
686 isErroneous(getTypeArguments()) ||
687 this != tsym.type && tsym.type.isErroneous();
688 }
690 public boolean isParameterized() {
691 return allparams().tail != null;
692 // optimization, was: allparams().nonEmpty();
693 }
695 /** A cache for the rank. */
696 int rank_field = -1;
698 /** A class type is raw if it misses some
699 * of its type parameter sections.
700 * After validation, this is equivalent to:
701 * {@code allparams.isEmpty() && tsym.type.allparams.nonEmpty(); }
702 */
703 public boolean isRaw() {
704 return
705 this != tsym.type && // necessary, but not sufficient condition
706 tsym.type.allparams().nonEmpty() &&
707 allparams().isEmpty();
708 }
710 public Type map(Mapping f) {
711 Type outer = getEnclosingType();
712 Type outer1 = f.apply(outer);
713 List<Type> typarams = getTypeArguments();
714 List<Type> typarams1 = map(typarams, f);
715 if (outer1 == outer && typarams1 == typarams) return this;
716 else return new ClassType(outer1, typarams1, tsym);
717 }
719 public boolean contains(Type elem) {
720 return
721 elem == this
722 || (isParameterized()
723 && (getEnclosingType().contains(elem) || contains(getTypeArguments(), elem)))
724 || (isCompound()
725 && (supertype_field.contains(elem) || contains(interfaces_field, elem)));
726 }
728 public void complete() {
729 if (tsym.completer != null) tsym.complete();
730 }
732 public TypeKind getKind() {
733 return TypeKind.DECLARED;
734 }
736 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
737 return v.visitDeclared(this, p);
738 }
739 }
741 public static class ErasedClassType extends ClassType {
742 public ErasedClassType(Type outer, TypeSymbol tsym) {
743 super(outer, List.<Type>nil(), tsym);
744 }
746 @Override
747 public boolean hasErasedSupertypes() {
748 return true;
749 }
750 }
752 // a clone of a ClassType that knows about the alternatives of a union type.
753 public static class UnionClassType extends ClassType implements UnionType {
754 final List<? extends Type> alternatives_field;
756 public UnionClassType(ClassType ct, List<? extends Type> alternatives) {
757 super(ct.outer_field, ct.typarams_field, ct.tsym);
758 allparams_field = ct.allparams_field;
759 supertype_field = ct.supertype_field;
760 interfaces_field = ct.interfaces_field;
761 all_interfaces_field = ct.interfaces_field;
762 alternatives_field = alternatives;
763 }
765 public Type getLub() {
766 return tsym.type;
767 }
769 public java.util.List<? extends TypeMirror> getAlternatives() {
770 return Collections.unmodifiableList(alternatives_field);
771 }
773 @Override
774 public TypeKind getKind() {
775 return TypeKind.UNION;
776 }
778 @Override
779 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
780 return v.visitUnion(this, p);
781 }
782 }
784 public static class ArrayType extends Type
785 implements javax.lang.model.type.ArrayType {
787 public Type elemtype;
789 public ArrayType(Type elemtype, TypeSymbol arrayClass) {
790 super(ARRAY, arrayClass);
791 this.elemtype = elemtype;
792 }
794 @Override
795 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
796 return v.visitArrayType(this, s);
797 }
799 public String toString() {
800 return elemtype + "[]";
801 }
803 public boolean equals(Object obj) {
804 return
805 this == obj ||
806 (obj instanceof ArrayType &&
807 this.elemtype.equals(((ArrayType)obj).elemtype));
808 }
810 public int hashCode() {
811 return (ARRAY << 5) + elemtype.hashCode();
812 }
814 public boolean isVarargs() {
815 return false;
816 }
818 public List<Type> allparams() { return elemtype.allparams(); }
820 public boolean isErroneous() {
821 return elemtype.isErroneous();
822 }
824 public boolean isParameterized() {
825 return elemtype.isParameterized();
826 }
828 public boolean isRaw() {
829 return elemtype.isRaw();
830 }
832 public ArrayType makeVarargs() {
833 return new ArrayType(elemtype, tsym) {
834 @Override
835 public boolean isVarargs() {
836 return true;
837 }
838 };
839 }
841 public Type map(Mapping f) {
842 Type elemtype1 = f.apply(elemtype);
843 if (elemtype1 == elemtype) return this;
844 else return new ArrayType(elemtype1, tsym);
845 }
847 public boolean contains(Type elem) {
848 return elem == this || elemtype.contains(elem);
849 }
851 public void complete() {
852 elemtype.complete();
853 }
855 public Type getComponentType() {
856 return elemtype;
857 }
859 public TypeKind getKind() {
860 return TypeKind.ARRAY;
861 }
863 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
864 return v.visitArray(this, p);
865 }
866 }
868 public static class MethodType extends Type implements ExecutableType {
870 public List<Type> argtypes;
871 public Type restype;
872 public List<Type> thrown;
874 public MethodType(List<Type> argtypes,
875 Type restype,
876 List<Type> thrown,
877 TypeSymbol methodClass) {
878 super(METHOD, methodClass);
879 this.argtypes = argtypes;
880 this.restype = restype;
881 this.thrown = thrown;
882 }
884 @Override
885 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
886 return v.visitMethodType(this, s);
887 }
889 /** The Java source which this type represents.
890 *
891 * XXX 06/09/99 iris This isn't correct Java syntax, but it probably
892 * should be.
893 */
894 public String toString() {
895 return "(" + argtypes + ")" + restype;
896 }
898 public boolean equals(Object obj) {
899 if (this == obj)
900 return true;
901 if (!(obj instanceof MethodType))
902 return false;
903 MethodType m = (MethodType)obj;
904 List<Type> args1 = argtypes;
905 List<Type> args2 = m.argtypes;
906 while (!args1.isEmpty() && !args2.isEmpty()) {
907 if (!args1.head.equals(args2.head))
908 return false;
909 args1 = args1.tail;
910 args2 = args2.tail;
911 }
912 if (!args1.isEmpty() || !args2.isEmpty())
913 return false;
914 return restype.equals(m.restype);
915 }
917 public int hashCode() {
918 int h = METHOD;
919 for (List<Type> thisargs = this.argtypes;
920 thisargs.tail != null; /*inlined: thisargs.nonEmpty()*/
921 thisargs = thisargs.tail)
922 h = (h << 5) + thisargs.head.hashCode();
923 return (h << 5) + this.restype.hashCode();
924 }
926 public List<Type> getParameterTypes() { return argtypes; }
927 public Type getReturnType() { return restype; }
928 public List<Type> getThrownTypes() { return thrown; }
930 public boolean isErroneous() {
931 return
932 isErroneous(argtypes) ||
933 restype != null && restype.isErroneous();
934 }
936 public Type map(Mapping f) {
937 List<Type> argtypes1 = map(argtypes, f);
938 Type restype1 = f.apply(restype);
939 List<Type> thrown1 = map(thrown, f);
940 if (argtypes1 == argtypes &&
941 restype1 == restype &&
942 thrown1 == thrown) return this;
943 else return new MethodType(argtypes1, restype1, thrown1, tsym);
944 }
946 public boolean contains(Type elem) {
947 return elem == this || contains(argtypes, elem) || restype.contains(elem);
948 }
950 public MethodType asMethodType() { return this; }
952 public void complete() {
953 for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
954 l.head.complete();
955 restype.complete();
956 for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
957 l.head.complete();
958 }
960 public List<TypeVar> getTypeVariables() {
961 return List.nil();
962 }
964 public TypeSymbol asElement() {
965 return null;
966 }
968 public TypeKind getKind() {
969 return TypeKind.EXECUTABLE;
970 }
972 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
973 return v.visitExecutable(this, p);
974 }
975 }
977 public static class PackageType extends Type implements NoType {
979 PackageType(TypeSymbol tsym) {
980 super(PACKAGE, tsym);
981 }
983 @Override
984 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
985 return v.visitPackageType(this, s);
986 }
988 public String toString() {
989 return tsym.getQualifiedName().toString();
990 }
992 public TypeKind getKind() {
993 return TypeKind.PACKAGE;
994 }
996 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
997 return v.visitNoType(this, p);
998 }
999 }
1001 public static class TypeVar extends Type implements TypeVariable {
1003 /** The upper bound of this type variable; set from outside.
1004 * Must be nonempty once it is set.
1005 * For a bound, `bound' is the bound type itself.
1006 * Multiple bounds are expressed as a single class type which has the
1007 * individual bounds as superclass, respectively interfaces.
1008 * The class type then has as `tsym' a compiler generated class `c',
1009 * which has a flag COMPOUND and whose owner is the type variable
1010 * itself. Furthermore, the erasure_field of the class
1011 * points to the first class or interface bound.
1012 */
1013 public Type bound = null;
1015 /** The lower bound of this type variable.
1016 * TypeVars don't normally have a lower bound, so it is normally set
1017 * to syms.botType.
1018 * Subtypes, such as CapturedType, may provide a different value.
1019 */
1020 public Type lower;
1022 public TypeVar(Name name, Symbol owner, Type lower) {
1023 super(TYPEVAR, null);
1024 tsym = new TypeSymbol(0, name, this, owner);
1025 this.lower = lower;
1026 }
1028 public TypeVar(TypeSymbol tsym, Type bound, Type lower) {
1029 super(TYPEVAR, tsym);
1030 this.bound = bound;
1031 this.lower = lower;
1032 }
1034 @Override
1035 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1036 return v.visitTypeVar(this, s);
1037 }
1039 @Override
1040 public Type getUpperBound() { return bound; }
1042 int rank_field = -1;
1044 @Override
1045 public Type getLowerBound() {
1046 return lower;
1047 }
1049 public TypeKind getKind() {
1050 return TypeKind.TYPEVAR;
1051 }
1053 public boolean isCaptured() {
1054 return false;
1055 }
1057 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1058 return v.visitTypeVariable(this, p);
1059 }
1060 }
1062 /** A captured type variable comes from wildcards which can have
1063 * both upper and lower bound. CapturedType extends TypeVar with
1064 * a lower bound.
1065 */
1066 public static class CapturedType extends TypeVar {
1068 public WildcardType wildcard;
1070 public CapturedType(Name name,
1071 Symbol owner,
1072 Type upper,
1073 Type lower,
1074 WildcardType wildcard) {
1075 super(name, owner, lower);
1076 this.lower = Assert.checkNonNull(lower);
1077 this.bound = upper;
1078 this.wildcard = wildcard;
1079 }
1081 @Override
1082 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1083 return v.visitCapturedType(this, s);
1084 }
1086 @Override
1087 public boolean isCaptured() {
1088 return true;
1089 }
1091 @Override
1092 public String toString() {
1093 return "capture#"
1094 + (hashCode() & 0xFFFFFFFFL) % Printer.PRIME
1095 + " of "
1096 + wildcard;
1097 }
1098 }
1100 public static abstract class DelegatedType extends Type {
1101 public Type qtype;
1102 public DelegatedType(int tag, Type qtype) {
1103 super(tag, qtype.tsym);
1104 this.qtype = qtype;
1105 }
1106 public String toString() { return qtype.toString(); }
1107 public List<Type> getTypeArguments() { return qtype.getTypeArguments(); }
1108 public Type getEnclosingType() { return qtype.getEnclosingType(); }
1109 public List<Type> getParameterTypes() { return qtype.getParameterTypes(); }
1110 public Type getReturnType() { return qtype.getReturnType(); }
1111 public List<Type> getThrownTypes() { return qtype.getThrownTypes(); }
1112 public List<Type> allparams() { return qtype.allparams(); }
1113 public Type getUpperBound() { return qtype.getUpperBound(); }
1114 public boolean isErroneous() { return qtype.isErroneous(); }
1115 }
1117 /**
1118 * The type of a generic method type. It consists of a method type and
1119 * a list of method type-parameters that are used within the method
1120 * type.
1121 */
1122 public static class ForAll extends DelegatedType implements ExecutableType {
1123 public List<Type> tvars;
1125 public ForAll(List<Type> tvars, Type qtype) {
1126 super(FORALL, (MethodType)qtype);
1127 this.tvars = tvars;
1128 }
1130 @Override
1131 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1132 return v.visitForAll(this, s);
1133 }
1135 public String toString() {
1136 return "<" + tvars + ">" + qtype;
1137 }
1139 public List<Type> getTypeArguments() { return tvars; }
1141 public boolean isErroneous() {
1142 return qtype.isErroneous();
1143 }
1145 public Type map(Mapping f) {
1146 return f.apply(qtype);
1147 }
1149 public boolean contains(Type elem) {
1150 return qtype.contains(elem);
1151 }
1153 public MethodType asMethodType() {
1154 return (MethodType)qtype;
1155 }
1157 public void complete() {
1158 for (List<Type> l = tvars; l.nonEmpty(); l = l.tail) {
1159 ((TypeVar)l.head).bound.complete();
1160 }
1161 qtype.complete();
1162 }
1164 public List<TypeVar> getTypeVariables() {
1165 return List.convert(TypeVar.class, getTypeArguments());
1166 }
1168 public TypeKind getKind() {
1169 return TypeKind.EXECUTABLE;
1170 }
1172 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1173 return v.visitExecutable(this, p);
1174 }
1175 }
1177 /** A class for inference variables, for use during method/diamond type
1178 * inference. An inference variable has upper/lower bounds and a set
1179 * of equality constraints. Such bounds are set during subtyping, type-containment,
1180 * type-equality checks, when the types being tested contain inference variables.
1181 * A change listener can be attached to an inference variable, to receive notifications
1182 * whenever the bounds of an inference variable change.
1183 */
1184 public static class UndetVar extends DelegatedType {
1186 /** Inference variable change listener. The listener method is called
1187 * whenever a change to the inference variable's bounds occurs
1188 */
1189 public interface UndetVarListener {
1190 /** called when some inference variable bounds (of given kinds ibs) change */
1191 void varChanged(UndetVar uv, Set<InferenceBound> ibs);
1192 }
1194 /**
1195 * Inference variable bound kinds
1196 */
1197 public enum InferenceBound {
1198 /** upper bounds */
1199 UPPER,
1200 /** lower bounds */
1201 LOWER,
1202 /** equality constraints */
1203 EQ;
1204 }
1206 /** inference variable bounds */
1207 private Map<InferenceBound, List<Type>> bounds;
1209 /** inference variable's inferred type (set from Infer.java) */
1210 public Type inst = null;
1212 /** inference variable's change listener */
1213 public UndetVarListener listener = null;
1215 @Override
1216 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1217 return v.visitUndetVar(this, s);
1218 }
1220 public UndetVar(TypeVar origin, Types types) {
1221 this(origin, types, true);
1222 }
1224 public UndetVar(TypeVar origin, Types types, boolean includeBounds) {
1225 super(UNDETVAR, origin);
1226 bounds = new EnumMap<InferenceBound, List<Type>>(InferenceBound.class);
1227 bounds.put(InferenceBound.UPPER, includeBounds ? types.getBounds(origin) : List.<Type>nil());
1228 bounds.put(InferenceBound.LOWER, List.<Type>nil());
1229 bounds.put(InferenceBound.EQ, List.<Type>nil());
1230 }
1232 public String toString() {
1233 if (inst != null) return inst.toString();
1234 else return qtype + "?";
1235 }
1237 public Type baseType() {
1238 if (inst != null) return inst.baseType();
1239 else return this;
1240 }
1242 /** get all bounds of a given kind */
1243 public List<Type> getBounds(InferenceBound ib) {
1244 return bounds.get(ib);
1245 }
1247 /** add a bound of a given kind - this might trigger listener notification */
1248 public void addBound(InferenceBound ib, Type bound, Types types) {
1249 List<Type> prevBounds = bounds.get(ib);
1250 for (Type b : prevBounds) {
1251 if (types.isSameType(b, bound)) {
1252 return;
1253 }
1254 }
1255 bounds.put(ib, prevBounds.prepend(bound));
1256 notifyChange(EnumSet.of(ib));
1257 }
1259 /** replace types in all bounds - this might trigger listener notification */
1260 public void substBounds(List<Type> from, List<Type> to, Types types) {
1261 EnumSet<InferenceBound> changed = EnumSet.noneOf(InferenceBound.class);
1262 Map<InferenceBound, List<Type>> bounds2 = new EnumMap<InferenceBound, List<Type>>(InferenceBound.class);
1263 for (Map.Entry<InferenceBound, List<Type>> _entry : bounds.entrySet()) {
1264 InferenceBound ib = _entry.getKey();
1265 List<Type> prevBounds = _entry.getValue();
1266 List<Type> newBounds = types.subst(prevBounds, from, to);
1267 bounds2.put(ib, newBounds);
1268 if (prevBounds != newBounds) {
1269 changed.add(ib);
1270 }
1271 }
1272 if (!changed.isEmpty()) {
1273 bounds = bounds2;
1274 notifyChange(changed);
1275 }
1276 }
1278 private void notifyChange(EnumSet<InferenceBound> ibs) {
1279 if (listener != null) {
1280 listener.varChanged(this, ibs);
1281 }
1282 }
1283 }
1285 /** Represents VOID or NONE.
1286 */
1287 static class JCNoType extends Type implements NoType {
1288 public JCNoType(int tag) {
1289 super(tag, null);
1290 }
1292 @Override
1293 public TypeKind getKind() {
1294 switch (tag) {
1295 case VOID: return TypeKind.VOID;
1296 case NONE: return TypeKind.NONE;
1297 default:
1298 throw new AssertionError("Unexpected tag: " + tag);
1299 }
1300 }
1302 @Override
1303 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1304 return v.visitNoType(this, p);
1305 }
1306 }
1308 static class BottomType extends Type implements NullType {
1309 public BottomType() {
1310 super(TypeTags.BOT, null);
1311 }
1313 @Override
1314 public TypeKind getKind() {
1315 return TypeKind.NULL;
1316 }
1318 @Override
1319 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1320 return v.visitNull(this, p);
1321 }
1323 @Override
1324 public Type constType(Object value) {
1325 return this;
1326 }
1328 @Override
1329 public String stringValue() {
1330 return "null";
1331 }
1332 }
1334 public static class ErrorType extends ClassType
1335 implements javax.lang.model.type.ErrorType {
1337 private Type originalType = null;
1339 public ErrorType(Type originalType, TypeSymbol tsym) {
1340 super(noType, List.<Type>nil(), null);
1341 tag = ERROR;
1342 this.tsym = tsym;
1343 this.originalType = (originalType == null ? noType : originalType);
1344 }
1346 public ErrorType(ClassSymbol c, Type originalType) {
1347 this(originalType, c);
1348 c.type = this;
1349 c.kind = ERR;
1350 c.members_field = new Scope.ErrorScope(c);
1351 }
1353 public ErrorType(Name name, TypeSymbol container, Type originalType) {
1354 this(new ClassSymbol(PUBLIC|STATIC|ACYCLIC, name, null, container), originalType);
1355 }
1357 @Override
1358 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1359 return v.visitErrorType(this, s);
1360 }
1362 public Type constType(Object constValue) { return this; }
1363 public Type getEnclosingType() { return this; }
1364 public Type getReturnType() { return this; }
1365 public Type asSub(Symbol sym) { return this; }
1366 public Type map(Mapping f) { return this; }
1368 public boolean isGenType(Type t) { return true; }
1369 public boolean isErroneous() { return true; }
1370 public boolean isCompound() { return false; }
1371 public boolean isInterface() { return false; }
1373 public List<Type> allparams() { return List.nil(); }
1374 public List<Type> getTypeArguments() { return List.nil(); }
1376 public TypeKind getKind() {
1377 return TypeKind.ERROR;
1378 }
1380 public Type getOriginalType() {
1381 return originalType;
1382 }
1384 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1385 return v.visitError(this, p);
1386 }
1387 }
1389 /**
1390 * A visitor for types. A visitor is used to implement operations
1391 * (or relations) on types. Most common operations on types are
1392 * binary relations and this interface is designed for binary
1393 * relations, that is, operations on the form
1394 * Type × S → R.
1395 * <!-- In plain text: Type x S -> R -->
1396 *
1397 * @param <R> the return type of the operation implemented by this
1398 * visitor; use Void if no return type is needed.
1399 * @param <S> the type of the second argument (the first being the
1400 * type itself) of the operation implemented by this visitor; use
1401 * Void if a second argument is not needed.
1402 */
1403 public interface Visitor<R,S> {
1404 R visitClassType(ClassType t, S s);
1405 R visitWildcardType(WildcardType t, S s);
1406 R visitArrayType(ArrayType t, S s);
1407 R visitMethodType(MethodType t, S s);
1408 R visitPackageType(PackageType t, S s);
1409 R visitTypeVar(TypeVar t, S s);
1410 R visitCapturedType(CapturedType t, S s);
1411 R visitForAll(ForAll t, S s);
1412 R visitUndetVar(UndetVar t, S s);
1413 R visitErrorType(ErrorType t, S s);
1414 R visitType(Type t, S s);
1415 }
1416 }