< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java

Print this page

  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.code;
  27 
  28 import java.lang.annotation.Annotation;
  29 import java.util.ArrayDeque;
  30 import java.util.Collections;
  31 import java.util.EnumMap;
  32 import java.util.Map;
  33 import java.util.function.Predicate;
  34 
  35 import javax.lang.model.type.*;
  36 
  37 import com.sun.tools.javac.code.Symbol.*;

  38 import com.sun.tools.javac.code.TypeMetadata.Entry;
  39 import com.sun.tools.javac.code.Types.TypeMapping;
  40 import com.sun.tools.javac.code.Types.UniqueType;
  41 import com.sun.tools.javac.comp.Infer.IncorporationAction;
  42 import com.sun.tools.javac.jvm.ClassFile;
  43 import com.sun.tools.javac.jvm.PoolConstant;
  44 import com.sun.tools.javac.util.*;
  45 import com.sun.tools.javac.util.DefinedBy.Api;
  46 
  47 import static com.sun.tools.javac.code.BoundKind.*;
  48 import static com.sun.tools.javac.code.Flags.*;
  49 import static com.sun.tools.javac.code.Kinds.Kind.*;
  50 import static com.sun.tools.javac.code.TypeTag.*;
  51 
  52 /** This class represents Java types. The class itself defines the behavior of
  53  *  the following types:
  54  *  <pre>
  55  *  base types (tags: BYTE, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, BOOLEAN),
  56  *  type `void' (tag: VOID),
  57  *  the bottom type (tag: BOT),

 219         return lb.toList();
 220     }
 221 
 222     /**For ErrorType, returns the original type, otherwise returns the type itself.
 223      */
 224     public Type getOriginalType() {
 225         return this;
 226     }
 227 
 228     public <R,S> R accept(Type.Visitor<R,S> v, S s) { return v.visitType(this, s); }
 229 
 230     /** Define a type given its tag, type symbol, and type annotations
 231      */
 232 
 233     public Type(TypeSymbol tsym, TypeMetadata metadata) {
 234         Assert.checkNonNull(metadata);
 235         this.tsym = tsym;
 236         this.metadata = metadata;
 237     }
 238 




























































 239     /**
 240      * A subclass of {@link Types.TypeMapping} which applies a mapping recursively to the subterms
 241      * of a given type expression. This mapping returns the original type is no changes occurred
 242      * when recursively mapping the original type's subterms.
 243      */
 244     public static abstract class StructuralTypeMapping<S> extends Types.TypeMapping<S> {
 245 
 246         @Override
 247         public Type visitClassType(ClassType t, S s) {
 248             Type outer = t.getEnclosingType();
 249             Type outer1 = visit(outer, s);
 250             List<Type> typarams = t.getTypeArguments();
 251             List<Type> typarams1 = visit(typarams, s);
 252             if (outer1 == outer && typarams1 == typarams) return t;
 253             else return new ClassType(outer1, typarams1, t.tsym, t.metadata) {
 254                 @Override
 255                 protected boolean needsStripping() {
 256                     return true;
 257                 }
 258             };
 259         }
 260 
 261         @Override
 262         public Type visitWildcardType(WildcardType wt, S s) {
 263             Type t = wt.type;
 264             if (t != null)
 265                 t = visit(t, s);
 266             if (t == wt.type)
 267                 return wt;
 268             else
 269                 return new WildcardType(t, wt.kind, wt.tsym, wt.bound, wt.metadata) {
 270                     @Override
 271                     protected boolean needsStripping() {
 272                         return true;
 273                     }

 929 
 930         @DefinedBy(Api.LANGUAGE_MODEL)
 931         public Type getSuperBound() {
 932             if (kind == SUPER)
 933                 return type;
 934             else
 935                 return null;
 936         }
 937 
 938         @DefinedBy(Api.LANGUAGE_MODEL)
 939         public TypeKind getKind() {
 940             return TypeKind.WILDCARD;
 941         }
 942 
 943         @DefinedBy(Api.LANGUAGE_MODEL)
 944         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
 945             return v.visitWildcard(this, p);
 946         }
 947     }
 948 


































 949     public static class ClassType extends Type implements DeclaredType, LoadableConstant,
 950                                                           javax.lang.model.type.ErrorType {
 951 


















































































 952         /** The enclosing type of this type. If this is the type of an inner
 953          *  class, outer_field refers to the type of its enclosing
 954          *  instance class, in all other cases it refers to noType.
 955          */
 956         private Type outer_field;
 957 
 958         /** The type parameters of this type (to be set once class is loaded).
 959          */
 960         public List<Type> typarams_field;
 961 
 962         /** A cache variable for the type parameters of this type,
 963          *  appended to all parameters of its enclosing class.
 964          *  @see #allparams
 965          */
 966         public List<Type> allparams_field;
 967 
 968         /** The supertype of this class (to be set once class is loaded).
 969          */
 970         public Type supertype_field;
 971 
 972         /** The interfaces of this class (to be set once class is loaded).
 973          */
 974         public List<Type> interfaces_field;
 975 
 976         /** All the interfaces of this class, including missing ones.
 977          */
 978         public List<Type> all_interfaces_field;
 979 













 980         public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
 981             this(outer, typarams, tsym, TypeMetadata.EMPTY);
 982         }
 983 
 984         public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym,
 985                          TypeMetadata metadata) {
 986             super(tsym, metadata);
 987             this.outer_field = outer;
 988             this.typarams_field = typarams;
 989             this.allparams_field = null;
 990             this.supertype_field = null;
 991             this.interfaces_field = null;

 992         }
 993 
 994         public int poolTag() {
 995             return ClassFile.CONSTANT_Class;
 996         }
 997 
 998         @Override
 999         public ClassType cloneWithMetadata(TypeMetadata md) {
1000             return new ClassType(outer_field, typarams_field, tsym, md) {
1001                 @Override
1002                 public Type baseType() { return ClassType.this.baseType(); }
1003             };
1004         }
1005 
1006         @Override
1007         public TypeTag getTag() {
1008             return CLASS;
1009         }
1010 
1011         @Override
1012         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1013             return v.visitClassType(this, s);
1014         }
1015 
1016         public Type constType(Object constValue) {
1017             final Object value = constValue;
1018             return new ClassType(getEnclosingType(), typarams_field, tsym, metadata) {
1019                     @Override
1020                     public Object constValue() {
1021                         return value;
1022                     }
1023                     @Override
1024                     public Type baseType() {
1025                         return tsym.type;
1026                     }
1027                 };
1028         }
1029 
1030         /** The Java source which this type represents.
1031          */
1032         @DefinedBy(Api.LANGUAGE_MODEL)
1033         public String toString() {
1034             StringBuilder buf = new StringBuilder();
1035             if (getEnclosingType().hasTag(CLASS) && tsym.owner.kind == TYP) {
1036                 buf.append(getEnclosingType().toString());
1037                 buf.append(".");
1038                 appendAnnotationsString(buf);
1039                 buf.append(className(tsym, false));
1040             } else {
1041                 appendAnnotationsString(buf);
1042                 buf.append(className(tsym, true));
1043             }
1044 










1045             if (getTypeArguments().nonEmpty()) {
1046                 buf.append('<');
1047                 buf.append(getTypeArguments().toString());
1048                 buf.append(">");
1049             }
1050             return buf.toString();
1051         }
1052 //where
1053             private String className(Symbol sym, boolean longform) {
1054                 if (sym.name.isEmpty() && (sym.flags() & COMPOUND) != 0) {
1055                     StringBuilder s = new StringBuilder(supertype_field.toString());
1056                     for (List<Type> is=interfaces_field; is.nonEmpty(); is = is.tail) {
1057                         s.append("&");
1058                         s.append(is.head.toString());
1059                     }
1060                     return s.toString();
1061                 } else if (sym.name.isEmpty()) {
1062                     String s;
1063                     ClassType norm = (ClassType) tsym.type;
1064                     if (norm == null) {
1065                         s = Log.getLocalizedString("anonymous.class", (Object)null);
1066                     } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
1067                         s = Log.getLocalizedString("anonymous.class",
1068                                                    norm.interfaces_field.head);
1069                     } else {
1070                         s = Log.getLocalizedString("anonymous.class",
1071                                                    norm.supertype_field);
1072                     }
1073                     if (moreInfo)
1074                         s += String.valueOf(sym.hashCode());
1075                     return s;
1076                 } else if (longform) {
1077                     return sym.getQualifiedName().toString();


1078                 } else {
1079                     return sym.name.toString();
1080                 }

