Type.java revision 3819:49170d831308
1282199Sdumbbell/*
2282199Sdumbbell * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
3282199Sdumbbell * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4282199Sdumbbell *
5282199Sdumbbell * This code is free software; you can redistribute it and/or modify it
6282199Sdumbbell * under the terms of the GNU General Public License version 2 only, as
7282199Sdumbbell * published by the Free Software Foundation.  Oracle designates this
8282199Sdumbbell * particular file as subject to the "Classpath" exception as provided
9282199Sdumbbell * by Oracle in the LICENSE file that accompanied this code.
10282199Sdumbbell *
11282199Sdumbbell * This code is distributed in the hope that it will be useful, but WITHOUT
12235783Skib * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13235783Skib * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14235783Skib * version 2 for more details (a copy is included in the LICENSE file that
15235783Skib * accompanied this code).
16235783Skib *
17235783Skib * You should have received a copy of the GNU General Public License version
18235783Skib * 2 along with this work; if not, write to the Free Software Foundation,
19235783Skib * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20235783Skib *
21235783Skib * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22235783Skib * or visit www.oracle.com if you need additional information or have any
23235783Skib * questions.
24235783Skib */
25235783Skib
26235783Skibpackage com.sun.tools.javac.code;
27235783Skib
28235783Skibimport java.lang.annotation.Annotation;
29235783Skibimport java.util.ArrayDeque;
30235783Skibimport java.util.Collections;
31235783Skibimport java.util.EnumMap;
32235783Skibimport java.util.Map;
33235783Skibimport java.util.function.Function;
34235783Skib
35235783Skibimport javax.lang.model.type.*;
36235783Skib
37235783Skibimport com.sun.tools.javac.code.Symbol.*;
38235783Skibimport com.sun.tools.javac.code.TypeMetadata.Entry;
39282199Sdumbbellimport com.sun.tools.javac.comp.Infer.IncorporationAction;
40282199Sdumbbellimport com.sun.tools.javac.util.*;
41235783Skibimport com.sun.tools.javac.util.DefinedBy.Api;
42235783Skib
43235783Skibimport static com.sun.tools.javac.code.BoundKind.*;
44235783Skibimport static com.sun.tools.javac.code.Flags.*;
45235783Skibimport static com.sun.tools.javac.code.Kinds.Kind.*;
46235783Skibimport static com.sun.tools.javac.code.TypeTag.*;
47235783Skib
48235783Skib/** This class represents Java types. The class itself defines the behavior of
49235783Skib *  the following types:
50235783Skib *  <pre>
51235783Skib *  base types (tags: BYTE, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, BOOLEAN),
52235783Skib *  type `void' (tag: VOID),
53235783Skib *  the bottom type (tag: BOT),
54235783Skib *  the missing type (tag: NONE).
55235783Skib *  </pre>
56235783Skib *  <p>The behavior of the following types is defined in subclasses, which are
57235783Skib *  all static inner classes of this class:
58235783Skib *  <pre>
59235783Skib *  class types (tag: CLASS, class: ClassType),
60235783Skib *  array types (tag: ARRAY, class: ArrayType),
61235783Skib *  method types (tag: METHOD, class: MethodType),
62235783Skib *  package types (tag: PACKAGE, class: PackageType),
63235783Skib *  type variables (tag: TYPEVAR, class: TypeVar),
64235783Skib *  type arguments (tag: WILDCARD, class: WildcardType),
65282199Sdumbbell *  generic method types (tag: FORALL, class: ForAll),
66235783Skib *  the error type (tag: ERROR, class: ErrorType).
67235783Skib *  </pre>
68235783Skib *
69235783Skib *  <p><b>This is NOT part of any supported API.
70235783Skib *  If you write code that depends on this, you do so at your own risk.
71235783Skib *  This code and its internal interfaces are subject to change or
72235783Skib *  deletion without notice.</b>
73235783Skib *
74235783Skib *  @see TypeTag
75235783Skib */
76235783Skibpublic abstract class Type extends AnnoConstruct implements TypeMirror {
77235783Skib
78235783Skib    /**
79235783Skib     * Type metadata,  Should be {@code null} for the default value.
80235783Skib     *
81235783Skib     * Note: it is an invariant that for any {@code TypeMetadata}
82235783Skib     * class, a given {@code Type} may have at most one metadata array
83282199Sdumbbell     * entry of that class.
84282199Sdumbbell     */
85282199Sdumbbell    protected final TypeMetadata metadata;
86282199Sdumbbell
87235783Skib    public TypeMetadata getMetadata() {
88235783Skib        return metadata;
89235783Skib    }
90282199Sdumbbell
91282199Sdumbbell    public Entry getMetadataOfKind(final Entry.Kind kind) {
92282199Sdumbbell        return metadata != null ? metadata.get(kind) : null;
93282199Sdumbbell    }
94282199Sdumbbell
95235783Skib    /** Constant type: no type at all. */
96235783Skib    public static final JCNoType noType = new JCNoType() {
97235783Skib        @Override @DefinedBy(Api.LANGUAGE_MODEL)
98235783Skib        public String toString() {
99235783Skib            return "none";
100282199Sdumbbell        }
101282199Sdumbbell    };
102282199Sdumbbell
103282199Sdumbbell    /** Constant type: special type to be used during recovery of deferred expressions. */
104235783Skib    public static final JCNoType recoveryType = new JCNoType(){
105235783Skib        @Override @DefinedBy(Api.LANGUAGE_MODEL)
106235783Skib        public String toString() {
107282199Sdumbbell            return "recovery";
108282199Sdumbbell        }
109282199Sdumbbell    };
110282199Sdumbbell
111282199Sdumbbell    /** Constant type: special type to be used for marking stuck trees. */
112235783Skib    public static final JCNoType stuckType = new JCNoType() {
113235783Skib        @Override @DefinedBy(Api.LANGUAGE_MODEL)
114282199Sdumbbell        public String toString() {
115282199Sdumbbell            return "stuck";
116235783Skib        }
117282199Sdumbbell    };
118282199Sdumbbell
119282199Sdumbbell    /** If this switch is turned on, the names of type variables
120282199Sdumbbell     *  and anonymous classes are printed with hashcodes appended.
121282199Sdumbbell     */
122282199Sdumbbell    public static boolean moreInfo = false;
123282199Sdumbbell
124282199Sdumbbell    /** The defining class / interface / package / type variable.
125282199Sdumbbell     */
126282199Sdumbbell    public TypeSymbol tsym;
127282199Sdumbbell
128282199Sdumbbell    /**
129282199Sdumbbell     * Checks if the current type tag is equal to the given tag.
130282199Sdumbbell     * @return true if tag is equal to the current type tag.
131282199Sdumbbell     */
132282199Sdumbbell    public boolean hasTag(TypeTag tag) {
133282199Sdumbbell        return tag == getTag();
134282199Sdumbbell    }
135282199Sdumbbell
136282199Sdumbbell    /**
137282199Sdumbbell     * Returns the current type tag.
138282199Sdumbbell     * @return the value of the current type tag.
139282199Sdumbbell     */
140282199Sdumbbell    public abstract TypeTag getTag();
141282199Sdumbbell
142282199Sdumbbell    public boolean isNumeric() {
143282199Sdumbbell        return false;
144282199Sdumbbell    }
145282199Sdumbbell
146282199Sdumbbell    public boolean isIntegral() {
147282199Sdumbbell        return false;
148282199Sdumbbell    }
149282199Sdumbbell
150282199Sdumbbell    public boolean isPrimitive() {
151282199Sdumbbell        return false;
152282199Sdumbbell    }
153282199Sdumbbell
154282199Sdumbbell    public boolean isPrimitiveOrVoid() {
155282199Sdumbbell        return false;
156282199Sdumbbell    }
157282199Sdumbbell
158282199Sdumbbell    public boolean isReference() {
159282199Sdumbbell        return false;
160282199Sdumbbell    }
161282199Sdumbbell
162282199Sdumbbell    public boolean isNullOrReference() {
163282199Sdumbbell        return false;
164282199Sdumbbell    }
165282199Sdumbbell
166282199Sdumbbell    public boolean isPartial() {
167282199Sdumbbell        return false;
168282199Sdumbbell    }
169282199Sdumbbell
170282199Sdumbbell    /**
171282199Sdumbbell     * The constant value of this type, null if this type does not
172282199Sdumbbell     * have a constant value attribute. Only primitive types and
173282199Sdumbbell     * strings (ClassType) can have a constant value attribute.
174282199Sdumbbell     * @return the constant value attribute of this type
175282199Sdumbbell     */
176282199Sdumbbell    public Object constValue() {
177282199Sdumbbell        return null;
178282199Sdumbbell    }
179282199Sdumbbell
180282199Sdumbbell    /** Is this a constant type whose value is false?
181282199Sdumbbell     */
182282199Sdumbbell    public boolean isFalse() {
183282199Sdumbbell        return false;
184282199Sdumbbell    }
185282199Sdumbbell
186282199Sdumbbell    /** Is this a constant type whose value is true?
187282199Sdumbbell     */
188282199Sdumbbell    public boolean isTrue() {
189282199Sdumbbell        return false;
190282199Sdumbbell    }
191282199Sdumbbell
192282199Sdumbbell    /**
193282199Sdumbbell     * Get the representation of this type used for modelling purposes.
194282199Sdumbbell     * By default, this is itself. For ErrorType, a different value
195282199Sdumbbell     * may be provided.
196282199Sdumbbell     */
197282199Sdumbbell    public Type getModelType() {
198282199Sdumbbell        return this;
199282199Sdumbbell    }
200282199Sdumbbell
201282199Sdumbbell    public static List<Type> getModelTypes(List<Type> ts) {
202282199Sdumbbell        ListBuffer<Type> lb = new ListBuffer<>();
203282199Sdumbbell        for (Type t: ts)
204282199Sdumbbell            lb.append(t.getModelType());
205282199Sdumbbell        return lb.toList();
206282199Sdumbbell    }
207282199Sdumbbell
208282199Sdumbbell    /**For ErrorType, returns the original type, otherwise returns the type itself.
209282199Sdumbbell     */
210282199Sdumbbell    public Type getOriginalType() {
211282199Sdumbbell        return this;
212282199Sdumbbell    }
213282199Sdumbbell
214282199Sdumbbell    public <R,S> R accept(Type.Visitor<R,S> v, S s) { return v.visitType(this, s); }
215282199Sdumbbell
216282199Sdumbbell    /** Define a type given its tag, type symbol, and type annotations
217235783Skib     */
218235783Skib
219282199Sdumbbell    public Type(TypeSymbol tsym, TypeMetadata metadata) {
220282199Sdumbbell        Assert.checkNonNull(metadata);
221282199Sdumbbell        this.tsym = tsym;
222282199Sdumbbell        this.metadata = metadata;
223282199Sdumbbell    }
224282199Sdumbbell
225282199Sdumbbell    /** An abstract class for mappings from types to types
226282199Sdumbbell     */
227282199Sdumbbell    public static abstract class TypeMapping<S> extends Types.MapVisitor<S> implements Function<Type, Type> {
228235783Skib
229235783Skib        @Override
230235783Skib        public Type apply(Type type) {
231235783Skib            return visit(type);
232282199Sdumbbell        }
233282199Sdumbbell
234282199Sdumbbell        List<Type> visit(List<Type> ts, S s) {
235235783Skib            return ts.map(t -> visit(t, s));
236282199Sdumbbell        }
237282199Sdumbbell
238235783Skib        @Override
239282199Sdumbbell        public Type visitClassType(ClassType t, S s) {
240282199Sdumbbell            Type outer = t.getEnclosingType();
241282199Sdumbbell            Type outer1 = visit(outer, s);
242235783Skib            List<Type> typarams = t.getTypeArguments();
243282199Sdumbbell            List<Type> typarams1 = visit(typarams, s);
244282199Sdumbbell            if (outer1 == outer && typarams1 == typarams) return t;
245235783Skib            else return new ClassType(outer1, typarams1, t.tsym, t.metadata) {
246282199Sdumbbell                @Override
247282199Sdumbbell                protected boolean needsStripping() {
248282199Sdumbbell                    return true;
249282199Sdumbbell                }
250235783Skib            };
251282199Sdumbbell        }
252282199Sdumbbell
253282199Sdumbbell        @Override
254235783Skib        public Type visitWildcardType(WildcardType wt, S s) {
255282199Sdumbbell            Type t = wt.type;
256282199Sdumbbell            if (t != null)
257235783Skib                t = visit(t, s);
258235783Skib            if (t == wt.type)
259235783Skib                return wt;
260235783Skib            else
261282199Sdumbbell                return new WildcardType(t, wt.kind, wt.tsym, wt.bound, wt.metadata) {
262282199Sdumbbell                    @Override
263282199Sdumbbell                    protected boolean needsStripping() {
264282199Sdumbbell                        return true;
265282199Sdumbbell                    }
266282199Sdumbbell                };
267282199Sdumbbell        }
268282199Sdumbbell
269282199Sdumbbell        @Override
270282199Sdumbbell        public Type visitArrayType(ArrayType t, S s) {
271282199Sdumbbell            Type elemtype = t.elemtype;
272282199Sdumbbell            Type elemtype1 = visit(elemtype, s);
273282199Sdumbbell            if (elemtype1 == elemtype) return t;
274282199Sdumbbell            else return new ArrayType(elemtype1, t.tsym, t.metadata) {
275282199Sdumbbell                @Override
276282199Sdumbbell                protected boolean needsStripping() {
277282199Sdumbbell                    return true;
278282199Sdumbbell                }
279282199Sdumbbell            };
280282199Sdumbbell        }
281282199Sdumbbell
282282199Sdumbbell        @Override
283282199Sdumbbell        public Type visitMethodType(MethodType t, S s) {
284282199Sdumbbell            List<Type> argtypes = t.argtypes;
285282199Sdumbbell            Type restype = t.restype;
286282199Sdumbbell            List<Type> thrown = t.thrown;
287282199Sdumbbell            List<Type> argtypes1 = visit(argtypes, s);
288282199Sdumbbell            Type restype1 = visit(restype, s);
289282199Sdumbbell            List<Type> thrown1 = visit(thrown, s);
290282199Sdumbbell            if (argtypes1 == argtypes &&
291282199Sdumbbell                restype1 == restype &&
292282199Sdumbbell                thrown1 == thrown) return t;
293282199Sdumbbell            else return new MethodType(argtypes1, restype1, thrown1, t.tsym) {
294282199Sdumbbell                @Override
295282199Sdumbbell                protected boolean needsStripping() {
296282199Sdumbbell                    return true;
297282199Sdumbbell                }
298282199Sdumbbell            };
299282199Sdumbbell        }
300282199Sdumbbell
301282199Sdumbbell        @Override
302282199Sdumbbell        public Type visitCapturedType(CapturedType t, S s) {
303282199Sdumbbell            return visitTypeVar(t, s);
304282199Sdumbbell        }
305282199Sdumbbell
306235783Skib        @Override
307235783Skib        public Type visitForAll(ForAll t, S s) {
308282199Sdumbbell            return visit(t.qtype, s);
309282199Sdumbbell        }
310282199Sdumbbell    }
311282199Sdumbbell
312282199Sdumbbell    /** map a type function over all immediate descendants of this type
313282199Sdumbbell     */
314282199Sdumbbell    public <Z> Type map(TypeMapping<Z> mapping, Z arg) {
315282199Sdumbbell        return mapping.visit(this, arg);
316282199Sdumbbell    }
317282199Sdumbbell
318282199Sdumbbell    /** map a type function over all immediate descendants of this type (no arg version)
319282199Sdumbbell     */
320282199Sdumbbell    public <Z> Type map(TypeMapping<Z> mapping) {
321282199Sdumbbell        return mapping.visit(this, null);
322235783Skib    }
323282199Sdumbbell
324282199Sdumbbell    /** Define a constant type, of the same kind as this type
325235783Skib     *  and with given constant value
326282199Sdumbbell     */
327235783Skib    public Type constType(Object constValue) {
328282199Sdumbbell        throw new AssertionError();
329235783Skib    }
330235783Skib
331282199Sdumbbell    /**
332282199Sdumbbell     * If this is a constant type, return its underlying type.
333235783Skib     * Otherwise, return the type itself.
334282199Sdumbbell     */
335235783Skib    public Type baseType() {
336282199Sdumbbell        return this;
337235783Skib    }
338235783Skib
339282199Sdumbbell    /**
340282199Sdumbbell     * Returns the original version of this type, before metadata were added. This routine is meant
341282199Sdumbbell     * for internal use only (i.e. {@link Type#equalsIgnoreMetadata(Type)}, {@link Type#stripMetadata});
342282199Sdumbbell     * it should not be used outside this class.
343282199Sdumbbell     */
344282199Sdumbbell    protected Type typeNoMetadata() {
345282199Sdumbbell        return metadata == TypeMetadata.EMPTY ? this : baseType();
346282199Sdumbbell    }
347282199Sdumbbell
348282199Sdumbbell    /**
349282199Sdumbbell     * Create a new copy of this type but with the specified TypeMetadata.
350282199Sdumbbell     */
351282199Sdumbbell    public abstract Type cloneWithMetadata(TypeMetadata metadata);
352235783Skib
353235783Skib    /**
354235783Skib     * Does this type require annotation stripping for API clients?
355235783Skib     */
356235783Skib    protected boolean needsStripping() {
357235783Skib        return false;
358235783Skib    }
359235783Skib
360282199Sdumbbell    /**
361235783Skib     * Strip all metadata associated with this type - this could return a new clone of the type.
362235783Skib     * This routine is only used to present the correct annotated types back to the users when types
363282199Sdumbbell     * are accessed through compiler APIs; it should not be used anywhere in the compiler internals
364282199Sdumbbell     * as doing so might result in performance penalties.
365282199Sdumbbell     */
366282199Sdumbbell    public Type stripMetadataIfNeeded() {
367282199Sdumbbell        return needsStripping() ?
368282199Sdumbbell                accept(stripMetadata, null) :
369282199Sdumbbell                this;
370282199Sdumbbell    }
371282199Sdumbbell
372235783Skib    public Type stripMetadata() {
373282199Sdumbbell        return accept(stripMetadata, null);
374235783Skib    }
375235783Skib    //where
376235783Skib        private final static TypeMapping<Void> stripMetadata = new TypeMapping<Void>() {
377235783Skib            @Override
378282199Sdumbbell            public Type visitClassType(ClassType t, Void aVoid) {
379235783Skib                return super.visitClassType((ClassType)t.typeNoMetadata(), aVoid);
380282199Sdumbbell            }
381282199Sdumbbell
382282199Sdumbbell            @Override
383282199Sdumbbell            public Type visitArrayType(ArrayType t, Void aVoid) {
384282199Sdumbbell                return super.visitArrayType((ArrayType)t.typeNoMetadata(), aVoid);
385235783Skib            }
386282199Sdumbbell
387282199Sdumbbell            @Override
388282199Sdumbbell            public Type visitTypeVar(TypeVar t, Void aVoid) {
389282199Sdumbbell                return super.visitTypeVar((TypeVar)t.typeNoMetadata(), aVoid);
390235783Skib            }
391235783Skib
392235783Skib            @Override
393282199Sdumbbell            public Type visitWildcardType(WildcardType wt, Void aVoid) {
394235783Skib                return super.visitWildcardType((WildcardType)wt.typeNoMetadata(), aVoid);
395282199Sdumbbell            }
396282199Sdumbbell        };
397235783Skib
398235783Skib    public Type annotatedType(final List<Attribute.TypeCompound> annos) {
399282199Sdumbbell        final Entry annoMetadata = new TypeMetadata.Annotations(annos);
400282199Sdumbbell        return cloneWithMetadata(metadata.combine(annoMetadata));
401282199Sdumbbell    }
402282199Sdumbbell
403235783Skib    public boolean isAnnotated() {
404235783Skib        final TypeMetadata.Annotations metadata =
405235783Skib            (TypeMetadata.Annotations)getMetadataOfKind(Entry.Kind.ANNOTATIONS);
406282199Sdumbbell
407282199Sdumbbell        return null != metadata && !metadata.getAnnotations().isEmpty();
408235783Skib    }
409282199Sdumbbell
410235783Skib    @Override @DefinedBy(Api.LANGUAGE_MODEL)
411282199Sdumbbell    public List<Attribute.TypeCompound> getAnnotationMirrors() {
412282199Sdumbbell        final TypeMetadata.Annotations metadata =
413282199Sdumbbell            (TypeMetadata.Annotations)getMetadataOfKind(Entry.Kind.ANNOTATIONS);
414235783Skib
415235783Skib        return metadata == null ? List.nil() : metadata.getAnnotations();
416235783Skib    }
417282199Sdumbbell
418235783Skib
419235783Skib    @Override @DefinedBy(Api.LANGUAGE_MODEL)
420282199Sdumbbell    public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
421282199Sdumbbell        return null;
422282199Sdumbbell    }
423282199Sdumbbell
424282199Sdumbbell
425282199Sdumbbell    @Override @DefinedBy(Api.LANGUAGE_MODEL)
426282199Sdumbbell    public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
427282199Sdumbbell        @SuppressWarnings("unchecked")
428282199Sdumbbell        A[] tmp = (A[]) java.lang.reflect.Array.newInstance(annotationType, 0);
429235783Skib        return tmp;
430282199Sdumbbell    }
431235783Skib
432282199Sdumbbell    /** Return the base types of a list of types.
433282199Sdumbbell     */
434282199Sdumbbell    public static List<Type> baseTypes(List<Type> ts) {
435282199Sdumbbell        if (ts.nonEmpty()) {
436282199Sdumbbell            Type t = ts.head.baseType();
437282199Sdumbbell            List<Type> baseTypes = baseTypes(ts.tail);
438282199Sdumbbell            if (t != ts.head || baseTypes != ts.tail)
439282199Sdumbbell                return baseTypes.prepend(t);
440282199Sdumbbell        }
441282199Sdumbbell        return ts;
442282199Sdumbbell    }
443282199Sdumbbell
444282199Sdumbbell    protected void appendAnnotationsString(StringBuilder sb,
445282199Sdumbbell                                         boolean prefix) {
446235783Skib        if (isAnnotated()) {
447282199Sdumbbell            if (prefix) {
448282199Sdumbbell                sb.append(" ");
449235783Skib            }
450282199Sdumbbell            sb.append(getAnnotationMirrors());
451282199Sdumbbell            sb.append(" ");
452282199Sdumbbell        }
453282199Sdumbbell    }
454282199Sdumbbell
455235783Skib    protected void appendAnnotationsString(StringBuilder sb) {
456282199Sdumbbell        appendAnnotationsString(sb, false);
457282199Sdumbbell    }
458282199Sdumbbell
459282199Sdumbbell    /** The Java source which this type represents.
460282199Sdumbbell     */
461282199Sdumbbell    @DefinedBy(Api.LANGUAGE_MODEL)
462282199Sdumbbell    public String toString() {
463282199Sdumbbell        StringBuilder sb = new StringBuilder();
464282199Sdumbbell        appendAnnotationsString(sb);
465282199Sdumbbell        if (tsym == null || tsym.name == null) {
466282199Sdumbbell            sb.append("<none>");
467235783Skib        } else {
468235783Skib            sb.append(tsym.name);
469282199Sdumbbell        }
470282199Sdumbbell        if (moreInfo && hasTag(TYPEVAR)) {
471282199Sdumbbell            sb.append(hashCode());
472282199Sdumbbell        }
473282199Sdumbbell        return sb.toString();
474282199Sdumbbell    }
475282199Sdumbbell
476282199Sdumbbell    /**
477282199Sdumbbell     * The Java source which this type list represents.  A List is
478282199Sdumbbell     * represented as a comma-spearated listing of the elements in
479282199Sdumbbell     * that list.
480282199Sdumbbell     */
481282199Sdumbbell    public static String toString(List<Type> ts) {
482235783Skib        if (ts.isEmpty()) {
483235783Skib            return "";
484235783Skib        } else {
485282199Sdumbbell            StringBuilder buf = new StringBuilder();
486282199Sdumbbell            buf.append(ts.head.toString());
487235783Skib            for (List<Type> l = ts.tail; l.nonEmpty(); l = l.tail)
488235783Skib                buf.append(",").append(l.head.toString());
489282199Sdumbbell            return buf.toString();
490282199Sdumbbell        }
491235783Skib    }
492282199Sdumbbell
493282199Sdumbbell    /**
494235783Skib     * The constant value of this type, converted to String
495282199Sdumbbell     */
496235783Skib    public String stringValue() {
497235783Skib        Object cv = Assert.checkNonNull(constValue());
498282199Sdumbbell        return cv.toString();
499282199Sdumbbell    }
500235783Skib
501235783Skib    /**
502235783Skib     * Override this method with care. For most Type instances this should behave as ==.
503282199Sdumbbell     */
504282199Sdumbbell    @Override @DefinedBy(Api.LANGUAGE_MODEL)
505282199Sdumbbell    public boolean equals(Object t) {
506282199Sdumbbell        return this == t;
507282199Sdumbbell    }
508282199Sdumbbell
509282199Sdumbbell    public boolean equalsIgnoreMetadata(Type t) {
510282199Sdumbbell        return typeNoMetadata().equals(t.typeNoMetadata());
511282199Sdumbbell    }
512282199Sdumbbell
513282199Sdumbbell    @Override @DefinedBy(Api.LANGUAGE_MODEL)
514235783Skib    public int hashCode() {
515282199Sdumbbell        return super.hashCode();
516282199Sdumbbell    }
517282199Sdumbbell
518235783Skib    public String argtypes(boolean varargs) {
519282199Sdumbbell        List<Type> args = getParameterTypes();
520282199Sdumbbell        if (!varargs) return args.toString();
521282199Sdumbbell        StringBuilder buf = new StringBuilder();
522282199Sdumbbell        while (args.tail.nonEmpty()) {
523282199Sdumbbell            buf.append(args.head);
524282199Sdumbbell            args = args.tail;
525282199Sdumbbell            buf.append(',');
526282199Sdumbbell        }
527282199Sdumbbell        if (args.head.hasTag(ARRAY)) {
528282199Sdumbbell            buf.append(((ArrayType)args.head).elemtype);
529282199Sdumbbell            if (args.head.getAnnotationMirrors().nonEmpty()) {
530282199Sdumbbell                buf.append(args.head.getAnnotationMirrors());
531235783Skib            }
532282199Sdumbbell            buf.append("...");
533282199Sdumbbell        } else {
534235783Skib            buf.append(args.head);
535235783Skib        }
536235783Skib        return buf.toString();
537282199Sdumbbell    }
538235783Skib
539235783Skib    /** Access methods.
540282199Sdumbbell     */
541282199Sdumbbell    public List<Type>        getTypeArguments()  { return List.nil(); }
542282199Sdumbbell    public Type              getEnclosingType()  { return null; }
543282199Sdumbbell    public List<Type>        getParameterTypes() { return List.nil(); }
544282199Sdumbbell    public Type              getReturnType()     { return null; }
545235783Skib    public Type              getReceiverType()   { return null; }
546235783Skib    public List<Type>        getThrownTypes()    { return List.nil(); }
547235783Skib    public Type              getUpperBound()     { return null; }
548282199Sdumbbell    public Type              getLowerBound()     { return null; }
549282199Sdumbbell
550282199Sdumbbell    /** Navigation methods, these will work for classes, type variables,
551282199Sdumbbell     *  foralls, but will return null for arrays and methods.
552282199Sdumbbell     */
553282199Sdumbbell
554282199Sdumbbell   /** Return all parameters of this type and all its outer types in order
555282199Sdumbbell    *  outer (first) to inner (last).
556235783Skib    */
557235783Skib    public List<Type> allparams() { return List.nil(); }
558235783Skib
559235783Skib    /** Does this type contain "error" elements?
560235783Skib     */
561235783Skib    public boolean isErroneous() {
562235783Skib        return false;
563282199Sdumbbell    }
564282199Sdumbbell
565235783Skib    public static boolean isErroneous(List<Type> ts) {
566235783Skib        for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
567282199Sdumbbell            if (l.head.isErroneous()) return true;
568235783Skib        return false;
569282199Sdumbbell    }
570282199Sdumbbell
571282199Sdumbbell    /** Is this type parameterized?
572235783Skib     *  A class type is parameterized if it has some parameters.
573282199Sdumbbell     *  An array type is parameterized if its element type is parameterized.
574282199Sdumbbell     *  All other types are not parameterized.
575282199Sdumbbell     */
576282199Sdumbbell    public boolean isParameterized() {
577282199Sdumbbell        return false;
578282199Sdumbbell    }
579235783Skib
580235783Skib    /** Is this type a raw type?
581282199Sdumbbell     *  A class type is a raw type if it misses some of its parameters.
582235783Skib     *  An array type is a raw type if its element type is raw.
583282199Sdumbbell     *  All other types are not raw.
584235783Skib     *  Type validation will ensure that the only raw types
585282199Sdumbbell     *  in a program are types that miss all their type variables.
586282199Sdumbbell     */
587282199Sdumbbell    public boolean isRaw() {
588282199Sdumbbell        return false;
589282199Sdumbbell    }
590282199Sdumbbell
591282199Sdumbbell    /**
592282199Sdumbbell     * A compound type is a special class type whose supertypes are used to store a list
593282199Sdumbbell     * of component types. There are two kinds of compound types: (i) intersection types
594282199Sdumbbell     * {@see IntersectionClassType} and (ii) union types {@see UnionClassType}.
595282199Sdumbbell     */
596282199Sdumbbell    public boolean isCompound() {
597282199Sdumbbell        return false;
598282199Sdumbbell    }
599235783Skib
600235783Skib    public boolean isIntersection() {
601235783Skib        return false;
602235783Skib    }
603235783Skib
604282199Sdumbbell    public boolean isUnion() {
605282199Sdumbbell        return false;
606282199Sdumbbell    }
607235783Skib
608235783Skib    public boolean isInterface() {
609282199Sdumbbell        return (tsym.flags() & INTERFACE) != 0;
610282199Sdumbbell    }
611282199Sdumbbell
612282199Sdumbbell    public boolean isFinal() {
613282199Sdumbbell        return (tsym.flags() & FINAL) != 0;
614235783Skib    }
615282199Sdumbbell
616235783Skib    /**
617235783Skib     * Does this type contain occurrences of type t?
618282199Sdumbbell     */
619282199Sdumbbell    public boolean contains(Type t) {
620282199Sdumbbell        return t.equalsIgnoreMetadata(this);
621282199Sdumbbell    }
622235783Skib
623282199Sdumbbell    public static boolean contains(List<Type> ts, Type t) {
624235783Skib        for (List<Type> l = ts;
625235783Skib             l.tail != null /*inlined: l.nonEmpty()*/;
626282199Sdumbbell             l = l.tail)
627282199Sdumbbell            if (l.head.contains(t)) return true;
628282199Sdumbbell        return false;
629282199Sdumbbell    }
630282199Sdumbbell
631235783Skib    /** Does this type contain an occurrence of some type in 'ts'?
632282199Sdumbbell     */
633282199Sdumbbell    public boolean containsAny(List<Type> ts) {
634235783Skib        for (Type t : ts)
635235783Skib            if (this.contains(t)) return true;
636282199Sdumbbell        return false;
637235783Skib    }
638235783Skib
639282199Sdumbbell    public static boolean containsAny(List<Type> ts1, List<Type> ts2) {
640282199Sdumbbell        for (Type t : ts1)
641282199Sdumbbell            if (t.containsAny(ts2)) return true;
642282199Sdumbbell        return false;
643282199Sdumbbell    }
644282199Sdumbbell
645282199Sdumbbell    public static List<Type> filter(List<Type> ts, Filter<Type> tf) {
646282199Sdumbbell        ListBuffer<Type> buf = new ListBuffer<>();
647282199Sdumbbell        for (Type t : ts) {
648282199Sdumbbell            if (tf.accepts(t)) {
649235783Skib                buf.append(t);
650235783Skib            }
651235783Skib        }
652235783Skib        return buf.toList();
653235783Skib    }
654282199Sdumbbell
655282199Sdumbbell    public boolean isSuperBound() { return false; }
656282199Sdumbbell    public boolean isExtendsBound() { return false; }
657235783Skib    public boolean isUnbound() { return false; }
658235783Skib    public Type withTypeVar(Type t) { return this; }
659235783Skib
660235783Skib    /** The underlying method type of this type.
661235783Skib     */
662235783Skib    public MethodType asMethodType() { throw new AssertionError(); }
663282199Sdumbbell
664282199Sdumbbell    /** Complete loading all classes in this type.
665235783Skib     */
666235783Skib    public void complete() {}
667235783Skib
668235783Skib    public TypeSymbol asElement() {
669235783Skib        return tsym;
670235783Skib    }
671235783Skib
672235783Skib    @Override @DefinedBy(Api.LANGUAGE_MODEL)
673282199Sdumbbell    public TypeKind getKind() {
674282199Sdumbbell        return TypeKind.OTHER;
675282199Sdumbbell    }
676282199Sdumbbell
677282199Sdumbbell    @Override @DefinedBy(Api.LANGUAGE_MODEL)
678282199Sdumbbell    public <R, P> R accept(TypeVisitor<R, P> v, P p) {
679282199Sdumbbell        throw new AssertionError();
680282199Sdumbbell    }
681282199Sdumbbell
682282199Sdumbbell    public static class JCPrimitiveType extends Type
683282199Sdumbbell            implements javax.lang.model.type.PrimitiveType {
684282199Sdumbbell
685282199Sdumbbell        TypeTag tag;
686235783Skib
687282199Sdumbbell        public JCPrimitiveType(TypeTag tag, TypeSymbol tsym) {
688282199Sdumbbell            this(tag, tsym, TypeMetadata.EMPTY);
689282199Sdumbbell        }
690282199Sdumbbell
691235783Skib        private JCPrimitiveType(TypeTag tag, TypeSymbol tsym, TypeMetadata metadata) {
692235783Skib            super(tsym, metadata);
693235783Skib            this.tag = tag;
694235783Skib            Assert.check(tag.isPrimitive);
695235783Skib        }
696235783Skib
697235783Skib        @Override
698235783Skib        public JCPrimitiveType cloneWithMetadata(TypeMetadata md) {
699235783Skib            return new JCPrimitiveType(tag, tsym, md) {
700282199Sdumbbell                @Override
701282199Sdumbbell                public Type baseType() { return JCPrimitiveType.this.baseType(); }
702235783Skib            };
703282199Sdumbbell        }
704282199Sdumbbell
705282199Sdumbbell        @Override
706235783Skib        public boolean isNumeric() {
707235783Skib            return tag != BOOLEAN;
708235783Skib        }
709235783Skib
710282199Sdumbbell        @Override
711282199Sdumbbell        public boolean isIntegral() {
712235783Skib            switch (tag) {
713235783Skib                case CHAR:
714235783Skib                case BYTE:
715235783Skib                case SHORT:
716235783Skib                case INT:
717235783Skib                case LONG:
718282199Sdumbbell                    return true;
719282199Sdumbbell                default:
720282199Sdumbbell                    return false;
721282199Sdumbbell            }
722282199Sdumbbell        }
723282199Sdumbbell
724282199Sdumbbell        @Override
725235783Skib        public boolean isPrimitive() {
726282199Sdumbbell            return true;
727282199Sdumbbell        }
728282199Sdumbbell
729235783Skib        @Override
730282199Sdumbbell        public TypeTag getTag() {
731282199Sdumbbell            return tag;
732235783Skib        }
733282199Sdumbbell
734235783Skib        @Override
735235783Skib        public boolean isPrimitiveOrVoid() {
736235783Skib            return true;
737235783Skib        }
738282199Sdumbbell
739235783Skib        /** Define a constant type, of the same kind as this type
740282199Sdumbbell         *  and with given constant value
741282199Sdumbbell         */
742282199Sdumbbell        @Override
743282199Sdumbbell        public Type constType(Object constValue) {
744282199Sdumbbell            final Object value = constValue;
745282199Sdumbbell            return new JCPrimitiveType(tag, tsym, metadata) {
746282199Sdumbbell                    @Override
747282199Sdumbbell                    public Object constValue() {
748282199Sdumbbell                        return value;
749235783Skib                    }
750282199Sdumbbell                    @Override
751235783Skib                    public Type baseType() {
752282199Sdumbbell                        return tsym.type;
753282199Sdumbbell                    }
754282199Sdumbbell                };
755282199Sdumbbell        }
756282199Sdumbbell
757235783Skib        /**
758282199Sdumbbell         * The constant value of this type, converted to String
759282199Sdumbbell         */
760282199Sdumbbell        @Override
761282199Sdumbbell        public String stringValue() {
762282199Sdumbbell            Object cv = Assert.checkNonNull(constValue());
763282199Sdumbbell            if (tag == BOOLEAN) {
764235783Skib                return ((Integer) cv).intValue() == 0 ? "false" : "true";
765235783Skib            }
766235783Skib            else if (tag == CHAR) {
767282199Sdumbbell                return String.valueOf((char) ((Integer) cv).intValue());
768282199Sdumbbell            }
769282199Sdumbbell            else {
770235783Skib                return cv.toString();
771235783Skib            }
772235783Skib        }
773235783Skib
774235783Skib        /** Is this a constant type whose value is false?
775235783Skib         */
776235783Skib        @Override
777235783Skib        public boolean isFalse() {
778282199Sdumbbell            return
779282199Sdumbbell                tag == BOOLEAN &&
780282199Sdumbbell                constValue() != null &&
781282199Sdumbbell                ((Integer)constValue()).intValue() == 0;
782282199Sdumbbell        }
783235783Skib
784282199Sdumbbell        /** Is this a constant type whose value is true?
785235783Skib         */
786235783Skib        @Override
787282199Sdumbbell        public boolean isTrue() {
788282199Sdumbbell            return
789235783Skib                tag == BOOLEAN &&
790235783Skib                constValue() != null &&
791235783Skib                ((Integer)constValue()).intValue() != 0;
792282199Sdumbbell        }
793235783Skib
794235783Skib        @Override @DefinedBy(Api.LANGUAGE_MODEL)
795282199Sdumbbell        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
796235783Skib            return v.visitPrimitive(this, p);
797235783Skib        }
798235783Skib
799282199Sdumbbell        @Override @DefinedBy(Api.LANGUAGE_MODEL)
800282199Sdumbbell        public TypeKind getKind() {
801282199Sdumbbell            switch (tag) {
802235783Skib                case BYTE:      return TypeKind.BYTE;
803235783Skib                case CHAR:      return TypeKind.CHAR;
804282199Sdumbbell                case SHORT:     return TypeKind.SHORT;
805282199Sdumbbell                case INT:       return TypeKind.INT;
806235783Skib                case LONG:      return TypeKind.LONG;
807235783Skib                case FLOAT:     return TypeKind.FLOAT;
808235783Skib                case DOUBLE:    return TypeKind.DOUBLE;
809235783Skib                case BOOLEAN:   return TypeKind.BOOLEAN;
810235783Skib            }
811235783Skib            throw new AssertionError();
812235783Skib        }
813235783Skib
814235783Skib    }
815235783Skib
816282199Sdumbbell    public static class WildcardType extends Type
817235783Skib            implements javax.lang.model.type.WildcardType {
818235783Skib
819282199Sdumbbell        public Type type;
820282199Sdumbbell        public BoundKind kind;
821282199Sdumbbell        public TypeVar bound;
822235783Skib
823235783Skib        @Override
824235783Skib        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
825235783Skib            return v.visitWildcardType(this, s);
826235783Skib        }
827235783Skib
828235783Skib        public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) {
829235783Skib            this(type, kind, tsym, null, TypeMetadata.EMPTY);
830282199Sdumbbell        }
831282199Sdumbbell
832235783Skib        public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
833235783Skib                            TypeMetadata metadata) {
834235783Skib            this(type, kind, tsym, null, metadata);
835235783Skib        }
836235783Skib
837282199Sdumbbell        public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
838282199Sdumbbell                            TypeVar bound) {
839235783Skib            this(type, kind, tsym, bound, TypeMetadata.EMPTY);
840235783Skib        }
841235783Skib
842235783Skib        public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
843235783Skib                            TypeVar bound, TypeMetadata metadata) {
844282199Sdumbbell            super(tsym, metadata);
845235783Skib            this.type = Assert.checkNonNull(type);
846235783Skib            this.kind = kind;
847282199Sdumbbell            this.bound = bound;
848282199Sdumbbell        }
849235783Skib
850282199Sdumbbell        @Override
851235783Skib        public WildcardType cloneWithMetadata(TypeMetadata md) {
852282199Sdumbbell            return new WildcardType(type, kind, tsym, bound, md) {
853235783Skib                @Override
854235783Skib                public Type baseType() { return WildcardType.this.baseType(); }
855235783Skib            };
856235783Skib        }
857235783Skib
858282199Sdumbbell        @Override
859282199Sdumbbell        public TypeTag getTag() {
860282199Sdumbbell            return WILDCARD;
861235783Skib        }
862235783Skib
863235783Skib        @Override
864235783Skib        public boolean contains(Type t) {
865235783Skib            return kind != UNBOUND && type.contains(t);
866235783Skib        }
867282199Sdumbbell
868235783Skib        public boolean isSuperBound() {
869282199Sdumbbell            return kind == SUPER ||
870282199Sdumbbell                kind == UNBOUND;
871282199Sdumbbell        }
872282199Sdumbbell        public boolean isExtendsBound() {
873282199Sdumbbell            return kind == EXTENDS ||
874282199Sdumbbell                kind == UNBOUND;
875282199Sdumbbell        }
876282199Sdumbbell        public boolean isUnbound() {
877282199Sdumbbell            return kind == UNBOUND;
878235783Skib        }
879235783Skib
880235783Skib        @Override
881235783Skib        public boolean isReference() {
882235783Skib            return true;
883282199Sdumbbell        }
884235783Skib
885282199Sdumbbell        @Override
886282199Sdumbbell        public boolean isNullOrReference() {
887282199Sdumbbell            return true;
888235783Skib        }
889282199Sdumbbell
890235783Skib        @Override
891235783Skib        public Type withTypeVar(Type t) {
892235783Skib            //-System.err.println(this+".withTypeVar("+t+");");//DEBUG
893282199Sdumbbell            if (bound == t)
894282199Sdumbbell                return this;
895282199Sdumbbell            bound = (TypeVar)t;
896282199Sdumbbell            return this;
897282199Sdumbbell        }
898282199Sdumbbell
899282199Sdumbbell        boolean isPrintingBound = false;
900282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
901282199Sdumbbell        public String toString() {
902235783Skib            StringBuilder s = new StringBuilder();
903282199Sdumbbell            appendAnnotationsString(s);
904282199Sdumbbell            s.append(kind.toString());
905282199Sdumbbell            if (kind != UNBOUND)
906282199Sdumbbell                s.append(type);
907282199Sdumbbell            if (moreInfo && bound != null && !isPrintingBound)
908235783Skib                try {
909282199Sdumbbell                    isPrintingBound = true;
910282199Sdumbbell                    s.append("{:").append(bound.bound).append(":}");
911282199Sdumbbell                } finally {
912282199Sdumbbell                    isPrintingBound = false;
913282199Sdumbbell                }
914282199Sdumbbell            return s.toString();
915235783Skib        }
916235783Skib
917282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
918282199Sdumbbell        public Type getExtendsBound() {
919282199Sdumbbell            if (kind == EXTENDS)
920282199Sdumbbell                return type;
921282199Sdumbbell            else
922282199Sdumbbell                return null;
923235783Skib        }
924235783Skib
925282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
926282199Sdumbbell        public Type getSuperBound() {
927282199Sdumbbell            if (kind == SUPER)
928282199Sdumbbell                return type;
929282199Sdumbbell            else
930282199Sdumbbell                return null;
931235783Skib        }
932235783Skib
933235783Skib        @DefinedBy(Api.LANGUAGE_MODEL)
934235783Skib        public TypeKind getKind() {
935235783Skib            return TypeKind.WILDCARD;
936235783Skib        }
937282199Sdumbbell
938282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
939235783Skib        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
940282199Sdumbbell            return v.visitWildcard(this, p);
941282199Sdumbbell        }
942282199Sdumbbell    }
943235783Skib
944282199Sdumbbell    public static class ClassType extends Type implements DeclaredType {
945282199Sdumbbell
946235783Skib        /** The enclosing type of this type. If this is the type of an inner
947282199Sdumbbell         *  class, outer_field refers to the type of its enclosing
948235783Skib         *  instance class, in all other cases it refers to noType.
949282199Sdumbbell         */
950235783Skib        private Type outer_field;
951235783Skib
952235783Skib        /** The type parameters of this type (to be set once class is loaded).
953235783Skib         */
954235783Skib        public List<Type> typarams_field;
955282199Sdumbbell
956282199Sdumbbell        /** A cache variable for the type parameters of this type,
957282199Sdumbbell         *  appended to all parameters of its enclosing class.
958282199Sdumbbell         *  @see #allparams
959235783Skib         */
960235783Skib        public List<Type> allparams_field;
961235783Skib
962235783Skib        /** The supertype of this class (to be set once class is loaded).
963235783Skib         */
964282199Sdumbbell        public Type supertype_field;
965282199Sdumbbell
966282199Sdumbbell        /** The interfaces of this class (to be set once class is loaded).
967235783Skib         */
968235783Skib        public List<Type> interfaces_field;
969235783Skib
970282199Sdumbbell        /** All the interfaces of this class, including missing ones.
971282199Sdumbbell         */
972282199Sdumbbell        public List<Type> all_interfaces_field;
973282199Sdumbbell
974282199Sdumbbell        public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
975235783Skib            this(outer, typarams, tsym, TypeMetadata.EMPTY);
976235783Skib        }
977282199Sdumbbell
978282199Sdumbbell        public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym,
979282199Sdumbbell                         TypeMetadata metadata) {
980282199Sdumbbell            super(tsym, metadata);
981282199Sdumbbell            this.outer_field = outer;
982282199Sdumbbell            this.typarams_field = typarams;
983282199Sdumbbell            this.allparams_field = null;
984282199Sdumbbell            this.supertype_field = null;
985282199Sdumbbell            this.interfaces_field = null;
986235783Skib        }
987282199Sdumbbell
988282199Sdumbbell        @Override
989235783Skib        public ClassType cloneWithMetadata(TypeMetadata md) {
990235783Skib            return new ClassType(outer_field, typarams_field, tsym, md) {
991235783Skib                @Override
992282199Sdumbbell                public Type baseType() { return ClassType.this.baseType(); }
993235783Skib            };
994235783Skib        }
995282199Sdumbbell
996235783Skib        @Override
997235783Skib        public TypeTag getTag() {
998235783Skib            return CLASS;
999235783Skib        }
1000235783Skib
1001282199Sdumbbell        @Override
1002282199Sdumbbell        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1003282199Sdumbbell            return v.visitClassType(this, s);
1004235783Skib        }
1005235783Skib
1006235783Skib        public Type constType(Object constValue) {
1007282199Sdumbbell            final Object value = constValue;
1008235783Skib            return new ClassType(getEnclosingType(), typarams_field, tsym, metadata) {
1009235783Skib                    @Override
1010235783Skib                    public Object constValue() {
1011235783Skib                        return value;
1012235783Skib                    }
1013235783Skib                    @Override
1014235783Skib                    public Type baseType() {
1015282199Sdumbbell                        return tsym.type;
1016235783Skib                    }
1017235783Skib                };
1018235783Skib        }
1019282199Sdumbbell
1020282199Sdumbbell        /** The Java source which this type represents.
1021282199Sdumbbell         */
1022235783Skib        @DefinedBy(Api.LANGUAGE_MODEL)
1023235783Skib        public String toString() {
1024235783Skib            StringBuilder buf = new StringBuilder();
1025235783Skib            if (getEnclosingType().hasTag(CLASS) && tsym.owner.kind == TYP) {
1026235783Skib                buf.append(getEnclosingType().toString());
1027235783Skib                buf.append(".");
1028235783Skib                appendAnnotationsString(buf);
1029282199Sdumbbell                buf.append(className(tsym, false));
1030235783Skib            } else {
1031235783Skib                appendAnnotationsString(buf);
1032282199Sdumbbell                buf.append(className(tsym, true));
1033282199Sdumbbell            }
1034282199Sdumbbell
1035235783Skib            if (getTypeArguments().nonEmpty()) {
1036235783Skib                buf.append('<');
1037235783Skib                buf.append(getTypeArguments().toString());
1038235783Skib                buf.append(">");
1039235783Skib            }
1040235783Skib            return buf.toString();
1041235783Skib        }
1042282199Sdumbbell//where
1043282199Sdumbbell            private String className(Symbol sym, boolean longform) {
1044235783Skib                if (sym.name.isEmpty() && (sym.flags() & COMPOUND) != 0) {
1045235783Skib                    StringBuilder s = new StringBuilder(supertype_field.toString());
1046235783Skib                    for (List<Type> is=interfaces_field; is.nonEmpty(); is = is.tail) {
1047282199Sdumbbell                        s.append("&");
1048282199Sdumbbell                        s.append(is.head.toString());
1049282199Sdumbbell                    }
1050282199Sdumbbell                    return s.toString();
1051235783Skib                } else if (sym.name.isEmpty()) {
1052235783Skib                    String s;
1053235783Skib                    ClassType norm = (ClassType) tsym.type;
1054282199Sdumbbell                    if (norm == null) {
1055235783Skib                        s = Log.getLocalizedString("anonymous.class", (Object)null);
1056282199Sdumbbell                    } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
1057235783Skib                        s = Log.getLocalizedString("anonymous.class",
1058282199Sdumbbell                                                   norm.interfaces_field.head);
1059282199Sdumbbell                    } else {
1060282199Sdumbbell                        s = Log.getLocalizedString("anonymous.class",
1061235783Skib                                                   norm.supertype_field);
1062235783Skib                    }
1063235783Skib                    if (moreInfo)
1064235783Skib                        s += String.valueOf(sym.hashCode());
1065235783Skib                    return s;
1066235783Skib                } else if (longform) {
1067235783Skib                    return sym.getQualifiedName().toString();
1068235783Skib                } else {
1069235783Skib                    return sym.name.toString();
1070235783Skib                }
1071282199Sdumbbell            }
1072235783Skib
1073282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
1074282199Sdumbbell        public List<Type> getTypeArguments() {
1075282199Sdumbbell            if (typarams_field == null) {
1076282199Sdumbbell                complete();
1077282199Sdumbbell                if (typarams_field == null)
1078282199Sdumbbell                    typarams_field = List.nil();
1079282199Sdumbbell            }
1080282199Sdumbbell            return typarams_field;
1081282199Sdumbbell        }
1082235783Skib
1083235783Skib        public boolean hasErasedSupertypes() {
1084235783Skib            return isRaw();
1085235783Skib        }
1086282199Sdumbbell
1087282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
1088235783Skib        public Type getEnclosingType() {
1089235783Skib            return outer_field;
1090235783Skib        }
1091235783Skib
1092235783Skib        public void setEnclosingType(Type outer) {
1093235783Skib            outer_field = outer;
1094282199Sdumbbell        }
1095282199Sdumbbell
1096282199Sdumbbell        public List<Type> allparams() {
1097282199Sdumbbell            if (allparams_field == null) {
1098282199Sdumbbell                allparams_field = getTypeArguments().prependList(getEnclosingType().allparams());
1099282199Sdumbbell            }
1100282199Sdumbbell            return allparams_field;
1101235783Skib        }
1102282199Sdumbbell
1103282199Sdumbbell        public boolean isErroneous() {
1104282199Sdumbbell            return
1105282199Sdumbbell                getEnclosingType().isErroneous() ||
1106282199Sdumbbell                isErroneous(getTypeArguments()) ||
1107282199Sdumbbell                this != tsym.type && tsym.type.isErroneous();
1108282199Sdumbbell        }
1109282199Sdumbbell
1110282199Sdumbbell        public boolean isParameterized() {
1111282199Sdumbbell            return allparams().tail != null;
1112282199Sdumbbell            // optimization, was: allparams().nonEmpty();
1113282199Sdumbbell        }
1114235783Skib
1115282199Sdumbbell        @Override
1116282199Sdumbbell        public boolean isReference() {
1117282199Sdumbbell            return true;
1118282199Sdumbbell        }
1119282199Sdumbbell
1120235783Skib        @Override
1121282199Sdumbbell        public boolean isNullOrReference() {
1122282199Sdumbbell            return true;
1123282199Sdumbbell        }
1124282199Sdumbbell
1125282199Sdumbbell        /** A cache for the rank. */
1126282199Sdumbbell        int rank_field = -1;
1127235783Skib
1128235783Skib        /** A class type is raw if it misses some
1129282199Sdumbbell         *  of its type parameter sections.
1130282199Sdumbbell         *  After validation, this is equivalent to:
1131282199Sdumbbell         *  {@code allparams.isEmpty() && tsym.type.allparams.nonEmpty(); }
1132282199Sdumbbell         */
1133282199Sdumbbell        public boolean isRaw() {
1134235783Skib            return
1135235783Skib                this != tsym.type && // necessary, but not sufficient condition
1136235783Skib                tsym.type.allparams().nonEmpty() &&
1137235783Skib                allparams().isEmpty();
1138235783Skib        }
1139235783Skib
1140235783Skib        public boolean contains(Type elem) {
1141282199Sdumbbell            return
1142282199Sdumbbell                elem.equalsIgnoreMetadata(this)
1143282199Sdumbbell                || (isParameterized()
1144282199Sdumbbell                    && (getEnclosingType().contains(elem) || contains(getTypeArguments(), elem)))
1145282199Sdumbbell                || (isCompound()
1146235783Skib                    && (supertype_field.contains(elem) || contains(interfaces_field, elem)));
1147282199Sdumbbell        }
1148235783Skib
1149282199Sdumbbell        public void complete() {
1150282199Sdumbbell            tsym.complete();
1151282199Sdumbbell        }
1152282199Sdumbbell
1153235783Skib        @DefinedBy(Api.LANGUAGE_MODEL)
1154235783Skib        public TypeKind getKind() {
1155235783Skib            return TypeKind.DECLARED;
1156282199Sdumbbell        }
1157235783Skib
1158235783Skib        @DefinedBy(Api.LANGUAGE_MODEL)
1159282199Sdumbbell        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1160235783Skib            return v.visitDeclared(this, p);
1161235783Skib        }
1162235783Skib    }
1163282199Sdumbbell
1164282199Sdumbbell    public static class ErasedClassType extends ClassType {
1165282199Sdumbbell        public ErasedClassType(Type outer, TypeSymbol tsym,
1166235783Skib                               TypeMetadata metadata) {
1167235783Skib            super(outer, List.<Type>nil(), tsym, metadata);
1168282199Sdumbbell        }
1169235783Skib
1170235783Skib        @Override
1171235783Skib        public boolean hasErasedSupertypes() {
1172235783Skib            return true;
1173235783Skib        }
1174235783Skib    }
1175235783Skib
1176235783Skib    // a clone of a ClassType that knows about the alternatives of a union type.
1177235783Skib    public static class UnionClassType extends ClassType implements UnionType {
1178235783Skib        final List<? extends Type> alternatives_field;
1179235783Skib
1180282199Sdumbbell        public UnionClassType(ClassType ct, List<? extends Type> alternatives) {
1181235783Skib            // Presently no way to refer to this type directly, so we
1182235783Skib            // cannot put annotations directly on it.
1183282199Sdumbbell            super(ct.outer_field, ct.typarams_field, ct.tsym);
1184282199Sdumbbell            allparams_field = ct.allparams_field;
1185282199Sdumbbell            supertype_field = ct.supertype_field;
1186235783Skib            interfaces_field = ct.interfaces_field;
1187235783Skib            all_interfaces_field = ct.interfaces_field;
1188235783Skib            alternatives_field = alternatives;
1189235783Skib        }
1190235783Skib
1191235783Skib        @Override
1192235783Skib        public UnionClassType cloneWithMetadata(TypeMetadata md) {
1193235783Skib            throw new AssertionError("Cannot add metadata to a union type");
1194282199Sdumbbell        }
1195282199Sdumbbell
1196235783Skib        public Type getLub() {
1197235783Skib            return tsym.type;
1198235783Skib        }
1199235783Skib
1200235783Skib        @DefinedBy(Api.LANGUAGE_MODEL)
1201282199Sdumbbell        public java.util.List<? extends TypeMirror> getAlternatives() {
1202282199Sdumbbell            return Collections.unmodifiableList(alternatives_field);
1203235783Skib        }
1204235783Skib
1205235783Skib        @Override
1206235783Skib        public boolean isUnion() {
1207235783Skib            return true;
1208282199Sdumbbell        }
1209235783Skib
1210235783Skib        @Override
1211235783Skib        public boolean isCompound() {
1212282199Sdumbbell            return getLub().isCompound();
1213235783Skib        }
1214282199Sdumbbell
1215282199Sdumbbell        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1216282199Sdumbbell        public TypeKind getKind() {
1217282199Sdumbbell            return TypeKind.UNION;
1218282199Sdumbbell        }
1219282199Sdumbbell
1220282199Sdumbbell        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1221282199Sdumbbell        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1222282199Sdumbbell            return v.visitUnion(this, p);
1223282199Sdumbbell        }
1224282199Sdumbbell
1225282199Sdumbbell        public Iterable<? extends Type> getAlternativeTypes() {
1226282199Sdumbbell            return alternatives_field;
1227282199Sdumbbell        }
1228235783Skib    }
1229282199Sdumbbell
1230282199Sdumbbell    // a clone of a ClassType that knows about the bounds of an intersection type.
1231235783Skib    public static class IntersectionClassType extends ClassType implements IntersectionType {
1232282199Sdumbbell
1233282199Sdumbbell        public boolean allInterfaces;
1234235783Skib
1235282199Sdumbbell        public IntersectionClassType(List<Type> bounds, ClassSymbol csym, boolean allInterfaces) {
1236282199Sdumbbell            // Presently no way to refer to this type directly, so we
1237235783Skib            // cannot put annotations directly on it.
1238282199Sdumbbell            super(Type.noType, List.<Type>nil(), csym);
1239282199Sdumbbell            this.allInterfaces = allInterfaces;
1240282199Sdumbbell            Assert.check((csym.flags() & COMPOUND) != 0);
1241235783Skib            supertype_field = bounds.head;
1242282199Sdumbbell            interfaces_field = bounds.tail;
1243282199Sdumbbell            Assert.check(!supertype_field.tsym.isCompleted() ||
1244282199Sdumbbell                    !supertype_field.isInterface(), supertype_field);
1245282199Sdumbbell        }
1246235783Skib
1247282199Sdumbbell        @Override
1248282199Sdumbbell        public IntersectionClassType cloneWithMetadata(TypeMetadata md) {
1249235783Skib            throw new AssertionError("Cannot add metadata to an intersection type");
1250282199Sdumbbell        }
1251282199Sdumbbell
1252282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
1253282199Sdumbbell        public java.util.List<? extends TypeMirror> getBounds() {
1254282199Sdumbbell            return Collections.unmodifiableList(getExplicitComponents());
1255282199Sdumbbell        }
1256282199Sdumbbell
1257235783Skib        @Override
1258235783Skib        public boolean isCompound() {
1259282199Sdumbbell            return true;
1260235783Skib        }
1261282199Sdumbbell
1262282199Sdumbbell        public List<Type> getComponents() {
1263282199Sdumbbell            return interfaces_field.prepend(supertype_field);
1264282199Sdumbbell        }
1265282199Sdumbbell
1266282199Sdumbbell        @Override
1267282199Sdumbbell        public boolean isIntersection() {
1268235783Skib            return true;
1269282199Sdumbbell        }
1270282199Sdumbbell
1271282199Sdumbbell        public List<Type> getExplicitComponents() {
1272282199Sdumbbell            return allInterfaces ?
1273282199Sdumbbell                    interfaces_field :
1274282199Sdumbbell                    getComponents();
1275235783Skib        }
1276282199Sdumbbell
1277282199Sdumbbell        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1278282199Sdumbbell        public TypeKind getKind() {
1279282199Sdumbbell            return TypeKind.INTERSECTION;
1280282199Sdumbbell        }
1281235783Skib
1282235783Skib        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1283282199Sdumbbell        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1284282199Sdumbbell            return v.visitIntersection(this, p);
1285282199Sdumbbell        }
1286282199Sdumbbell    }
1287282199Sdumbbell
1288282199Sdumbbell    public static class ArrayType extends Type
1289282199Sdumbbell            implements javax.lang.model.type.ArrayType {
1290235783Skib
1291282199Sdumbbell        public Type elemtype;
1292282199Sdumbbell
1293235783Skib        public ArrayType(Type elemtype, TypeSymbol arrayClass) {
1294282199Sdumbbell            this(elemtype, arrayClass, TypeMetadata.EMPTY);
1295235783Skib        }
1296282199Sdumbbell
1297282199Sdumbbell        public ArrayType(Type elemtype, TypeSymbol arrayClass,
1298282199Sdumbbell                         TypeMetadata metadata) {
1299282199Sdumbbell            super(arrayClass, metadata);
1300282199Sdumbbell            this.elemtype = elemtype;
1301282199Sdumbbell        }
1302235783Skib
1303282199Sdumbbell        public ArrayType(ArrayType that) {
1304282199Sdumbbell            //note: type metadata is deliberately shared here, as we want side-effects from annotation
1305282199Sdumbbell            //processing to flow from original array to the cloned array.
1306282199Sdumbbell            this(that.elemtype, that.tsym, that.getMetadata());
1307282199Sdumbbell        }
1308282199Sdumbbell
1309282199Sdumbbell        @Override
1310235783Skib        public ArrayType cloneWithMetadata(TypeMetadata md) {
1311282199Sdumbbell            return new ArrayType(elemtype, tsym, md) {
1312282199Sdumbbell                @Override
1313282199Sdumbbell                public Type baseType() { return ArrayType.this.baseType(); }
1314282199Sdumbbell            };
1315282199Sdumbbell        }
1316282199Sdumbbell
1317282199Sdumbbell        @Override
1318282199Sdumbbell        public TypeTag getTag() {
1319282199Sdumbbell            return ARRAY;
1320282199Sdumbbell        }
1321282199Sdumbbell
1322235783Skib        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1323282199Sdumbbell            return v.visitArrayType(this, s);
1324235783Skib        }
1325282199Sdumbbell
1326282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
1327282199Sdumbbell        public String toString() {
1328282199Sdumbbell            StringBuilder sb = new StringBuilder();
1329235783Skib
1330282199Sdumbbell            // First append root component type
1331282199Sdumbbell            Type t = elemtype;
1332282199Sdumbbell            while (t.getKind() == TypeKind.ARRAY)
1333282199Sdumbbell                t = ((ArrayType) t).getComponentType();
1334282199Sdumbbell            sb.append(t);
1335282199Sdumbbell
1336282199Sdumbbell            // then append @Anno[] @Anno[] ... @Anno[]
1337282199Sdumbbell            t = this;
1338282199Sdumbbell            do {
1339282199Sdumbbell                t.appendAnnotationsString(sb, true);
1340282199Sdumbbell                sb.append("[]");
1341235783Skib                t = ((ArrayType) t).getComponentType();
1342282199Sdumbbell            } while (t.getKind() == TypeKind.ARRAY);
1343282199Sdumbbell
1344282199Sdumbbell            return sb.toString();
1345282199Sdumbbell        }
1346235783Skib
1347235783Skib        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1348282199Sdumbbell        public boolean equals(Object obj) {
1349282199Sdumbbell            if (obj instanceof ArrayType) {
1350282199Sdumbbell                ArrayType that = (ArrayType)obj;
1351282199Sdumbbell                return this == that ||
1352235783Skib                        elemtype.equals(that.elemtype);
1353282199Sdumbbell            }
1354282199Sdumbbell
1355235783Skib            return false;
1356282199Sdumbbell        }
1357282199Sdumbbell
1358282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
1359282199Sdumbbell        public int hashCode() {
1360282199Sdumbbell            return (ARRAY.ordinal() << 5) + elemtype.hashCode();
1361282199Sdumbbell        }
1362282199Sdumbbell
1363282199Sdumbbell        public boolean isVarargs() {
1364282199Sdumbbell            return false;
1365235783Skib        }
1366235783Skib
1367282199Sdumbbell        public List<Type> allparams() { return elemtype.allparams(); }
1368282199Sdumbbell
1369282199Sdumbbell        public boolean isErroneous() {
1370282199Sdumbbell            return elemtype.isErroneous();
1371282199Sdumbbell        }
1372282199Sdumbbell
1373282199Sdumbbell        public boolean isParameterized() {
1374282199Sdumbbell            return elemtype.isParameterized();
1375282199Sdumbbell        }
1376282199Sdumbbell
1377282199Sdumbbell        @Override
1378282199Sdumbbell        public boolean isReference() {
1379282199Sdumbbell            return true;
1380282199Sdumbbell        }
1381282199Sdumbbell
1382282199Sdumbbell        @Override
1383282199Sdumbbell        public boolean isNullOrReference() {
1384235783Skib            return true;
1385235783Skib        }
1386282199Sdumbbell
1387235783Skib        public boolean isRaw() {
1388282199Sdumbbell            return elemtype.isRaw();
1389282199Sdumbbell        }
1390282199Sdumbbell
1391282199Sdumbbell        public ArrayType makeVarargs() {
1392235783Skib            return new ArrayType(elemtype, tsym, metadata) {
1393282199Sdumbbell                @Override
1394235783Skib                public boolean isVarargs() {
1395282199Sdumbbell                    return true;
1396282199Sdumbbell                }
1397282199Sdumbbell            };
1398282199Sdumbbell        }
1399282199Sdumbbell
1400282199Sdumbbell        public boolean contains(Type elem) {
1401282199Sdumbbell            return elem.equalsIgnoreMetadata(this) || elemtype.contains(elem);
1402235783Skib        }
1403282199Sdumbbell
1404235783Skib        public void complete() {
1405235783Skib            elemtype.complete();
1406282199Sdumbbell        }
1407282199Sdumbbell
1408282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
1409282199Sdumbbell        public Type getComponentType() {
1410282199Sdumbbell            return elemtype;
1411282199Sdumbbell        }
1412282199Sdumbbell
1413282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
1414282199Sdumbbell        public TypeKind getKind() {
1415282199Sdumbbell            return TypeKind.ARRAY;
1416282199Sdumbbell        }
1417282199Sdumbbell
1418282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
1419282199Sdumbbell        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1420282199Sdumbbell            return v.visitArray(this, p);
1421282199Sdumbbell        }
1422282199Sdumbbell    }
1423282199Sdumbbell
1424282199Sdumbbell    public static class MethodType extends Type implements ExecutableType {
1425235783Skib
1426282199Sdumbbell        public List<Type> argtypes;
1427235783Skib        public Type restype;
1428235783Skib        public List<Type> thrown;
1429235783Skib
1430235783Skib        /** The type annotations on the method receiver.
1431282199Sdumbbell         */
1432282199Sdumbbell        public Type recvtype;
1433282199Sdumbbell
1434282199Sdumbbell        public MethodType(List<Type> argtypes,
1435282199Sdumbbell                          Type restype,
1436282199Sdumbbell                          List<Type> thrown,
1437282199Sdumbbell                          TypeSymbol methodClass) {
1438282199Sdumbbell            // Presently no way to refer to a method type directly, so
1439282199Sdumbbell            // we cannot put type annotations on it.
1440282199Sdumbbell            super(methodClass, TypeMetadata.EMPTY);
1441282199Sdumbbell            this.argtypes = argtypes;
1442235783Skib            this.restype = restype;
1443282199Sdumbbell            this.thrown = thrown;
1444235783Skib        }
1445235783Skib
1446235783Skib        @Override
1447235783Skib        public MethodType cloneWithMetadata(TypeMetadata md) {
1448235783Skib            throw new AssertionError("Cannot add metadata to a method type");
1449235783Skib        }
1450235783Skib
1451235783Skib        @Override
1452235783Skib        public TypeTag getTag() {
1453235783Skib            return METHOD;
1454235783Skib        }
1455282199Sdumbbell
1456282199Sdumbbell        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1457282199Sdumbbell            return v.visitMethodType(this, s);
1458282199Sdumbbell        }
1459282199Sdumbbell
1460282199Sdumbbell        /** The Java source which this type represents.
1461282199Sdumbbell         *
1462282199Sdumbbell         *  XXX 06/09/99 iris This isn't correct Java syntax, but it probably
1463282199Sdumbbell         *  should be.
1464282199Sdumbbell         */
1465282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
1466282199Sdumbbell        public String toString() {
1467282199Sdumbbell            StringBuilder sb = new StringBuilder();
1468282199Sdumbbell            appendAnnotationsString(sb);
1469282199Sdumbbell            sb.append('(');
1470282199Sdumbbell            sb.append(argtypes);
1471282199Sdumbbell            sb.append(')');
1472235783Skib            sb.append(restype);
1473235783Skib            return sb.toString();
1474282199Sdumbbell        }
1475282199Sdumbbell
1476282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
1477282199Sdumbbell        public List<Type>        getParameterTypes() { return argtypes; }
1478282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
1479235783Skib        public Type              getReturnType()     { return restype; }
1480235783Skib        @DefinedBy(Api.LANGUAGE_MODEL)
1481235783Skib        public Type              getReceiverType()   { return recvtype; }
1482235783Skib        @DefinedBy(Api.LANGUAGE_MODEL)
1483235783Skib        public List<Type>        getThrownTypes()    { return thrown; }
1484235783Skib
1485282199Sdumbbell        public boolean isErroneous() {
1486235783Skib            return
1487235783Skib                isErroneous(argtypes) ||
1488282199Sdumbbell                restype != null && restype.isErroneous();
1489282199Sdumbbell        }
1490282199Sdumbbell
1491282199Sdumbbell        public boolean contains(Type elem) {
1492282199Sdumbbell            return elem.equalsIgnoreMetadata(this) || contains(argtypes, elem) || restype.contains(elem) || contains(thrown, elem);
1493282199Sdumbbell        }
1494282199Sdumbbell
1495282199Sdumbbell        public MethodType asMethodType() { return this; }
1496282199Sdumbbell
1497282199Sdumbbell        public void complete() {
1498282199Sdumbbell            for (List<Type> l = argtypes; l.nonEmpty(); l = l.tail)
1499282199Sdumbbell                l.head.complete();
1500282199Sdumbbell            restype.complete();
1501282199Sdumbbell            recvtype.complete();
1502282199Sdumbbell            for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
1503282199Sdumbbell                l.head.complete();
1504235783Skib        }
1505282199Sdumbbell
1506235783Skib        @DefinedBy(Api.LANGUAGE_MODEL)
1507235783Skib        public List<TypeVar> getTypeVariables() {
1508282199Sdumbbell            return List.nil();
1509235783Skib        }
1510282199Sdumbbell
1511282199Sdumbbell        public TypeSymbol asElement() {
1512282199Sdumbbell            return null;
1513282199Sdumbbell        }
1514282199Sdumbbell
1515282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
1516235783Skib        public TypeKind getKind() {
1517235783Skib            return TypeKind.EXECUTABLE;
1518282199Sdumbbell        }
1519282199Sdumbbell
1520282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
1521282199Sdumbbell        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1522235783Skib            return v.visitExecutable(this, p);
1523282199Sdumbbell        }
1524282199Sdumbbell    }
1525282199Sdumbbell
1526282199Sdumbbell    public static class PackageType extends Type implements NoType {
1527235783Skib
1528282199Sdumbbell        PackageType(PackageSymbol tsym) {
1529282199Sdumbbell            // Package types cannot be annotated
1530235783Skib            super(tsym, TypeMetadata.EMPTY);
1531235783Skib        }
1532235783Skib
1533235783Skib        @Override
1534282199Sdumbbell        public PackageType cloneWithMetadata(TypeMetadata md) {
1535282199Sdumbbell            throw new AssertionError("Cannot add metadata to a package type");
1536282199Sdumbbell        }
1537282199Sdumbbell
1538282199Sdumbbell        @Override
1539282199Sdumbbell        public TypeTag getTag() {
1540282199Sdumbbell            return PACKAGE;
1541282199Sdumbbell        }
1542282199Sdumbbell
1543282199Sdumbbell        @Override
1544282199Sdumbbell        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1545282199Sdumbbell            return v.visitPackageType(this, s);
1546282199Sdumbbell        }
1547282199Sdumbbell
1548235783Skib        @DefinedBy(Api.LANGUAGE_MODEL)
1549282199Sdumbbell        public String toString() {
1550235783Skib            return tsym.getQualifiedName().toString();
1551235783Skib        }
1552235783Skib
1553282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
1554235783Skib        public TypeKind getKind() {
1555282199Sdumbbell            return TypeKind.PACKAGE;
1556282199Sdumbbell        }
1557282199Sdumbbell
1558282199Sdumbbell        @DefinedBy(Api.LANGUAGE_MODEL)
1559282199Sdumbbell        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1560282199Sdumbbell            return v.visitNoType(this, p);
1561235783Skib        }
1562235783Skib    }
1563282199Sdumbbell
1564282199Sdumbbell    public static class ModuleType extends Type implements NoType {
1565235783Skib
1566235783Skib        ModuleType(ModuleSymbol tsym) {
1567282199Sdumbbell            // Module types cannot be annotated
1568282199Sdumbbell            super(tsym, TypeMetadata.EMPTY);
1569235783Skib        }
1570235783Skib
1571235783Skib        @Override
1572235783Skib        public ModuleType cloneWithMetadata(TypeMetadata md) {
1573282199Sdumbbell            throw new AssertionError("Cannot add metadata to a module type");
1574282199Sdumbbell        }
1575235783Skib
1576235783Skib        @Override
1577235783Skib        public ModuleType annotatedType(List<Attribute.TypeCompound> annos) {
1578235783Skib            throw new AssertionError("Cannot annotate a module type");
1579282199Sdumbbell        }
1580235783Skib
1581235783Skib        @Override
1582282199Sdumbbell        public TypeTag getTag() {
1583282199Sdumbbell            return TypeTag.MODULE;
1584282199Sdumbbell        }
1585282199Sdumbbell
1586282199Sdumbbell        @Override
1587282199Sdumbbell        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1588282199Sdumbbell            return v.visitModuleType(this, s);
1589282199Sdumbbell        }
1590282199Sdumbbell
1591282199Sdumbbell        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1592282199Sdumbbell        public String toString() {
1593282199Sdumbbell            return tsym.getQualifiedName().toString();
1594282199Sdumbbell        }
1595282199Sdumbbell
1596282199Sdumbbell        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1597282199Sdumbbell        public TypeKind getKind() {
1598235783Skib            return TypeKind.MODULE;
1599282199Sdumbbell        }
1600235783Skib
1601235783Skib        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1602282199Sdumbbell        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1603235783Skib            return v.visitNoType(this, p);
1604235783Skib        }
1605235783Skib    }
1606235783Skib
1607235783Skib    public static class TypeVar extends Type implements TypeVariable {
1608282199Sdumbbell
1609282199Sdumbbell        /** The upper bound of this type variable; set from outside.
1610235783Skib         *  Must be nonempty once it is set.
1611282199Sdumbbell         *  For a bound, `bound' is the bound type itself.
1612282199Sdumbbell         *  Multiple bounds are expressed as a single class type which has the
1613235783Skib         *  individual bounds as superclass, respectively interfaces.
1614282199Sdumbbell         *  The class type then has as `tsym' a compiler generated class `c',
1615282199Sdumbbell         *  which has a flag COMPOUND and whose owner is the type variable
1616282199Sdumbbell         *  itself. Furthermore, the erasure_field of the class
1617282199Sdumbbell         *  points to the first class or interface bound.
1618235783Skib         */
1619282199Sdumbbell        public Type bound = null;
1620282199Sdumbbell
1621235783Skib        /** The lower bound of this type variable.
1622282199Sdumbbell         *  TypeVars don't normally have a lower bound, so it is normally set
1623235783Skib         *  to syms.botType.
1624282199Sdumbbell         *  Subtypes, such as CapturedType, may provide a different value.
1625282199Sdumbbell         */
1626282199Sdumbbell        public Type lower;
1627282199Sdumbbell
1628282199Sdumbbell        public TypeVar(Name name, Symbol owner, Type lower) {
1629282199Sdumbbell            super(null, TypeMetadata.EMPTY);
1630282199Sdumbbell            tsym = new TypeVariableSymbol(0, name, this, owner);
1631282199Sdumbbell            this.bound = null;
1632235783Skib            this.lower = lower;
1633282199Sdumbbell        }
1634282199Sdumbbell
1635282199Sdumbbell        public TypeVar(TypeSymbol tsym, Type bound, Type lower) {
1636282199Sdumbbell            this(tsym, bound, lower, TypeMetadata.EMPTY);
1637282199Sdumbbell        }
1638282199Sdumbbell
1639282199Sdumbbell        public TypeVar(TypeSymbol tsym, Type bound, Type lower,
1640282199Sdumbbell                       TypeMetadata metadata) {
1641282199Sdumbbell            super(tsym, metadata);
1642282199Sdumbbell            this.bound = bound;
1643282199Sdumbbell            this.lower = lower;
1644282199Sdumbbell        }
1645282199Sdumbbell
1646235783Skib        @Override
1647282199Sdumbbell        public TypeVar cloneWithMetadata(TypeMetadata md) {
1648282199Sdumbbell            return new TypeVar(tsym, bound, lower, md) {
1649282199Sdumbbell                @Override
1650235783Skib                public Type baseType() { return TypeVar.this.baseType(); }
1651235783Skib            };
1652282199Sdumbbell        }
1653282199Sdumbbell
1654282199Sdumbbell        @Override
1655282199Sdumbbell        public TypeTag getTag() {
1656282199Sdumbbell            return TYPEVAR;
1657282199Sdumbbell        }
1658282199Sdumbbell
1659282199Sdumbbell        @Override
1660282199Sdumbbell        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1661282199Sdumbbell            return v.visitTypeVar(this, s);
1662282199Sdumbbell        }
1663282199Sdumbbell
1664282199Sdumbbell        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1665282199Sdumbbell        public Type getUpperBound() {
1666282199Sdumbbell            if ((bound == null || bound.hasTag(NONE)) && this != tsym.type) {
1667282199Sdumbbell                bound = tsym.type.getUpperBound();
1668282199Sdumbbell            }
1669282199Sdumbbell            return bound;
1670282199Sdumbbell        }
1671282199Sdumbbell
1672282199Sdumbbell        int rank_field = -1;
1673282199Sdumbbell
1674282199Sdumbbell        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1675282199Sdumbbell        public Type getLowerBound() {
1676282199Sdumbbell            return lower;
1677282199Sdumbbell        }
1678235783Skib
1679235783Skib        @DefinedBy(Api.LANGUAGE_MODEL)
1680282199Sdumbbell        public TypeKind getKind() {
1681235783Skib            return TypeKind.TYPEVAR;
1682235783Skib        }
1683235783Skib
1684235783Skib        public boolean isCaptured() {
1685235783Skib            return false;
1686235783Skib        }
1687282199Sdumbbell
1688282199Sdumbbell        @Override
1689282199Sdumbbell        public boolean isReference() {
1690282199Sdumbbell            return true;
1691282199Sdumbbell        }
1692282199Sdumbbell
1693282199Sdumbbell        @Override
1694282199Sdumbbell        public boolean isNullOrReference() {
1695235783Skib            return true;
1696235783Skib        }
1697235783Skib
1698235783Skib        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1699282199Sdumbbell        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1700235783Skib            return v.visitTypeVariable(this, p);
1701282199Sdumbbell        }
1702235783Skib    }
1703282199Sdumbbell
1704235783Skib    /** A captured type variable comes from wildcards which can have
1705235783Skib     *  both upper and lower bound.  CapturedType extends TypeVar with
1706235783Skib     *  a lower bound.
1707235783Skib     */
1708282199Sdumbbell    public static class CapturedType extends TypeVar {
1709
1710        public WildcardType wildcard;
1711
1712        public CapturedType(Name name,
1713                            Symbol owner,
1714                            Type upper,
1715                            Type lower,
1716                            WildcardType wildcard) {
1717            super(name, owner, lower);
1718            this.lower = Assert.checkNonNull(lower);
1719            this.bound = upper;
1720            this.wildcard = wildcard;
1721        }
1722
1723        public CapturedType(TypeSymbol tsym,
1724                            Type bound,
1725                            Type upper,
1726                            Type lower,
1727                            WildcardType wildcard,
1728                            TypeMetadata metadata) {
1729            super(tsym, bound, lower, metadata);
1730            this.wildcard = wildcard;
1731        }
1732
1733        @Override
1734        public CapturedType cloneWithMetadata(TypeMetadata md) {
1735            return new CapturedType(tsym, bound, bound, lower, wildcard, md) {
1736                @Override
1737                public Type baseType() { return CapturedType.this.baseType(); }
1738            };
1739        }
1740
1741        @Override
1742        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1743            return v.visitCapturedType(this, s);
1744        }
1745
1746        @Override
1747        public boolean isCaptured() {
1748            return true;
1749        }
1750
1751        @Override @DefinedBy(Api.LANGUAGE_MODEL)
1752        public String toString() {
1753            StringBuilder sb = new StringBuilder();
1754            appendAnnotationsString(sb);
1755            sb.append("capture#");
1756            sb.append((hashCode() & 0xFFFFFFFFL) % Printer.PRIME);
1757            sb.append(" of ");
1758            sb.append(wildcard);
1759            return sb.toString();
1760        }
1761    }
1762
1763    public static abstract class DelegatedType extends Type {
1764        public Type qtype;
1765        public TypeTag tag;
1766
1767        public DelegatedType(TypeTag tag, Type qtype) {
1768            this(tag, qtype, TypeMetadata.EMPTY);
1769        }
1770
1771        public DelegatedType(TypeTag tag, Type qtype,
1772                             TypeMetadata metadata) {
1773            super(qtype.tsym, metadata);
1774            this.tag = tag;
1775            this.qtype = qtype;
1776        }
1777
1778        public TypeTag getTag() { return tag; }
1779        @DefinedBy(Api.LANGUAGE_MODEL)
1780        public String toString() { return qtype.toString(); }
1781        public List<Type> getTypeArguments() { return qtype.getTypeArguments(); }
1782        public Type getEnclosingType() { return qtype.getEnclosingType(); }
1783        public List<Type> getParameterTypes() { return qtype.getParameterTypes(); }
1784        public Type getReturnType() { return qtype.getReturnType(); }
1785        public Type getReceiverType() { return qtype.getReceiverType(); }
1786        public List<Type> getThrownTypes() { return qtype.getThrownTypes(); }
1787        public List<Type> allparams() { return qtype.allparams(); }
1788        public Type getUpperBound() { return qtype.getUpperBound(); }
1789        public boolean isErroneous() { return qtype.isErroneous(); }
1790    }
1791
1792    /**
1793     * The type of a generic method type. It consists of a method type and
1794     * a list of method type-parameters that are used within the method
1795     * type.
1796     */
1797    public static class ForAll extends DelegatedType implements ExecutableType {
1798        public List<Type> tvars;
1799
1800        public ForAll(List<Type> tvars, Type qtype) {
1801            super(FORALL, (MethodType)qtype);
1802            this.tvars = tvars;
1803        }
1804
1805        @Override
1806        public ForAll cloneWithMetadata(TypeMetadata md) {
1807            throw new AssertionError("Cannot add metadata to a forall type");
1808        }
1809
1810        @Override
1811        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1812            return v.visitForAll(this, s);
1813        }
1814
1815        @DefinedBy(Api.LANGUAGE_MODEL)
1816        public String toString() {
1817            StringBuilder sb = new StringBuilder();
1818            appendAnnotationsString(sb);
1819            sb.append('<');
1820            sb.append(tvars);
1821            sb.append('>');
1822            sb.append(qtype);
1823            return sb.toString();
1824        }
1825
1826        public List<Type> getTypeArguments()   { return tvars; }
1827
1828        public boolean isErroneous()  {
1829            return qtype.isErroneous();
1830        }
1831
1832        public boolean contains(Type elem) {
1833            return qtype.contains(elem);
1834        }
1835
1836        public MethodType asMethodType() {
1837            return (MethodType)qtype;
1838        }
1839
1840        public void complete() {
1841            for (List<Type> l = tvars; l.nonEmpty(); l = l.tail) {
1842                ((TypeVar)l.head).bound.complete();
1843            }
1844            qtype.complete();
1845        }
1846
1847        @DefinedBy(Api.LANGUAGE_MODEL)
1848        public List<TypeVar> getTypeVariables() {
1849            return List.convert(TypeVar.class, getTypeArguments());
1850        }
1851
1852        @DefinedBy(Api.LANGUAGE_MODEL)
1853        public TypeKind getKind() {
1854            return TypeKind.EXECUTABLE;
1855        }
1856
1857        @DefinedBy(Api.LANGUAGE_MODEL)
1858        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1859            return v.visitExecutable(this, p);
1860        }
1861    }
1862
1863    /** A class for inference variables, for use during method/diamond type
1864     *  inference. An inference variable has upper/lower bounds and a set
1865     *  of equality constraints. Such bounds are set during subtyping, type-containment,
1866     *  type-equality checks, when the types being tested contain inference variables.
1867     *  A change listener can be attached to an inference variable, to receive notifications
1868     *  whenever the bounds of an inference variable change.
1869     */
1870    public static class UndetVar extends DelegatedType {
1871
1872        enum Kind {
1873            NORMAL,
1874            CAPTURED,
1875            THROWS;
1876        }
1877
1878        /** Inference variable change listener. The listener method is called
1879         *  whenever a change to the inference variable's bounds occurs
1880         */
1881        public interface UndetVarListener {
1882            /** called when some inference variable bounds (of given kinds ibs) change */
1883            void varBoundChanged(UndetVar uv, InferenceBound ib, Type bound, boolean update);
1884            /** called when the inferred type is set on some inference variable */
1885            default void varInstantiated(UndetVar uv) { Assert.error(); }
1886        }
1887
1888        /**
1889         * Inference variable bound kinds
1890         */
1891        public enum InferenceBound {
1892            /** lower bounds */
1893            LOWER {
1894                public InferenceBound complement() { return UPPER; }
1895            },
1896            /** equality constraints */
1897            EQ {
1898                public InferenceBound complement() { return EQ; }
1899            },
1900            /** upper bounds */
1901            UPPER {
1902                public InferenceBound complement() { return LOWER; }
1903            };
1904
1905            public abstract InferenceBound complement();
1906
1907            public boolean lessThan(InferenceBound that) {
1908                if (that == this) {
1909                    return false;
1910                } else {
1911                    switch (that) {
1912                        case UPPER: return true;
1913                        case LOWER: return false;
1914                        case EQ: return (this != UPPER);
1915                        default:
1916                            Assert.error("Cannot get here!");
1917                            return false;
1918                    }
1919                }
1920            }
1921        }
1922
1923        /** list of incorporation actions (used by the incorporation engine). */
1924        public ArrayDeque<IncorporationAction> incorporationActions = new ArrayDeque<>();
1925
1926        /** inference variable bounds */
1927        protected Map<InferenceBound, List<Type>> bounds;
1928
1929        /** inference variable's inferred type (set from Infer.java) */
1930        private Type inst = null;
1931
1932        /** number of declared (upper) bounds */
1933        public int declaredCount;
1934
1935        /** inference variable's change listener */
1936        public UndetVarListener listener = null;
1937
1938        Kind kind;
1939
1940        @Override
1941        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1942            return v.visitUndetVar(this, s);
1943        }
1944
1945        public UndetVar(TypeVar origin, UndetVarListener listener, Types types) {
1946            // This is a synthesized internal type, so we cannot annotate it.
1947            super(UNDETVAR, origin);
1948            this.kind = origin.isCaptured() ?
1949                    Kind.CAPTURED :
1950                    Kind.NORMAL;
1951            this.listener = listener;
1952            bounds = new EnumMap<>(InferenceBound.class);
1953            List<Type> declaredBounds = types.getBounds(origin);
1954            declaredCount = declaredBounds.length();
1955            bounds.put(InferenceBound.UPPER, List.nil());
1956            bounds.put(InferenceBound.LOWER, List.nil());
1957            bounds.put(InferenceBound.EQ, List.nil());
1958            for (Type t : declaredBounds.reverse()) {
1959                //add bound works in reverse order
1960                addBound(InferenceBound.UPPER, t, types, true);
1961            }
1962            if (origin.isCaptured() && !origin.lower.hasTag(BOT)) {
1963                //add lower bound if needed
1964                addBound(InferenceBound.LOWER, origin.lower, types, true);
1965            }
1966        }
1967
1968        @DefinedBy(Api.LANGUAGE_MODEL)
1969        public String toString() {
1970            StringBuilder sb = new StringBuilder();
1971            appendAnnotationsString(sb);
1972            if (inst == null) {
1973                sb.append(qtype);
1974                sb.append('?');
1975            } else {
1976                sb.append(inst);
1977            }
1978            return sb.toString();
1979        }
1980
1981        public String debugString() {
1982            String result = "inference var = " + qtype + "\n";
1983            if (inst != null) {
1984                result += "inst = " + inst + '\n';
1985            }
1986            for (InferenceBound bound: InferenceBound.values()) {
1987                List<Type> aboundList = bounds.get(bound);
1988                if (aboundList.size() > 0) {
1989                    result += bound + " = " + aboundList + '\n';
1990                }
1991            }
1992            return result;
1993        }
1994
1995        public void setThrow() {
1996            if (this.kind == Kind.CAPTURED) {
1997                //invalid state transition
1998                throw new IllegalStateException();
1999            }
2000            this.kind = Kind.THROWS;
2001        }
2002
2003        /**
2004         * Returns a new copy of this undet var.
2005         */
2006        public UndetVar dup(Types types) {
2007            UndetVar uv2 = new UndetVar((TypeVar)qtype, listener, types);
2008            dupTo(uv2, types);
2009            return uv2;
2010        }
2011
2012        /**
2013         * Dumps the contents of this undet var on another undet var.
2014         */
2015        public void dupTo(UndetVar uv2, Types types) {
2016            uv2.listener = null;
2017            uv2.bounds.clear();
2018            for (InferenceBound ib : InferenceBound.values()) {
2019                uv2.bounds.put(ib, List.nil());
2020                for (Type t : getBounds(ib)) {
2021                    uv2.addBound(ib, t, types, true);
2022                }
2023            }
2024            uv2.inst = inst;
2025            uv2.listener = listener;
2026            uv2.incorporationActions = new ArrayDeque<>();
2027            for (IncorporationAction action : incorporationActions) {
2028                uv2.incorporationActions.add(action.dup(uv2));
2029            }
2030        }
2031
2032        @Override
2033        public UndetVar cloneWithMetadata(TypeMetadata md) {
2034            throw new AssertionError("Cannot add metadata to an UndetVar type");
2035        }
2036
2037        @Override
2038        public boolean isPartial() {
2039            return true;
2040        }
2041
2042        @Override
2043        public Type baseType() {
2044            return (inst == null) ? this : inst.baseType();
2045        }
2046
2047        public Type getInst() {
2048            return inst;
2049        }
2050
2051        public void setInst(Type inst) {
2052            this.inst = inst;
2053            if (listener != null) {
2054                listener.varInstantiated(this);
2055            }
2056        }
2057
2058        /** get all bounds of a given kind */
2059        public List<Type> getBounds(InferenceBound... ibs) {
2060            ListBuffer<Type> buf = new ListBuffer<>();
2061            for (InferenceBound ib : ibs) {
2062                buf.appendList(bounds.get(ib));
2063            }
2064            return buf.toList();
2065        }
2066
2067        /** get the list of declared (upper) bounds */
2068        public List<Type> getDeclaredBounds() {
2069            ListBuffer<Type> buf = new ListBuffer<>();
2070            int count = 0;
2071            for (Type b : getBounds(InferenceBound.UPPER)) {
2072                if (count++ == declaredCount) break;
2073                buf.append(b);
2074            }
2075            return buf.toList();
2076        }
2077
2078        /** internal method used to override an undetvar bounds */
2079        public void setBounds(InferenceBound ib, List<Type> newBounds) {
2080            bounds.put(ib, newBounds);
2081        }
2082
2083        /** add a bound of a given kind - this might trigger listener notification */
2084        public final void addBound(InferenceBound ib, Type bound, Types types) {
2085            // Per JDK-8075793: in pre-8 sources, follow legacy javac behavior
2086            // when capture variables are inferred as bounds: for lower bounds,
2087            // map to the capture variable's upper bound; for upper bounds,
2088            // if the capture variable has a lower bound, map to that type
2089            if (types.mapCapturesToBounds) {
2090                switch (ib) {
2091                    case LOWER:
2092                        bound = types.cvarUpperBound(bound);
2093                        break;
2094                    case UPPER:
2095                        Type altBound = types.cvarLowerBound(bound);
2096                        if (!altBound.hasTag(TypeTag.BOT)) bound = altBound;
2097                        break;
2098                }
2099            }
2100            addBound(ib, bound, types, false);
2101        }
2102
2103        @SuppressWarnings("fallthrough")
2104        private void addBound(InferenceBound ib, Type bound, Types types, boolean update) {
2105            if (kind == Kind.CAPTURED && !update) {
2106                //Captured inference variables bounds must not be updated during incorporation,
2107                //except when some inference variable (beta) has been instantiated in the
2108                //right-hand-side of a 'C<alpha> = capture(C<? extends/super beta>) constraint.
2109                if (bound.hasTag(UNDETVAR) && !((UndetVar)bound).isCaptured()) {
2110                    //If the new incoming bound is itself a (regular) inference variable,
2111                    //then we are allowed to propagate this inference variable bounds to it.
2112                    ((UndetVar)bound).addBound(ib.complement(), this, types, false);
2113                }
2114            } else {
2115                Type bound2 = bound.map(toTypeVarMap).baseType();
2116                List<Type> prevBounds = bounds.get(ib);
2117                if (bound == qtype) return;
2118                for (Type b : prevBounds) {
2119                    //check for redundancy - use strict version of isSameType on tvars
2120                    //(as the standard version will lead to false positives w.r.t. clones ivars)
2121                    if (types.isSameType(b, bound2, true)) return;
2122                }
2123                bounds.put(ib, prevBounds.prepend(bound2));
2124                notifyBoundChange(ib, bound2, false);
2125            }
2126        }
2127        //where
2128            TypeMapping<Void> toTypeVarMap = new TypeMapping<Void>() {
2129                @Override
2130                public Type visitUndetVar(UndetVar uv, Void _unused) {
2131                    return uv.inst != null ? uv.inst : uv.qtype;
2132                }
2133            };
2134
2135        /** replace types in all bounds - this might trigger listener notification */
2136        public void substBounds(List<Type> from, List<Type> to, Types types) {
2137            final ListBuffer<Pair<InferenceBound, Type>>  boundsChanged = new ListBuffer<>();
2138            UndetVarListener prevListener = listener;
2139            try {
2140                //setup new listener for keeping track of changed bounds
2141                listener = new UndetVarListener() {
2142                    public void varBoundChanged(UndetVar uv, InferenceBound ib, Type t, boolean _ignored) {
2143                        Assert.check(uv == UndetVar.this);
2144                        boundsChanged.add(new Pair<>(ib, t));
2145                    }
2146                };
2147                for (Map.Entry<InferenceBound, List<Type>> _entry : bounds.entrySet()) {
2148                    InferenceBound ib = _entry.getKey();
2149                    List<Type> prevBounds = _entry.getValue();
2150                    ListBuffer<Type> newBounds = new ListBuffer<>();
2151                    ListBuffer<Type> deps = new ListBuffer<>();
2152                    //step 1 - re-add bounds that are not dependent on ivars
2153                    for (Type t : prevBounds) {
2154                        if (!t.containsAny(from)) {
2155                            newBounds.append(t);
2156                        } else {
2157                            deps.append(t);
2158                        }
2159                    }
2160                    //step 2 - replace bounds
2161                    bounds.put(ib, newBounds.toList());
2162                    //step 3 - for each dependency, add new replaced bound
2163                    for (Type dep : deps) {
2164                        addBound(ib, types.subst(dep, from, to), types, true);
2165                    }
2166                }
2167            } finally {
2168                listener = prevListener;
2169                for (Pair<InferenceBound, Type> boundUpdate : boundsChanged) {
2170                    notifyBoundChange(boundUpdate.fst, boundUpdate.snd, true);
2171                }
2172            }
2173        }
2174
2175        private void notifyBoundChange(InferenceBound ib, Type bound, boolean update) {
2176            if (listener != null) {
2177                listener.varBoundChanged(this, ib, bound, update);
2178            }
2179        }
2180
2181        public final boolean isCaptured() {
2182            return kind == Kind.CAPTURED;
2183        }
2184
2185        public final boolean isThrows() {
2186            return kind == Kind.THROWS;
2187        }
2188    }
2189
2190    /** Represents NONE.
2191     */
2192    public static class JCNoType extends Type implements NoType {
2193        public JCNoType() {
2194            // Need to use List.nil(), because JCNoType constructor
2195            // gets called in static initializers in Type, where
2196            // noAnnotations is also defined.
2197            super(null, TypeMetadata.EMPTY);
2198        }
2199
2200        @Override
2201        public JCNoType cloneWithMetadata(TypeMetadata md) {
2202            throw new AssertionError("Cannot add metadata to a JCNoType");
2203        }
2204
2205        @Override
2206        public TypeTag getTag() {
2207            return NONE;
2208        }
2209
2210        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2211        public TypeKind getKind() {
2212            return TypeKind.NONE;
2213        }
2214
2215        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2216        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2217            return v.visitNoType(this, p);
2218        }
2219
2220        @Override
2221        public boolean isCompound() { return false; }
2222    }
2223
2224    /** Represents VOID.
2225     */
2226    public static class JCVoidType extends Type implements NoType {
2227
2228        public JCVoidType() {
2229            // Void cannot be annotated
2230            super(null, TypeMetadata.EMPTY);
2231        }
2232
2233        @Override
2234        public JCVoidType cloneWithMetadata(TypeMetadata md) {
2235            throw new AssertionError("Cannot add metadata to a void type");
2236        }
2237
2238        @Override
2239        public TypeTag getTag() {
2240            return VOID;
2241        }
2242
2243        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2244        public TypeKind getKind() {
2245            return TypeKind.VOID;
2246        }
2247
2248        @Override
2249        public boolean isCompound() { return false; }
2250
2251        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2252        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2253            return v.visitNoType(this, p);
2254        }
2255
2256        @Override
2257        public boolean isPrimitiveOrVoid() {
2258            return true;
2259        }
2260    }
2261
2262    static class BottomType extends Type implements NullType {
2263        public BottomType() {
2264            // Bottom is a synthesized internal type, so it cannot be annotated
2265            super(null, TypeMetadata.EMPTY);
2266        }
2267
2268        @Override
2269        public BottomType cloneWithMetadata(TypeMetadata md) {
2270            throw new AssertionError("Cannot add metadata to a bottom type");
2271        }
2272
2273        @Override
2274        public TypeTag getTag() {
2275            return BOT;
2276        }
2277
2278        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2279        public TypeKind getKind() {
2280            return TypeKind.NULL;
2281        }
2282
2283        @Override
2284        public boolean isCompound() { return false; }
2285
2286        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2287        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2288            return v.visitNull(this, p);
2289        }
2290
2291        @Override
2292        public Type constType(Object value) {
2293            return this;
2294        }
2295
2296        @Override
2297        public String stringValue() {
2298            return "null";
2299        }
2300
2301        @Override
2302        public boolean isNullOrReference() {
2303            return true;
2304        }
2305
2306    }
2307
2308    public static class ErrorType extends ClassType
2309            implements javax.lang.model.type.ErrorType {
2310
2311        private Type originalType = null;
2312
2313        public ErrorType(ClassSymbol c, Type originalType) {
2314            this(originalType, c);
2315            c.type = this;
2316            c.kind = ERR;
2317            c.members_field = new Scope.ErrorScope(c);
2318        }
2319
2320        public ErrorType(Type originalType, TypeSymbol tsym) {
2321            super(noType, List.<Type>nil(), null);
2322            this.tsym = tsym;
2323            this.originalType = (originalType == null ? noType : originalType);
2324        }
2325
2326        private ErrorType(Type originalType, TypeSymbol tsym,
2327                          TypeMetadata metadata) {
2328            super(noType, List.<Type>nil(), null, metadata);
2329            this.tsym = tsym;
2330            this.originalType = (originalType == null ? noType : originalType);
2331        }
2332
2333        @Override
2334        public ErrorType cloneWithMetadata(TypeMetadata md) {
2335            return new ErrorType(originalType, tsym, md) {
2336                @Override
2337                public Type baseType() { return ErrorType.this.baseType(); }
2338            };
2339        }
2340
2341        @Override
2342        public TypeTag getTag() {
2343            return ERROR;
2344        }
2345
2346        @Override
2347        public boolean isPartial() {
2348            return true;
2349        }
2350
2351        @Override
2352        public boolean isReference() {
2353            return true;
2354        }
2355
2356        @Override
2357        public boolean isNullOrReference() {
2358            return true;
2359        }
2360
2361        public ErrorType(Name name, TypeSymbol container, Type originalType) {
2362            this(new ClassSymbol(PUBLIC|STATIC|ACYCLIC, name, null, container), originalType);
2363        }
2364
2365        @Override
2366        public <R,S> R accept(Type.Visitor<R,S> v, S s) {
2367            return v.visitErrorType(this, s);
2368        }
2369
2370        public Type constType(Object constValue) { return this; }
2371        @DefinedBy(Api.LANGUAGE_MODEL)
2372        public Type getEnclosingType()           { return this; }
2373        public Type getReturnType()              { return this; }
2374        public Type asSub(Symbol sym)            { return this; }
2375
2376        public boolean isGenType(Type t)         { return true; }
2377        public boolean isErroneous()             { return true; }
2378        public boolean isCompound()              { return false; }
2379        public boolean isInterface()             { return false; }
2380
2381        public List<Type> allparams()            { return List.nil(); }
2382        @DefinedBy(Api.LANGUAGE_MODEL)
2383        public List<Type> getTypeArguments()     { return List.nil(); }
2384
2385        @DefinedBy(Api.LANGUAGE_MODEL)
2386        public TypeKind getKind() {
2387            return TypeKind.ERROR;
2388        }
2389
2390        public Type getOriginalType() {
2391            return originalType;
2392        }
2393
2394        @DefinedBy(Api.LANGUAGE_MODEL)
2395        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2396            return v.visitError(this, p);
2397        }
2398    }
2399
2400    public static class UnknownType extends Type {
2401
2402        public UnknownType() {
2403            // Unknown is a synthesized internal type, so it cannot be
2404            // annotated.
2405            super(null, TypeMetadata.EMPTY);
2406        }
2407
2408        @Override
2409        public UnknownType cloneWithMetadata(TypeMetadata md) {
2410            throw new AssertionError("Cannot add metadata to an unknown type");
2411        }
2412
2413        @Override
2414        public TypeTag getTag() {
2415            return UNKNOWN;
2416        }
2417
2418        @Override @DefinedBy(Api.LANGUAGE_MODEL)
2419        public <R, P> R accept(TypeVisitor<R, P> v, P p) {
2420            return v.visitUnknown(this, p);
2421        }
2422
2423        @Override
2424        public boolean isPartial() {
2425            return true;
2426        }
2427    }
2428
2429    /**
2430     * A visitor for types.  A visitor is used to implement operations
2431     * (or relations) on types.  Most common operations on types are
2432     * binary relations and this interface is designed for binary
2433     * relations, that is, operations of the form
2434     * Type&nbsp;&times;&nbsp;S&nbsp;&rarr;&nbsp;R.
2435     * <!-- In plain text: Type x S -> R -->
2436     *
2437     * @param <R> the return type of the operation implemented by this
2438     * visitor; use Void if no return type is needed.
2439     * @param <S> the type of the second argument (the first being the
2440     * type itself) of the operation implemented by this visitor; use
2441     * Void if a second argument is not needed.
2442     */
2443    public interface Visitor<R,S> {
2444        R visitClassType(ClassType t, S s);
2445        R visitWildcardType(WildcardType t, S s);
2446        R visitArrayType(ArrayType t, S s);
2447        R visitMethodType(MethodType t, S s);
2448        R visitPackageType(PackageType t, S s);
2449        R visitModuleType(ModuleType t, S s);
2450        R visitTypeVar(TypeVar t, S s);
2451        R visitCapturedType(CapturedType t, S s);
2452        R visitForAll(ForAll t, S s);
2453        R visitUndetVar(UndetVar t, S s);
2454        R visitErrorType(ErrorType t, S s);
2455        R visitType(Type t, S s);
2456    }
2457}
2458