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