1081             }
1082 




1083         @DefinedBy(Api.LANGUAGE_MODEL)
1084         public List<Type> getTypeArguments() {
1085             if (typarams_field == null) {
1086                 complete();
1087                 if (typarams_field == null)
1088                     typarams_field = List.nil();
1089             }
1090             return typarams_field;
1091         }
1092 
1093         public boolean hasErasedSupertypes() {
1094             return isRaw();
1095         }
1096 
1097         @DefinedBy(Api.LANGUAGE_MODEL)
1098         public Type getEnclosingType() {



1099             return outer_field;
1100         }
1101 
1102         public void setEnclosingType(Type outer) {
1103             outer_field = outer;
1104         }
1105 
1106         public List<Type> allparams() {
1107             if (allparams_field == null) {
1108                 allparams_field = getTypeArguments().prependList(getEnclosingType().allparams());
1109             }
1110             return allparams_field;
1111         }
1112 
1113         public boolean isErroneous() {
1114             return
1115                 getEnclosingType().isErroneous() ||
1116                 isErroneous(getTypeArguments()) ||
1117                 this != tsym.type && tsym.type.isErroneous();
1118         }
1119 
1120         public boolean isParameterized() {
1121             return allparams().tail != null;
1122             // optimization, was: allparams().nonEmpty();
1123         }
1124 
1125         @Override
1126         public boolean isReference() {
1127             return true;
1128         }
1129 






























































































