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