Type.java revision 2877:62e285806e83
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        return tsym.completer == null
584            // Compound types can't have a completer.  Calling
585            // flags() will complete the symbol causing the
586            // compiler to load classes unnecessarily.  This led
587            // to regression 6180021.
588            && (tsym.flags() & COMPOUND) != 0;
589    }
590
591    public boolean isIntersection() {
592        return false;
593    }
594
595    public boolean isUnion() {
596        return false;
597    }
598
599    public boolean isInterface() {
600        return (tsym.flags() & INTERFACE) != 0;
601    }
602
603    public boolean isFinal() {
604        return (tsym.flags() & FINAL) != 0;
605    }
606
607    /**
608     * Does this type contain occurrences of type t?
609     */
610    public boolean contains(Type t) {
611        return t.equalsIgnoreMetadata(this);
612    }
613
614    public static boolean contains(List<Type> ts, Type t) {
615        for (List<Type> l = ts;
616             l.tail != null /*inlined: l.nonEmpty()*/;
617             l = l.tail)
618            if (l.head.contains(t)) return true;
619        return false;
620    }
621
622    /** Does this type contain an occurrence of some type in 'ts'?
623     */
624    public boolean containsAny(List<Type> ts) {
625        for (Type t : ts)
626            if (this.contains(t)) return true;
627        return false;
628    }
629
630    public static boolean containsAny(List<Type> ts1, List<Type> ts2) {
631        for (Type t : ts1)
632            if (t.containsAny(ts2)) return true;
633        return false;
634    }
635
636    public static List<Type> filter(List<Type> ts, Filter<Type> tf) {
637        ListBuffer<Type> buf = new ListBuffer<>();
638        for (Type t : ts) {
639            if (tf.accepts(t)) {
640                buf.append(t);
641            }
642        }
643        return buf.toList();
644    }
645
646    public boolean isSuperBound() { return false; }
647    public boolean isExtendsBound() { return false; }
648    public boolean isUnbound() { return false; }
649    public Type withTypeVar(Type t) { return this; }
650
651    /** The underlying method type of this type.
652     */
653    public MethodType asMethodType() { throw new AssertionError(); }
654
655    /** Complete loading all classes in this type.
656     */
657    public void complete() {}
658
659    public TypeSymbol asElement() {
660        return tsym;
661    }
662
663    @Override @DefinedBy(Api.LANGUAGE_MODEL)
664    public TypeKind getKind() {
665        return TypeKind.OTHER;
666    }
667
668    @Override @DefinedBy(Api.LANGUAGE_MODEL)
669    public <R, P> R accept(TypeVisitor<R, P> v, P p) {
670        throw new AssertionError();
671    }
672
673    public static class JCPrimitiveType extends Type
674            implements javax.lang.model.type.PrimitiveType {
675
676        TypeTag tag;
677
678        public JCPrimitiveType(TypeTag tag, TypeSymbol tsym) {
679            this(tag, tsym, TypeMetadata.EMPTY);
680        }
681
682        private JCPrimitiveType(TypeTag tag, TypeSymbol tsym, TypeMetadata metadata) {
683            super(tsym, metadata);
684            this.tag = tag;
685            Assert.check(tag.isPrimitive);
686        }
687
688        @Override
689        public JCPrimitiveType cloneWithMetadata(TypeMetadata md) {
690            return new JCPrimitiveType(tag, tsym, md) {
691                @Override
692                public Type baseType() { return JCPrimitiveType.this.baseType(); }
693            };
694        }
695
696        @Override
697        public boolean isNumeric() {
698            return tag != BOOLEAN;
699        }
700
701        @Override
702        public boolean isPrimitive() {
703            return true;
704        }
705
706        @Override
707        public TypeTag getTag() {
708            return tag;
709        }
710
711        @Override
712        public boolean isPrimitiveOrVoid() {
713            return true;
714        }
715
716        /** Define a constant type, of the same kind as this type
717         *  and with given constant value
718         */
719        @Override
720        public Type constType(Object constValue) {
721            final Object value = constValue;
722            return new JCPrimitiveType(tag, tsym, metadata) {
723                    @Override
724                    public Object constValue() {
725                        return value;
726                    }
727                    @Override
728                    public Type baseType() {
729                        return tsym.type;
730                    }
731                };
732        }
733
734        /**
735         * The constant value of this type, converted to String
736         */
737        @Override
738        public String stringValue() {
739            Object cv = Assert.checkNonNull(constValue());
740            if (tag == BOOLEAN) {
741                return ((Integer) cv).intValue() == 0 ? "false" : "true";
742            }
743            else if (tag == CHAR) {
744                return String.valueOf((char) ((Integer) cv).intValue());
745            }
746            else {
747                return cv.toString();
748            }
749        }
750
751        /** Is this a constant type whose value is false?
752         */
753        @Override
754        public boolean isFalse() {
755            return
756                tag == BOOLEAN &&
757                constValue() != null &&
758                ((Integer)constValue()).intValue() == 0;
759        }
760
761        /** Is this a constant type whose value is true?
762         */
763        @Override
764        public boolean isTrue() {
765            return
766                tag == BOOLEAN &&
767                constValue() != null &&
768                ((Integer)constValue()).intValue() != 0;
769        }
770
771        @Override @DefinedBy(Api.LANGUAGE_MODEL)
772        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
773            return v.visitPrimitive(this, p);
774        }
775
776        @Override @DefinedBy(Api.LANGUAGE_MODEL)
777        public TypeKind getKind() {
778            switch (tag) {
779                case BYTE:      return TypeKind.BYTE;
780                case CHAR:      return TypeKind.CHAR;
781                case SHORT:     return TypeKind.SHORT;
782                case INT:       return TypeKind.INT;
783                case LONG:      return TypeKind.LONG;
784                case FLOAT:     return TypeKind.FLOAT;
785                case DOUBLE:    return TypeKind.DOUBLE;
786                case BOOLEAN:   return TypeKind.BOOLEAN;
787            }
788            throw new AssertionError();
789        }
790
791    }
792
793    public static class WildcardType extends Type
794            implements javax.lang.model.type.WildcardType {
795
796        public Type type;
797        public BoundKind kind;
798        public TypeVar bound;
799
800        @Override
801        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
802            return v.visitWildcardType(this, s);
803        }
804
805        public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) {
806            this(type, kind, tsym, null, TypeMetadata.EMPTY);
807        }
808
809        public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
810                            TypeMetadata metadata) {
811            this(type, kind, tsym, null, metadata);
812        }
813
814        public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
815                            TypeVar bound) {
816            this(type, kind, tsym, bound, TypeMetadata.EMPTY);
817        }
818
819        public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
820                            TypeVar bound, TypeMetadata metadata) {
821            super(tsym, metadata);
822            this.type = Assert.checkNonNull(type);
823            this.kind = kind;
824            this.bound = bound;
825        }
826
827        @Override
828        public WildcardType cloneWithMetadata(TypeMetadata md) {
829            return new WildcardType(type, kind, tsym, bound, md) {
830                @Override
831                public Type baseType() { return WildcardType.this.baseType(); }
832            };
833        }
834
835        @Override
836        public TypeTag getTag() {
837            return WILDCARD;
838        }
839
840        @Override
841        public boolean contains(Type t) {
842            return kind != UNBOUND && type.contains(t);
843        }
844
845        public boolean isSuperBound() {
846            return kind == SUPER ||
847                kind == UNBOUND;
848        }
849        public boolean isExtendsBound() {
850            return kind == EXTENDS ||
851                kind == UNBOUND;
852        }
853        public boolean isUnbound() {
854            return kind == UNBOUND;
855        }
856
857        @Override
858        public boolean isReference() {
859            return true;
860        }
861
862        @Override
863        public boolean isNullOrReference() {
864            return true;
865        }
866
867        @Override
868        public Type withTypeVar(Type t) {
869            //-System.err.println(this+".withTypeVar("+t+");");//DEBUG
870            if (bound == t)
871                return this;
872            bound = (TypeVar)t;
873            return this;
874        }
875
876        boolean isPrintingBound = false;
877        @DefinedBy(Api.LANGUAGE_MODEL)
878        public String toString() {
879            StringBuilder s = new StringBuilder();
880            appendAnnotationsString(s);
881            s.append(kind.toString());
882            if (kind != UNBOUND)
883                s.append(type);
884            if (moreInfo && bound != null && !isPrintingBound)
885                try {
886                    isPrintingBound = true;
887                    s.append("{:").append(bound.bound).append(":}");
888                } finally {
889                    isPrintingBound = false;
890                }
891            return s.toString();
892        }
893
894        @DefinedBy(Api.LANGUAGE_MODEL)
895        public Type getExtendsBound() {
896            if (kind == EXTENDS)
897                return type;
898            else
899                return null;
900        }
901
902        @DefinedBy(Api.LANGUAGE_MODEL)
903        public Type getSuperBound() {
904            if (kind == SUPER)
905                return type;
906            else
907                return null;
908        }
909
910        @DefinedBy(Api.LANGUAGE_MODEL)
911        public TypeKind getKind() {
912            return TypeKind.WILDCARD;
913        }
914
915        @DefinedBy(Api.LANGUAGE_MODEL)
916        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
917            return v.visitWildcard(this, p);
918        }
919    }
920
921    public static class ClassType extends Type implements DeclaredType {
922
923        /** The enclosing type of this type. If this is the type of an inner
924         *  class, outer_field refers to the type of its enclosing
925         *  instance class, in all other cases it refers to noType.
926         */
927        private Type outer_field;
928
929        /** The type parameters of this type (to be set once class is loaded).
930         */
931        public List<Type> typarams_field;
932
933        /** A cache variable for the type parameters of this type,
934         *  appended to all parameters of its enclosing class.
935         *  @see #allparams
936         */
937        public List<Type> allparams_field;
938
939        /** The supertype of this class (to be set once class is loaded).
940         */
941        public Type supertype_field;
942
943        /** The interfaces of this class (to be set once class is loaded).
944         */
945        public List<Type> interfaces_field;
946
947        /** All the interfaces of this class, including missing ones.
948         */
949        public List<Type> all_interfaces_field;
950
951        public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
952            this(outer, typarams, tsym, TypeMetadata.EMPTY);
953        }
954
955        public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym,
956                         TypeMetadata metadata) {
957            super(tsym, metadata);
958            this.outer_field = outer;
959            this.typarams_field = typarams;
960            this.allparams_field = null;
961            this.supertype_field = null;
962            this.interfaces_field = null;
963        }
964
965        @Override
966        public ClassType cloneWithMetadata(TypeMetadata md) {
967            return new ClassType(outer_field, typarams_field, tsym, md) {
968                @Override
969                public Type baseType() { return ClassType.this.baseType(); }
970            };
971        }
972
973        @Override
974        public TypeTag getTag() {
975            return CLASS;
976        }
977
978        @Override
979        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
980            return v.visitClassType(this, s);
981        }
982
983        public Type constType(Object constValue) {
984            final Object value = constValue;
985            return new ClassType(getEnclosingType(), typarams_field, tsym, metadata) {
986                    @Override
987                    public Object constValue() {
988                        return value;
989                    }
990                    @Override
991                    public Type baseType() {
992                        return tsym.type;
993                    }
994                };
995        }
996
997        /** The Java source which this type represents.
998         */
999        @DefinedBy(Api.LANGUAGE_MODEL)
1000        public String toString() {
1001            StringBuilder buf = new StringBuilder();
1002            if (getEnclosingType().hasTag(CLASS) && tsym.owner.kind == TYP) {
1003                buf.append(getEnclosingType().toString());
1004                buf.append(".");
1005                appendAnnotationsString(buf);
1006                buf.append(className(tsym, false));
1007            } else {
1008                appendAnnotationsString(buf);
1009                buf.append(className(tsym, true));
1010            }
1011
1012            if (getTypeArguments().nonEmpty()) {
1013                buf.append('<');
1014                buf.append(getTypeArguments().toString());
1015                buf.append(">");
1016            }
1017            return buf.toString();
1018        }
1019//where
1020            private String className(Symbol sym, boolean longform) {
1021                if (sym.name.isEmpty() && (sym.flags() & COMPOUND) != 0) {
1022                    StringBuilder s = new StringBuilder(supertype_field.toString());
1023                    for (List<Type> is=interfaces_field; is.nonEmpty(); is = is.tail) {
1024                        s.append("&");
1025                        s.append(is.head.toString());
1026                    }
1027                    return s.toString();
1028                } else if (sym.name.isEmpty()) {
1029                    String s;
1030                    ClassType norm = (ClassType) tsym.type;
1031                    if (norm == null) {
1032                        s = Log.getLocalizedString("anonymous.class", (Object)null);
1033                    } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
1034                        s = Log.getLocalizedString("anonymous.class",
1035                                                   norm.interfaces_field.head);
1036                    } else {
1037                        s = Log.getLocalizedString("anonymous.class",
1038                                                   norm.supertype_field);
1039                    }
1040                    if (moreInfo)
1041                        s += String.valueOf(sym.hashCode());
1042                    return s;
1043                } else if (longform) {
1044                    return sym.getQualifiedName().toString();
1045                } else {
1046                    return sym.name.toString();
1047                }
1048            }
1049
1050        @DefinedBy(Api.LANGUAGE_MODEL)
1051        public List<Type> getTypeArguments() {
1052            if (typarams_field == null) {
1053                complete();
1054                if (typarams_field == null)
1055                    typarams_field = List.nil();
1056            }
1057            return typarams_field;
1058        }
1059
1060        public boolean hasErasedSupertypes() {
1061            return isRaw();
1062        }
1063
1064        @DefinedBy(Api.LANGUAGE_MODEL)
1065        public Type getEnclosingType() {
1066            return outer_field;
1067        }
1068
1069        public void setEnclosingType(Type outer) {
1070            outer_field = outer;
1071        }
1072
1073        public List<Type> allparams() {
1074            if (allparams_field == null) {
1075                allparams_field = getTypeArguments().prependList(getEnclosingType().allparams());
1076            }
1077            return allparams_field;
1078        }
1079
1080        public boolean isErroneous() {
1081            return
1082                getEnclosingType().isErroneous() ||
1083                isErroneous(getTypeArguments()) ||
1084                this != tsym.type && tsym.type.isErroneous();
1085        }
1086
1087        public boolean isParameterized() {
1088            return allparams().tail != null;
1089            // optimization, was: allparams().nonEmpty();
1090        }
1091
1092        @Override
1093        public boolean isReference() {
1094            return true;
1095        }
1096
1097        @Override
1098        public boolean isNullOrReference() {
1099            return true;
1100        }
1101
1102        /** A cache for the rank. */
1103        int rank_field = -1;
1104
1105        /** A class type is raw if it misses some
1106         *  of its type parameter sections.
1107         *  After validation, this is equivalent to:
1108         *  {@code allparams.isEmpty() && tsym.type.allparams.nonEmpty(); }
1109         */
1110        public boolean isRaw() {
1111            return
1112                this != tsym.type && // necessary, but not sufficient condition
1113                tsym.type.allparams().nonEmpty() &&
1114                allparams().isEmpty();
1115        }
1116
1117        public boolean contains(Type elem) {
1118            return
1119                elem.equalsIgnoreMetadata(this)
1120                || (isParameterized()
1121                    && (getEnclosingType().contains(elem) || contains(getTypeArguments(), elem)))
1122                || (isCompound()
1123                    && (supertype_field.contains(elem) || contains(interfaces_field, elem)));
1124        }
1125
1126        public void complete() {
1127            if (tsym.completer != null) tsym.complete();
1128        }
1129
1130        @DefinedBy(Api.LANGUAGE_MODEL)
1131        public TypeKind getKind() {
1132            return TypeKind.DECLARED;
1133        }
1134
1135        @DefinedBy(Api.LANGUAGE_MODEL)
1136        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1137            return v.visitDeclared(this, p);
1138        }
1139    }
1140
1141    public static class ErasedClassType extends ClassType {
1142        public ErasedClassType(Type outer, TypeSymbol tsym,
1143                               TypeMetadata metadata) {
1144            super(outer, List.<Type>nil(), tsym, metadata);
1145        }
1146
1147        @Override
1148        public boolean hasErasedSupertypes() {
1149            return true;
1150        }
1151    }
1152
1153    // a clone of a ClassType that knows about the alternatives of a union type.
1154    public static class UnionClassType extends ClassType implements UnionType {
1155        final List<? extends Type> alternatives_field;
1156
1157        public UnionClassType(ClassType ct, List<? extends Type> alternatives) {
1158            // Presently no way to refer to this type directly, so we
1159            // cannot put annotations directly on it.
1160            super(ct.outer_field, ct.typarams_field, ct.tsym);
1161            allparams_field = ct.allparams_field;
1162            supertype_field = ct.supertype_field;
1163            interfaces_field = ct.interfaces_field;
1164            all_interfaces_field = ct.interfaces_field;
1165            alternatives_field = alternatives;
1166        }
1167
1168        @Override
1169        public UnionClassType cloneWithMetadata(TypeMetadata md) {
1170            throw new AssertionError("Cannot add metadata to a union type");
1171        }
1172
1173        public Type getLub() {
1174            return tsym.type;
1175        }
1176
1177        @DefinedBy(Api.LANGUAGE_MODEL)
1178        public java.util.List<? extends TypeMirror> getAlternatives() {
1179            return Collections.unmodifiableList(alternatives_field);
1180        }
1181
1182        @Override
1183        public boolean isUnion() {
1184            return true;
1185        }
1186
1187        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1188        public TypeKind getKind() {
1189            return TypeKind.UNION;
1190        }
1191
1192        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1193        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1194            return v.visitUnion(this, p);
1195        }
1196
1197        public Iterable<? extends Type> getAlternativeTypes() {
1198            return alternatives_field;
1199        }
1200    }
1201
1202    // a clone of a ClassType that knows about the bounds of an intersection type.
1203    public static class IntersectionClassType extends ClassType implements IntersectionType {
1204
1205        public boolean allInterfaces;
1206
1207        public IntersectionClassType(List<Type> bounds, ClassSymbol csym, boolean allInterfaces) {
1208            // Presently no way to refer to this type directly, so we
1209            // cannot put annotations directly on it.
1210            super(Type.noType, List.<Type>nil(), csym);
1211            this.allInterfaces = allInterfaces;
1212            Assert.check((csym.flags() & COMPOUND) != 0);
1213            supertype_field = bounds.head;
1214            interfaces_field = bounds.tail;
1215            Assert.check(supertype_field.tsym.completer != null ||
1216                    !supertype_field.isInterface(), supertype_field);
1217        }
1218
1219        @Override
1220        public IntersectionClassType cloneWithMetadata(TypeMetadata md) {
1221            throw new AssertionError("Cannot add metadata to an intersection type");
1222        }
1223
1224        @DefinedBy(Api.LANGUAGE_MODEL)
1225        public java.util.List<? extends TypeMirror> getBounds() {
1226            return Collections.unmodifiableList(getExplicitComponents());
1227        }
1228
1229        public List<Type> getComponents() {
1230            return interfaces_field.prepend(supertype_field);
1231        }
1232
1233        @Override
1234        public boolean isIntersection() {
1235            return true;
1236        }
1237
1238        public List<Type> getExplicitComponents() {
1239            return allInterfaces ?
1240                    interfaces_field :
1241                    getComponents();
1242        }
1243
1244        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1245        public TypeKind getKind() {
1246            return TypeKind.INTERSECTION;
1247        }
1248
1249        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1250        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1251            return v.visitIntersection(this, p);
1252        }
1253    }
1254
1255    public static class ArrayType extends Type
1256            implements javax.lang.model.type.ArrayType {
1257
1258        public Type elemtype;
1259
1260        public ArrayType(Type elemtype, TypeSymbol arrayClass) {
1261            this(elemtype, arrayClass, TypeMetadata.EMPTY);
1262        }
1263
1264        public ArrayType(Type elemtype, TypeSymbol arrayClass,
1265                         TypeMetadata metadata) {
1266            super(arrayClass, metadata);
1267            this.elemtype = elemtype;
1268        }
1269
1270        public ArrayType(ArrayType that) {
1271            //note: type metadata is deliberately shared here, as we want side-effects from annotation
1272            //processing to flow from original array to the cloned array.
1273            this(that.elemtype, that.tsym, that.getMetadata());
1274        }
1275
1276        @Override
1277        public ArrayType cloneWithMetadata(TypeMetadata md) {
1278            return new ArrayType(elemtype, tsym, md) {
1279                @Override
1280                public Type baseType() { return ArrayType.this.baseType(); }
1281            };
1282        }
1283
1284        @Override
1285        public TypeTag getTag() {
1286            return ARRAY;
1287        }
1288
1289        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1290            return v.visitArrayType(this, s);
1291        }
1292
1293        @DefinedBy(Api.LANGUAGE_MODEL)
1294        public String toString() {
1295            StringBuilder sb = new StringBuilder();
1296            sb.append(elemtype);
1297            appendAnnotationsString(sb, true);
1298            sb.append("[]");
1299            return sb.toString();
1300        }
1301
1302        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1303        public boolean equals(Object obj) {
1304            if (obj instanceof ArrayType) {
1305                ArrayType that = (ArrayType)obj;
1306                return this == that ||
1307                        elemtype.equals(that.elemtype);
1308            }
1309
1310            return false;
1311        }
1312
1313        @DefinedBy(Api.LANGUAGE_MODEL)
1314        public int hashCode() {
1315            return (ARRAY.ordinal() << 5) + elemtype.hashCode();
1316        }
1317
1318        public boolean isVarargs() {
1319            return false;
1320        }
1321
1322        public List<Type> allparams() { return elemtype.allparams(); }
1323
1324        public boolean isErroneous() {
1325            return elemtype.isErroneous();
1326        }
1327
1328        public boolean isParameterized() {
1329            return elemtype.isParameterized();
1330        }
1331
1332        @Override
1333        public boolean isReference() {
1334            return true;
1335        }
1336
1337        @Override
1338        public boolean isNullOrReference() {
1339            return true;
1340        }
1341
1342        public boolean isRaw() {
1343            return elemtype.isRaw();
1344        }
1345
1346        public ArrayType makeVarargs() {
1347            return new ArrayType(elemtype, tsym, metadata) {
1348                @Override
1349                public boolean isVarargs() {
1350                    return true;
1351                }
1352            };
1353        }
1354
1355        public boolean contains(Type elem) {
1356            return elem.equalsIgnoreMetadata(this) || elemtype.contains(elem);
1357        }
1358
1359        public void complete() {
1360            elemtype.complete();
1361        }
1362
1363        @DefinedBy(Api.LANGUAGE_MODEL)
1364        public Type getComponentType() {
1365            return elemtype;
1366        }
1367
1368        @DefinedBy(Api.LANGUAGE_MODEL)
1369        public TypeKind getKind() {
1370            return TypeKind.ARRAY;
1371        }
1372
1373        @DefinedBy(Api.LANGUAGE_MODEL)
1374        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1375            return v.visitArray(this, p);
1376        }
1377    }
1378
1379    public static class MethodType extends Type implements ExecutableType {
1380
1381        public List<Type> argtypes;
1382        public Type restype;
1383        public List<Type> thrown;
1384
1385        /** The type annotations on the method receiver.
1386         */
1387        public Type recvtype;
1388
1389        public MethodType(List<Type> argtypes,
1390                          Type restype,
1391                          List<Type> thrown,
1392                          TypeSymbol methodClass) {
1393            // Presently no way to refer to a method type directly, so
1394            // we cannot put type annotations on it.
1395            super(methodClass, TypeMetadata.EMPTY);
1396            this.argtypes = argtypes;
1397            this.restype = restype;
1398            this.thrown = thrown;
1399        }
1400
1401        @Override
1402        public MethodType cloneWithMetadata(TypeMetadata md) {
1403            throw new AssertionError("Cannot add metadata to a method type");
1404        }
1405
1406        @Override
1407        public TypeTag getTag() {
1408            return METHOD;
1409        }
1410
1411        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1412            return v.visitMethodType(this, s);
1413        }
1414
1415        /** The Java source which this type represents.
1416         *
1417         *  XXX 06/09/99 iris This isn't correct Java syntax, but it probably
1418         *  should be.
1419         */
1420        @DefinedBy(Api.LANGUAGE_MODEL)
1421        public String toString() {
1422            StringBuilder sb = new StringBuilder();
1423            appendAnnotationsString(sb);
1424            sb.append('(');
1425            sb.append(argtypes);
1426            sb.append(')');
1427            sb.append(restype);
1428            return sb.toString();
1429        }
1430
1431        @DefinedBy(Api.LANGUAGE_MODEL)
1432        public List<Type>        getParameterTypes() { return argtypes; }
1433        @DefinedBy(Api.LANGUAGE_MODEL)
1434        public Type              getReturnType()     { return restype; }
1435        @DefinedBy(Api.LANGUAGE_MODEL)
1436        public Type              getReceiverType()   { return recvtype; }
1437        @DefinedBy(Api.LANGUAGE_MODEL)
1438        public List<Type>        getThrownTypes()    { return thrown; }
1439
1440        public boolean isErroneous() {
1441            return
1442                isErroneous(argtypes) ||
1443                restype != null && restype.isErroneous();
1444        }
1445
1446        public boolean contains(Type elem) {
1447            return elem.equalsIgnoreMetadata(this) || contains(argtypes, elem) || restype.contains(elem) || contains(thrown, elem);
1448        }
1449
1450        public MethodType asMethodType() { return this; }
1451
1452        public void complete() {
1453            for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
1454                l.head.complete();
1455            restype.complete();
1456            recvtype.complete();
1457            for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
1458                l.head.complete();
1459        }
1460
1461        @DefinedBy(Api.LANGUAGE_MODEL)
1462        public List<TypeVar> getTypeVariables() {
1463            return List.nil();
1464        }
1465
1466        public TypeSymbol asElement() {
1467            return null;
1468        }
1469
1470        @DefinedBy(Api.LANGUAGE_MODEL)
1471        public TypeKind getKind() {
1472            return TypeKind.EXECUTABLE;
1473        }
1474
1475        @DefinedBy(Api.LANGUAGE_MODEL)
1476        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1477            return v.visitExecutable(this, p);
1478        }
1479    }
1480
1481    public static class PackageType extends Type implements NoType {
1482
1483        PackageType(TypeSymbol tsym) {
1484            // Package types cannot be annotated
1485            super(tsym, TypeMetadata.EMPTY);
1486        }
1487
1488        @Override
1489        public PackageType cloneWithMetadata(TypeMetadata md) {
1490            throw new AssertionError("Cannot add metadata to a package type");
1491        }
1492
1493        @Override
1494        public TypeTag getTag() {
1495            return PACKAGE;
1496        }
1497
1498        @Override
1499        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1500            return v.visitPackageType(this, s);
1501        }
1502
1503        @DefinedBy(Api.LANGUAGE_MODEL)
1504        public String toString() {
1505            return tsym.getQualifiedName().toString();
1506        }
1507
1508        @DefinedBy(Api.LANGUAGE_MODEL)
1509        public TypeKind getKind() {
1510            return TypeKind.PACKAGE;
1511        }
1512
1513        @DefinedBy(Api.LANGUAGE_MODEL)
1514        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1515            return v.visitNoType(this, p);
1516        }
1517    }
1518
1519    public static class TypeVar extends Type implements TypeVariable {
1520
1521        /** The upper bound of this type variable; set from outside.
1522         *  Must be nonempty once it is set.
1523         *  For a bound, `bound' is the bound type itself.
1524         *  Multiple bounds are expressed as a single class type which has the
1525         *  individual bounds as superclass, respectively interfaces.
1526         *  The class type then has as `tsym' a compiler generated class `c',
1527         *  which has a flag COMPOUND and whose owner is the type variable
1528         *  itself. Furthermore, the erasure_field of the class
1529         *  points to the first class or interface bound.
1530         */
1531        public Type bound = null;
1532
1533        /** The lower bound of this type variable.
1534         *  TypeVars don't normally have a lower bound, so it is normally set
1535         *  to syms.botType.
1536         *  Subtypes, such as CapturedType, may provide a different value.
1537         */
1538        public Type lower;
1539
1540        public TypeVar(Name name, Symbol owner, Type lower) {
1541            super(null, TypeMetadata.EMPTY);
1542            tsym = new TypeVariableSymbol(0, name, this, owner);
1543            this.bound = null;
1544            this.lower = lower;
1545        }
1546
1547        public TypeVar(TypeSymbol tsym, Type bound, Type lower) {
1548            this(tsym, bound, lower, TypeMetadata.EMPTY);
1549        }
1550
1551        public TypeVar(TypeSymbol tsym, Type bound, Type lower,
1552                       TypeMetadata metadata) {
1553            super(tsym, metadata);
1554            this.bound = bound;
1555            this.lower = lower;
1556        }
1557
1558        @Override
1559        public TypeVar cloneWithMetadata(TypeMetadata md) {
1560            return new TypeVar(tsym, bound, lower, md) {
1561                @Override
1562                public Type baseType() { return TypeVar.this.baseType(); }
1563            };
1564        }
1565
1566        @Override
1567        public TypeTag getTag() {
1568            return TYPEVAR;
1569        }
1570
1571        @Override
1572        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1573            return v.visitTypeVar(this, s);
1574        }
1575
1576        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1577        public Type getUpperBound() {
1578            if ((bound == null || bound.hasTag(NONE)) && this != tsym.type) {
1579                bound = tsym.type.getUpperBound();
1580            }
1581            return bound;
1582        }
1583
1584        int rank_field = -1;
1585
1586        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1587        public Type getLowerBound() {
1588            return lower;
1589        }
1590
1591        @DefinedBy(Api.LANGUAGE_MODEL)
1592        public TypeKind getKind() {
1593            return TypeKind.TYPEVAR;
1594        }
1595
1596        public boolean isCaptured() {
1597            return false;
1598        }
1599
1600        @Override
1601        public boolean isReference() {
1602            return true;
1603        }
1604
1605        @Override
1606        public boolean isNullOrReference() {
1607            return true;
1608        }
1609
1610        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1611        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1612            return v.visitTypeVariable(this, p);
1613        }
1614    }
1615
1616    /** A captured type variable comes from wildcards which can have
1617     *  both upper and lower bound.  CapturedType extends TypeVar with
1618     *  a lower bound.
1619     */
1620    public static class CapturedType extends TypeVar {
1621
1622        public WildcardType wildcard;
1623
1624        public CapturedType(Name name,
1625                            Symbol owner,
1626                            Type upper,
1627                            Type lower,
1628                            WildcardType wildcard) {
1629            super(name, owner, lower);
1630            this.lower = Assert.checkNonNull(lower);
1631            this.bound = upper;
1632            this.wildcard = wildcard;
1633        }
1634
1635        public CapturedType(TypeSymbol tsym,
1636                            Type bound,
1637                            Type upper,
1638                            Type lower,
1639                            WildcardType wildcard,
1640                            TypeMetadata metadata) {
1641            super(tsym, bound, lower, metadata);
1642            this.wildcard = wildcard;
1643        }
1644
1645        @Override
1646        public CapturedType cloneWithMetadata(TypeMetadata md) {
1647            return new CapturedType(tsym, bound, bound, lower, wildcard, md) {
1648                @Override
1649                public Type baseType() { return CapturedType.this.baseType(); }
1650            };
1651        }
1652
1653        @Override
1654        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1655            return v.visitCapturedType(this, s);
1656        }
1657
1658        @Override
1659        public boolean isCaptured() {
1660            return true;
1661        }
1662
1663        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1664        public String toString() {
1665            StringBuilder sb = new StringBuilder();
1666            appendAnnotationsString(sb);
1667            sb.append("capture#");
1668            sb.append((hashCode() & 0xFFFFFFFFL) % Printer.PRIME);
1669            sb.append(" of ");
1670            sb.append(wildcard);
1671            return sb.toString();
1672        }
1673    }
1674
1675    public static abstract class DelegatedType extends Type {
1676        public Type qtype;
1677        public TypeTag tag;
1678
1679        public DelegatedType(TypeTag tag, Type qtype) {
1680            this(tag, qtype, TypeMetadata.EMPTY);
1681        }
1682
1683        public DelegatedType(TypeTag tag, Type qtype,
1684                             TypeMetadata metadata) {
1685            super(qtype.tsym, metadata);
1686            this.tag = tag;
1687            this.qtype = qtype;
1688        }
1689
1690        public TypeTag getTag() { return tag; }
1691        @DefinedBy(Api.LANGUAGE_MODEL)
1692        public String toString() { return qtype.toString(); }
1693        public List<Type> getTypeArguments() { return qtype.getTypeArguments(); }
1694        public Type getEnclosingType() { return qtype.getEnclosingType(); }
1695        public List<Type> getParameterTypes() { return qtype.getParameterTypes(); }
1696        public Type getReturnType() { return qtype.getReturnType(); }
1697        public Type getReceiverType() { return qtype.getReceiverType(); }
1698        public List<Type> getThrownTypes() { return qtype.getThrownTypes(); }
1699        public List<Type> allparams() { return qtype.allparams(); }
1700        public Type getUpperBound() { return qtype.getUpperBound(); }
1701        public boolean isErroneous() { return qtype.isErroneous(); }
1702    }
1703
1704    /**
1705     * The type of a generic method type. It consists of a method type and
1706     * a list of method type-parameters that are used within the method
1707     * type.
1708     */
1709    public static class ForAll extends DelegatedType implements ExecutableType {
1710        public List<Type> tvars;
1711
1712        public ForAll(List<Type> tvars, Type qtype) {
1713            super(FORALL, (MethodType)qtype);
1714            this.tvars = tvars;
1715        }
1716
1717        @Override
1718        public ForAll cloneWithMetadata(TypeMetadata md) {
1719            throw new AssertionError("Cannot add metadata to a forall type");
1720        }
1721
1722        @Override
1723        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1724            return v.visitForAll(this, s);
1725        }
1726
1727        @DefinedBy(Api.LANGUAGE_MODEL)
1728        public String toString() {
1729            StringBuilder sb = new StringBuilder();
1730            appendAnnotationsString(sb);
1731            sb.append('<');
1732            sb.append(tvars);
1733            sb.append('>');
1734            sb.append(qtype);
1735            return sb.toString();
1736        }
1737
1738        public List<Type> getTypeArguments()   { return tvars; }
1739
1740        public boolean isErroneous()  {
1741            return qtype.isErroneous();
1742        }
1743
1744        public boolean contains(Type elem) {
1745            return qtype.contains(elem);
1746        }
1747
1748        public MethodType asMethodType() {
1749            return (MethodType)qtype;
1750        }
1751
1752        public void complete() {
1753            for (List<Type> l = tvars; l.nonEmpty(); l = l.tail) {
1754                ((TypeVar)l.head).bound.complete();
1755            }
1756            qtype.complete();
1757        }
1758
1759        @DefinedBy(Api.LANGUAGE_MODEL)
1760        public List<TypeVar> getTypeVariables() {
1761            return List.convert(TypeVar.class, getTypeArguments());
1762        }
1763
1764        @DefinedBy(Api.LANGUAGE_MODEL)
1765        public TypeKind getKind() {
1766            return TypeKind.EXECUTABLE;
1767        }
1768
1769        @DefinedBy(Api.LANGUAGE_MODEL)
1770        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1771            return v.visitExecutable(this, p);
1772        }
1773    }
1774
1775    /** A class for inference variables, for use during method/diamond type
1776     *  inference. An inference variable has upper/lower bounds and a set
1777     *  of equality constraints. Such bounds are set during subtyping, type-containment,
1778     *  type-equality checks, when the types being tested contain inference variables.
1779     *  A change listener can be attached to an inference variable, to receive notifications
1780     *  whenever the bounds of an inference variable change.
1781     */
1782    public static class UndetVar extends DelegatedType {
1783
1784        /** Inference variable change listener. The listener method is called
1785         *  whenever a change to the inference variable's bounds occurs
1786         */
1787        public interface UndetVarListener {
1788            /** called when some inference variable bounds (of given kinds ibs) change */
1789            void varChanged(UndetVar uv, Set<InferenceBound> ibs);
1790        }
1791
1792        /**
1793         * Inference variable bound kinds
1794         */
1795        public enum InferenceBound {
1796            /** upper bounds */
1797            UPPER {
1798                public InferenceBound complement() { return LOWER; }
1799            },
1800            /** lower bounds */
1801            LOWER {
1802                public InferenceBound complement() { return UPPER; }
1803            },
1804            /** equality constraints */
1805            EQ {
1806                public InferenceBound complement() { return EQ; }
1807            };
1808
1809            public abstract InferenceBound complement();
1810        }
1811
1812        /** inference variable bounds */
1813        protected Map<InferenceBound, List<Type>> bounds;
1814
1815        /** inference variable's inferred type (set from Infer.java) */
1816        public Type inst = null;
1817
1818        /** number of declared (upper) bounds */
1819        public int declaredCount;
1820
1821        /** inference variable's change listener */
1822        public UndetVarListener listener = null;
1823
1824        @Override
1825        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1826            return v.visitUndetVar(this, s);
1827        }
1828
1829        public UndetVar(TypeVar origin, Types types) {
1830            // This is a synthesized internal type, so we cannot annotate it.
1831            super(UNDETVAR, origin);
1832            bounds = new EnumMap<>(InferenceBound.class);
1833            List<Type> declaredBounds = types.getBounds(origin);
1834            declaredCount = declaredBounds.length();
1835            bounds.put(InferenceBound.UPPER, declaredBounds);
1836            bounds.put(InferenceBound.LOWER, List.<Type>nil());
1837            bounds.put(InferenceBound.EQ, List.<Type>nil());
1838        }
1839
1840        @DefinedBy(Api.LANGUAGE_MODEL)
1841        public String toString() {
1842            StringBuilder sb = new StringBuilder();
1843            appendAnnotationsString(sb);
1844            if (inst == null) {
1845                sb.append(qtype);
1846                sb.append('?');
1847            } else {
1848                sb.append(inst);
1849            }
1850            return sb.toString();
1851        }
1852
1853        public String debugString() {
1854            String result = "inference var = " + qtype + "\n";
1855            if (inst != null) {
1856                result += "inst = " + inst + '\n';
1857            }
1858            for (InferenceBound bound: InferenceBound.values()) {
1859                List<Type> aboundList = bounds.get(bound);
1860                if (aboundList.size() > 0) {
1861                    result += bound + " = " + aboundList + '\n';
1862                }
1863            }
1864            return result;
1865        }
1866
1867        @Override
1868        public UndetVar cloneWithMetadata(TypeMetadata md) {
1869            throw new AssertionError("Cannot add metadata to an UndetVar type");
1870        }
1871
1872        @Override
1873        public boolean isPartial() {
1874            return true;
1875        }
1876
1877        @Override
1878        public Type baseType() {
1879            return (inst == null) ? this : inst.baseType();
1880        }
1881
1882        /** get all bounds of a given kind */
1883        public List<Type> getBounds(InferenceBound... ibs) {
1884            ListBuffer<Type> buf = new ListBuffer<>();
1885            for (InferenceBound ib : ibs) {
1886                buf.appendList(bounds.get(ib));
1887            }
1888            return buf.toList();
1889        }
1890
1891        /** get the list of declared (upper) bounds */
1892        public List<Type> getDeclaredBounds() {
1893            ListBuffer<Type> buf = new ListBuffer<>();
1894            int count = 0;
1895            for (Type b : getBounds(InferenceBound.UPPER)) {
1896                if (count++ == declaredCount) break;
1897                buf.append(b);
1898            }
1899            return buf.toList();
1900        }
1901
1902        /** internal method used to override an undetvar bounds */
1903        public void setBounds(InferenceBound ib, List<Type> newBounds) {
1904            bounds.put(ib, newBounds);
1905        }
1906
1907        /** add a bound of a given kind - this might trigger listener notification */
1908        public final void addBound(InferenceBound ib, Type bound, Types types) {
1909            addBound(ib, bound, types, false);
1910        }
1911
1912        protected void addBound(InferenceBound ib, Type bound, Types types, boolean update) {
1913            Type bound2 = bound.map(toTypeVarMap).baseType();
1914            List<Type> prevBounds = bounds.get(ib);
1915            for (Type b : prevBounds) {
1916                //check for redundancy - use strict version of isSameType on tvars
1917                //(as the standard version will lead to false positives w.r.t. clones ivars)
1918                if (types.isSameType(b, bound2, true) || bound == qtype) return;
1919            }
1920            bounds.put(ib, prevBounds.prepend(bound2));
1921            notifyChange(EnumSet.of(ib));
1922        }
1923        //where
1924            TypeMapping<Void> toTypeVarMap = new TypeMapping<Void>() {
1925                @Override
1926                public Type visitUndetVar(UndetVar uv, Void _unused) {
1927                    return uv.inst != null ? uv.inst : uv.qtype;
1928                }
1929            };
1930
1931        /** replace types in all bounds - this might trigger listener notification */
1932        public void substBounds(List<Type> from, List<Type> to, Types types) {
1933            List<Type> instVars = from.diff(to);
1934            //if set of instantiated ivars is empty, there's nothing to do!
1935            if (instVars.isEmpty()) return;
1936            final EnumSet<InferenceBound> boundsChanged = EnumSet.noneOf(InferenceBound.class);
1937            UndetVarListener prevListener = listener;
1938            try {
1939                //setup new listener for keeping track of changed bounds
1940                listener = new UndetVarListener() {
1941                    public void varChanged(UndetVar uv, Set<InferenceBound> ibs) {
1942                        boundsChanged.addAll(ibs);
1943                    }
1944                };
1945                for (Map.Entry<InferenceBound, List<Type>> _entry : bounds.entrySet()) {
1946                    InferenceBound ib = _entry.getKey();
1947                    List<Type> prevBounds = _entry.getValue();
1948                    ListBuffer<Type> newBounds = new ListBuffer<>();
1949                    ListBuffer<Type> deps = new ListBuffer<>();
1950                    //step 1 - re-add bounds that are not dependent on ivars
1951                    for (Type t : prevBounds) {
1952                        if (!t.containsAny(instVars)) {
1953                            newBounds.append(t);
1954                        } else {
1955                            deps.append(t);
1956                        }
1957                    }
1958                    //step 2 - replace bounds
1959                    bounds.put(ib, newBounds.toList());
1960                    //step 3 - for each dependency, add new replaced bound
1961                    for (Type dep : deps) {
1962                        addBound(ib, types.subst(dep, from, to), types, true);
1963                    }
1964                }
1965            } finally {
1966                listener = prevListener;
1967                if (!boundsChanged.isEmpty()) {
1968                    notifyChange(boundsChanged);
1969                }
1970            }
1971        }
1972
1973        private void notifyChange(EnumSet<InferenceBound> ibs) {
1974            if (listener != null) {
1975                listener.varChanged(this, ibs);
1976            }
1977        }
1978
1979        public boolean isCaptured() {
1980            return false;
1981        }
1982    }
1983
1984    /**
1985     * This class is used to represent synthetic captured inference variables
1986     * that can be generated during nested generic method calls. The only difference
1987     * between these inference variables and ordinary ones is that captured inference
1988     * variables cannot get new bounds through incorporation.
1989     */
1990    public static class CapturedUndetVar extends UndetVar {
1991
1992        public CapturedUndetVar(CapturedType origin, Types types) {
1993            super(origin, types);
1994            if (!origin.lower.hasTag(BOT)) {
1995                bounds.put(InferenceBound.LOWER, List.of(origin.lower));
1996            }
1997        }
1998
1999        @Override
2000        public void addBound(InferenceBound ib, Type bound, Types types, boolean update) {
2001            if (update) {
2002                //only change bounds if request comes from substBounds
2003                super.addBound(ib, bound, types, update);
2004            }
2005            else if (bound.hasTag(UNDETVAR) && !((UndetVar) bound).isCaptured()) {
2006                ((UndetVar) bound).addBound(ib.complement(), this, types, false);
2007            }
2008        }
2009
2010        @Override
2011        public boolean isCaptured() {
2012            return true;
2013        }
2014    }
2015
2016    /** Represents NONE.
2017     */
2018    public static class JCNoType extends Type implements NoType {
2019        public JCNoType() {
2020            // Need to use List.nil(), because JCNoType constructor
2021            // gets called in static initializers in Type, where
2022            // noAnnotations is also defined.
2023            super(null, TypeMetadata.EMPTY);
2024        }
2025
2026        @Override
2027        public JCNoType cloneWithMetadata(TypeMetadata md) {
2028            throw new AssertionError("Cannot add metadata to a JCNoType");
2029        }
2030
2031        @Override
2032        public TypeTag getTag() {
2033            return NONE;
2034        }
2035
2036        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2037        public TypeKind getKind() {
2038            return TypeKind.NONE;
2039        }
2040
2041        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2042        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2043            return v.visitNoType(this, p);
2044        }
2045
2046        @Override
2047        public boolean isCompound() { return false; }
2048    }
2049
2050    /** Represents VOID.
2051     */
2052    public static class JCVoidType extends Type implements NoType {
2053
2054        public JCVoidType() {
2055            // Void cannot be annotated
2056            super(null, TypeMetadata.EMPTY);
2057        }
2058
2059        @Override
2060        public JCVoidType cloneWithMetadata(TypeMetadata md) {
2061            throw new AssertionError("Cannot add metadata to a void type");
2062        }
2063
2064        @Override
2065        public TypeTag getTag() {
2066            return VOID;
2067        }
2068
2069        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2070        public TypeKind getKind() {
2071            return TypeKind.VOID;
2072        }
2073
2074        @Override
2075        public boolean isCompound() { return false; }
2076
2077        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2078        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2079            return v.visitNoType(this, p);
2080        }
2081
2082        @Override
2083        public boolean isPrimitiveOrVoid() {
2084            return true;
2085        }
2086    }
2087
2088    static class BottomType extends Type implements NullType {
2089        public BottomType() {
2090            // Bottom is a synthesized internal type, so it cannot be annotated
2091            super(null, TypeMetadata.EMPTY);
2092        }
2093
2094        @Override
2095        public BottomType cloneWithMetadata(TypeMetadata md) {
2096            throw new AssertionError("Cannot add metadata to a bottom type");
2097        }
2098
2099        @Override
2100        public TypeTag getTag() {
2101            return BOT;
2102        }
2103
2104        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2105        public TypeKind getKind() {
2106            return TypeKind.NULL;
2107        }
2108
2109        @Override
2110        public boolean isCompound() { return false; }
2111
2112        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2113        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2114            return v.visitNull(this, p);
2115        }
2116
2117        @Override
2118        public Type constType(Object value) {
2119            return this;
2120        }
2121
2122        @Override
2123        public String stringValue() {
2124            return "null";
2125        }
2126
2127        @Override
2128        public boolean isNullOrReference() {
2129            return true;
2130        }
2131
2132    }
2133
2134    public static class ErrorType extends ClassType
2135            implements javax.lang.model.type.ErrorType {
2136
2137        private Type originalType = null;
2138
2139        public ErrorType(ClassSymbol c, Type originalType) {
2140            this(originalType, c);
2141            c.type = this;
2142            c.kind = ERR;
2143            c.members_field = new Scope.ErrorScope(c);
2144        }
2145
2146        public ErrorType(Type originalType, TypeSymbol tsym) {
2147            super(noType, List.<Type>nil(), null);
2148            this.tsym = tsym;
2149            this.originalType = (originalType == null ? noType : originalType);
2150        }
2151
2152        private ErrorType(Type originalType, TypeSymbol tsym,
2153                          TypeMetadata metadata) {
2154            super(noType, List.<Type>nil(), null, metadata);
2155            this.tsym = tsym;
2156            this.originalType = (originalType == null ? noType : originalType);
2157        }
2158
2159        @Override
2160        public ErrorType cloneWithMetadata(TypeMetadata md) {
2161            return new ErrorType(originalType, tsym, md) {
2162                @Override
2163                public Type baseType() { return ErrorType.this.baseType(); }
2164            };
2165        }
2166
2167        @Override
2168        public TypeTag getTag() {
2169            return ERROR;
2170        }
2171
2172        @Override
2173        public boolean isPartial() {
2174            return true;
2175        }
2176
2177        @Override
2178        public boolean isReference() {
2179            return true;
2180        }
2181
2182        @Override
2183        public boolean isNullOrReference() {
2184            return true;
2185        }
2186
2187        public ErrorType(Name name, TypeSymbol container, Type originalType) {
2188            this(new ClassSymbol(PUBLIC|STATIC|ACYCLIC, name, null, container), originalType);
2189        }
2190
2191        @Override
2192        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
2193            return v.visitErrorType(this, s);
2194        }
2195
2196        public Type constType(Object constValue) { return this; }
2197        @DefinedBy(Api.LANGUAGE_MODEL)
2198        public Type getEnclosingType()           { return this; }
2199        public Type getReturnType()              { return this; }
2200        public Type asSub(Symbol sym)            { return this; }
2201
2202        public boolean isGenType(Type t)         { return true; }
2203        public boolean isErroneous()             { return true; }
2204        public boolean isCompound()              { return false; }
2205        public boolean isInterface()             { return false; }
2206
2207        public List<Type> allparams()            { return List.nil(); }
2208        @DefinedBy(Api.LANGUAGE_MODEL)
2209        public List<Type> getTypeArguments()     { return List.nil(); }
2210
2211        @DefinedBy(Api.LANGUAGE_MODEL)
2212        public TypeKind getKind() {
2213            return TypeKind.ERROR;
2214        }
2215
2216        public Type getOriginalType() {
2217            return originalType;
2218        }
2219
2220        @DefinedBy(Api.LANGUAGE_MODEL)
2221        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2222            return v.visitError(this, p);
2223        }
2224    }
2225
2226    public static class UnknownType extends Type {
2227
2228        public UnknownType() {
2229            // Unknown is a synthesized internal type, so it cannot be
2230            // annotated.
2231            super(null, TypeMetadata.EMPTY);
2232        }
2233
2234        @Override
2235        public UnknownType cloneWithMetadata(TypeMetadata md) {
2236            throw new AssertionError("Cannot add metadata to an unknown type");
2237        }
2238
2239        @Override
2240        public TypeTag getTag() {
2241            return UNKNOWN;
2242        }
2243
2244        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2245        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2246            return v.visitUnknown(this, p);
2247        }
2248
2249        @Override
2250        public boolean isPartial() {
2251            return true;
2252        }
2253    }
2254
2255    /**
2256     * A visitor for types.  A visitor is used to implement operations
2257     * (or relations) on types.  Most common operations on types are
2258     * binary relations and this interface is designed for binary
2259     * relations, that is, operations of the form
2260     * Type&nbsp;&times;&nbsp;S&nbsp;&rarr;&nbsp;R.
2261     * <!-- In plain text: Type x S -> R -->
2262     *
2263     * @param <R> the return type of the operation implemented by this
2264     * visitor; use Void if no return type is needed.
2265     * @param <S> the type of the second argument (the first being the
2266     * type itself) of the operation implemented by this visitor; use
2267     * Void if a second argument is not needed.
2268     */
2269    public interface Visitor<R,S> {
2270        R visitClassType(ClassType t, S s);
2271        R visitWildcardType(WildcardType t, S s);
2272        R visitArrayType(ArrayType t, S s);
2273        R visitMethodType(MethodType t, S s);
2274        R visitPackageType(PackageType t, S s);
2275        R visitTypeVar(TypeVar t, S s);
2276        R visitCapturedType(CapturedType t, S s);
2277        R visitForAll(ForAll t, S s);
2278        R visitUndetVar(UndetVar t, S s);
2279        R visitErrorType(ErrorType t, S s);
2280        R visitType(Type t, S s);
2281    }
2282}
2283