Type.java revision 4038:95c92c634f60
1/*
2 * Copyright (c) 1999, 2016, 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 */
25
26package com.sun.tools.javac.code;
27
28import java.lang.annotation.Annotation;
29import java.util.ArrayDeque;
30import java.util.Collections;
31import java.util.EnumMap;
32import java.util.Map;
33
34import javax.lang.model.type.*;
35
36import com.sun.tools.javac.code.Symbol.*;
37import com.sun.tools.javac.code.TypeMetadata.Entry;
38import com.sun.tools.javac.code.Types.TypeMapping;
39import com.sun.tools.javac.comp.Infer.IncorporationAction;
40import com.sun.tools.javac.util.*;
41import com.sun.tools.javac.util.DefinedBy.Api;
42
43import static com.sun.tools.javac.code.BoundKind.*;
44import static com.sun.tools.javac.code.Flags.*;
45import static com.sun.tools.javac.code.Kinds.Kind.*;
46import static com.sun.tools.javac.code.TypeTag.*;
47
48/** This class represents Java types. The class itself defines the behavior of
49 *  the following types:
50 *  <pre>
51 *  base types (tags: BYTE, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, BOOLEAN),
52 *  type `void' (tag: VOID),
53 *  the bottom type (tag: BOT),
54 *  the missing type (tag: NONE).
55 *  </pre>
56 *  <p>The behavior of the following types is defined in subclasses, which are
57 *  all static inner classes of this class:
58 *  <pre>
59 *  class types (tag: CLASS, class: ClassType),
60 *  array types (tag: ARRAY, class: ArrayType),
61 *  method types (tag: METHOD, class: MethodType),
62 *  package types (tag: PACKAGE, class: PackageType),
63 *  type variables (tag: TYPEVAR, class: TypeVar),
64 *  type arguments (tag: WILDCARD, class: WildcardType),
65 *  generic method types (tag: FORALL, class: ForAll),
66 *  the error type (tag: ERROR, class: ErrorType).
67 *  </pre>
68 *
69 *  <p><b>This is NOT part of any supported API.
70 *  If you write code that depends on this, you do so at your own risk.
71 *  This code and its internal interfaces are subject to change or
72 *  deletion without notice.</b>
73 *
74 *  @see TypeTag
75 */
76public abstract class Type extends AnnoConstruct implements TypeMirror {
77
78    /**
79     * Type metadata,  Should be {@code null} for the default value.
80     *
81     * Note: it is an invariant that for any {@code TypeMetadata}
82     * class, a given {@code Type} may have at most one metadata array
83     * entry of that class.
84     */
85    protected final TypeMetadata metadata;
86
87    public TypeMetadata getMetadata() {
88        return metadata;
89    }
90
91    public Entry getMetadataOfKind(final Entry.Kind kind) {
92        return metadata != null ? metadata.get(kind) : null;
93    }
94
95    /** Constant type: no type at all. */
96    public static final JCNoType noType = new JCNoType() {
97        @Override @DefinedBy(Api.LANGUAGE_MODEL)
98        public String toString() {
99            return "none";
100        }
101    };
102
103    /** Constant type: special type to be used during recovery of deferred expressions. */
104    public static final JCNoType recoveryType = new JCNoType(){
105        @Override @DefinedBy(Api.LANGUAGE_MODEL)
106        public String toString() {
107            return "recovery";
108        }
109    };
110
111    /** Constant type: special type to be used for marking stuck trees. */
112    public static final JCNoType stuckType = new JCNoType() {
113        @Override @DefinedBy(Api.LANGUAGE_MODEL)
114        public String toString() {
115            return "stuck";
116        }
117    };
118
119    /** If this switch is turned on, the names of type variables
120     *  and anonymous classes are printed with hashcodes appended.
121     */
122    public static boolean moreInfo = false;
123
124    /** The defining class / interface / package / type variable.
125     */
126    public TypeSymbol tsym;
127
128    /**
129     * Checks if the current type tag is equal to the given tag.
130     * @return true if tag is equal to the current type tag.
131     */
132    public boolean hasTag(TypeTag tag) {
133        return tag == getTag();
134    }
135
136    /**
137     * Returns the current type tag.
138     * @return the value of the current type tag.
139     */
140    public abstract TypeTag getTag();
141
142    public boolean isNumeric() {
143        return false;
144    }
145
146    public boolean isIntegral() {
147        return false;
148    }
149
150    public boolean isPrimitive() {
151        return false;
152    }
153
154    public boolean isPrimitiveOrVoid() {
155        return false;
156    }
157
158    public boolean isReference() {
159        return false;
160    }
161
162    public boolean isNullOrReference() {
163        return false;
164    }
165
166    public boolean isPartial() {
167        return false;
168    }
169
170    /**
171     * The constant value of this type, null if this type does not
172     * have a constant value attribute. Only primitive types and
173     * strings (ClassType) can have a constant value attribute.
174     * @return the constant value attribute of this type
175     */
176    public Object constValue() {
177        return null;
178    }
179
180    /** Is this a constant type whose value is false?
181     */
182    public boolean isFalse() {
183        return false;
184    }
185
186    /** Is this a constant type whose value is true?
187     */
188    public boolean isTrue() {
189        return false;
190    }
191
192    /**
193     * Get the representation of this type used for modelling purposes.
194     * By default, this is itself. For ErrorType, a different value
195     * may be provided.
196     */
197    public Type getModelType() {
198        return this;
199    }
200
201    public static List<Type> getModelTypes(List<Type> ts) {
202        ListBuffer<Type> lb = new ListBuffer<>();
203        for (Type t: ts)
204            lb.append(t.getModelType());
205        return lb.toList();
206    }
207
208    /**For ErrorType, returns the original type, otherwise returns the type itself.
209     */
210    public Type getOriginalType() {
211        return this;
212    }
213
214    public <R,S> R accept(Type.Visitor<R,S> v, S s) { return v.visitType(this, s); }
215
216    /** Define a type given its tag, type symbol, and type annotations
217     */
218
219    public Type(TypeSymbol tsym, TypeMetadata metadata) {
220        Assert.checkNonNull(metadata);
221        this.tsym = tsym;
222        this.metadata = metadata;
223    }
224
225    /**
226     * A subclass of {@link Types.TypeMapping} which applies a mapping recursively to the subterms
227     * of a given type expression. This mapping returns the original type is no changes occurred
228     * when recursively mapping the original type's subterms.
229     */
230    public static abstract class StructuralTypeMapping<S> extends Types.TypeMapping<S> {
231
232        @Override
233        public Type visitClassType(ClassType t, S s) {
234            Type outer = t.getEnclosingType();
235            Type outer1 = visit(outer, s);
236            List<Type> typarams = t.getTypeArguments();
237            List<Type> typarams1 = visit(typarams, s);
238            if (outer1 == outer && typarams1 == typarams) return t;
239            else return new ClassType(outer1, typarams1, t.tsym, t.metadata) {
240                @Override
241                protected boolean needsStripping() {
242                    return true;
243                }
244            };
245        }
246
247        @Override
248        public Type visitWildcardType(WildcardType wt, S s) {
249            Type t = wt.type;
250            if (t != null)
251                t = visit(t, s);
252            if (t == wt.type)
253                return wt;
254            else
255                return new WildcardType(t, wt.kind, wt.tsym, wt.bound, wt.metadata) {
256                    @Override
257                    protected boolean needsStripping() {
258                        return true;
259                    }
260                };
261        }
262
263        @Override
264        public Type visitArrayType(ArrayType t, S s) {
265            Type elemtype = t.elemtype;
266            Type elemtype1 = visit(elemtype, s);
267            if (elemtype1 == elemtype) return t;
268            else return new ArrayType(elemtype1, t.tsym, t.metadata) {
269                @Override
270                protected boolean needsStripping() {
271                    return true;
272                }
273            };
274        }
275
276        @Override
277        public Type visitMethodType(MethodType t, S s) {
278            List<Type> argtypes = t.argtypes;
279            Type restype = t.restype;
280            List<Type> thrown = t.thrown;
281            List<Type> argtypes1 = visit(argtypes, s);
282            Type restype1 = visit(restype, s);
283            List<Type> thrown1 = visit(thrown, s);
284            if (argtypes1 == argtypes &&
285                restype1 == restype &&
286                thrown1 == thrown) return t;
287            else return new MethodType(argtypes1, restype1, thrown1, t.tsym) {
288                @Override
289                protected boolean needsStripping() {
290                    return true;
291                }
292            };
293        }
294
295        @Override
296        public Type visitForAll(ForAll t, S s) {
297            return visit(t.qtype, s);
298        }
299    }
300
301    /** map a type function over all immediate descendants of this type
302     */
303    public <Z> Type map(TypeMapping<Z> mapping, Z arg) {
304        return mapping.visit(this, arg);
305    }
306
307    /** map a type function over all immediate descendants of this type (no arg version)
308     */
309    public <Z> Type map(TypeMapping<Z> mapping) {
310        return mapping.visit(this, null);
311    }
312
313    /** Define a constant type, of the same kind as this type
314     *  and with given constant value
315     */
316    public Type constType(Object constValue) {
317        throw new AssertionError();
318    }
319
320    /**
321     * If this is a constant type, return its underlying type.
322     * Otherwise, return the type itself.
323     */
324    public Type baseType() {
325        return this;
326    }
327
328    /**
329     * Returns the original version of this type, before metadata were added. This routine is meant
330     * for internal use only (i.e. {@link Type#equalsIgnoreMetadata(Type)}, {@link Type#stripMetadata});
331     * it should not be used outside this class.
332     */
333    protected Type typeNoMetadata() {
334        return metadata == TypeMetadata.EMPTY ? this : baseType();
335    }
336
337    /**
338     * Create a new copy of this type but with the specified TypeMetadata.
339     */
340    public abstract Type cloneWithMetadata(TypeMetadata metadata);
341
342    /**
343     * Does this type require annotation stripping for API clients?
344     */
345    protected boolean needsStripping() {
346        return false;
347    }
348
349    /**
350     * Strip all metadata associated with this type - this could return a new clone of the type.
351     * This routine is only used to present the correct annotated types back to the users when types
352     * are accessed through compiler APIs; it should not be used anywhere in the compiler internals
353     * as doing so might result in performance penalties.
354     */
355    public Type stripMetadataIfNeeded() {
356        return needsStripping() ?
357                accept(stripMetadata, null) :
358                this;
359    }
360
361    public Type stripMetadata() {
362        return accept(stripMetadata, null);
363    }
364    //where
365        private final static TypeMapping<Void> stripMetadata = new StructuralTypeMapping<Void>() {
366            @Override
367            public Type visitClassType(ClassType t, Void aVoid) {
368                return super.visitClassType((ClassType)t.typeNoMetadata(), aVoid);
369            }
370
371            @Override
372            public Type visitArrayType(ArrayType t, Void aVoid) {
373                return super.visitArrayType((ArrayType)t.typeNoMetadata(), aVoid);
374            }
375
376            @Override
377            public Type visitTypeVar(TypeVar t, Void aVoid) {
378                return super.visitTypeVar((TypeVar)t.typeNoMetadata(), aVoid);
379            }
380
381            @Override
382            public Type visitWildcardType(WildcardType wt, Void aVoid) {
383                return super.visitWildcardType((WildcardType)wt.typeNoMetadata(), aVoid);
384            }
385        };
386
387    public Type annotatedType(final List<Attribute.TypeCompound> annos) {
388        final Entry annoMetadata = new TypeMetadata.Annotations(annos);
389        return cloneWithMetadata(metadata.combine(annoMetadata));
390    }
391
392    public boolean isAnnotated() {
393        final TypeMetadata.Annotations metadata =
394            (TypeMetadata.Annotations)getMetadataOfKind(Entry.Kind.ANNOTATIONS);
395
396        return null != metadata && !metadata.getAnnotations().isEmpty();
397    }
398
399    @Override @DefinedBy(Api.LANGUAGE_MODEL)
400    public List<Attribute.TypeCompound> getAnnotationMirrors() {
401        final TypeMetadata.Annotations metadata =
402            (TypeMetadata.Annotations)getMetadataOfKind(Entry.Kind.ANNOTATIONS);
403
404        return metadata == null ? List.nil() : metadata.getAnnotations();
405    }
406
407
408    @Override @DefinedBy(Api.LANGUAGE_MODEL)
409    public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
410        return null;
411    }
412
413
414    @Override @DefinedBy(Api.LANGUAGE_MODEL)
415    public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
416        @SuppressWarnings("unchecked")
417        A[] tmp = (A[]) java.lang.reflect.Array.newInstance(annotationType, 0);
418        return tmp;
419    }
420
421    /** Return the base types of a list of types.
422     */
423    public static List<Type> baseTypes(List<Type> ts) {
424        if (ts.nonEmpty()) {
425            Type t = ts.head.baseType();
426            List<Type> baseTypes = baseTypes(ts.tail);
427            if (t != ts.head || baseTypes != ts.tail)
428                return baseTypes.prepend(t);
429        }
430        return ts;
431    }
432
433    protected void appendAnnotationsString(StringBuilder sb,
434                                         boolean prefix) {
435        if (isAnnotated()) {
436            if (prefix) {
437                sb.append(" ");
438            }
439            sb.append(getAnnotationMirrors());
440            sb.append(" ");
441        }
442    }
443
444    protected void appendAnnotationsString(StringBuilder sb) {
445        appendAnnotationsString(sb, false);
446    }
447
448    /** The Java source which this type represents.
449     */
450    @DefinedBy(Api.LANGUAGE_MODEL)
451    public String toString() {
452        StringBuilder sb = new StringBuilder();
453        appendAnnotationsString(sb);
454        if (tsym == null || tsym.name == null) {
455            sb.append("<none>");
456        } else {
457            sb.append(tsym.name);
458        }
459        if (moreInfo && hasTag(TYPEVAR)) {
460            sb.append(hashCode());
461        }
462        return sb.toString();
463    }
464
465    /**
466     * The Java source which this type list represents.  A List is
467     * represented as a comma-spearated listing of the elements in
468     * that list.
469     */
470    public static String toString(List<Type> ts) {
471        if (ts.isEmpty()) {
472            return "";
473        } else {
474            StringBuilder buf = new StringBuilder();
475            buf.append(ts.head.toString());
476            for (List<Type> l = ts.tail; l.nonEmpty(); l = l.tail)
477                buf.append(",").append(l.head.toString());
478            return buf.toString();
479        }
480    }
481
482    /**
483     * The constant value of this type, converted to String
484     */
485    public String stringValue() {
486        Object cv = Assert.checkNonNull(constValue());
487        return cv.toString();
488    }
489
490    /**
491     * Override this method with care. For most Type instances this should behave as ==.
492     */
493    @Override @DefinedBy(Api.LANGUAGE_MODEL)
494    public boolean equals(Object t) {
495        return this == t;
496    }
497
498    public boolean equalsIgnoreMetadata(Type t) {
499        return typeNoMetadata().equals(t.typeNoMetadata());
500    }
501
502    @Override @DefinedBy(Api.LANGUAGE_MODEL)
503    public int hashCode() {
504        return super.hashCode();
505    }
506
507    public String argtypes(boolean varargs) {
508        List<Type> args = getParameterTypes();
509        if (!varargs) return args.toString();
510        StringBuilder buf = new StringBuilder();
511        while (args.tail.nonEmpty()) {
512            buf.append(args.head);
513            args = args.tail;
514            buf.append(',');
515        }
516        if (args.head.hasTag(ARRAY)) {
517            buf.append(((ArrayType)args.head).elemtype);
518            if (args.head.getAnnotationMirrors().nonEmpty()) {
519                buf.append(args.head.getAnnotationMirrors());
520            }
521            buf.append("...");
522        } else {
523            buf.append(args.head);
524        }
525        return buf.toString();
526    }
527
528    /** Access methods.
529     */
530    public List<Type>        getTypeArguments()  { return List.nil(); }
531    public Type              getEnclosingType()  { return null; }
532    public List<Type>        getParameterTypes() { return List.nil(); }
533    public Type              getReturnType()     { return null; }
534    public Type              getReceiverType()   { return null; }
535    public List<Type>        getThrownTypes()    { return List.nil(); }
536    public Type              getUpperBound()     { return null; }
537    public Type              getLowerBound()     { return null; }
538
539    /** Navigation methods, these will work for classes, type variables,
540     *  foralls, but will return null for arrays and methods.
541     */
542
543   /** Return all parameters of this type and all its outer types in order
544    *  outer (first) to inner (last).
545    */
546    public List<Type> allparams() { return List.nil(); }
547
548    /** Does this type contain "error" elements?
549     */
550    public boolean isErroneous() {
551        return false;
552    }
553
554    public static boolean isErroneous(List<Type> ts) {
555        for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
556            if (l.head.isErroneous()) return true;
557        return false;
558    }
559
560    /** Is this type parameterized?
561     *  A class type is parameterized if it has some parameters.
562     *  An array type is parameterized if its element type is parameterized.
563     *  All other types are not parameterized.
564     */
565    public boolean isParameterized() {
566        return false;
567    }
568
569    /** Is this type a raw type?
570     *  A class type is a raw type if it misses some of its parameters.
571     *  An array type is a raw type if its element type is raw.
572     *  All other types are not raw.
573     *  Type validation will ensure that the only raw types
574     *  in a program are types that miss all their type variables.
575     */
576    public boolean isRaw() {
577        return false;
578    }
579
580    /**
581     * A compound type is a special class type whose supertypes are used to store a list
582     * of component types. There are two kinds of compound types: (i) intersection types
583     * {@see IntersectionClassType} and (ii) union types {@see UnionClassType}.
584     */
585    public boolean isCompound() {
586        return false;
587    }
588
589    public boolean isIntersection() {
590        return false;
591    }
592
593    public boolean isUnion() {
594        return false;
595    }
596
597    public boolean isInterface() {
598        return (tsym.flags() & INTERFACE) != 0;
599    }
600
601    public boolean isFinal() {
602        return (tsym.flags() & FINAL) != 0;
603    }
604
605    /**
606     * Does this type contain occurrences of type t?
607     */
608    public boolean contains(Type t) {
609        return t.equalsIgnoreMetadata(this);
610    }
611
612    public static boolean contains(List<Type> ts, Type t) {
613        for (List<Type> l = ts;
614             l.tail != null /*inlined: l.nonEmpty()*/;
615             l = l.tail)
616            if (l.head.contains(t)) return true;
617        return false;
618    }
619
620    /** Does this type contain an occurrence of some type in 'ts'?
621     */
622    public boolean containsAny(List<Type> ts) {
623        for (Type t : ts)
624            if (this.contains(t)) return true;
625        return false;
626    }
627
628    public static boolean containsAny(List<Type> ts1, List<Type> ts2) {
629        for (Type t : ts1)
630            if (t.containsAny(ts2)) return true;
631        return false;
632    }
633
634    public static List<Type> filter(List<Type> ts, Filter<Type> tf) {
635        ListBuffer<Type> buf = new ListBuffer<>();
636        for (Type t : ts) {
637            if (tf.accepts(t)) {
638                buf.append(t);
639            }
640        }
641        return buf.toList();
642    }
643
644    public boolean isSuperBound() { return false; }
645    public boolean isExtendsBound() { return false; }
646    public boolean isUnbound() { return false; }
647    public Type withTypeVar(Type t) { return this; }
648
649    /** The underlying method type of this type.
650     */
651    public MethodType asMethodType() { throw new AssertionError(); }
652
653    /** Complete loading all classes in this type.
654     */
655    public void complete() {}
656
657    public TypeSymbol asElement() {
658        return tsym;
659    }
660
661    @Override @DefinedBy(Api.LANGUAGE_MODEL)
662    public TypeKind getKind() {
663        return TypeKind.OTHER;
664    }
665
666    @Override @DefinedBy(Api.LANGUAGE_MODEL)
667    public <R, P> R accept(TypeVisitor<R, P> v, P p) {
668        throw new AssertionError();
669    }
670
671    public static class JCPrimitiveType extends Type
672            implements javax.lang.model.type.PrimitiveType {
673
674        TypeTag tag;
675
676        public JCPrimitiveType(TypeTag tag, TypeSymbol tsym) {
677            this(tag, tsym, TypeMetadata.EMPTY);
678        }
679
680        private JCPrimitiveType(TypeTag tag, TypeSymbol tsym, TypeMetadata metadata) {
681            super(tsym, metadata);
682            this.tag = tag;
683            Assert.check(tag.isPrimitive);
684        }
685
686        @Override
687        public JCPrimitiveType cloneWithMetadata(TypeMetadata md) {
688            return new JCPrimitiveType(tag, tsym, md) {
689                @Override
690                public Type baseType() { return JCPrimitiveType.this.baseType(); }
691            };
692        }
693
694        @Override
695        public boolean isNumeric() {
696            return tag != BOOLEAN;
697        }
698
699        @Override
700        public boolean isIntegral() {
701            switch (tag) {
702                case CHAR:
703                case BYTE:
704                case SHORT:
705                case INT:
706                case LONG:
707                    return true;
708                default:
709                    return false;
710            }
711        }
712
713        @Override
714        public boolean isPrimitive() {
715            return true;
716        }
717
718        @Override
719        public TypeTag getTag() {
720            return tag;
721        }
722
723        @Override
724        public boolean isPrimitiveOrVoid() {
725            return true;
726        }
727
728        /** Define a constant type, of the same kind as this type
729         *  and with given constant value
730         */
731        @Override
732        public Type constType(Object constValue) {
733            final Object value = constValue;
734            return new JCPrimitiveType(tag, tsym, metadata) {
735                    @Override
736                    public Object constValue() {
737                        return value;
738                    }
739                    @Override
740                    public Type baseType() {
741                        return tsym.type;
742                    }
743                };
744        }
745
746        /**
747         * The constant value of this type, converted to String
748         */
749        @Override
750        public String stringValue() {
751            Object cv = Assert.checkNonNull(constValue());
752            if (tag == BOOLEAN) {
753                return ((Integer) cv).intValue() == 0 ? "false" : "true";
754            }
755            else if (tag == CHAR) {
756                return String.valueOf((char) ((Integer) cv).intValue());
757            }
758            else {
759                return cv.toString();
760            }
761        }
762
763        /** Is this a constant type whose value is false?
764         */
765        @Override
766        public boolean isFalse() {
767            return
768                tag == BOOLEAN &&
769                constValue() != null &&
770                ((Integer)constValue()).intValue() == 0;
771        }
772
773        /** Is this a constant type whose value is true?
774         */
775        @Override
776        public boolean isTrue() {
777            return
778                tag == BOOLEAN &&
779                constValue() != null &&
780                ((Integer)constValue()).intValue() != 0;
781        }
782
783        @Override @DefinedBy(Api.LANGUAGE_MODEL)
784        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
785            return v.visitPrimitive(this, p);
786        }
787
788        @Override @DefinedBy(Api.LANGUAGE_MODEL)
789        public TypeKind getKind() {
790            switch (tag) {
791                case BYTE:      return TypeKind.BYTE;
792                case CHAR:      return TypeKind.CHAR;
793                case SHORT:     return TypeKind.SHORT;
794                case INT:       return TypeKind.INT;
795                case LONG:      return TypeKind.LONG;
796                case FLOAT:     return TypeKind.FLOAT;
797                case DOUBLE:    return TypeKind.DOUBLE;
798                case BOOLEAN:   return TypeKind.BOOLEAN;
799            }
800            throw new AssertionError();
801        }
802
803    }
804
805    public static class WildcardType extends Type
806            implements javax.lang.model.type.WildcardType {
807
808        public Type type;
809        public BoundKind kind;
810        public TypeVar bound;
811
812        @Override
813        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
814            return v.visitWildcardType(this, s);
815        }
816
817        public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) {
818            this(type, kind, tsym, null, TypeMetadata.EMPTY);
819        }
820
821        public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
822                            TypeMetadata metadata) {
823            this(type, kind, tsym, null, metadata);
824        }
825
826        public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
827                            TypeVar bound) {
828            this(type, kind, tsym, bound, TypeMetadata.EMPTY);
829        }
830
831        public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
832                            TypeVar bound, TypeMetadata metadata) {
833            super(tsym, metadata);
834            this.type = Assert.checkNonNull(type);
835            this.kind = kind;
836            this.bound = bound;
837        }
838
839        @Override
840        public WildcardType cloneWithMetadata(TypeMetadata md) {
841            return new WildcardType(type, kind, tsym, bound, md) {
842                @Override
843                public Type baseType() { return WildcardType.this.baseType(); }
844            };
845        }
846
847        @Override
848        public TypeTag getTag() {
849            return WILDCARD;
850        }
851
852        @Override
853        public boolean contains(Type t) {
854            return kind != UNBOUND && type.contains(t);
855        }
856
857        public boolean isSuperBound() {
858            return kind == SUPER ||
859                kind == UNBOUND;
860        }
861        public boolean isExtendsBound() {
862            return kind == EXTENDS ||
863                kind == UNBOUND;
864        }
865        public boolean isUnbound() {
866            return kind == UNBOUND;
867        }
868
869        @Override
870        public boolean isReference() {
871            return true;
872        }
873
874        @Override
875        public boolean isNullOrReference() {
876            return true;
877        }
878
879        @Override
880        public Type withTypeVar(Type t) {
881            //-System.err.println(this+".withTypeVar("+t+");");//DEBUG
882            if (bound == t)
883                return this;
884            bound = (TypeVar)t;
885            return this;
886        }
887
888        boolean isPrintingBound = false;
889        @DefinedBy(Api.LANGUAGE_MODEL)
890        public String toString() {
891            StringBuilder s = new StringBuilder();
892            appendAnnotationsString(s);
893            s.append(kind.toString());
894            if (kind != UNBOUND)
895                s.append(type);
896            if (moreInfo && bound != null && !isPrintingBound)
897                try {
898                    isPrintingBound = true;
899                    s.append("{:").append(bound.bound).append(":}");
900                } finally {
901                    isPrintingBound = false;
902                }
903            return s.toString();
904        }
905
906        @DefinedBy(Api.LANGUAGE_MODEL)
907        public Type getExtendsBound() {
908            if (kind == EXTENDS)
909                return type;
910            else
911                return null;
912        }
913
914        @DefinedBy(Api.LANGUAGE_MODEL)
915        public Type getSuperBound() {
916            if (kind == SUPER)
917                return type;
918            else
919                return null;
920        }
921
922        @DefinedBy(Api.LANGUAGE_MODEL)
923        public TypeKind getKind() {
924            return TypeKind.WILDCARD;
925        }
926
927        @DefinedBy(Api.LANGUAGE_MODEL)
928        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
929            return v.visitWildcard(this, p);
930        }
931    }
932
933    public static class ClassType extends Type implements DeclaredType {
934
935        /** The enclosing type of this type. If this is the type of an inner
936         *  class, outer_field refers to the type of its enclosing
937         *  instance class, in all other cases it refers to noType.
938         */
939        private Type outer_field;
940
941        /** The type parameters of this type (to be set once class is loaded).
942         */
943        public List<Type> typarams_field;
944
945        /** A cache variable for the type parameters of this type,
946         *  appended to all parameters of its enclosing class.
947         *  @see #allparams
948         */
949        public List<Type> allparams_field;
950
951        /** The supertype of this class (to be set once class is loaded).
952         */
953        public Type supertype_field;
954
955        /** The interfaces of this class (to be set once class is loaded).
956         */
957        public List<Type> interfaces_field;
958
959        /** All the interfaces of this class, including missing ones.
960         */
961        public List<Type> all_interfaces_field;
962
963        public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
964            this(outer, typarams, tsym, TypeMetadata.EMPTY);
965        }
966
967        public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym,
968                         TypeMetadata metadata) {
969            super(tsym, metadata);
970            this.outer_field = outer;
971            this.typarams_field = typarams;
972            this.allparams_field = null;
973            this.supertype_field = null;
974            this.interfaces_field = null;
975        }
976
977        @Override
978        public ClassType cloneWithMetadata(TypeMetadata md) {
979            return new ClassType(outer_field, typarams_field, tsym, md) {
980                @Override
981                public Type baseType() { return ClassType.this.baseType(); }
982            };
983        }
984
985        @Override
986        public TypeTag getTag() {
987            return CLASS;
988        }
989
990        @Override
991        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
992            return v.visitClassType(this, s);
993        }
994
995        public Type constType(Object constValue) {
996            final Object value = constValue;
997            return new ClassType(getEnclosingType(), typarams_field, tsym, metadata) {
998                    @Override
999                    public Object constValue() {
1000                        return value;
1001                    }
1002                    @Override
1003                    public Type baseType() {
1004                        return tsym.type;
1005                    }
1006                };
1007        }
1008
1009        /** The Java source which this type represents.
1010         */
1011        @DefinedBy(Api.LANGUAGE_MODEL)
1012        public String toString() {
1013            StringBuilder buf = new StringBuilder();
1014            if (getEnclosingType().hasTag(CLASS) && tsym.owner.kind == TYP) {
1015                buf.append(getEnclosingType().toString());
1016                buf.append(".");
1017                appendAnnotationsString(buf);
1018                buf.append(className(tsym, false));
1019            } else {
1020                appendAnnotationsString(buf);
1021                buf.append(className(tsym, true));
1022            }
1023
1024            if (getTypeArguments().nonEmpty()) {
1025                buf.append('<');
1026                buf.append(getTypeArguments().toString());
1027                buf.append(">");
1028            }
1029            return buf.toString();
1030        }
1031//where
1032            private String className(Symbol sym, boolean longform) {
1033                if (sym.name.isEmpty() && (sym.flags() & COMPOUND) != 0) {
1034                    StringBuilder s = new StringBuilder(supertype_field.toString());
1035                    for (List<Type> is=interfaces_field; is.nonEmpty(); is = is.tail) {
1036                        s.append("&");
1037                        s.append(is.head.toString());
1038                    }
1039                    return s.toString();
1040                } else if (sym.name.isEmpty()) {
1041                    String s;
1042                    ClassType norm = (ClassType) tsym.type;
1043                    if (norm == null) {
1044                        s = Log.getLocalizedString("anonymous.class", (Object)null);
1045                    } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
1046                        s = Log.getLocalizedString("anonymous.class",
1047                                                   norm.interfaces_field.head);
1048                    } else {
1049                        s = Log.getLocalizedString("anonymous.class",
1050                                                   norm.supertype_field);
1051                    }
1052                    if (moreInfo)
1053                        s += String.valueOf(sym.hashCode());
1054                    return s;
1055                } else if (longform) {
1056                    return sym.getQualifiedName().toString();
1057                } else {
1058                    return sym.name.toString();
1059                }
1060            }
1061
1062        @DefinedBy(Api.LANGUAGE_MODEL)
1063        public List<Type> getTypeArguments() {
1064            if (typarams_field == null) {
1065                complete();
1066                if (typarams_field == null)
1067                    typarams_field = List.nil();
1068            }
1069            return typarams_field;
1070        }
1071
1072        public boolean hasErasedSupertypes() {
1073            return isRaw();
1074        }
1075
1076        @DefinedBy(Api.LANGUAGE_MODEL)
1077        public Type getEnclosingType() {
1078            return outer_field;
1079        }
1080
1081        public void setEnclosingType(Type outer) {
1082            outer_field = outer;
1083        }
1084
1085        public List<Type> allparams() {
1086            if (allparams_field == null) {
1087                allparams_field = getTypeArguments().prependList(getEnclosingType().allparams());
1088            }
1089            return allparams_field;
1090        }
1091
1092        public boolean isErroneous() {
1093            return
1094                getEnclosingType().isErroneous() ||
1095                isErroneous(getTypeArguments()) ||
1096                this != tsym.type && tsym.type.isErroneous();
1097        }
1098
1099        public boolean isParameterized() {
1100            return allparams().tail != null;
1101            // optimization, was: allparams().nonEmpty();
1102        }
1103
1104        @Override
1105        public boolean isReference() {
1106            return true;
1107        }
1108
1109        @Override
1110        public boolean isNullOrReference() {
1111            return true;
1112        }
1113
1114        /** A cache for the rank. */
1115        int rank_field = -1;
1116
1117        /** A class type is raw if it misses some
1118         *  of its type parameter sections.
1119         *  After validation, this is equivalent to:
1120         *  {@code allparams.isEmpty() && tsym.type.allparams.nonEmpty(); }
1121         */
1122        public boolean isRaw() {
1123            return
1124                this != tsym.type && // necessary, but not sufficient condition
1125                tsym.type.allparams().nonEmpty() &&
1126                allparams().isEmpty();
1127        }
1128
1129        public boolean contains(Type elem) {
1130            return
1131                elem.equalsIgnoreMetadata(this)
1132                || (isParameterized()
1133                    && (getEnclosingType().contains(elem) || contains(getTypeArguments(), elem)))
1134                || (isCompound()
1135                    && (supertype_field.contains(elem) || contains(interfaces_field, elem)));
1136        }
1137
1138        public void complete() {
1139            tsym.complete();
1140        }
1141
1142        @DefinedBy(Api.LANGUAGE_MODEL)
1143        public TypeKind getKind() {
1144            return TypeKind.DECLARED;
1145        }
1146
1147        @DefinedBy(Api.LANGUAGE_MODEL)
1148        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1149            return v.visitDeclared(this, p);
1150        }
1151    }
1152
1153    public static class ErasedClassType extends ClassType {
1154        public ErasedClassType(Type outer, TypeSymbol tsym,
1155                               TypeMetadata metadata) {
1156            super(outer, List.nil(), tsym, metadata);
1157        }
1158
1159        @Override
1160        public boolean hasErasedSupertypes() {
1161            return true;
1162        }
1163    }
1164
1165    // a clone of a ClassType that knows about the alternatives of a union type.
1166    public static class UnionClassType extends ClassType implements UnionType {
1167        final List<? extends Type> alternatives_field;
1168
1169        public UnionClassType(ClassType ct, List<? extends Type> alternatives) {
1170            // Presently no way to refer to this type directly, so we
1171            // cannot put annotations directly on it.
1172            super(ct.outer_field, ct.typarams_field, ct.tsym);
1173            allparams_field = ct.allparams_field;
1174            supertype_field = ct.supertype_field;
1175            interfaces_field = ct.interfaces_field;
1176            all_interfaces_field = ct.interfaces_field;
1177            alternatives_field = alternatives;
1178        }
1179
1180        @Override
1181        public UnionClassType cloneWithMetadata(TypeMetadata md) {
1182            throw new AssertionError("Cannot add metadata to a union type");
1183        }
1184
1185        public Type getLub() {
1186            return tsym.type;
1187        }
1188
1189        @DefinedBy(Api.LANGUAGE_MODEL)
1190        public java.util.List<? extends TypeMirror> getAlternatives() {
1191            return Collections.unmodifiableList(alternatives_field);
1192        }
1193
1194        @Override
1195        public boolean isUnion() {
1196            return true;
1197        }
1198
1199        @Override
1200        public boolean isCompound() {
1201            return getLub().isCompound();
1202        }
1203
1204        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1205        public TypeKind getKind() {
1206            return TypeKind.UNION;
1207        }
1208
1209        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1210        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1211            return v.visitUnion(this, p);
1212        }
1213
1214        public Iterable<? extends Type> getAlternativeTypes() {
1215            return alternatives_field;
1216        }
1217    }
1218
1219    // a clone of a ClassType that knows about the bounds of an intersection type.
1220    public static class IntersectionClassType extends ClassType implements IntersectionType {
1221
1222        public boolean allInterfaces;
1223
1224        public IntersectionClassType(List<Type> bounds, ClassSymbol csym, boolean allInterfaces) {
1225            // Presently no way to refer to this type directly, so we
1226            // cannot put annotations directly on it.
1227            super(Type.noType, List.nil(), csym);
1228            this.allInterfaces = allInterfaces;
1229            Assert.check((csym.flags() & COMPOUND) != 0);
1230            supertype_field = bounds.head;
1231            interfaces_field = bounds.tail;
1232            Assert.check(!supertype_field.tsym.isCompleted() ||
1233                    !supertype_field.isInterface(), supertype_field);
1234        }
1235
1236        @Override
1237        public IntersectionClassType cloneWithMetadata(TypeMetadata md) {
1238            throw new AssertionError("Cannot add metadata to an intersection type");
1239        }
1240
1241        @DefinedBy(Api.LANGUAGE_MODEL)
1242        public java.util.List<? extends TypeMirror> getBounds() {
1243            return Collections.unmodifiableList(getExplicitComponents());
1244        }
1245
1246        @Override
1247        public boolean isCompound() {
1248            return true;
1249        }
1250
1251        public List<Type> getComponents() {
1252            return interfaces_field.prepend(supertype_field);
1253        }
1254
1255        @Override
1256        public boolean isIntersection() {
1257            return true;
1258        }
1259
1260        public List<Type> getExplicitComponents() {
1261            return allInterfaces ?
1262                    interfaces_field :
1263                    getComponents();
1264        }
1265
1266        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1267        public TypeKind getKind() {
1268            return TypeKind.INTERSECTION;
1269        }
1270
1271        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1272        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1273            return v.visitIntersection(this, p);
1274        }
1275    }
1276
1277    public static class ArrayType extends Type
1278            implements javax.lang.model.type.ArrayType {
1279
1280        public Type elemtype;
1281
1282        public ArrayType(Type elemtype, TypeSymbol arrayClass) {
1283            this(elemtype, arrayClass, TypeMetadata.EMPTY);
1284        }
1285
1286        public ArrayType(Type elemtype, TypeSymbol arrayClass,
1287                         TypeMetadata metadata) {
1288            super(arrayClass, metadata);
1289            this.elemtype = elemtype;
1290        }
1291
1292        public ArrayType(ArrayType that) {
1293            //note: type metadata is deliberately shared here, as we want side-effects from annotation
1294            //processing to flow from original array to the cloned array.
1295            this(that.elemtype, that.tsym, that.getMetadata());
1296        }
1297
1298        @Override
1299        public ArrayType cloneWithMetadata(TypeMetadata md) {
1300            return new ArrayType(elemtype, tsym, md) {
1301                @Override
1302                public Type baseType() { return ArrayType.this.baseType(); }
1303            };
1304        }
1305
1306        @Override
1307        public TypeTag getTag() {
1308            return ARRAY;
1309        }
1310
1311        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1312            return v.visitArrayType(this, s);
1313        }
1314
1315        @DefinedBy(Api.LANGUAGE_MODEL)
1316        public String toString() {
1317            StringBuilder sb = new StringBuilder();
1318
1319            // First append root component type
1320            Type t = elemtype;
1321            while (t.getKind() == TypeKind.ARRAY)
1322                t = ((ArrayType) t).getComponentType();
1323            sb.append(t);
1324
1325            // then append @Anno[] @Anno[] ... @Anno[]
1326            t = this;
1327            do {
1328                t.appendAnnotationsString(sb, true);
1329                sb.append("[]");
1330                t = ((ArrayType) t).getComponentType();
1331            } while (t.getKind() == TypeKind.ARRAY);
1332
1333            return sb.toString();
1334        }
1335
1336        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1337        public boolean equals(Object obj) {
1338            if (obj instanceof ArrayType) {
1339                ArrayType that = (ArrayType)obj;
1340                return this == that ||
1341                        elemtype.equals(that.elemtype);
1342            }
1343
1344            return false;
1345        }
1346
1347        @DefinedBy(Api.LANGUAGE_MODEL)
1348        public int hashCode() {
1349            return (ARRAY.ordinal() << 5) + elemtype.hashCode();
1350        }
1351
1352        public boolean isVarargs() {
1353            return false;
1354        }
1355
1356        public List<Type> allparams() { return elemtype.allparams(); }
1357
1358        public boolean isErroneous() {
1359            return elemtype.isErroneous();
1360        }
1361
1362        public boolean isParameterized() {
1363            return elemtype.isParameterized();
1364        }
1365
1366        @Override
1367        public boolean isReference() {
1368            return true;
1369        }
1370
1371        @Override
1372        public boolean isNullOrReference() {
1373            return true;
1374        }
1375
1376        public boolean isRaw() {
1377            return elemtype.isRaw();
1378        }
1379
1380        public ArrayType makeVarargs() {
1381            return new ArrayType(elemtype, tsym, metadata) {
1382                @Override
1383                public boolean isVarargs() {
1384                    return true;
1385                }
1386            };
1387        }
1388
1389        public boolean contains(Type elem) {
1390            return elem.equalsIgnoreMetadata(this) || elemtype.contains(elem);
1391        }
1392
1393        public void complete() {
1394            elemtype.complete();
1395        }
1396
1397        @DefinedBy(Api.LANGUAGE_MODEL)
1398        public Type getComponentType() {
1399            return elemtype;
1400        }
1401
1402        @DefinedBy(Api.LANGUAGE_MODEL)
1403        public TypeKind getKind() {
1404            return TypeKind.ARRAY;
1405        }
1406
1407        @DefinedBy(Api.LANGUAGE_MODEL)
1408        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1409            return v.visitArray(this, p);
1410        }
1411    }
1412
1413    public static class MethodType extends Type implements ExecutableType {
1414
1415        public List<Type> argtypes;
1416        public Type restype;
1417        public List<Type> thrown;
1418
1419        /** The type annotations on the method receiver.
1420         */
1421        public Type recvtype;
1422
1423        public MethodType(List<Type> argtypes,
1424                          Type restype,
1425                          List<Type> thrown,
1426                          TypeSymbol methodClass) {
1427            // Presently no way to refer to a method type directly, so
1428            // we cannot put type annotations on it.
1429            super(methodClass, TypeMetadata.EMPTY);
1430            this.argtypes = argtypes;
1431            this.restype = restype;
1432            this.thrown = thrown;
1433        }
1434
1435        @Override
1436        public MethodType cloneWithMetadata(TypeMetadata md) {
1437            throw new AssertionError("Cannot add metadata to a method type");
1438        }
1439
1440        @Override
1441        public TypeTag getTag() {
1442            return METHOD;
1443        }
1444
1445        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1446            return v.visitMethodType(this, s);
1447        }
1448
1449        /** The Java source which this type represents.
1450         *
1451         *  XXX 06/09/99 iris This isn't correct Java syntax, but it probably
1452         *  should be.
1453         */
1454        @DefinedBy(Api.LANGUAGE_MODEL)
1455        public String toString() {
1456            StringBuilder sb = new StringBuilder();
1457            appendAnnotationsString(sb);
1458            sb.append('(');
1459            sb.append(argtypes);
1460            sb.append(')');
1461            sb.append(restype);
1462            return sb.toString();
1463        }
1464
1465        @DefinedBy(Api.LANGUAGE_MODEL)
1466        public List<Type>        getParameterTypes() { return argtypes; }
1467        @DefinedBy(Api.LANGUAGE_MODEL)
1468        public Type              getReturnType()     { return restype; }
1469        @DefinedBy(Api.LANGUAGE_MODEL)
1470        public Type              getReceiverType()   { return recvtype; }
1471        @DefinedBy(Api.LANGUAGE_MODEL)
1472        public List<Type>        getThrownTypes()    { return thrown; }
1473
1474        public boolean isErroneous() {
1475            return
1476                isErroneous(argtypes) ||
1477                restype != null && restype.isErroneous();
1478        }
1479
1480        public boolean contains(Type elem) {
1481            return elem.equalsIgnoreMetadata(this) || contains(argtypes, elem) || restype.contains(elem) || contains(thrown, elem);
1482        }
1483
1484        public MethodType asMethodType() { return this; }
1485
1486        public void complete() {
1487            for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
1488                l.head.complete();
1489            restype.complete();
1490            recvtype.complete();
1491            for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
1492                l.head.complete();
1493        }
1494
1495        @DefinedBy(Api.LANGUAGE_MODEL)
1496        public List<TypeVar> getTypeVariables() {
1497            return List.nil();
1498        }
1499
1500        public TypeSymbol asElement() {
1501            return null;
1502        }
1503
1504        @DefinedBy(Api.LANGUAGE_MODEL)
1505        public TypeKind getKind() {
1506            return TypeKind.EXECUTABLE;
1507        }
1508
1509        @DefinedBy(Api.LANGUAGE_MODEL)
1510        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1511            return v.visitExecutable(this, p);
1512        }
1513    }
1514
1515    public static class PackageType extends Type implements NoType {
1516
1517        PackageType(PackageSymbol tsym) {
1518            // Package types cannot be annotated
1519            super(tsym, TypeMetadata.EMPTY);
1520        }
1521
1522        @Override
1523        public PackageType cloneWithMetadata(TypeMetadata md) {
1524            throw new AssertionError("Cannot add metadata to a package type");
1525        }
1526
1527        @Override
1528        public TypeTag getTag() {
1529            return PACKAGE;
1530        }
1531
1532        @Override
1533        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1534            return v.visitPackageType(this, s);
1535        }
1536
1537        @DefinedBy(Api.LANGUAGE_MODEL)
1538        public String toString() {
1539            return tsym.getQualifiedName().toString();
1540        }
1541
1542        @DefinedBy(Api.LANGUAGE_MODEL)
1543        public TypeKind getKind() {
1544            return TypeKind.PACKAGE;
1545        }
1546
1547        @DefinedBy(Api.LANGUAGE_MODEL)
1548        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1549            return v.visitNoType(this, p);
1550        }
1551    }
1552
1553    public static class ModuleType extends Type implements NoType {
1554
1555        ModuleType(ModuleSymbol tsym) {
1556            // Module types cannot be annotated
1557            super(tsym, TypeMetadata.EMPTY);
1558        }
1559
1560        @Override
1561        public ModuleType cloneWithMetadata(TypeMetadata md) {
1562            throw new AssertionError("Cannot add metadata to a module type");
1563        }
1564
1565        @Override
1566        public ModuleType annotatedType(List<Attribute.TypeCompound> annos) {
1567            throw new AssertionError("Cannot annotate a module type");
1568        }
1569
1570        @Override
1571        public TypeTag getTag() {
1572            return TypeTag.MODULE;
1573        }
1574
1575        @Override
1576        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1577            return v.visitModuleType(this, s);
1578        }
1579
1580        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1581        public String toString() {
1582            return tsym.getQualifiedName().toString();
1583        }
1584
1585        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1586        public TypeKind getKind() {
1587            return TypeKind.MODULE;
1588        }
1589
1590        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1591        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1592            return v.visitNoType(this, p);
1593        }
1594    }
1595
1596    public static class TypeVar extends Type implements TypeVariable {
1597
1598        /** The upper bound of this type variable; set from outside.
1599         *  Must be nonempty once it is set.
1600         *  For a bound, `bound' is the bound type itself.
1601         *  Multiple bounds are expressed as a single class type which has the
1602         *  individual bounds as superclass, respectively interfaces.
1603         *  The class type then has as `tsym' a compiler generated class `c',
1604         *  which has a flag COMPOUND and whose owner is the type variable
1605         *  itself. Furthermore, the erasure_field of the class
1606         *  points to the first class or interface bound.
1607         */
1608        public Type bound = null;
1609
1610        /** The lower bound of this type variable.
1611         *  TypeVars don't normally have a lower bound, so it is normally set
1612         *  to syms.botType.
1613         *  Subtypes, such as CapturedType, may provide a different value.
1614         */
1615        public Type lower;
1616
1617        public TypeVar(Name name, Symbol owner, Type lower) {
1618            super(null, TypeMetadata.EMPTY);
1619            tsym = new TypeVariableSymbol(0, name, this, owner);
1620            this.bound = null;
1621            this.lower = lower;
1622        }
1623
1624        public TypeVar(TypeSymbol tsym, Type bound, Type lower) {
1625            this(tsym, bound, lower, TypeMetadata.EMPTY);
1626        }
1627
1628        public TypeVar(TypeSymbol tsym, Type bound, Type lower,
1629                       TypeMetadata metadata) {
1630            super(tsym, metadata);
1631            this.bound = bound;
1632            this.lower = lower;
1633        }
1634
1635        @Override
1636        public TypeVar cloneWithMetadata(TypeMetadata md) {
1637            return new TypeVar(tsym, bound, lower, md) {
1638                @Override
1639                public Type baseType() { return TypeVar.this.baseType(); }
1640            };
1641        }
1642
1643        @Override
1644        public TypeTag getTag() {
1645            return TYPEVAR;
1646        }
1647
1648        @Override
1649        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1650            return v.visitTypeVar(this, s);
1651        }
1652
1653        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1654        public Type getUpperBound() {
1655            if ((bound == null || bound.hasTag(NONE)) && this != tsym.type) {
1656                bound = tsym.type.getUpperBound();
1657            }
1658            return bound;
1659        }
1660
1661        int rank_field = -1;
1662
1663        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1664        public Type getLowerBound() {
1665            return lower;
1666        }
1667
1668        @DefinedBy(Api.LANGUAGE_MODEL)
1669        public TypeKind getKind() {
1670            return TypeKind.TYPEVAR;
1671        }
1672
1673        public boolean isCaptured() {
1674            return false;
1675        }
1676
1677        @Override
1678        public boolean isReference() {
1679            return true;
1680        }
1681
1682        @Override
1683        public boolean isNullOrReference() {
1684            return true;
1685        }
1686
1687        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1688        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1689            return v.visitTypeVariable(this, p);
1690        }
1691    }
1692
1693    /** A captured type variable comes from wildcards which can have
1694     *  both upper and lower bound.  CapturedType extends TypeVar with
1695     *  a lower bound.
1696     */
1697    public static class CapturedType extends TypeVar {
1698
1699        public WildcardType wildcard;
1700
1701        public CapturedType(Name name,
1702                            Symbol owner,
1703                            Type upper,
1704                            Type lower,
1705                            WildcardType wildcard) {
1706            super(name, owner, lower);
1707            this.lower = Assert.checkNonNull(lower);
1708            this.bound = upper;
1709            this.wildcard = wildcard;
1710        }
1711
1712        public CapturedType(TypeSymbol tsym,
1713                            Type bound,
1714                            Type upper,
1715                            Type lower,
1716                            WildcardType wildcard,
1717                            TypeMetadata metadata) {
1718            super(tsym, bound, lower, metadata);
1719            this.wildcard = wildcard;
1720        }
1721
1722        @Override
1723        public CapturedType cloneWithMetadata(TypeMetadata md) {
1724            return new CapturedType(tsym, bound, bound, lower, wildcard, md) {
1725                @Override
1726                public Type baseType() { return CapturedType.this.baseType(); }
1727            };
1728        }
1729
1730        @Override
1731        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1732            return v.visitCapturedType(this, s);
1733        }
1734
1735        @Override
1736        public boolean isCaptured() {
1737            return true;
1738        }
1739
1740        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1741        public String toString() {
1742            StringBuilder sb = new StringBuilder();
1743            appendAnnotationsString(sb);
1744            sb.append("capture#");
1745            sb.append((hashCode() & 0xFFFFFFFFL) % Printer.PRIME);
1746            sb.append(" of ");
1747            sb.append(wildcard);
1748            return sb.toString();
1749        }
1750    }
1751
1752    public static abstract class DelegatedType extends Type {
1753        public Type qtype;
1754        public TypeTag tag;
1755
1756        public DelegatedType(TypeTag tag, Type qtype) {
1757            this(tag, qtype, TypeMetadata.EMPTY);
1758        }
1759
1760        public DelegatedType(TypeTag tag, Type qtype,
1761                             TypeMetadata metadata) {
1762            super(qtype.tsym, metadata);
1763            this.tag = tag;
1764            this.qtype = qtype;
1765        }
1766
1767        public TypeTag getTag() { return tag; }
1768        @DefinedBy(Api.LANGUAGE_MODEL)
1769        public String toString() { return qtype.toString(); }
1770        public List<Type> getTypeArguments() { return qtype.getTypeArguments(); }
1771        public Type getEnclosingType() { return qtype.getEnclosingType(); }
1772        public List<Type> getParameterTypes() { return qtype.getParameterTypes(); }
1773        public Type getReturnType() { return qtype.getReturnType(); }
1774        public Type getReceiverType() { return qtype.getReceiverType(); }
1775        public List<Type> getThrownTypes() { return qtype.getThrownTypes(); }
1776        public List<Type> allparams() { return qtype.allparams(); }
1777        public Type getUpperBound() { return qtype.getUpperBound(); }
1778        public boolean isErroneous() { return qtype.isErroneous(); }
1779    }
1780
1781    /**
1782     * The type of a generic method type. It consists of a method type and
1783     * a list of method type-parameters that are used within the method
1784     * type.
1785     */
1786    public static class ForAll extends DelegatedType implements ExecutableType {
1787        public List<Type> tvars;
1788
1789        public ForAll(List<Type> tvars, Type qtype) {
1790            super(FORALL, (MethodType)qtype);
1791            this.tvars = tvars;
1792        }
1793
1794        @Override
1795        public ForAll cloneWithMetadata(TypeMetadata md) {
1796            throw new AssertionError("Cannot add metadata to a forall type");
1797        }
1798
1799        @Override
1800        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1801            return v.visitForAll(this, s);
1802        }
1803
1804        @DefinedBy(Api.LANGUAGE_MODEL)
1805        public String toString() {
1806            StringBuilder sb = new StringBuilder();
1807            appendAnnotationsString(sb);
1808            sb.append('<');
1809            sb.append(tvars);
1810            sb.append('>');
1811            sb.append(qtype);
1812            return sb.toString();
1813        }
1814
1815        public List<Type> getTypeArguments()   { return tvars; }
1816
1817        public boolean isErroneous()  {
1818            return qtype.isErroneous();
1819        }
1820
1821        public boolean contains(Type elem) {
1822            return qtype.contains(elem);
1823        }
1824
1825        public MethodType asMethodType() {
1826            return (MethodType)qtype;
1827        }
1828
1829        public void complete() {
1830            for (List<Type> l = tvars; l.nonEmpty(); l = l.tail) {
1831                ((TypeVar)l.head).bound.complete();
1832            }
1833            qtype.complete();
1834        }
1835
1836        @DefinedBy(Api.LANGUAGE_MODEL)
1837        public List<TypeVar> getTypeVariables() {
1838            return List.convert(TypeVar.class, getTypeArguments());
1839        }
1840
1841        @DefinedBy(Api.LANGUAGE_MODEL)
1842        public TypeKind getKind() {
1843            return TypeKind.EXECUTABLE;
1844        }
1845
1846        @DefinedBy(Api.LANGUAGE_MODEL)
1847        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1848            return v.visitExecutable(this, p);
1849        }
1850    }
1851
1852    /** A class for inference variables, for use during method/diamond type
1853     *  inference. An inference variable has upper/lower bounds and a set
1854     *  of equality constraints. Such bounds are set during subtyping, type-containment,
1855     *  type-equality checks, when the types being tested contain inference variables.
1856     *  A change listener can be attached to an inference variable, to receive notifications
1857     *  whenever the bounds of an inference variable change.
1858     */
1859    public static class UndetVar extends DelegatedType {
1860
1861        enum Kind {
1862            NORMAL,
1863            CAPTURED,
1864            THROWS;
1865        }
1866
1867        /** Inference variable change listener. The listener method is called
1868         *  whenever a change to the inference variable's bounds occurs
1869         */
1870        public interface UndetVarListener {
1871            /** called when some inference variable bounds (of given kinds ibs) change */
1872            void varBoundChanged(UndetVar uv, InferenceBound ib, Type bound, boolean update);
1873            /** called when the inferred type is set on some inference variable */
1874            default void varInstantiated(UndetVar uv) { Assert.error(); }
1875        }
1876
1877        /**
1878         * Inference variable bound kinds
1879         */
1880        public enum InferenceBound {
1881            /** lower bounds */
1882            LOWER {
1883                public InferenceBound complement() { return UPPER; }
1884            },
1885            /** equality constraints */
1886            EQ {
1887                public InferenceBound complement() { return EQ; }
1888            },
1889            /** upper bounds */
1890            UPPER {
1891                public InferenceBound complement() { return LOWER; }
1892            };
1893
1894            public abstract InferenceBound complement();
1895
1896            public boolean lessThan(InferenceBound that) {
1897                if (that == this) {
1898                    return false;
1899                } else {
1900                    switch (that) {
1901                        case UPPER: return true;
1902                        case LOWER: return false;
1903                        case EQ: return (this != UPPER);
1904                        default:
1905                            Assert.error("Cannot get here!");
1906                            return false;
1907                    }
1908                }
1909            }
1910        }
1911
1912        /** list of incorporation actions (used by the incorporation engine). */
1913        public ArrayDeque<IncorporationAction> incorporationActions = new ArrayDeque<>();
1914
1915        /** inference variable bounds */
1916        protected Map<InferenceBound, List<Type>> bounds;
1917
1918        /** inference variable's inferred type (set from Infer.java) */
1919        private Type inst = null;
1920
1921        /** number of declared (upper) bounds */
1922        public int declaredCount;
1923
1924        /** inference variable's change listener */
1925        public UndetVarListener listener = null;
1926
1927        Kind kind;
1928
1929        @Override
1930        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1931            return v.visitUndetVar(this, s);
1932        }
1933
1934        public UndetVar(TypeVar origin, UndetVarListener listener, Types types) {
1935            // This is a synthesized internal type, so we cannot annotate it.
1936            super(UNDETVAR, origin);
1937            this.kind = origin.isCaptured() ?
1938                    Kind.CAPTURED :
1939                    Kind.NORMAL;
1940            this.listener = listener;
1941            bounds = new EnumMap<>(InferenceBound.class);
1942            List<Type> declaredBounds = types.getBounds(origin);
1943            declaredCount = declaredBounds.length();
1944            bounds.put(InferenceBound.UPPER, List.nil());
1945            bounds.put(InferenceBound.LOWER, List.nil());
1946            bounds.put(InferenceBound.EQ, List.nil());
1947            for (Type t : declaredBounds.reverse()) {
1948                //add bound works in reverse order
1949                addBound(InferenceBound.UPPER, t, types, true);
1950            }
1951            if (origin.isCaptured() && !origin.lower.hasTag(BOT)) {
1952                //add lower bound if needed
1953                addBound(InferenceBound.LOWER, origin.lower, types, true);
1954            }
1955        }
1956
1957        @DefinedBy(Api.LANGUAGE_MODEL)
1958        public String toString() {
1959            StringBuilder sb = new StringBuilder();
1960            appendAnnotationsString(sb);
1961            if (inst == null) {
1962                sb.append(qtype);
1963                sb.append('?');
1964            } else {
1965                sb.append(inst);
1966            }
1967            return sb.toString();
1968        }
1969
1970        public String debugString() {
1971            String result = "inference var = " + qtype + "\n";
1972            if (inst != null) {
1973                result += "inst = " + inst + '\n';
1974            }
1975            for (InferenceBound bound: InferenceBound.values()) {
1976                List<Type> aboundList = bounds.get(bound);
1977                if (aboundList.size() > 0) {
1978                    result += bound + " = " + aboundList + '\n';
1979                }
1980            }
1981            return result;
1982        }
1983
1984        public void setThrow() {
1985            if (this.kind == Kind.CAPTURED) {
1986                //invalid state transition
1987                throw new IllegalStateException();
1988            }
1989            this.kind = Kind.THROWS;
1990        }
1991
1992        /**
1993         * Returns a new copy of this undet var.
1994         */
1995        public UndetVar dup(Types types) {
1996            UndetVar uv2 = new UndetVar((TypeVar)qtype, listener, types);
1997            dupTo(uv2, types);
1998            return uv2;
1999        }
2000
2001        /**
2002         * Dumps the contents of this undet var on another undet var.
2003         */
2004        public void dupTo(UndetVar uv2, Types types) {
2005            uv2.listener = null;
2006            uv2.bounds.clear();
2007            for (InferenceBound ib : InferenceBound.values()) {
2008                uv2.bounds.put(ib, List.nil());
2009                for (Type t : getBounds(ib)) {
2010                    uv2.addBound(ib, t, types, true);
2011                }
2012            }
2013            uv2.inst = inst;
2014            uv2.listener = listener;
2015            uv2.incorporationActions = new ArrayDeque<>();
2016            for (IncorporationAction action : incorporationActions) {
2017                uv2.incorporationActions.add(action.dup(uv2));
2018            }
2019        }
2020
2021        @Override
2022        public UndetVar cloneWithMetadata(TypeMetadata md) {
2023            throw new AssertionError("Cannot add metadata to an UndetVar type");
2024        }
2025
2026        @Override
2027        public boolean isPartial() {
2028            return true;
2029        }
2030
2031        @Override
2032        public Type baseType() {
2033            return (inst == null) ? this : inst.baseType();
2034        }
2035
2036        public Type getInst() {
2037            return inst;
2038        }
2039
2040        public void setInst(Type inst) {
2041            this.inst = inst;
2042            if (listener != null) {
2043                listener.varInstantiated(this);
2044            }
2045        }
2046
2047        /** get all bounds of a given kind */
2048        public List<Type> getBounds(InferenceBound... ibs) {
2049            ListBuffer<Type> buf = new ListBuffer<>();
2050            for (InferenceBound ib : ibs) {
2051                buf.appendList(bounds.get(ib));
2052            }
2053            return buf.toList();
2054        }
2055
2056        /** get the list of declared (upper) bounds */
2057        public List<Type> getDeclaredBounds() {
2058            ListBuffer<Type> buf = new ListBuffer<>();
2059            int count = 0;
2060            for (Type b : getBounds(InferenceBound.UPPER)) {
2061                if (count++ == declaredCount) break;
2062                buf.append(b);
2063            }
2064            return buf.toList();
2065        }
2066
2067        /** internal method used to override an undetvar bounds */
2068        public void setBounds(InferenceBound ib, List<Type> newBounds) {
2069            bounds.put(ib, newBounds);
2070        }
2071
2072        /** add a bound of a given kind - this might trigger listener notification */
2073        public final void addBound(InferenceBound ib, Type bound, Types types) {
2074            // Per JDK-8075793: in pre-8 sources, follow legacy javac behavior
2075            // when capture variables are inferred as bounds: for lower bounds,
2076            // map to the capture variable's upper bound; for upper bounds,
2077            // if the capture variable has a lower bound, map to that type
2078            if (types.mapCapturesToBounds) {
2079                switch (ib) {
2080                    case LOWER:
2081                        bound = types.cvarUpperBound(bound);
2082                        break;
2083                    case UPPER:
2084                        Type altBound = types.cvarLowerBound(bound);
2085                        if (!altBound.hasTag(TypeTag.BOT)) bound = altBound;
2086                        break;
2087                }
2088            }
2089            addBound(ib, bound, types, false);
2090        }
2091
2092        @SuppressWarnings("fallthrough")
2093        private void addBound(InferenceBound ib, Type bound, Types types, boolean update) {
2094            if (kind == Kind.CAPTURED && !update) {
2095                //Captured inference variables bounds must not be updated during incorporation,
2096                //except when some inference variable (beta) has been instantiated in the
2097                //right-hand-side of a 'C<alpha> = capture(C<? extends/super beta>) constraint.
2098                if (bound.hasTag(UNDETVAR) && !((UndetVar)bound).isCaptured()) {
2099                    //If the new incoming bound is itself a (regular) inference variable,
2100                    //then we are allowed to propagate this inference variable bounds to it.
2101                    ((UndetVar)bound).addBound(ib.complement(), this, types, false);
2102                }
2103            } else {
2104                Type bound2 = bound.map(toTypeVarMap).baseType();
2105                List<Type> prevBounds = bounds.get(ib);
2106                if (bound == qtype) return;
2107                for (Type b : prevBounds) {
2108                    //check for redundancy - use strict version of isSameType on tvars
2109                    //(as the standard version will lead to false positives w.r.t. clones ivars)
2110                    if (types.isSameType(b, bound2, true)) return;
2111                }
2112                bounds.put(ib, prevBounds.prepend(bound2));
2113                notifyBoundChange(ib, bound2, false);
2114            }
2115        }
2116        //where
2117            TypeMapping<Void> toTypeVarMap = new StructuralTypeMapping<Void>() {
2118                @Override
2119                public Type visitUndetVar(UndetVar uv, Void _unused) {
2120                    return uv.inst != null ? uv.inst : uv.qtype;
2121                }
2122            };
2123
2124        /** replace types in all bounds - this might trigger listener notification */
2125        public void substBounds(List<Type> from, List<Type> to, Types types) {
2126            final ListBuffer<Pair<InferenceBound, Type>>  boundsChanged = new ListBuffer<>();
2127            UndetVarListener prevListener = listener;
2128            try {
2129                //setup new listener for keeping track of changed bounds
2130                listener = (uv, ib, t, _ignored) -> {
2131                    Assert.check(uv == UndetVar.this);
2132                    boundsChanged.add(new Pair<>(ib, t));
2133                };
2134                for (Map.Entry<InferenceBound, List<Type>> _entry : bounds.entrySet()) {
2135                    InferenceBound ib = _entry.getKey();
2136                    List<Type> prevBounds = _entry.getValue();
2137                    ListBuffer<Type> newBounds = new ListBuffer<>();
2138                    ListBuffer<Type> deps = new ListBuffer<>();
2139                    //step 1 - re-add bounds that are not dependent on ivars
2140                    for (Type t : prevBounds) {
2141                        if (!t.containsAny(from)) {
2142                            newBounds.append(t);
2143                        } else {
2144                            deps.append(t);
2145                        }
2146                    }
2147                    //step 2 - replace bounds
2148                    bounds.put(ib, newBounds.toList());
2149                    //step 3 - for each dependency, add new replaced bound
2150                    for (Type dep : deps) {
2151                        addBound(ib, types.subst(dep, from, to), types, true);
2152                    }
2153                }
2154            } finally {
2155                listener = prevListener;
2156                for (Pair<InferenceBound, Type> boundUpdate : boundsChanged) {
2157                    notifyBoundChange(boundUpdate.fst, boundUpdate.snd, true);
2158                }
2159            }
2160        }
2161
2162        private void notifyBoundChange(InferenceBound ib, Type bound, boolean update) {
2163            if (listener != null) {
2164                listener.varBoundChanged(this, ib, bound, update);
2165            }
2166        }
2167
2168        public final boolean isCaptured() {
2169            return kind == Kind.CAPTURED;
2170        }
2171
2172        public final boolean isThrows() {
2173            return kind == Kind.THROWS;
2174        }
2175    }
2176
2177    /** Represents NONE.
2178     */
2179    public static class JCNoType extends Type implements NoType {
2180        public JCNoType() {
2181            // Need to use List.nil(), because JCNoType constructor
2182            // gets called in static initializers in Type, where
2183            // noAnnotations is also defined.
2184            super(null, TypeMetadata.EMPTY);
2185        }
2186
2187        @Override
2188        public JCNoType cloneWithMetadata(TypeMetadata md) {
2189            throw new AssertionError("Cannot add metadata to a JCNoType");
2190        }
2191
2192        @Override
2193        public TypeTag getTag() {
2194            return NONE;
2195        }
2196
2197        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2198        public TypeKind getKind() {
2199            return TypeKind.NONE;
2200        }
2201
2202        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2203        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2204            return v.visitNoType(this, p);
2205        }
2206
2207        @Override
2208        public boolean isCompound() { return false; }
2209    }
2210
2211    /** Represents VOID.
2212     */
2213    public static class JCVoidType extends Type implements NoType {
2214
2215        public JCVoidType() {
2216            // Void cannot be annotated
2217            super(null, TypeMetadata.EMPTY);
2218        }
2219
2220        @Override
2221        public JCVoidType cloneWithMetadata(TypeMetadata md) {
2222            throw new AssertionError("Cannot add metadata to a void type");
2223        }
2224
2225        @Override
2226        public TypeTag getTag() {
2227            return VOID;
2228        }
2229
2230        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2231        public TypeKind getKind() {
2232            return TypeKind.VOID;
2233        }
2234
2235        @Override
2236        public boolean isCompound() { return false; }
2237
2238        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2239        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2240            return v.visitNoType(this, p);
2241        }
2242
2243        @Override
2244        public boolean isPrimitiveOrVoid() {
2245            return true;
2246        }
2247    }
2248
2249    static class BottomType extends Type implements NullType {
2250        public BottomType() {
2251            // Bottom is a synthesized internal type, so it cannot be annotated
2252            super(null, TypeMetadata.EMPTY);
2253        }
2254
2255        @Override
2256        public BottomType cloneWithMetadata(TypeMetadata md) {
2257            throw new AssertionError("Cannot add metadata to a bottom type");
2258        }
2259
2260        @Override
2261        public TypeTag getTag() {
2262            return BOT;
2263        }
2264
2265        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2266        public TypeKind getKind() {
2267            return TypeKind.NULL;
2268        }
2269
2270        @Override
2271        public boolean isCompound() { return false; }
2272
2273        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2274        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2275            return v.visitNull(this, p);
2276        }
2277
2278        @Override
2279        public Type constType(Object value) {
2280            return this;
2281        }
2282
2283        @Override
2284        public String stringValue() {
2285            return "null";
2286        }
2287
2288        @Override
2289        public boolean isNullOrReference() {
2290            return true;
2291        }
2292
2293    }
2294
2295    public static class ErrorType extends ClassType
2296            implements javax.lang.model.type.ErrorType {
2297
2298        private Type originalType = null;
2299
2300        public ErrorType(ClassSymbol c, Type originalType) {
2301            this(originalType, c);
2302            c.type = this;
2303            c.kind = ERR;
2304            c.members_field = new Scope.ErrorScope(c);
2305        }
2306
2307        public ErrorType(Type originalType, TypeSymbol tsym) {
2308            super(noType, List.nil(), null);
2309            this.tsym = tsym;
2310            this.originalType = (originalType == null ? noType : originalType);
2311        }
2312
2313        private ErrorType(Type originalType, TypeSymbol tsym,
2314                          TypeMetadata metadata) {
2315            super(noType, List.nil(), null, metadata);
2316            this.tsym = tsym;
2317            this.originalType = (originalType == null ? noType : originalType);
2318        }
2319
2320        @Override
2321        public ErrorType cloneWithMetadata(TypeMetadata md) {
2322            return new ErrorType(originalType, tsym, md) {
2323                @Override
2324                public Type baseType() { return ErrorType.this.baseType(); }
2325            };
2326        }
2327
2328        @Override
2329        public TypeTag getTag() {
2330            return ERROR;
2331        }
2332
2333        @Override
2334        public boolean isPartial() {
2335            return true;
2336        }
2337
2338        @Override
2339        public boolean isReference() {
2340            return true;
2341        }
2342
2343        @Override
2344        public boolean isNullOrReference() {
2345            return true;
2346        }
2347
2348        public ErrorType(Name name, TypeSymbol container, Type originalType) {
2349            this(new ClassSymbol(PUBLIC|STATIC|ACYCLIC, name, null, container), originalType);
2350        }
2351
2352        @Override
2353        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
2354            return v.visitErrorType(this, s);
2355        }
2356
2357        public Type constType(Object constValue) { return this; }
2358        @DefinedBy(Api.LANGUAGE_MODEL)
2359        public Type getEnclosingType()           { return this; }
2360        public Type getReturnType()              { return this; }
2361        public Type asSub(Symbol sym)            { return this; }
2362
2363        public boolean isGenType(Type t)         { return true; }
2364        public boolean isErroneous()             { return true; }
2365        public boolean isCompound()              { return false; }
2366        public boolean isInterface()             { return false; }
2367
2368        public List<Type> allparams()            { return List.nil(); }
2369        @DefinedBy(Api.LANGUAGE_MODEL)
2370        public List<Type> getTypeArguments()     { return List.nil(); }
2371
2372        @DefinedBy(Api.LANGUAGE_MODEL)
2373        public TypeKind getKind() {
2374            return TypeKind.ERROR;
2375        }
2376
2377        public Type getOriginalType() {
2378            return originalType;
2379        }
2380
2381        @DefinedBy(Api.LANGUAGE_MODEL)
2382        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2383            return v.visitError(this, p);
2384        }
2385    }
2386
2387    public static class UnknownType extends Type {
2388
2389        public UnknownType() {
2390            // Unknown is a synthesized internal type, so it cannot be
2391            // annotated.
2392            super(null, TypeMetadata.EMPTY);
2393        }
2394
2395        @Override
2396        public UnknownType cloneWithMetadata(TypeMetadata md) {
2397            throw new AssertionError("Cannot add metadata to an unknown type");
2398        }
2399
2400        @Override
2401        public TypeTag getTag() {
2402            return UNKNOWN;
2403        }
2404
2405        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2406        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2407            return v.visitUnknown(this, p);
2408        }
2409
2410        @Override
2411        public boolean isPartial() {
2412            return true;
2413        }
2414    }
2415
2416    /**
2417     * A visitor for types.  A visitor is used to implement operations
2418     * (or relations) on types.  Most common operations on types are
2419     * binary relations and this interface is designed for binary
2420     * relations, that is, operations of the form
2421     * Type&nbsp;&times;&nbsp;S&nbsp;&rarr;&nbsp;R.
2422     * <!-- In plain text: Type x S -> R -->
2423     *
2424     * @param <R> the return type of the operation implemented by this
2425     * visitor; use Void if no return type is needed.
2426     * @param <S> the type of the second argument (the first being the
2427     * type itself) of the operation implemented by this visitor; use
2428     * Void if a second argument is not needed.
2429     */
2430    public interface Visitor<R,S> {
2431        R visitClassType(ClassType t, S s);
2432        R visitWildcardType(WildcardType t, S s);
2433        R visitArrayType(ArrayType t, S s);
2434        R visitMethodType(MethodType t, S s);
2435        R visitPackageType(PackageType t, S s);
2436        R visitModuleType(ModuleType t, S s);
2437        R visitTypeVar(TypeVar t, S s);
2438        R visitCapturedType(CapturedType t, S s);
2439        R visitForAll(ForAll t, S s);
2440        R visitUndetVar(UndetVar t, S s);
2441        R visitErrorType(ErrorType t, S s);
2442        R visitType(Type t, S s);
2443    }
2444}
2445