1130         @Override
1131         public boolean isNullOrReference() {
1132             return true;
1133         }
1134 
1135         /** A cache for the rank. */
1136         int rank_field = -1;
1137 
1138         /** A class type is raw if it misses some
1139          *  of its type parameter sections.
1140          *  After validation, this is equivalent to:
1141          *  {@code allparams.isEmpty() && tsym.type.allparams.nonEmpty(); }
1142          */
1143         public boolean isRaw() {
1144             return
1145                 this != tsym.type && // necessary, but not sufficient condition
1146                 tsym.type.allparams().nonEmpty() &&
1147                 allparams().isEmpty();
1148         }
1149 

1158 
1159         public void complete() {
1160             tsym.complete();
1161         }
1162 
1163         @DefinedBy(Api.LANGUAGE_MODEL)
1164         public TypeKind getKind() {
1165             tsym.apiComplete();
1166             return tsym.kind == TYP ? TypeKind.DECLARED : TypeKind.ERROR;
1167         }
1168 
1169         @DefinedBy(Api.LANGUAGE_MODEL)
1170         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1171             return v.visitDeclared(this, p);
1172         }
1173     }
1174 
1175     public static class ErasedClassType extends ClassType {
1176         public ErasedClassType(Type outer, TypeSymbol tsym,
1177                                TypeMetadata metadata) {
1178             super(outer, List.nil(), tsym, metadata);
1179         }
1180 
1181         @Override
1182         public boolean hasErasedSupertypes() {
1183             return true;
1184         }
1185     }
1186 
1187     // a clone of a ClassType that knows about the alternatives of a union type.
1188     public static class UnionClassType extends ClassType implements UnionType {
1189         final List<? extends Type> alternatives_field;
1190 
1191         public UnionClassType(ClassType ct, List<? extends Type> alternatives) {
1192             // Presently no way to refer to this type directly, so we
1193             // cannot put annotations directly on it.
1194             super(ct.outer_field, ct.typarams_field, ct.tsym);
1195             allparams_field = ct.allparams_field;
1196             supertype_field = ct.supertype_field;
1197             interfaces_field = ct.interfaces_field;
1198             all_interfaces_field = ct.interfaces_field;

2325         @Override
2326         public boolean isNullOrReference() {
2327             return true;
2328         }
2329 
2330     }
2331 
2332     public static class ErrorType extends ClassType
2333             implements javax.lang.model.type.ErrorType {
2334 
2335         private Type originalType = null;
2336 
2337         public ErrorType(ClassSymbol c, Type originalType) {
2338             this(originalType, c);
2339             c.type = this;
2340             c.kind = ERR;
2341             c.members_field = new Scope.ErrorScope(c);
2342         }
2343 
2344         public ErrorType(Type originalType, TypeSymbol tsym) {
2345             super(noType, List.nil(), null);
2346             this.tsym = tsym;
2347             this.originalType = (originalType == null ? noType : originalType);
2348         }
2349 
2350         private ErrorType(Type originalType, TypeSymbol tsym,
2351                           TypeMetadata metadata) {
2352             super(noType, List.nil(), null, metadata);
2353             this.tsym = tsym;
2354             this.originalType = (originalType == null ? noType : originalType);
2355         }
2356 
2357         @Override
2358         public ErrorType cloneWithMetadata(TypeMetadata md) {
2359             return new ErrorType(originalType, tsym, md) {
2360                 @Override
2361                 public Type baseType() { return ErrorType.this.baseType(); }
2362             };
2363         }
2364 
2365         @Override
2366         public TypeTag getTag() {
2367             return ERROR;
2368         }
2369 
2370         @Override
2371         public boolean isPartial() {
2372             return true;
2373         }
2374 
2375         @Override
2376         public boolean isReference() {
2377             return true;
2378         }
2379 

  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.code;
  27 
  28 import java.lang.annotation.Annotation;
  29 import java.util.ArrayDeque;
  30 import java.util.Collections;
  31 import java.util.EnumMap;
  32 import java.util.Map;
  33 import java.util.function.Predicate;
  34 
  35 import javax.lang.model.type.*;
  36 
  37 import com.sun.tools.javac.code.Symbol.*;
  38 import com.sun.tools.javac.code.Type.ClassType.Flavor;
  39 import com.sun.tools.javac.code.TypeMetadata.Entry;
  40 import com.sun.tools.javac.code.Types.TypeMapping;
  41 import com.sun.tools.javac.code.Types.UniqueType;
  42 import com.sun.tools.javac.comp.Infer.IncorporationAction;
  43 import com.sun.tools.javac.jvm.ClassFile;
  44 import com.sun.tools.javac.jvm.PoolConstant;
  45 import com.sun.tools.javac.util.*;
  46 import com.sun.tools.javac.util.DefinedBy.Api;
  47 
  48 import static com.sun.tools.javac.code.BoundKind.*;
  49 import static com.sun.tools.javac.code.Flags.*;
  50 import static com.sun.tools.javac.code.Kinds.Kind.*;
  51 import static com.sun.tools.javac.code.TypeTag.*;
  52 
  53 /** This class represents Java types. The class itself defines the behavior of
  54  *  the following types:
  55  *  <pre>
  56  *  base types (tags: BYTE, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, BOOLEAN),
  57  *  type `void' (tag: VOID),
  58  *  the bottom type (tag: BOT),

 220         return lb.toList();
 221     }
 222 
 223     /**For ErrorType, returns the original type, otherwise returns the type itself.
 224      */
 225     public Type getOriginalType() {
 226         return this;
 227     }
 228 
 229     public <R,S> R accept(Type.Visitor<R,S> v, S s) { return v.visitType(this, s); }
 230 
 231     /** Define a type given its tag, type symbol, and type annotations
 232      */
 233 
 234     public Type(TypeSymbol tsym, TypeMetadata metadata) {
 235         Assert.checkNonNull(metadata);
 236         this.tsym = tsym;
 237         this.metadata = metadata;
 238     }
 239 
 240     public boolean isPrimitiveClass() {
 241         return false;
 242     }
 243 
 244     /**
 245      * Return the `flavor' associated with a ClassType.
 246      * @see ClassType.Flavor
 247      */
 248     public Flavor getFlavor() {
 249         throw new AssertionError("Unexpected call to getFlavor() on a Type that is not a ClassType: " + this);
 250     }
 251 
 252     /**
 253      * @return true IFF the receiver is a reference projection type of a *value favoring* primitive class
 254      * and false otherwise.
 255      */
 256     public boolean isReferenceProjection() {
 257         return false;
 258     }
 259 
 260     /**
 261      * @return true IFF the receiver is a primitive reference type and false otherwise.
 262      */
 263     public boolean isPrimitiveReferenceType() {
 264         return false;
 265     }
 266 
 267     /**
 268      * @return true IFF the receiver is a value projection of a *reference favoring* primitive class type
 269      * and false otherwise.
 270      */
 271     public boolean isValueProjection() {
 272         return false;
 273     }
 274 
 275     /**
 276      * Returns the ClassType representing the primitive value type
 277      * of this type, if the class of this type is a primitive class
 278      * null otherwise
 279      */
 280     public ClassType asValueType() {
 281         return null;
 282     }
 283 
 284     /**
 285      * @return the reference projection type IFF the receiver is a primitive class type
 286      * and null otherwise
 287      */
 288     public Type referenceProjection() {
 289         return null;
 290     }
 291 
 292     /**
 293      * @return the reference projection type IFF the receiver is a primitive class type or self otherwise.
 294      */
 295     public Type referenceProjectionOrSelf() {
 296         Type projection = referenceProjection();
 297         return projection != null ? projection : this;
 298     }
 299 
 300     /**
 301      * A subclass of {@link Types.TypeMapping} which applies a mapping recursively to the subterms
 302      * of a given type expression. This mapping returns the original type is no changes occurred
 303      * when recursively mapping the original type's subterms.
 304      */
 305     public static abstract class StructuralTypeMapping<S> extends Types.TypeMapping<S> {
 306 
 307         @Override
 308         public Type visitClassType(ClassType t, S s) {
 309             Type outer = t.getEnclosingType();
 310             Type outer1 = visit(outer, s);
 311             List<Type> typarams = t.getTypeArguments();
 312             List<Type> typarams1 = visit(typarams, s);
 313             if (outer1 == outer && typarams1 == typarams) return t;
 314             else return new ClassType(outer1, typarams1, t.tsym, t.metadata, t.getFlavor()) {
 315                 @Override
 316                 protected boolean needsStripping() {
 317                     return true;
 318                 }
 319             };
 320         }
 321 
 322         @Override
 323         public Type visitWildcardType(WildcardType wt, S s) {
 324             Type t = wt.type;
 325             if (t != null)
 326                 t = visit(t, s);
 327             if (t == wt.type)
 328                 return wt;
 329             else
 330                 return new WildcardType(t, wt.kind, wt.tsym, wt.bound, wt.metadata) {
 331                     @Override
 332                     protected boolean needsStripping() {
 333                         return true;
 334                     }

 990 
 991         @DefinedBy(Api.LANGUAGE_MODEL)
 992         public Type getSuperBound() {
 993             if (kind == SUPER)
 994                 return type;
 995             else
 996                 return null;
 997         }
 998 
 999         @DefinedBy(Api.LANGUAGE_MODEL)
1000         public TypeKind getKind() {
1001             return TypeKind.WILDCARD;
1002         }
1003 
1004         @DefinedBy(Api.LANGUAGE_MODEL)
1005         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1006             return v.visitWildcard(this, p);
1007         }
1008     }
1009 
1010     public static class ConstantPoolQType implements PoolConstant {
1011 
1012         public final Type type;
1013         final Types types;
1014 
1015         public ConstantPoolQType(Type type, Types types) {
1016             this.type = type;
1017             this.types = types;
1018         }
1019 
1020         @Override
1021         public Object poolKey(Types types) {
1022             return this;
1023         }
1024 
1025         @Override
1026         public int poolTag() {
1027             return ClassFile.CONSTANT_Class;
1028         }
1029 
1030         public int hashCode() {
1031             return types.hashCode(type);
1032         }
1033 
1034         public boolean equals(Object obj) {
1035             return (obj instanceof ConstantPoolQType) &&
1036                     types.isSameType(type, ((ConstantPoolQType)obj).type);
1037         }
1038 
1039         public String toString() {
1040             return type.toString();
1041         }
1042     }
1043 
1044     public static class ClassType extends Type implements DeclaredType, LoadableConstant,
1045                                                           javax.lang.model.type.ErrorType {
1046 
1047         /**
1048          * The 'flavor' of a ClassType indicates its reference/primitive projectionness
1049          * viewed against the default nature of the associated class.
1050          */
1051         public enum Flavor {
1052 
1053             /**
1054              * Classic reference type. Also reference projection type of a reference-favoring aka
1055              * reference-default primitive class type
1056              */
1057             L_TypeOf_L,
1058 
1059             /**
1060              * A primitive reference type:  (Assosiated primitive class could be either
1061              * reference default or value-default)
1062              */
1063             L_TypeOf_Q,
1064 
1065             /**
1066              * Value projection type of a primitive-favoring aka primitive-default
1067              * plain vanilla primitive class type,
1068              */
1069             Q_TypeOf_Q,
1070 
1071             /**
1072              * Value projection type of a reference-favoring aka
1073              * reference-default primitive class type
1074              */
1075             Q_TypeOf_L,
1076 
1077             /**
1078              * Reference projection type of a class type of an as yet unknown default provenance, 'X' will be
1079              * discovered to be 'L' or 'Q' in "due course" and mutated suitably.
1080              */
1081             L_TypeOf_X,
1082 
1083             /**
1084              * Value projection type of a class type of an as yet unknown default provenance, 'X' will be
1085              * discovered to be 'L' or 'Q' in "due course" and mutated suitably.
1086              */
1087             Q_TypeOf_X,
1088 
1089             /**
1090              *  As yet unknown projection type of an as yet unknown default provenance class. Is also
1091              *  the terminal flavor for package-info/module-info files.
1092              */
1093             X_Typeof_X,
1094 
1095             /**
1096              *  An error type - we don't care to discriminate them any further.
1097              */
1098              E_Typeof_X;
1099 
1100             // We don't seem to need X_Typeof_L or X_Typeof_Q so far.
1101 
1102             // Transform a larval form into a more evolved form
1103             public Flavor metamorphose(long classFlags) {
1104 
1105                 boolean isPrimtiveClass = (classFlags & PRIMITIVE_CLASS) != 0;
1106                 boolean isReferenceFavoring = (classFlags & REFERENCE_FAVORING) != 0;
1107 
1108                 switch (this) {
1109 
1110                     case E_Typeof_X:  // stunted form
1111                     case L_TypeOf_L:
1112                     case L_TypeOf_Q:
1113                     case Q_TypeOf_L:
1114                     case Q_TypeOf_Q:
1115                             // These are fully evolved sealed forms or stunted - no futher transformation
1116                             return this;
1117                     case L_TypeOf_X:
1118                             return isPrimtiveClass ? L_TypeOf_Q : L_TypeOf_L;
1119                     case Q_TypeOf_X:
1120                             return isReferenceFavoring ? Q_TypeOf_L : Q_TypeOf_Q;
1121                     case X_Typeof_X:
1122                             return isPrimtiveClass ? (isReferenceFavoring ? L_TypeOf_Q : Q_TypeOf_Q) : L_TypeOf_L;
1123                     default:
1124                             throw new AssertionError("Unexpected class type flavor");
1125                 }
1126             }
1127         }
1128 
1129         /** The enclosing type of this type. If this is the type of an inner
1130          *  class, outer_field refers to the type of its enclosing
1131          *  instance class, in all other cases it refers to noType.
1132          */
1133         private Type outer_field;
1134 
1135         /** The type parameters of this type (to be set once class is loaded).
1136          */
1137         public List<Type> typarams_field;
1138 
1139         /** A cache variable for the type parameters of this type,
1140          *  appended to all parameters of its enclosing class.
1141          *  @see #allparams
1142          */
1143         public List<Type> allparams_field;
1144 
1145         /** The supertype of this class (to be set once class is loaded).
1146          */
1147         public Type supertype_field;
1148 
1149         /** The interfaces of this class (to be set once class is loaded).
1150          */
1151         public List<Type> interfaces_field;
1152 
1153         /** All the interfaces of this class, including missing ones.
1154          */
1155         public List<Type> all_interfaces_field;
1156 
1157         /** The 'other' projection: If 'this' is type of a primitive class, then 'projection' is the
1158          *  reference projection type and vice versa. Lazily initialized, not to be accessed directly.
1159         */
1160         public ClassType projection;
1161 
1162         /** Is this L of default {L, Q, X} or Q of default {L, Q, X} ?
1163          */
1164         public Flavor flavor;
1165 
1166         /*
1167          * Use of this constructor is kinda sorta deprecated, use the other constructor
1168          * that forces the call site to consider and include the class type flavor.
1169          */
1170         public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
1171             this(outer, typarams, tsym, TypeMetadata.EMPTY, Flavor.L_TypeOf_L);
1172         }
1173 
1174         public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym,
1175                          TypeMetadata metadata, Flavor flavor) {
1176             super(tsym, metadata);
1177             this.outer_field = outer;
1178             this.typarams_field = typarams;
1179             this.allparams_field = null;
1180             this.supertype_field = null;
1181             this.interfaces_field = null;
1182             this.flavor = flavor;
1183         }
1184 
1185         public int poolTag() {
1186             return ClassFile.CONSTANT_Class;
1187         }
1188 
1189         @Override
1190         public ClassType cloneWithMetadata(TypeMetadata md) {
1191             return new ClassType(outer_field, typarams_field, tsym, md, flavor) {
1192                 @Override
1193                 public Type baseType() { return ClassType.this.baseType(); }
1194             };
1195         }
1196 
1197         @Override
1198         public TypeTag getTag() {
1199             return CLASS;
1200         }
1201 
1202         @Override
1203         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1204             return v.visitClassType(this, s);
1205         }
1206 
1207         public Type constType(Object constValue) {
1208             final Object value = constValue;
1209             return new ClassType(getEnclosingType(), typarams_field, tsym, metadata, flavor) {
1210                     @Override
1211                     public Object constValue() {
1212                         return value;
1213                     }
1214                     @Override
1215                     public Type baseType() {
1216                         return tsym.type;
1217                     }
1218                 };
1219         }
1220 
1221         /** The Java source which this type represents.
1222          */
1223         @DefinedBy(Api.LANGUAGE_MODEL)
1224         public String toString() {
1225             StringBuilder buf = new StringBuilder();
1226             if (getEnclosingType().hasTag(CLASS) && tsym.owner.kind == TYP) {
1227                 buf.append(getEnclosingType().toString());
1228                 buf.append(".");
1229                 appendAnnotationsString(buf);
1230                 buf.append(className(tsym, false));
1231             } else {
1232                 appendAnnotationsString(buf);
1233                 buf.append(className(tsym, true));
1234             }
1235             try {
1236                 if (isReferenceProjection()) {
1237                     buf.append('.');
1238                     buf.append(tsym.name.table.names.ref);
1239                 } else if (isValueProjection()) {
1240                     buf.append('.');
1241                     buf.append(tsym.name.table.names.val);
1242                 }
1243             } catch (CompletionFailure cf) {
1244                 // don't let missing types capsize the boat.
1245             }
1246             if (getTypeArguments().nonEmpty()) {
1247                 buf.append('<');
1248                 buf.append(getTypeArguments().toString());
1249                 buf.append(">");
1250             }
1251             return buf.toString();
1252         }
1253 //where
1254             private String className(Symbol sym, boolean longform) {
1255                 if (sym.name.isEmpty() && (sym.flags() & COMPOUND) != 0) {
1256                     StringBuilder s = new StringBuilder(supertype_field.toString());
1257                     for (List<Type> is=interfaces_field; is.nonEmpty(); is = is.tail) {
1258                         s.append("&");
1259                         s.append(is.head.toString());
1260                     }
1261                     return s.toString();
1262                 } else if (sym.name.isEmpty()) {
1263                     String s;
1264                     ClassType norm = (ClassType) tsym.type;
1265                     if (norm == null) {
1266                         s = Log.getLocalizedString("anonymous.class", (Object)null);
1267                     } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
1268                         s = Log.getLocalizedString("anonymous.class",
1269                                                    norm.interfaces_field.head);
1270                     } else {
1271                         s = Log.getLocalizedString("anonymous.class",
1272                                                    norm.supertype_field);
1273                     }
1274                     if (moreInfo)
1275                         s += String.valueOf(sym.hashCode());
1276                     return s;
1277                 }
1278                 String s;
1279                 if (longform) {
1280                     s =  sym.getQualifiedName().toString();
1281                 } else {
1282                     s = sym.name.toString();
1283                 }
1284                 return s;
1285             }
1286 
1287         public Flavor getFlavor() {
1288             return flavor;
1289         }
1290 
1291         @DefinedBy(Api.LANGUAGE_MODEL)
1292         public List<Type> getTypeArguments() {
1293             if (typarams_field == null) {
1294                 complete();
1295                 if (typarams_field == null)
1296                     typarams_field = List.nil();
1297             }
1298             return typarams_field;
1299         }
1300 
1301         public boolean hasErasedSupertypes() {
1302             return isRaw();
1303         }
1304 
1305         @DefinedBy(Api.LANGUAGE_MODEL)
1306         public Type getEnclosingType() {
1307             if (outer_field != null && outer_field.isReferenceProjection()) {
1308                 outer_field = outer_field.asValueType();
1309             }
1310             return outer_field;
1311         }
1312 
1313         public void setEnclosingType(Type outer) {
1314             outer_field = outer;
1315         }
1316 
1317         public List<Type> allparams() {
1318             if (allparams_field == null) {
1319                 allparams_field = getTypeArguments().prependList(getEnclosingType().allparams());
1320             }
1321             return allparams_field;
1322         }
1323 
1324         public boolean isErroneous() {
1325             return
1326                 getEnclosingType().isErroneous() ||
1327                 isErroneous(getTypeArguments()) ||
1328                 this != tsym.type && tsym.type.isErroneous();
1329         }
1330 
1331         public boolean isParameterized() {
1332             return allparams().tail != null;
1333             // optimization, was: allparams().nonEmpty();
1334         }
1335 
1336         @Override
1337         public boolean isReference() {
1338             return true;
1339         }
1340 
1341         @Override
1342         public boolean isPrimitiveClass() {
1343             // guard against over-eager and/or inopportune completion
1344             if (tsym != null) {
1345                 if (flavor == Flavor.Q_TypeOf_X || tsym.isCompleted()) {
1346                     flavor = flavor.metamorphose(tsym.flags());
1347                 }
1348             }
1349             return flavor == Flavor.Q_TypeOf_Q || flavor == Flavor.Q_TypeOf_L;
1350         }
1351 
1352         @Override
1353         public boolean isReferenceProjection() {
1354             // guard against over-eager and/or inopportune completion
1355             if (tsym != null) {
1356                 if (flavor == Flavor.L_TypeOf_X || tsym.isCompleted()) {
1357                     flavor = flavor.metamorphose(tsym.flags());
1358                 }
1359             }
1360             return flavor == Flavor.L_TypeOf_Q && tsym.type.getFlavor() == Flavor.Q_TypeOf_Q; // discount reference favoring primitives.
1361         }
1362 
1363         @Override
1364         public boolean isPrimitiveReferenceType() {
1365             // guard against over-eager and/or inopportune completion
1366             if (tsym != null) {
1367                 if (flavor == Flavor.L_TypeOf_X || tsym.isCompleted()) {
1368                     flavor = flavor.metamorphose(tsym.flags());
1369                 }
1370             }
1371             return flavor == Flavor.L_TypeOf_Q;
1372         }
1373 
1374         @Override
1375         public boolean isValueProjection() {
1376             // guard against over-eager and/or inopportune completion
1377             if (tsym != null) {
1378                 if (flavor == Flavor.Q_TypeOf_X || tsym.isCompleted()) {
1379                     flavor = flavor.metamorphose(tsym.flags());
1380 
1381                 }
1382             }
1383             return flavor == Flavor.Q_TypeOf_L;
1384         }
1385 
1386         // return the primitive value type *preserving parameterizations*
1387         @Override
1388         public ClassType asValueType() {
1389             if (tsym == null || !tsym.isPrimitiveClass())
1390                 return null;
1391 
1392             switch (flavor) {
1393                 case Q_TypeOf_L:
1394                 case Q_TypeOf_Q:
1395                     return this;
1396                 case L_TypeOf_Q:
1397                     if (projection != null)
1398                         return projection;
1399 
1400                     projection = new ClassType(outer_field, typarams_field, tsym, getMetadata(),
1401                             tsym.isReferenceFavoringPrimitiveClass() ? Flavor.Q_TypeOf_L : Flavor.Q_TypeOf_Q);
1402                     projection.allparams_field = allparams_field;
1403                     projection.supertype_field = supertype_field;
1404 
1405                     projection.interfaces_field = interfaces_field;
1406                     projection.all_interfaces_field = all_interfaces_field;
1407                     projection.projection = this;
1408                     return projection;
1409                 default:
1410                     Assert.check(false, "Should not get here");
1411                     return null;
1412             }
1413         }
1414 
1415         // return the reference projection type preserving parameterizations
1416         @Override
1417         public ClassType referenceProjection() {
1418 
1419             if (!isPrimitiveClass())
1420                 return null;
1421 
1422             if (projection != null)
1423                 return projection;
1424 
1425             projection = new ClassType(outer_field, typarams_field, tsym, getMetadata(), Flavor.L_TypeOf_Q);
1426             projection.allparams_field = allparams_field;
1427             projection.supertype_field = supertype_field;
1428 
1429             projection.interfaces_field = interfaces_field;
1430             projection.all_interfaces_field = all_interfaces_field;
1431             projection.projection = this;
1432             return projection;
1433         }
1434 
1435         @Override
1436         public boolean isNullOrReference() {
1437             return true;
1438         }
1439 
1440         /** A cache for the rank. */
1441         int rank_field = -1;
1442 
1443         /** A class type is raw if it misses some
1444          *  of its type parameter sections.
1445          *  After validation, this is equivalent to:
1446          *  {@code allparams.isEmpty() && tsym.type.allparams.nonEmpty(); }
1447          */
1448         public boolean isRaw() {
1449             return
1450                 this != tsym.type && // necessary, but not sufficient condition
1451                 tsym.type.allparams().nonEmpty() &&
1452                 allparams().isEmpty();
1453         }
1454 

