Thu, 04 Jul 2013 10:41:08 +0100
6356530: -Xlint:serial does not flag abstract classes with concrete methods/members
Reviewed-by: mcimadamore
1 /*
2 * Copyright (c) 1999, 2013, 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.lang.annotation.Annotation;
29 import java.util.Collections;
30 import java.util.EnumMap;
31 import java.util.EnumSet;
32 import java.util.Map;
33 import java.util.Set;
35 import javax.lang.model.type.*;
37 import com.sun.tools.javac.code.Symbol.*;
38 import com.sun.tools.javac.model.JavacAnnoConstructs;
39 import com.sun.tools.javac.util.*;
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.TypeTag.*;
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 TypeTag
72 */
73 public abstract class Type implements TypeMirror {
75 /** Constant type: no type at all. */
76 public static final JCNoType noType = new JCNoType();
78 /** Constant type: special type to be used during recovery of deferred expressions. */
79 public static final JCNoType recoveryType = new JCNoType();
81 /** If this switch is turned on, the names of type variables
82 * and anonymous classes are printed with hashcodes appended.
83 */
84 public static boolean moreInfo = false;
86 /** The defining class / interface / package / type variable.
87 */
88 public TypeSymbol tsym;
90 /**
91 * Checks if the current type tag is equal to the given tag.
92 * @return true if tag is equal to the current type tag.
93 */
94 public boolean hasTag(TypeTag tag) {
95 return tag == getTag();
96 }
98 /**
99 * Returns the current type tag.
100 * @return the value of the current type tag.
101 */
102 public abstract TypeTag getTag();
104 public boolean isNumeric() {
105 return false;
106 }
108 public boolean isPrimitive() {
109 return false;
110 }
112 public boolean isPrimitiveOrVoid() {
113 return false;
114 }
116 public boolean isReference() {
117 return false;
118 }
120 public boolean isNullOrReference() {
121 return false;
122 }
124 public boolean isPartial() {
125 return false;
126 }
128 /**
129 * The constant value of this type, null if this type does not
130 * have a constant value attribute. Only primitive types and
131 * strings (ClassType) can have a constant value attribute.
132 * @return the constant value attribute of this type
133 */
134 public Object constValue() {
135 return null;
136 }
138 /** Is this a constant type whose value is false?
139 */
140 public boolean isFalse() {
141 return false;
142 }
144 /** Is this a constant type whose value is true?
145 */
146 public boolean isTrue() {
147 return false;
148 }
150 /**
151 * Get the representation of this type used for modelling purposes.
152 * By default, this is itself. For ErrorType, a different value
153 * may be provided.
154 */
155 public Type getModelType() {
156 return this;
157 }
159 public static List<Type> getModelTypes(List<Type> ts) {
160 ListBuffer<Type> lb = new ListBuffer<>();
161 for (Type t: ts)
162 lb.append(t.getModelType());
163 return lb.toList();
164 }
166 public <R,S> R accept(Type.Visitor<R,S> v, S s) { return v.visitType(this, s); }
168 /** Define a type given its tag and type symbol
169 */
170 public Type(TypeSymbol tsym) {
171 this.tsym = tsym;
172 }
174 /** An abstract class for mappings from types to types
175 */
176 public static abstract class Mapping {
177 private String name;
178 public Mapping(String name) {
179 this.name = name;
180 }
181 public abstract Type apply(Type t);
182 public String toString() {
183 return name;
184 }
185 }
187 /** map a type function over all immediate descendants of this type
188 */
189 public Type map(Mapping f) {
190 return this;
191 }
193 /** map a type function over a list of types
194 */
195 public static List<Type> map(List<Type> ts, Mapping f) {
196 if (ts.nonEmpty()) {
197 List<Type> tail1 = map(ts.tail, f);
198 Type t = f.apply(ts.head);
199 if (tail1 != ts.tail || t != ts.head)
200 return tail1.prepend(t);
201 }
202 return ts;
203 }
205 /** Define a constant type, of the same kind as this type
206 * and with given constant value
207 */
208 public Type constType(Object constValue) {
209 throw new AssertionError();
210 }
212 /**
213 * If this is a constant type, return its underlying type.
214 * Otherwise, return the type itself.
215 */
216 public Type baseType() {
217 return this;
218 }
220 public boolean isAnnotated() {
221 return false;
222 }
224 /**
225 * If this is an annotated type, return the underlying type.
226 * Otherwise, return the type itself.
227 */
228 public Type unannotatedType() {
229 return this;
230 }
232 @Override
233 public List<? extends Attribute.TypeCompound> getAnnotationMirrors() {
234 return List.nil();
235 }
237 @Override
238 public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
239 return null;
240 }
242 @Override
243 public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
244 @SuppressWarnings("unchecked")
245 A[] tmp = (A[]) java.lang.reflect.Array.newInstance(annotationType, 0);
246 return tmp;
247 }
249 /** Return the base types of a list of types.
250 */
251 public static List<Type> baseTypes(List<Type> ts) {
252 if (ts.nonEmpty()) {
253 Type t = ts.head.baseType();
254 List<Type> baseTypes = baseTypes(ts.tail);
255 if (t != ts.head || baseTypes != ts.tail)
256 return baseTypes.prepend(t);
257 }
258 return ts;
259 }
261 /** The Java source which this type represents.
262 */
263 public String toString() {
264 String s = (tsym == null || tsym.name == null)
265 ? "<none>"
266 : tsym.name.toString();
267 if (moreInfo && hasTag(TYPEVAR)) {
268 s = s + hashCode();
269 }
270 return s;
271 }
273 /**
274 * The Java source which this type list represents. A List is
275 * represented as a comma-spearated listing of the elements in
276 * that list.
277 */
278 public static String toString(List<Type> ts) {
279 if (ts.isEmpty()) {
280 return "";
281 } else {
282 StringBuilder buf = new StringBuilder();
283 buf.append(ts.head.toString());
284 for (List<Type> l = ts.tail; l.nonEmpty(); l = l.tail)
285 buf.append(",").append(l.head.toString());
286 return buf.toString();
287 }
288 }
290 /**
291 * The constant value of this type, converted to String
292 */
293 public String stringValue() {
294 Object cv = Assert.checkNonNull(constValue());
295 return cv.toString();
296 }
298 /**
299 * This method is analogous to isSameType, but weaker, since we
300 * never complete classes. Where isSameType would complete a
301 * class, equals assumes that the two types are different.
302 */
303 @Override
304 public boolean equals(Object t) {
305 return super.equals(t);
306 }
308 @Override
309 public int hashCode() {
310 return super.hashCode();
311 }
313 public String argtypes(boolean varargs) {
314 List<Type> args = getParameterTypes();
315 if (!varargs) return args.toString();
316 StringBuilder buf = new StringBuilder();
317 while (args.tail.nonEmpty()) {
318 buf.append(args.head);
319 args = args.tail;
320 buf.append(',');
321 }
322 if (args.head.unannotatedType().hasTag(ARRAY)) {
323 buf.append(((ArrayType)args.head.unannotatedType()).elemtype);
324 if (args.head.getAnnotationMirrors().nonEmpty()) {
325 buf.append(args.head.getAnnotationMirrors());
326 }
327 buf.append("...");
328 } else {
329 buf.append(args.head);
330 }
331 return buf.toString();
332 }
334 /** Access methods.
335 */
336 public List<Type> getTypeArguments() { return List.nil(); }
337 public Type getEnclosingType() { return null; }
338 public List<Type> getParameterTypes() { return List.nil(); }
339 public Type getReturnType() { return null; }
340 public Type getReceiverType() { return null; }
341 public List<Type> getThrownTypes() { return List.nil(); }
342 public Type getUpperBound() { return null; }
343 public Type getLowerBound() { return null; }
345 /** Navigation methods, these will work for classes, type variables,
346 * foralls, but will return null for arrays and methods.
347 */
349 /** Return all parameters of this type and all its outer types in order
350 * outer (first) to inner (last).
351 */
352 public List<Type> allparams() { return List.nil(); }
354 /** Does this type contain "error" elements?
355 */
356 public boolean isErroneous() {
357 return false;
358 }
360 public static boolean isErroneous(List<Type> ts) {
361 for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
362 if (l.head.isErroneous()) return true;
363 return false;
364 }
366 /** Is this type parameterized?
367 * A class type is parameterized if it has some parameters.
368 * An array type is parameterized if its element type is parameterized.
369 * All other types are not parameterized.
370 */
371 public boolean isParameterized() {
372 return false;
373 }
375 /** Is this type a raw type?
376 * A class type is a raw type if it misses some of its parameters.
377 * An array type is a raw type if its element type is raw.
378 * All other types are not raw.
379 * Type validation will ensure that the only raw types
380 * in a program are types that miss all their type variables.
381 */
382 public boolean isRaw() {
383 return false;
384 }
386 public boolean isCompound() {
387 return tsym.completer == null
388 // Compound types can't have a completer. Calling
389 // flags() will complete the symbol causing the
390 // compiler to load classes unnecessarily. This led
391 // to regression 6180021.
392 && (tsym.flags() & COMPOUND) != 0;
393 }
395 public boolean isInterface() {
396 return (tsym.flags() & INTERFACE) != 0;
397 }
399 public boolean isFinal() {
400 return (tsym.flags() & FINAL) != 0;
401 }
403 /**
404 * Does this type contain occurrences of type t?
405 */
406 public boolean contains(Type t) {
407 return t == this;
408 }
410 public static boolean contains(List<Type> ts, Type t) {
411 for (List<Type> l = ts;
412 l.tail != null /*inlined: l.nonEmpty()*/;
413 l = l.tail)
414 if (l.head.contains(t)) return true;
415 return false;
416 }
418 /** Does this type contain an occurrence of some type in 'ts'?
419 */
420 public boolean containsAny(List<Type> ts) {
421 for (Type t : ts)
422 if (this.contains(t)) return true;
423 return false;
424 }
426 public static boolean containsAny(List<Type> ts1, List<Type> ts2) {
427 for (Type t : ts1)
428 if (t.containsAny(ts2)) return true;
429 return false;
430 }
432 public static List<Type> filter(List<Type> ts, Filter<Type> tf) {
433 ListBuffer<Type> buf = ListBuffer.lb();
434 for (Type t : ts) {
435 if (tf.accepts(t)) {
436 buf.append(t);
437 }
438 }
439 return buf.toList();
440 }
442 public boolean isSuperBound() { return false; }
443 public boolean isExtendsBound() { return false; }
444 public boolean isUnbound() { return false; }
445 public Type withTypeVar(Type t) { return this; }
447 /** The underlying method type of this type.
448 */
449 public MethodType asMethodType() { throw new AssertionError(); }
451 /** Complete loading all classes in this type.
452 */
453 public void complete() {}
455 public TypeSymbol asElement() {
456 return tsym;
457 }
459 @Override
460 public TypeKind getKind() {
461 return TypeKind.OTHER;
462 }
464 @Override
465 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
466 throw new AssertionError();
467 }
469 public static class JCPrimitiveType extends Type
470 implements javax.lang.model.type.PrimitiveType {
472 TypeTag tag;
474 public JCPrimitiveType(TypeTag tag, TypeSymbol tsym) {
475 super(tsym);
476 this.tag = tag;
477 Assert.check(tag.isPrimitive);
478 }
480 @Override
481 public boolean isNumeric() {
482 return tag != BOOLEAN;
483 }
485 @Override
486 public boolean isPrimitive() {
487 return true;
488 }
490 @Override
491 public TypeTag getTag() {
492 return tag;
493 }
495 @Override
496 public boolean isPrimitiveOrVoid() {
497 return true;
498 }
500 /** Define a constant type, of the same kind as this type
501 * and with given constant value
502 */
503 @Override
504 public Type constType(Object constValue) {
505 final Object value = constValue;
506 return new JCPrimitiveType(tag, tsym) {
507 @Override
508 public Object constValue() {
509 return value;
510 }
511 @Override
512 public Type baseType() {
513 return tsym.type;
514 }
515 };
516 }
518 /**
519 * The constant value of this type, converted to String
520 */
521 @Override
522 public String stringValue() {
523 Object cv = Assert.checkNonNull(constValue());
524 if (tag == BOOLEAN) {
525 return ((Integer) cv).intValue() == 0 ? "false" : "true";
526 }
527 else if (tag == CHAR) {
528 return String.valueOf((char) ((Integer) cv).intValue());
529 }
530 else {
531 return cv.toString();
532 }
533 }
535 /** Is this a constant type whose value is false?
536 */
537 @Override
538 public boolean isFalse() {
539 return
540 tag == BOOLEAN &&
541 constValue() != null &&
542 ((Integer)constValue()).intValue() == 0;
543 }
545 /** Is this a constant type whose value is true?
546 */
547 @Override
548 public boolean isTrue() {
549 return
550 tag == BOOLEAN &&
551 constValue() != null &&
552 ((Integer)constValue()).intValue() != 0;
553 }
555 @Override
556 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
557 return v.visitPrimitive(this, p);
558 }
560 @Override
561 public TypeKind getKind() {
562 switch (tag) {
563 case BYTE: return TypeKind.BYTE;
564 case CHAR: return TypeKind.CHAR;
565 case SHORT: return TypeKind.SHORT;
566 case INT: return TypeKind.INT;
567 case LONG: return TypeKind.LONG;
568 case FLOAT: return TypeKind.FLOAT;
569 case DOUBLE: return TypeKind.DOUBLE;
570 case BOOLEAN: return TypeKind.BOOLEAN;
571 }
572 throw new AssertionError();
573 }
575 }
577 public static class WildcardType extends Type
578 implements javax.lang.model.type.WildcardType {
580 public Type type;
581 public BoundKind kind;
582 public TypeVar bound;
584 @Override
585 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
586 return v.visitWildcardType(this, s);
587 }
589 public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) {
590 super(tsym);
591 this.type = Assert.checkNonNull(type);
592 this.kind = kind;
593 }
594 public WildcardType(WildcardType t, TypeVar bound) {
595 this(t.type, t.kind, t.tsym, bound);
596 }
598 public WildcardType(Type type, BoundKind kind, TypeSymbol tsym, TypeVar bound) {
599 this(type, kind, tsym);
600 this.bound = bound;
601 }
603 @Override
604 public TypeTag getTag() {
605 return WILDCARD;
606 }
608 @Override
609 public boolean contains(Type t) {
610 return kind != UNBOUND && type.contains(t);
611 }
613 public boolean isSuperBound() {
614 return kind == SUPER ||
615 kind == UNBOUND;
616 }
617 public boolean isExtendsBound() {
618 return kind == EXTENDS ||
619 kind == UNBOUND;
620 }
621 public boolean isUnbound() {
622 return kind == UNBOUND;
623 }
625 @Override
626 public boolean isReference() {
627 return true;
628 }
630 @Override
631 public boolean isNullOrReference() {
632 return true;
633 }
635 @Override
636 public Type withTypeVar(Type t) {
637 //-System.err.println(this+".withTypeVar("+t+");");//DEBUG
638 if (bound == t)
639 return this;
640 bound = (TypeVar)t;
641 return this;
642 }
644 boolean isPrintingBound = false;
645 public String toString() {
646 StringBuilder s = new StringBuilder();
647 s.append(kind.toString());
648 if (kind != UNBOUND)
649 s.append(type);
650 if (moreInfo && bound != null && !isPrintingBound)
651 try {
652 isPrintingBound = true;
653 s.append("{:").append(bound.bound).append(":}");
654 } finally {
655 isPrintingBound = false;
656 }
657 return s.toString();
658 }
660 public Type map(Mapping f) {
661 //- System.err.println(" (" + this + ").map(" + f + ")");//DEBUG
662 Type t = type;
663 if (t != null)
664 t = f.apply(t);
665 if (t == type)
666 return this;
667 else
668 return new WildcardType(t, kind, tsym, bound);
669 }
671 public Type getExtendsBound() {
672 if (kind == EXTENDS)
673 return type;
674 else
675 return null;
676 }
678 public Type getSuperBound() {
679 if (kind == SUPER)
680 return type;
681 else
682 return null;
683 }
685 public TypeKind getKind() {
686 return TypeKind.WILDCARD;
687 }
689 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
690 return v.visitWildcard(this, p);
691 }
692 }
694 public static class ClassType extends Type implements DeclaredType {
696 /** The enclosing type of this type. If this is the type of an inner
697 * class, outer_field refers to the type of its enclosing
698 * instance class, in all other cases it refers to noType.
699 */
700 private Type outer_field;
702 /** The type parameters of this type (to be set once class is loaded).
703 */
704 public List<Type> typarams_field;
706 /** A cache variable for the type parameters of this type,
707 * appended to all parameters of its enclosing class.
708 * @see #allparams
709 */
710 public List<Type> allparams_field;
712 /** The supertype of this class (to be set once class is loaded).
713 */
714 public Type supertype_field;
716 /** The interfaces of this class (to be set once class is loaded).
717 */
718 public List<Type> interfaces_field;
720 /** All the interfaces of this class, including missing ones.
721 */
722 public List<Type> all_interfaces_field;
724 public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
725 super(tsym);
726 this.outer_field = outer;
727 this.typarams_field = typarams;
728 this.allparams_field = null;
729 this.supertype_field = null;
730 this.interfaces_field = null;
731 /*
732 // this can happen during error recovery
733 assert
734 outer.isParameterized() ?
735 typarams.length() == tsym.type.typarams().length() :
736 outer.isRaw() ?
737 typarams.length() == 0 :
738 true;
739 */
740 }
742 @Override
743 public TypeTag getTag() {
744 return CLASS;
745 }
747 @Override
748 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
749 return v.visitClassType(this, s);
750 }
752 public Type constType(Object constValue) {
753 final Object value = constValue;
754 return new ClassType(getEnclosingType(), typarams_field, tsym) {
755 @Override
756 public Object constValue() {
757 return value;
758 }
759 @Override
760 public Type baseType() {
761 return tsym.type;
762 }
763 };
764 }
766 /** The Java source which this type represents.
767 */
768 public String toString() {
769 StringBuilder buf = new StringBuilder();
770 if (getEnclosingType().hasTag(CLASS) && tsym.owner.kind == TYP) {
771 buf.append(getEnclosingType().toString());
772 buf.append(".");
773 buf.append(className(tsym, false));
774 } else {
775 buf.append(className(tsym, true));
776 }
777 if (getTypeArguments().nonEmpty()) {
778 buf.append('<');
779 buf.append(getTypeArguments().toString());
780 buf.append(">");
781 }
782 return buf.toString();
783 }
784 //where
785 private String className(Symbol sym, boolean longform) {
786 if (sym.name.isEmpty() && (sym.flags() & COMPOUND) != 0) {
787 StringBuilder s = new StringBuilder(supertype_field.toString());
788 for (List<Type> is=interfaces_field; is.nonEmpty(); is = is.tail) {
789 s.append("&");
790 s.append(is.head.toString());
791 }
792 return s.toString();
793 } else if (sym.name.isEmpty()) {
794 String s;
795 ClassType norm = (ClassType) tsym.type.unannotatedType();
796 if (norm == null) {
797 s = Log.getLocalizedString("anonymous.class", (Object)null);
798 } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
799 s = Log.getLocalizedString("anonymous.class",
800 norm.interfaces_field.head);
801 } else {
802 s = Log.getLocalizedString("anonymous.class",
803 norm.supertype_field);
804 }
805 if (moreInfo)
806 s += String.valueOf(sym.hashCode());
807 return s;
808 } else if (longform) {
809 return sym.getQualifiedName().toString();
810 } else {
811 return sym.name.toString();
812 }
813 }
815 public List<Type> getTypeArguments() {
816 if (typarams_field == null) {
817 complete();
818 if (typarams_field == null)
819 typarams_field = List.nil();
820 }
821 return typarams_field;
822 }
824 public boolean hasErasedSupertypes() {
825 return isRaw();
826 }
828 public Type getEnclosingType() {
829 return outer_field;
830 }
832 public void setEnclosingType(Type outer) {
833 outer_field = outer;
834 }
836 public List<Type> allparams() {
837 if (allparams_field == null) {
838 allparams_field = getTypeArguments().prependList(getEnclosingType().allparams());
839 }
840 return allparams_field;
841 }
843 public boolean isErroneous() {
844 return
845 getEnclosingType().isErroneous() ||
846 isErroneous(getTypeArguments()) ||
847 this != tsym.type.unannotatedType() && tsym.type.isErroneous();
848 }
850 public boolean isParameterized() {
851 return allparams().tail != null;
852 // optimization, was: allparams().nonEmpty();
853 }
855 @Override
856 public boolean isReference() {
857 return true;
858 }
860 @Override
861 public boolean isNullOrReference() {
862 return true;
863 }
865 /** A cache for the rank. */
866 int rank_field = -1;
868 /** A class type is raw if it misses some
869 * of its type parameter sections.
870 * After validation, this is equivalent to:
871 * {@code allparams.isEmpty() && tsym.type.allparams.nonEmpty(); }
872 */
873 public boolean isRaw() {
874 return
875 this != tsym.type && // necessary, but not sufficient condition
876 tsym.type.allparams().nonEmpty() &&
877 allparams().isEmpty();
878 }
880 public Type map(Mapping f) {
881 Type outer = getEnclosingType();
882 Type outer1 = f.apply(outer);
883 List<Type> typarams = getTypeArguments();
884 List<Type> typarams1 = map(typarams, f);
885 if (outer1 == outer && typarams1 == typarams) return this;
886 else return new ClassType(outer1, typarams1, tsym);
887 }
889 public boolean contains(Type elem) {
890 return
891 elem == this
892 || (isParameterized()
893 && (getEnclosingType().contains(elem) || contains(getTypeArguments(), elem)))
894 || (isCompound()
895 && (supertype_field.contains(elem) || contains(interfaces_field, elem)));
896 }
898 public void complete() {
899 if (tsym.completer != null) tsym.complete();
900 }
902 public TypeKind getKind() {
903 return TypeKind.DECLARED;
904 }
906 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
907 return v.visitDeclared(this, p);
908 }
909 }
911 public static class ErasedClassType extends ClassType {
912 public ErasedClassType(Type outer, TypeSymbol tsym) {
913 super(outer, List.<Type>nil(), tsym);
914 }
916 @Override
917 public boolean hasErasedSupertypes() {
918 return true;
919 }
920 }
922 // a clone of a ClassType that knows about the alternatives of a union type.
923 public static class UnionClassType extends ClassType implements UnionType {
924 final List<? extends Type> alternatives_field;
926 public UnionClassType(ClassType ct, List<? extends Type> alternatives) {
927 super(ct.outer_field, ct.typarams_field, ct.tsym);
928 allparams_field = ct.allparams_field;
929 supertype_field = ct.supertype_field;
930 interfaces_field = ct.interfaces_field;
931 all_interfaces_field = ct.interfaces_field;
932 alternatives_field = alternatives;
933 }
935 public Type getLub() {
936 return tsym.type;
937 }
939 public java.util.List<? extends TypeMirror> getAlternatives() {
940 return Collections.unmodifiableList(alternatives_field);
941 }
943 @Override
944 public TypeKind getKind() {
945 return TypeKind.UNION;
946 }
948 @Override
949 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
950 return v.visitUnion(this, p);
951 }
952 }
954 // a clone of a ClassType that knows about the bounds of an intersection type.
955 public static class IntersectionClassType extends ClassType implements IntersectionType {
957 public boolean allInterfaces;
959 public enum IntersectionKind {
960 EXPLICIT,
961 IMPLICT;
962 }
964 public IntersectionKind intersectionKind;
966 public IntersectionClassType(List<Type> bounds, ClassSymbol csym, boolean allInterfaces) {
967 super(Type.noType, List.<Type>nil(), csym);
968 this.allInterfaces = allInterfaces;
969 Assert.check((csym.flags() & COMPOUND) != 0);
970 supertype_field = bounds.head;
971 interfaces_field = bounds.tail;
972 Assert.check(supertype_field.tsym.completer != null ||
973 !supertype_field.isInterface(), supertype_field);
974 }
976 public java.util.List<? extends TypeMirror> getBounds() {
977 return Collections.unmodifiableList(getComponents());
978 }
980 public List<Type> getComponents() {
981 return interfaces_field.prepend(supertype_field);
982 }
984 public List<Type> getExplicitComponents() {
985 return allInterfaces ?
986 interfaces_field :
987 getComponents();
988 }
990 @Override
991 public TypeKind getKind() {
992 return TypeKind.INTERSECTION;
993 }
995 @Override
996 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
997 return intersectionKind == IntersectionKind.EXPLICIT ?
998 v.visitIntersection(this, p) :
999 v.visitDeclared(this, p);
1000 }
1001 }
1003 public static class ArrayType extends Type
1004 implements javax.lang.model.type.ArrayType {
1006 public Type elemtype;
1008 public ArrayType(Type elemtype, TypeSymbol arrayClass) {
1009 super(arrayClass);
1010 this.elemtype = elemtype;
1011 }
1013 @Override
1014 public TypeTag getTag() {
1015 return ARRAY;
1016 }
1018 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1019 return v.visitArrayType(this, s);
1020 }
1022 public String toString() {
1023 return elemtype + "[]";
1024 }
1026 public boolean equals(Object obj) {
1027 return
1028 this == obj ||
1029 (obj instanceof ArrayType &&
1030 this.elemtype.equals(((ArrayType)obj).elemtype));
1031 }
1033 public int hashCode() {
1034 return (ARRAY.ordinal() << 5) + elemtype.hashCode();
1035 }
1037 public boolean isVarargs() {
1038 return false;
1039 }
1041 public List<Type> allparams() { return elemtype.allparams(); }
1043 public boolean isErroneous() {
1044 return elemtype.isErroneous();
1045 }
1047 public boolean isParameterized() {
1048 return elemtype.isParameterized();
1049 }
1051 @Override
1052 public boolean isReference() {
1053 return true;
1054 }
1056 @Override
1057 public boolean isNullOrReference() {
1058 return true;
1059 }
1061 public boolean isRaw() {
1062 return elemtype.isRaw();
1063 }
1065 public ArrayType makeVarargs() {
1066 return new ArrayType(elemtype, tsym) {
1067 @Override
1068 public boolean isVarargs() {
1069 return true;
1070 }
1071 };
1072 }
1074 public Type map(Mapping f) {
1075 Type elemtype1 = f.apply(elemtype);
1076 if (elemtype1 == elemtype) return this;
1077 else return new ArrayType(elemtype1, tsym);
1078 }
1080 public boolean contains(Type elem) {
1081 return elem == this || elemtype.contains(elem);
1082 }
1084 public void complete() {
1085 elemtype.complete();
1086 }
1088 public Type getComponentType() {
1089 return elemtype;
1090 }
1092 public TypeKind getKind() {
1093 return TypeKind.ARRAY;
1094 }
1096 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1097 return v.visitArray(this, p);
1098 }
1099 }
1101 public static class MethodType extends Type implements ExecutableType {
1103 public List<Type> argtypes;
1104 public Type restype;
1105 public List<Type> thrown;
1107 /** The type annotations on the method receiver.
1108 */
1109 public Type recvtype;
1111 public MethodType(List<Type> argtypes,
1112 Type restype,
1113 List<Type> thrown,
1114 TypeSymbol methodClass) {
1115 super(methodClass);
1116 this.argtypes = argtypes;
1117 this.restype = restype;
1118 this.thrown = thrown;
1119 }
1121 @Override
1122 public TypeTag getTag() {
1123 return METHOD;
1124 }
1126 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1127 return v.visitMethodType(this, s);
1128 }
1130 /** The Java source which this type represents.
1131 *
1132 * XXX 06/09/99 iris This isn't correct Java syntax, but it probably
1133 * should be.
1134 */
1135 public String toString() {
1136 return "(" + argtypes + ")" + restype;
1137 }
1139 public List<Type> getParameterTypes() { return argtypes; }
1140 public Type getReturnType() { return restype; }
1141 public Type getReceiverType() { return recvtype; }
1142 public List<Type> getThrownTypes() { return thrown; }
1144 public boolean isErroneous() {
1145 return
1146 isErroneous(argtypes) ||
1147 restype != null && restype.isErroneous();
1148 }
1150 public Type map(Mapping f) {
1151 List<Type> argtypes1 = map(argtypes, f);
1152 Type restype1 = f.apply(restype);
1153 List<Type> thrown1 = map(thrown, f);
1154 if (argtypes1 == argtypes &&
1155 restype1 == restype &&
1156 thrown1 == thrown) return this;
1157 else return new MethodType(argtypes1, restype1, thrown1, tsym);
1158 }
1160 public boolean contains(Type elem) {
1161 return elem == this || contains(argtypes, elem) || restype.contains(elem);
1162 }
1164 public MethodType asMethodType() { return this; }
1166 public void complete() {
1167 for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
1168 l.head.complete();
1169 restype.complete();
1170 recvtype.complete();
1171 for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
1172 l.head.complete();
1173 }
1175 public List<TypeVar> getTypeVariables() {
1176 return List.nil();
1177 }
1179 public TypeSymbol asElement() {
1180 return null;
1181 }
1183 public TypeKind getKind() {
1184 return TypeKind.EXECUTABLE;
1185 }
1187 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1188 return v.visitExecutable(this, p);
1189 }
1190 }
1192 public static class PackageType extends Type implements NoType {
1194 PackageType(TypeSymbol tsym) {
1195 super(tsym);
1196 }
1198 @Override
1199 public TypeTag getTag() {
1200 return PACKAGE;
1201 }
1203 @Override
1204 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1205 return v.visitPackageType(this, s);
1206 }
1208 public String toString() {
1209 return tsym.getQualifiedName().toString();
1210 }
1212 public TypeKind getKind() {
1213 return TypeKind.PACKAGE;
1214 }
1216 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1217 return v.visitNoType(this, p);
1218 }
1219 }
1221 public static class TypeVar extends Type implements TypeVariable {
1223 /** The upper bound of this type variable; set from outside.
1224 * Must be nonempty once it is set.
1225 * For a bound, `bound' is the bound type itself.
1226 * Multiple bounds are expressed as a single class type which has the
1227 * individual bounds as superclass, respectively interfaces.
1228 * The class type then has as `tsym' a compiler generated class `c',
1229 * which has a flag COMPOUND and whose owner is the type variable
1230 * itself. Furthermore, the erasure_field of the class
1231 * points to the first class or interface bound.
1232 */
1233 public Type bound = null;
1235 /** The lower bound of this type variable.
1236 * TypeVars don't normally have a lower bound, so it is normally set
1237 * to syms.botType.
1238 * Subtypes, such as CapturedType, may provide a different value.
1239 */
1240 public Type lower;
1242 public TypeVar(Name name, Symbol owner, Type lower) {
1243 super(null);
1244 tsym = new TypeVariableSymbol(0, name, this, owner);
1245 this.lower = lower;
1246 }
1248 public TypeVar(TypeSymbol tsym, Type bound, Type lower) {
1249 super(tsym);
1250 this.bound = bound;
1251 this.lower = lower;
1252 }
1254 @Override
1255 public TypeTag getTag() {
1256 return TYPEVAR;
1257 }
1259 @Override
1260 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1261 return v.visitTypeVar(this, s);
1262 }
1264 @Override
1265 public Type getUpperBound() {
1266 if ((bound == null || bound.hasTag(NONE)) && this != tsym.type) {
1267 bound = tsym.type.getUpperBound();
1268 }
1269 return bound;
1270 }
1272 int rank_field = -1;
1274 @Override
1275 public Type getLowerBound() {
1276 return lower;
1277 }
1279 public TypeKind getKind() {
1280 return TypeKind.TYPEVAR;
1281 }
1283 public boolean isCaptured() {
1284 return false;
1285 }
1287 @Override
1288 public boolean isReference() {
1289 return true;
1290 }
1292 @Override
1293 public boolean isNullOrReference() {
1294 return true;
1295 }
1297 @Override
1298 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1299 return v.visitTypeVariable(this, p);
1300 }
1301 }
1303 /** A captured type variable comes from wildcards which can have
1304 * both upper and lower bound. CapturedType extends TypeVar with
1305 * a lower bound.
1306 */
1307 public static class CapturedType extends TypeVar {
1309 public WildcardType wildcard;
1311 public CapturedType(Name name,
1312 Symbol owner,
1313 Type upper,
1314 Type lower,
1315 WildcardType wildcard) {
1316 super(name, owner, lower);
1317 this.lower = Assert.checkNonNull(lower);
1318 this.bound = upper;
1319 this.wildcard = wildcard;
1320 }
1322 @Override
1323 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1324 return v.visitCapturedType(this, s);
1325 }
1327 @Override
1328 public boolean isCaptured() {
1329 return true;
1330 }
1332 @Override
1333 public String toString() {
1334 return "capture#"
1335 + (hashCode() & 0xFFFFFFFFL) % Printer.PRIME
1336 + " of "
1337 + wildcard;
1338 }
1339 }
1341 public static abstract class DelegatedType extends Type {
1342 public Type qtype;
1343 public TypeTag tag;
1344 public DelegatedType(TypeTag tag, Type qtype) {
1345 super(qtype.tsym);
1346 this.tag = tag;
1347 this.qtype = qtype;
1348 }
1349 public TypeTag getTag() { return tag; }
1350 public String toString() { return qtype.toString(); }
1351 public List<Type> getTypeArguments() { return qtype.getTypeArguments(); }
1352 public Type getEnclosingType() { return qtype.getEnclosingType(); }
1353 public List<Type> getParameterTypes() { return qtype.getParameterTypes(); }
1354 public Type getReturnType() { return qtype.getReturnType(); }
1355 public Type getReceiverType() { return qtype.getReceiverType(); }
1356 public List<Type> getThrownTypes() { return qtype.getThrownTypes(); }
1357 public List<Type> allparams() { return qtype.allparams(); }
1358 public Type getUpperBound() { return qtype.getUpperBound(); }
1359 public boolean isErroneous() { return qtype.isErroneous(); }
1360 }
1362 /**
1363 * The type of a generic method type. It consists of a method type and
1364 * a list of method type-parameters that are used within the method
1365 * type.
1366 */
1367 public static class ForAll extends DelegatedType implements ExecutableType {
1368 public List<Type> tvars;
1370 public ForAll(List<Type> tvars, Type qtype) {
1371 super(FORALL, (MethodType)qtype);
1372 this.tvars = tvars;
1373 }
1375 @Override
1376 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1377 return v.visitForAll(this, s);
1378 }
1380 public String toString() {
1381 return "<" + tvars + ">" + qtype;
1382 }
1384 public List<Type> getTypeArguments() { return tvars; }
1386 public boolean isErroneous() {
1387 return qtype.isErroneous();
1388 }
1390 public Type map(Mapping f) {
1391 return f.apply(qtype);
1392 }
1394 public boolean contains(Type elem) {
1395 return qtype.contains(elem);
1396 }
1398 public MethodType asMethodType() {
1399 return (MethodType)qtype;
1400 }
1402 public void complete() {
1403 for (List<Type> l = tvars; l.nonEmpty(); l = l.tail) {
1404 ((TypeVar)l.head).bound.complete();
1405 }
1406 qtype.complete();
1407 }
1409 public List<TypeVar> getTypeVariables() {
1410 return List.convert(TypeVar.class, getTypeArguments());
1411 }
1413 public TypeKind getKind() {
1414 return TypeKind.EXECUTABLE;
1415 }
1417 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1418 return v.visitExecutable(this, p);
1419 }
1420 }
1422 /** A class for inference variables, for use during method/diamond type
1423 * inference. An inference variable has upper/lower bounds and a set
1424 * of equality constraints. Such bounds are set during subtyping, type-containment,
1425 * type-equality checks, when the types being tested contain inference variables.
1426 * A change listener can be attached to an inference variable, to receive notifications
1427 * whenever the bounds of an inference variable change.
1428 */
1429 public static class UndetVar extends DelegatedType {
1431 /** Inference variable change listener. The listener method is called
1432 * whenever a change to the inference variable's bounds occurs
1433 */
1434 public interface UndetVarListener {
1435 /** called when some inference variable bounds (of given kinds ibs) change */
1436 void varChanged(UndetVar uv, Set<InferenceBound> ibs);
1437 }
1439 /**
1440 * Inference variable bound kinds
1441 */
1442 public enum InferenceBound {
1443 /** upper bounds */
1444 UPPER,
1445 /** lower bounds */
1446 LOWER,
1447 /** equality constraints */
1448 EQ;
1449 }
1451 /** inference variable bounds */
1452 private Map<InferenceBound, List<Type>> bounds;
1454 /** inference variable's inferred type (set from Infer.java) */
1455 public Type inst = null;
1457 /** number of declared (upper) bounds */
1458 public int declaredCount;
1460 /** inference variable's change listener */
1461 public UndetVarListener listener = null;
1463 @Override
1464 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1465 return v.visitUndetVar(this, s);
1466 }
1468 public UndetVar(TypeVar origin, Types types) {
1469 super(UNDETVAR, origin);
1470 bounds = new EnumMap<InferenceBound, List<Type>>(InferenceBound.class);
1471 List<Type> declaredBounds = types.getBounds(origin);
1472 declaredCount = declaredBounds.length();
1473 bounds.put(InferenceBound.UPPER, declaredBounds);
1474 bounds.put(InferenceBound.LOWER, List.<Type>nil());
1475 bounds.put(InferenceBound.EQ, List.<Type>nil());
1476 }
1478 public String toString() {
1479 if (inst != null) return inst.toString();
1480 else return qtype + "?";
1481 }
1483 @Override
1484 public boolean isPartial() {
1485 return true;
1486 }
1488 @Override
1489 public Type baseType() {
1490 if (inst != null) return inst.baseType();
1491 else return this;
1492 }
1494 /** get all bounds of a given kind */
1495 public List<Type> getBounds(InferenceBound... ibs) {
1496 ListBuffer<Type> buf = ListBuffer.lb();
1497 for (InferenceBound ib : ibs) {
1498 buf.appendList(bounds.get(ib));
1499 }
1500 return buf.toList();
1501 }
1503 /** get the list of declared (upper) bounds */
1504 public List<Type> getDeclaredBounds() {
1505 ListBuffer<Type> buf = ListBuffer.lb();
1506 int count = 0;
1507 for (Type b : getBounds(InferenceBound.UPPER)) {
1508 if (count++ == declaredCount) break;
1509 buf.append(b);
1510 }
1511 return buf.toList();
1512 }
1514 /** add a bound of a given kind - this might trigger listener notification */
1515 public void addBound(InferenceBound ib, Type bound, Types types) {
1516 Type bound2 = toTypeVarMap.apply(bound);
1517 List<Type> prevBounds = bounds.get(ib);
1518 for (Type b : prevBounds) {
1519 //check for redundancy - use strict version of isSameType on tvars
1520 //(as the standard version will lead to false positives w.r.t. clones ivars)
1521 if (types.isSameType(b, bound2, true) || bound == qtype) return;
1522 }
1523 bounds.put(ib, prevBounds.prepend(bound2));
1524 notifyChange(EnumSet.of(ib));
1525 }
1526 //where
1527 Type.Mapping toTypeVarMap = new Mapping("toTypeVarMap") {
1528 @Override
1529 public Type apply(Type t) {
1530 if (t.hasTag(UNDETVAR)) {
1531 UndetVar uv = (UndetVar)t;
1532 return uv.qtype;
1533 } else {
1534 return t.map(this);
1535 }
1536 }
1537 };
1539 /** replace types in all bounds - this might trigger listener notification */
1540 public void substBounds(List<Type> from, List<Type> to, Types types) {
1541 List<Type> instVars = from.diff(to);
1542 //if set of instantiated ivars is empty, there's nothing to do!
1543 if (instVars.isEmpty()) return;
1544 final EnumSet<InferenceBound> boundsChanged = EnumSet.noneOf(InferenceBound.class);
1545 UndetVarListener prevListener = listener;
1546 try {
1547 //setup new listener for keeping track of changed bounds
1548 listener = new UndetVarListener() {
1549 public void varChanged(UndetVar uv, Set<InferenceBound> ibs) {
1550 boundsChanged.addAll(ibs);
1551 }
1552 };
1553 for (Map.Entry<InferenceBound, List<Type>> _entry : bounds.entrySet()) {
1554 InferenceBound ib = _entry.getKey();
1555 List<Type> prevBounds = _entry.getValue();
1556 ListBuffer<Type> newBounds = ListBuffer.lb();
1557 ListBuffer<Type> deps = ListBuffer.lb();
1558 //step 1 - re-add bounds that are not dependent on ivars
1559 for (Type t : prevBounds) {
1560 if (!t.containsAny(instVars)) {
1561 newBounds.append(t);
1562 } else {
1563 deps.append(t);
1564 }
1565 }
1566 //step 2 - replace bounds
1567 bounds.put(ib, newBounds.toList());
1568 //step 3 - for each dependency, add new replaced bound
1569 for (Type dep : deps) {
1570 addBound(ib, types.subst(dep, from, to), types);
1571 }
1572 }
1573 } finally {
1574 listener = prevListener;
1575 if (!boundsChanged.isEmpty()) {
1576 notifyChange(boundsChanged);
1577 }
1578 }
1579 }
1581 private void notifyChange(EnumSet<InferenceBound> ibs) {
1582 if (listener != null) {
1583 listener.varChanged(this, ibs);
1584 }
1585 }
1586 }
1588 /** Represents NONE.
1589 */
1590 public static class JCNoType extends Type implements NoType {
1591 public JCNoType() {
1592 super(null);
1593 }
1595 @Override
1596 public TypeTag getTag() {
1597 return NONE;
1598 }
1600 @Override
1601 public TypeKind getKind() {
1602 return TypeKind.NONE;
1603 }
1605 @Override
1606 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1607 return v.visitNoType(this, p);
1608 }
1609 }
1611 /** Represents VOID.
1612 */
1613 public static class JCVoidType extends Type implements NoType {
1615 public JCVoidType() {
1616 super(null);
1617 }
1619 @Override
1620 public TypeTag getTag() {
1621 return VOID;
1622 }
1624 @Override
1625 public TypeKind getKind() {
1626 return TypeKind.VOID;
1627 }
1629 @Override
1630 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1631 return v.visitNoType(this, p);
1632 }
1634 @Override
1635 public boolean isPrimitiveOrVoid() {
1636 return true;
1637 }
1638 }
1640 static class BottomType extends Type implements NullType {
1641 public BottomType() {
1642 super(null);
1643 }
1645 @Override
1646 public TypeTag getTag() {
1647 return BOT;
1648 }
1650 @Override
1651 public TypeKind getKind() {
1652 return TypeKind.NULL;
1653 }
1655 @Override
1656 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1657 return v.visitNull(this, p);
1658 }
1660 @Override
1661 public Type constType(Object value) {
1662 return this;
1663 }
1665 @Override
1666 public String stringValue() {
1667 return "null";
1668 }
1670 @Override
1671 public boolean isNullOrReference() {
1672 return true;
1673 }
1675 }
1677 public static class ErrorType extends ClassType
1678 implements javax.lang.model.type.ErrorType {
1680 private Type originalType = null;
1682 public ErrorType(Type originalType, TypeSymbol tsym) {
1683 super(noType, List.<Type>nil(), null);
1684 this.tsym = tsym;
1685 this.originalType = (originalType == null ? noType : originalType);
1686 }
1688 public ErrorType(ClassSymbol c, Type originalType) {
1689 this(originalType, c);
1690 c.type = this;
1691 c.kind = ERR;
1692 c.members_field = new Scope.ErrorScope(c);
1693 }
1695 @Override
1696 public TypeTag getTag() {
1697 return ERROR;
1698 }
1700 @Override
1701 public boolean isPartial() {
1702 return true;
1703 }
1705 @Override
1706 public boolean isReference() {
1707 return true;
1708 }
1710 @Override
1711 public boolean isNullOrReference() {
1712 return true;
1713 }
1715 public ErrorType(Name name, TypeSymbol container, Type originalType) {
1716 this(new ClassSymbol(PUBLIC|STATIC|ACYCLIC, name, null, container), originalType);
1717 }
1719 @Override
1720 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1721 return v.visitErrorType(this, s);
1722 }
1724 public Type constType(Object constValue) { return this; }
1725 public Type getEnclosingType() { return this; }
1726 public Type getReturnType() { return this; }
1727 public Type asSub(Symbol sym) { return this; }
1728 public Type map(Mapping f) { return this; }
1730 public boolean isGenType(Type t) { return true; }
1731 public boolean isErroneous() { return true; }
1732 public boolean isCompound() { return false; }
1733 public boolean isInterface() { return false; }
1735 public List<Type> allparams() { return List.nil(); }
1736 public List<Type> getTypeArguments() { return List.nil(); }
1738 public TypeKind getKind() {
1739 return TypeKind.ERROR;
1740 }
1742 public Type getOriginalType() {
1743 return originalType;
1744 }
1746 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1747 return v.visitError(this, p);
1748 }
1749 }
1751 public static class AnnotatedType extends Type
1752 implements
1753 javax.lang.model.type.ArrayType,
1754 javax.lang.model.type.DeclaredType,
1755 javax.lang.model.type.PrimitiveType,
1756 javax.lang.model.type.TypeVariable,
1757 javax.lang.model.type.WildcardType {
1758 /** The type annotations on this type.
1759 */
1760 public List<Attribute.TypeCompound> typeAnnotations;
1762 /** The underlying type that is annotated.
1763 */
1764 public Type underlyingType;
1766 public AnnotatedType(Type underlyingType) {
1767 super(underlyingType.tsym);
1768 this.typeAnnotations = List.nil();
1769 this.underlyingType = underlyingType;
1770 Assert.check(!underlyingType.isAnnotated(),
1771 "Can't annotate already annotated type: " + underlyingType);
1772 }
1774 public AnnotatedType(List<Attribute.TypeCompound> typeAnnotations,
1775 Type underlyingType) {
1776 super(underlyingType.tsym);
1777 this.typeAnnotations = typeAnnotations;
1778 this.underlyingType = underlyingType;
1779 Assert.check(!underlyingType.isAnnotated(),
1780 "Can't annotate already annotated type: " + underlyingType +
1781 "; adding: " + typeAnnotations);
1782 }
1784 @Override
1785 public TypeTag getTag() {
1786 return underlyingType.getTag();
1787 }
1789 @Override
1790 public boolean isAnnotated() {
1791 return true;
1792 }
1794 @Override
1795 public List<? extends Attribute.TypeCompound> getAnnotationMirrors() {
1796 return typeAnnotations;
1797 }
1799 @Override
1800 public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
1801 return JavacAnnoConstructs.getAnnotation(this, annotationType);
1802 }
1804 @Override
1805 public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
1806 return JavacAnnoConstructs.getAnnotationsByType(this, annotationType);
1807 }
1809 @Override
1810 public TypeKind getKind() {
1811 return underlyingType.getKind();
1812 }
1814 @Override
1815 public Type unannotatedType() {
1816 return underlyingType;
1817 }
1819 @Override
1820 public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1821 return v.visitAnnotatedType(this, s);
1822 }
1824 @Override
1825 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1826 return underlyingType.accept(v, p);
1827 }
1829 @Override
1830 public Type map(Mapping f) {
1831 underlyingType.map(f);
1832 return this;
1833 }
1835 @Override
1836 public Type constType(Object constValue) { return underlyingType.constType(constValue); }
1837 @Override
1838 public Type getEnclosingType() { return underlyingType.getEnclosingType(); }
1840 @Override
1841 public Type getReturnType() { return underlyingType.getReturnType(); }
1842 @Override
1843 public List<Type> getTypeArguments() { return underlyingType.getTypeArguments(); }
1844 @Override
1845 public List<Type> getParameterTypes() { return underlyingType.getParameterTypes(); }
1846 @Override
1847 public Type getReceiverType() { return underlyingType.getReceiverType(); }
1848 @Override
1849 public List<Type> getThrownTypes() { return underlyingType.getThrownTypes(); }
1850 @Override
1851 public Type getUpperBound() { return underlyingType.getUpperBound(); }
1852 @Override
1853 public Type getLowerBound() { return underlyingType.getLowerBound(); }
1855 @Override
1856 public boolean isErroneous() { return underlyingType.isErroneous(); }
1857 @Override
1858 public boolean isCompound() { return underlyingType.isCompound(); }
1859 @Override
1860 public boolean isInterface() { return underlyingType.isInterface(); }
1861 @Override
1862 public List<Type> allparams() { return underlyingType.allparams(); }
1863 @Override
1864 public boolean isPrimitive() { return underlyingType.isPrimitive(); }
1865 @Override
1866 public boolean isPrimitiveOrVoid() { return underlyingType.isPrimitiveOrVoid(); }
1867 @Override
1868 public boolean isNumeric() { return underlyingType.isNumeric(); }
1869 @Override
1870 public boolean isReference() { return underlyingType.isReference(); }
1871 @Override
1872 public boolean isNullOrReference() { return underlyingType.isNullOrReference(); }
1873 @Override
1874 public boolean isPartial() { return underlyingType.isPartial(); }
1875 @Override
1876 public boolean isParameterized() { return underlyingType.isParameterized(); }
1877 @Override
1878 public boolean isRaw() { return underlyingType.isRaw(); }
1879 @Override
1880 public boolean isFinal() { return underlyingType.isFinal(); }
1881 @Override
1882 public boolean isSuperBound() { return underlyingType.isSuperBound(); }
1883 @Override
1884 public boolean isExtendsBound() { return underlyingType.isExtendsBound(); }
1885 @Override
1886 public boolean isUnbound() { return underlyingType.isUnbound(); }
1888 @Override
1889 public String toString() {
1890 // This method is only used for internal debugging output.
1891 // See
1892 // com.sun.tools.javac.code.Printer.visitAnnotatedType(AnnotatedType, Locale)
1893 // for the user-visible logic.
1894 if (typeAnnotations != null &&
1895 !typeAnnotations.isEmpty()) {
1896 return "(" + typeAnnotations.toString() + " :: " + underlyingType.toString() + ")";
1897 } else {
1898 return "({} :: " + underlyingType.toString() +")";
1899 }
1900 }
1902 @Override
1903 public boolean contains(Type t) { return underlyingType.contains(t); }
1905 @Override
1906 public Type withTypeVar(Type t) {
1907 // Don't create a new AnnotatedType, as 'this' will
1908 // get its annotations set later.
1909 underlyingType = underlyingType.withTypeVar(t);
1910 return this;
1911 }
1913 // TODO: attach annotations?
1914 @Override
1915 public TypeSymbol asElement() { return underlyingType.asElement(); }
1917 // TODO: attach annotations?
1918 @Override
1919 public MethodType asMethodType() { return underlyingType.asMethodType(); }
1921 @Override
1922 public void complete() { underlyingType.complete(); }
1924 @Override
1925 public TypeMirror getComponentType() { return ((ArrayType)underlyingType).getComponentType(); }
1927 // The result is an ArrayType, but only in the model sense, not the Type sense.
1928 public AnnotatedType makeVarargs() {
1929 AnnotatedType atype = new AnnotatedType(((ArrayType)underlyingType).makeVarargs());
1930 atype.typeAnnotations = this.typeAnnotations;
1931 return atype;
1932 }
1934 @Override
1935 public TypeMirror getExtendsBound() { return ((WildcardType)underlyingType).getExtendsBound(); }
1936 @Override
1937 public TypeMirror getSuperBound() { return ((WildcardType)underlyingType).getSuperBound(); }
1938 }
1940 public static class UnknownType extends Type {
1942 public UnknownType() {
1943 super(null);
1944 }
1946 @Override
1947 public TypeTag getTag() {
1948 return UNKNOWN;
1949 }
1951 @Override
1952 public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1953 return v.visitUnknown(this, p);
1954 }
1956 @Override
1957 public boolean isPartial() {
1958 return true;
1959 }
1960 }
1962 /**
1963 * A visitor for types. A visitor is used to implement operations
1964 * (or relations) on types. Most common operations on types are
1965 * binary relations and this interface is designed for binary
1966 * relations, that is, operations of the form
1967 * Type × S → R.
1968 * <!-- In plain text: Type x S -> R -->
1969 *
1970 * @param <R> the return type of the operation implemented by this
1971 * visitor; use Void if no return type is needed.
1972 * @param <S> the type of the second argument (the first being the
1973 * type itself) of the operation implemented by this visitor; use
1974 * Void if a second argument is not needed.
1975 */
1976 public interface Visitor<R,S> {
1977 R visitClassType(ClassType t, S s);
1978 R visitWildcardType(WildcardType t, S s);
1979 R visitArrayType(ArrayType t, S s);
1980 R visitMethodType(MethodType t, S s);
1981 R visitPackageType(PackageType t, S s);
1982 R visitTypeVar(TypeVar t, S s);
1983 R visitCapturedType(CapturedType t, S s);
1984 R visitForAll(ForAll t, S s);
1985 R visitUndetVar(UndetVar t, S s);
1986 R visitErrorType(ErrorType t, S s);
1987 R visitAnnotatedType(AnnotatedType t, S s);
1988 R visitType(Type t, S s);
1989 }
1990 }