1463 
1464         public void complete() {
1465             tsym.complete();
1466         }
1467 
1468         @DefinedBy(Api.LANGUAGE_MODEL)
1469         public TypeKind getKind() {
1470             tsym.apiComplete();
1471             return tsym.kind == TYP ? TypeKind.DECLARED : TypeKind.ERROR;
1472         }
1473 
1474         @DefinedBy(Api.LANGUAGE_MODEL)
1475         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1476             return v.visitDeclared(this, p);
1477         }
1478     }
1479 
1480     public static class ErasedClassType extends ClassType {
1481         public ErasedClassType(Type outer, TypeSymbol tsym,
1482                                TypeMetadata metadata) {
1483             super(outer, List.nil(), tsym, metadata, tsym.type.getFlavor());
1484         }
1485 
1486         @Override
1487         public boolean hasErasedSupertypes() {
1488             return true;
1489         }
1490     }
1491 
1492     // a clone of a ClassType that knows about the alternatives of a union type.
1493     public static class UnionClassType extends ClassType implements UnionType {
1494         final List<? extends Type> alternatives_field;
1495 
1496         public UnionClassType(ClassType ct, List<? extends Type> alternatives) {
1497             // Presently no way to refer to this type directly, so we
1498             // cannot put annotations directly on it.
1499             super(ct.outer_field, ct.typarams_field, ct.tsym);
1500             allparams_field = ct.allparams_field;
1501             supertype_field = ct.supertype_field;
1502             interfaces_field = ct.interfaces_field;
1503             all_interfaces_field = ct.interfaces_field;

2630         @Override
2631         public boolean isNullOrReference() {
2632             return true;
2633         }
2634 
2635     }
2636 
2637     public static class ErrorType extends ClassType
2638             implements javax.lang.model.type.ErrorType {
2639 
2640         private Type originalType = null;
2641 
2642         public ErrorType(ClassSymbol c, Type originalType) {
2643             this(originalType, c);
2644             c.type = this;
2645             c.kind = ERR;
2646             c.members_field = new Scope.ErrorScope(c);
2647         }
2648 
2649         public ErrorType(Type originalType, TypeSymbol tsym) {
2650             super(noType, List.nil(), tsym, TypeMetadata.EMPTY, Flavor.E_Typeof_X);

2651             this.originalType = (originalType == null ? noType : originalType);
2652         }
2653 
2654         private ErrorType(Type originalType, TypeSymbol tsym,
2655                           TypeMetadata metadata, Flavor flavor) {
2656             super(noType, List.nil(), null, metadata, flavor);
2657             this.tsym = tsym;
2658             this.originalType = (originalType == null ? noType : originalType);
2659         }
2660 
2661         @Override
2662         public ErrorType cloneWithMetadata(TypeMetadata md) {
2663             return new ErrorType(originalType, tsym, md, getFlavor()) {
2664                 @Override
2665                 public Type baseType() { return ErrorType.this.baseType(); }
2666             };
2667         }
2668 
2669         @Override
2670         public TypeTag getTag() {
2671             return ERROR;
2672         }
2673 
2674         @Override
2675         public boolean isPartial() {
2676             return true;
2677         }
2678 
2679         @Override
2680         public boolean isReference() {
2681             return true;
2682         }
2683 
< prev index next >