< 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 abstract static 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);

1041                 if (isAnnotated()) {
1042                     if (!tsym.packge().isUnnamed()) {
1043                         buf.append(tsym.packge());
1044                         buf.append(".");
1045                     }
1046                     ListBuffer<Name> names = new ListBuffer<>();
1047                     for (Symbol sym = tsym.owner; sym != null && sym.kind == TYP; sym = sym.owner) {
1048                         names.prepend(sym.name);
1049                     }
1050                     for (Name name : names) {
1051                         buf.append(name);
1052                         buf.append(".");
1053                     }
1054                     appendAnnotationsString(buf);
1055                     buf.append(tsym.name);
1056                 } else {
1057                     buf.append(className(tsym, true));
1058                 }
1059             }
1060 











1061             if (getTypeArguments().nonEmpty()) {
1062                 buf.append('<');
1063                 buf.append(getTypeArguments().toString());
1064                 buf.append(">");
1065             }
1066             return buf.toString();
1067         }
1068 //where
1069             private String className(Symbol sym, boolean longform) {
1070                 if (sym.name.isEmpty() && (sym.flags() & COMPOUND) != 0) {
1071                     StringBuilder s = new StringBuilder(supertype_field.toString());
1072                     for (List<Type> is=interfaces_field; is.nonEmpty(); is = is.tail) {
1073                         s.append("&");
1074                         s.append(is.head.toString());
1075                     }
1076                     return s.toString();
1077                 } else if (sym.name.isEmpty()) {
1078                     String s;
1079                     ClassType norm = (ClassType) tsym.type;
1080                     if (norm == null) {
1081                         s = Log.getLocalizedString("anonymous.class", (Object)null);
1082                     } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
1083                         s = Log.getLocalizedString("anonymous.class",
1084                                                    norm.interfaces_field.head);
1085                     } else {
1086                         s = Log.getLocalizedString("anonymous.class",
1087                                                    norm.supertype_field);
1088                     }
1089                     if (moreInfo)
1090                         s += String.valueOf(sym.hashCode());
1091                     return s;
1092                 } else if (longform) {
1093                     return sym.getQualifiedName().toString();
1094                 } else {
1095                     return sym.name.toString();
1096                 }
1097             }
1098 




1099         @DefinedBy(Api.LANGUAGE_MODEL)
1100         public List<Type> getTypeArguments() {
1101             if (typarams_field == null) {
1102                 complete();
1103                 if (typarams_field == null)
1104                     typarams_field = List.nil();
1105             }
1106             return typarams_field;
1107         }
1108 
1109         public boolean hasErasedSupertypes() {
1110             return isRaw();
1111         }
1112 
1113         @DefinedBy(Api.LANGUAGE_MODEL)
1114         public Type getEnclosingType() {



1115             return outer_field;
1116         }
1117 
1118         public void setEnclosingType(Type outer) {
1119             outer_field = outer;
1120         }
1121 
1122         public List<Type> allparams() {
1123             if (allparams_field == null) {
1124                 allparams_field = getTypeArguments().prependList(getEnclosingType().allparams());
1125             }
1126             return allparams_field;
1127         }
1128 
1129         public boolean isErroneous() {
1130             return
1131                 getEnclosingType().isErroneous() ||
1132                 isErroneous(getTypeArguments()) ||
1133                 this != tsym.type && tsym.type.isErroneous();
1134         }
1135 
1136         public boolean isParameterized() {
1137             return allparams().tail != null;
1138             // optimization, was: allparams().nonEmpty();
1139         }
1140 
1141         @Override
1142         public boolean isReference() {
1143             return true;
1144         }
1145 










































































1146         @Override
1147         public boolean isNullOrReference() {
1148             return true;
1149         }
1150 
1151         /** A cache for the rank. */
1152         int rank_field = -1;
1153 
1154         /** A class type is raw if it misses some
1155          *  of its type parameter sections.
1156          *  After validation, this is equivalent to:
1157          *  {@code allparams.isEmpty() && tsym.type.allparams.nonEmpty(); }
1158          */
1159         public boolean isRaw() {
1160             return
1161                 this != tsym.type && // necessary, but not sufficient condition
1162                 tsym.type.allparams().nonEmpty() &&
1163                 allparams().isEmpty();
1164         }
1165 

1174 
1175         public void complete() {
1176             tsym.complete();
1177         }
1178 
1179         @DefinedBy(Api.LANGUAGE_MODEL)
1180         public TypeKind getKind() {
1181             tsym.apiComplete();
1182             return tsym.kind == TYP ? TypeKind.DECLARED : TypeKind.ERROR;
1183         }
1184 
1185         @DefinedBy(Api.LANGUAGE_MODEL)
1186         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1187             return v.visitDeclared(this, p);
1188         }
1189     }
1190 
1191     public static class ErasedClassType extends ClassType {
1192         public ErasedClassType(Type outer, TypeSymbol tsym,
1193                                TypeMetadata metadata) {
1194             super(outer, List.nil(), tsym, metadata);
1195         }
1196 
1197         @Override
1198         public boolean hasErasedSupertypes() {
1199             return true;
1200         }
1201     }
1202 
1203     // a clone of a ClassType that knows about the alternatives of a union type.
1204     public static class UnionClassType extends ClassType implements UnionType {
1205         final List<? extends Type> alternatives_field;
1206 
1207         public UnionClassType(ClassType ct, List<? extends Type> alternatives) {
1208             // Presently no way to refer to this type directly, so we
1209             // cannot put annotations directly on it.
1210             super(ct.outer_field, ct.typarams_field, ct.tsym);
1211             allparams_field = ct.allparams_field;
1212             supertype_field = ct.supertype_field;
1213             interfaces_field = ct.interfaces_field;
1214             all_interfaces_field = ct.interfaces_field;

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

  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     public boolean isValueClass() {
 245         return false;
 246     }
 247 
 248     public boolean isValueInterface() {
 249         return false;
 250     }
 251 
 252     public boolean isIdentityClass() {
 253         return false;
 254     }
 255 
 256     public boolean isIdentityInterface() {
 257         return false;
 258     }
 259 
 260     // Does this type need to be preloaded in the context of the referring class ??
 261     public boolean requiresPreload(Symbol referringClass) {
 262         if (this.tsym == referringClass)
 263             return false; // pointless
 264         if (this.isReferenceProjection())
 265             return true;
 266         return this.isValueClass() && !this.isPrimitiveClass();
 267     }
 268 
 269     /**
 270      * Return the `flavor' associated with a ClassType.
 271      * @see ClassType.Flavor
 272      */
 273     public Flavor getFlavor() {
 274         throw new AssertionError("Unexpected call to getFlavor() on a Type that is not a ClassType: " + this);
 275     }
 276 
 277     /**
 278      * @return true IFF the receiver is a reference projection of a primitive class type and false
 279      * for primitives or plain references
 280      */
 281     public boolean isReferenceProjection() {
 282         return false;
 283     }
 284 
 285     /**
 286      * @return the value projection type IFF the receiver is a reference projection of a primitive class type
 287      * and null otherwise
 288      */
 289     public Type valueProjection() {
 290         return null;
 291     }
 292 
 293     /**
 294      * @return the reference projection type IFF the receiver is a primitive class type
 295      * and null otherwise
 296      */
 297     public Type referenceProjection() {
 298         return null;
 299     }
 300 
 301     /**
 302      * @return the reference projection type IFF the receiver is a primitive class type or self otherwise.
 303      */
 304     public Type referenceProjectionOrSelf() {
 305         Type projection = referenceProjection();
 306         return projection != null ? projection : this;
 307     }
 308 
 309     /**
 310      * A subclass of {@link Types.TypeMapping} which applies a mapping recursively to the subterms
 311      * of a given type expression. This mapping returns the original type is no changes occurred
 312      * when recursively mapping the original type's subterms.
 313      */
 314     public abstract static class StructuralTypeMapping<S> extends Types.TypeMapping<S> {
 315 
 316         @Override
 317         public Type visitClassType(ClassType t, S s) {
 318             Type outer = t.getEnclosingType();
 319             Type outer1 = visit(outer, s);
 320             List<Type> typarams = t.getTypeArguments();
 321             List<Type> typarams1 = visit(typarams, s);
 322             if (outer1 == outer && typarams1 == typarams) return t;
 323             else return new ClassType(outer1, typarams1, t.tsym, t.metadata, t.getFlavor()) {
 324                 @Override
 325                 protected boolean needsStripping() {
 326                     return true;
 327                 }
 328             };
 329         }
 330 
 331         @Override
 332         public Type visitWildcardType(WildcardType wt, S s) {
 333             Type t = wt.type;
 334             if (t != null)
 335                 t = visit(t, s);
 336             if (t == wt.type)
 337                 return wt;
 338             else
 339                 return new WildcardType(t, wt.kind, wt.tsym, wt.bound, wt.metadata) {
 340                     @Override
 341                     protected boolean needsStripping() {
 342                         return true;
 343                     }

 999 
1000         @DefinedBy(Api.LANGUAGE_MODEL)
1001         public Type getSuperBound() {
1002             if (kind == SUPER)
1003                 return type;
1004             else
1005                 return null;
1006         }
1007 
1008         @DefinedBy(Api.LANGUAGE_MODEL)
1009         public TypeKind getKind() {
1010             return TypeKind.WILDCARD;
1011         }
1012 
1013         @DefinedBy(Api.LANGUAGE_MODEL)
1014         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1015             return v.visitWildcard(this, p);
1016         }
1017     }
1018 
1019     public static class ConstantPoolQType implements PoolConstant {
1020 
1021         public final Type type;
1022         final Types types;
1023 
1024         public ConstantPoolQType(Type type, Types types) {
1025             this.type = type;
1026             this.types = types;
1027         }
1028 
1029         @Override
1030         public Object poolKey(Types types) {
1031             return this;
1032         }
1033 
1034         @Override
1035         public int poolTag() {
1036             return ClassFile.CONSTANT_Class;
1037         }
1038 
1039         public int hashCode() {
1040             return types.hashCode(type);
1041         }
1042 
1043         public boolean equals(Object obj) {
1044             return (obj instanceof ConstantPoolQType) &&
1045                     types.isSameType(type, ((ConstantPoolQType)obj).type);
1046         }
1047 
1048         public String toString() {
1049             return type.toString();
1050         }
1051     }
1052 
1053     public static class ClassType extends Type implements DeclaredType, LoadableConstant,
1054                                                           javax.lang.model.type.ErrorType {
1055 
1056         /**
1057          * The 'flavor' of a ClassType indicates its reference/primitive projectionness
1058          * viewed against the default nature of the associated class.
1059          */
1060         public enum Flavor {
1061 
1062             /**
1063              * Classic reference type. Also reference projection type of a reference-favoring aka
1064              * reference-default primitive class type
1065              */
1066             L_TypeOf_L,
1067 
1068             /**
1069              * Reference projection type of a primitive-favoring aka primitive-default
1070              * plain vanilla primitive class type,
1071              */
1072             L_TypeOf_Q,
1073 
1074             /**
1075              * Value projection type of a primitive-favoring aka primitive-default
1076              * plain vanilla primitive class type,
1077              */
1078             Q_TypeOf_Q,
1079 
1080             /**
1081              * Value projection type of a reference-favoring aka
1082              * reference-default primitive class type
1083              */
1084             Q_TypeOf_L,
1085 
1086             /**
1087              * Reference projection type of a class type of an as yet unknown default provenance, 'X' will be
1088              * discovered to be 'L' or 'Q' in "due course" and mutated suitably.
1089              */
1090             L_TypeOf_X,
1091 
1092             /**
1093              * Value projection type of a class type of an as yet unknown default provenance, 'X' will be
1094              * discovered to be 'L' or 'Q' in "due course" and mutated suitably.
1095              */
1096             Q_TypeOf_X,
1097 
1098             /**
1099              *  As yet unknown projection type of an as yet unknown default provenance class.
1100              */
1101             X_Typeof_X,
1102 
1103             /**
1104              *  An error type - we don't care to discriminate them any further.
1105              */
1106              E_Typeof_X;
1107 
1108             // We don't seem to need X_Typeof_L or X_Typeof_Q so far.
1109 
1110             // Transform a larval form into a more evolved form
1111             public Flavor metamorphose(boolean isPrimtiveClass) {
1112 
1113                 switch (this) {
1114 
1115                     case E_Typeof_X:  // stunted form
1116                     case L_TypeOf_L:
1117                     case L_TypeOf_Q:
1118                     case Q_TypeOf_L:
1119                     case Q_TypeOf_Q:
1120                             // These are fully evolved sealed forms or stunted - no futher transformation
1121                             return this;
1122                     case L_TypeOf_X:
1123                             return isPrimtiveClass ? L_TypeOf_Q : L_TypeOf_L;
1124                     case Q_TypeOf_X:
1125                             return isPrimtiveClass ? Q_TypeOf_Q : Q_TypeOf_L;
1126                     case X_Typeof_X:
1127                             return isPrimtiveClass ? Q_TypeOf_Q : L_TypeOf_L;
1128                     default:
1129                             throw new AssertionError("Unexpected class type flavor");
1130                 }
1131             }
1132         }
1133 
1134         /** The enclosing type of this type. If this is the type of an inner
1135          *  class, outer_field refers to the type of its enclosing
1136          *  instance class, in all other cases it refers to noType.
1137          */
1138         private Type outer_field;
1139 
1140         /** The type parameters of this type (to be set once class is loaded).
1141          */
1142         public List<Type> typarams_field;
1143 
1144         /** A cache variable for the type parameters of this type,
1145          *  appended to all parameters of its enclosing class.
1146          *  @see #allparams
1147          */
1148         public List<Type> allparams_field;
1149 
1150         /** The supertype of this class (to be set once class is loaded).
1151          */
1152         public Type supertype_field;
1153 
1154         /** The interfaces of this class (to be set once class is loaded).
1155          */
1156         public List<Type> interfaces_field;
1157 
1158         /** All the interfaces of this class, including missing ones.
1159          */
1160         public List<Type> all_interfaces_field;
1161 
1162         /** The 'other' projection: If 'this' is type of a primitive class, then 'projection' is the
1163          *  reference projection type and vice versa. Lazily initialized, not to be accessed directly.
1164         */
1165         public ClassType projection;
1166 
1167         /** Is this L of default {L, Q, X} or Q of default {L, Q, X} ?
1168          */
1169         public Flavor flavor;
1170 
1171         /*
1172          * Use of this constructor is kinda sorta deprecated, use the other constructor
1173          * that forces the call site to consider and include the class type flavor.
1174          */
1175         public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
1176             this(outer, typarams, tsym, TypeMetadata.EMPTY, Flavor.L_TypeOf_L);
1177         }
1178 
1179         public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym,
1180                          TypeMetadata metadata, Flavor flavor) {
1181             super(tsym, metadata);
1182             this.outer_field = outer;
1183             this.typarams_field = typarams;
1184             this.allparams_field = null;
1185             this.supertype_field = null;
1186             this.interfaces_field = null;
1187             this.flavor = flavor;
1188         }
1189 
1190         public int poolTag() {
1191             return ClassFile.CONSTANT_Class;
1192         }
1193 
1194         @Override
1195         public ClassType cloneWithMetadata(TypeMetadata md) {
1196             return new ClassType(outer_field, typarams_field, tsym, md, flavor) {
1197                 @Override
1198                 public Type baseType() { return ClassType.this.baseType(); }
1199             };
1200         }
1201 
1202         @Override
1203         public TypeTag getTag() {
1204             return CLASS;
1205         }
1206 
1207         @Override
1208         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1209             return v.visitClassType(this, s);
1210         }
1211 
1212         public Type constType(Object constValue) {
1213             final Object value = constValue;
1214             return new ClassType(getEnclosingType(), typarams_field, tsym, metadata, flavor) {
1215                     @Override
1216                     public Object constValue() {
1217                         return value;
1218                     }
1219                     @Override
1220                     public Type baseType() {
1221                         return tsym.type;
1222                     }
1223                 };
1224         }
1225 
1226         /** The Java source which this type represents.
1227          */
1228         @DefinedBy(Api.LANGUAGE_MODEL)
1229         public String toString() {
1230             StringBuilder buf = new StringBuilder();
1231             if (getEnclosingType().hasTag(CLASS) && tsym.owner.kind == TYP) {
1232                 buf.append(getEnclosingType().toString());
1233                 buf.append(".");
1234                 appendAnnotationsString(buf);

1237                 if (isAnnotated()) {
1238                     if (!tsym.packge().isUnnamed()) {
1239                         buf.append(tsym.packge());
1240                         buf.append(".");
1241                     }
1242                     ListBuffer<Name> names = new ListBuffer<>();
1243                     for (Symbol sym = tsym.owner; sym != null && sym.kind == TYP; sym = sym.owner) {
1244                         names.prepend(sym.name);
1245                     }
1246                     for (Name name : names) {
1247                         buf.append(name);
1248                         buf.append(".");
1249                     }
1250                     appendAnnotationsString(buf);
1251                     buf.append(tsym.name);
1252                 } else {
1253                     buf.append(className(tsym, true));
1254                 }
1255             }
1256 
1257             boolean isReferenceProjection;
1258             try {
1259                 isReferenceProjection = isReferenceProjection();
1260             } catch (CompletionFailure cf) {
1261                 isReferenceProjection = false; // handle missing types gracefully.
1262             }
1263             if (isReferenceProjection) {
1264                 buf.append('.');
1265                 buf.append(tsym.name.table.names.ref);
1266             }
1267 
1268             if (getTypeArguments().nonEmpty()) {
1269                 buf.append('<');
1270                 buf.append(getTypeArguments().toString());
1271                 buf.append(">");
1272             }
1273             return buf.toString();
1274         }
1275 //where
1276             private String className(Symbol sym, boolean longform) {
1277                 if (sym.name.isEmpty() && (sym.flags() & COMPOUND) != 0) {
1278                     StringBuilder s = new StringBuilder(supertype_field.toString());
1279                     for (List<Type> is=interfaces_field; is.nonEmpty(); is = is.tail) {
1280                         s.append("&");
1281                         s.append(is.head.toString());
1282                     }
1283                     return s.toString();
1284                 } else if (sym.name.isEmpty()) {
1285                     String s;
1286                     ClassType norm = (ClassType) tsym.type;
1287                     if (norm == null) {
1288                         s = Log.getLocalizedString("anonymous.class", (Object)null);
1289                     } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
1290                         s = Log.getLocalizedString("anonymous.class",
1291                                                    norm.interfaces_field.head);
1292                     } else {
1293                         s = Log.getLocalizedString("anonymous.class",
1294                                                    norm.supertype_field);
1295                     }
1296                     if (moreInfo)
1297                         s += String.valueOf(sym.hashCode());
1298                     return s;
1299                 } else if (longform) {
1300                     return sym.getQualifiedName().toString();
1301                 } else {
1302                     return sym.name.toString();
1303                 }
1304             }
1305 
1306         public Flavor getFlavor() {
1307             return flavor;
1308         }
1309 
1310         @DefinedBy(Api.LANGUAGE_MODEL)
1311         public List<Type> getTypeArguments() {
1312             if (typarams_field == null) {
1313                 complete();
1314                 if (typarams_field == null)
1315                     typarams_field = List.nil();
1316             }
1317             return typarams_field;
1318         }
1319 
1320         public boolean hasErasedSupertypes() {
1321             return isRaw();
1322         }
1323 
1324         @DefinedBy(Api.LANGUAGE_MODEL)
1325         public Type getEnclosingType() {
1326             if (outer_field != null && outer_field.isReferenceProjection()) {
1327                 outer_field = outer_field.valueProjection();
1328             }
1329             return outer_field;
1330         }
1331 
1332         public void setEnclosingType(Type outer) {
1333             outer_field = outer;
1334         }
1335 
1336         public List<Type> allparams() {
1337             if (allparams_field == null) {
1338                 allparams_field = getTypeArguments().prependList(getEnclosingType().allparams());
1339             }
1340             return allparams_field;
1341         }
1342 
1343         public boolean isErroneous() {
1344             return
1345                 getEnclosingType().isErroneous() ||
1346                 isErroneous(getTypeArguments()) ||
1347                 this != tsym.type && tsym.type.isErroneous();
1348         }
1349 
1350         public boolean isParameterized() {
1351             return allparams().tail != null;
1352             // optimization, was: allparams().nonEmpty();
1353         }
1354 
1355         @Override
1356         public boolean isReference() {
1357             return true;
1358         }
1359 
1360         @Override
1361         public boolean isPrimitiveClass() {
1362             return !isReferenceProjection() && tsym != null && tsym.isPrimitiveClass();
1363         }
1364 
1365         @Override
1366         public boolean isValueClass() {
1367             return !isReferenceProjection() && tsym != null && tsym.isValueClass();
1368         }
1369 
1370         @Override
1371         public boolean isValueInterface() {
1372             return tsym != null && tsym.isValueInterface();
1373         }
1374 
1375         @Override
1376         public boolean isIdentityClass() {
1377             return !isReferenceProjection() && tsym != null && tsym.isIdentityClass();
1378         }
1379 
1380         @Override
1381         public boolean isIdentityInterface() {
1382             return isInterface() && tsym.isIdentityInterface();
1383         }
1384 
1385         @Override
1386         public boolean isReferenceProjection() {
1387             // gaurd against over-eager and/or inopportune completion
1388             if (tsym != null) {
1389                 if (flavor == Flavor.L_TypeOf_X || tsym.isCompleted()) {
1390                     flavor = flavor.metamorphose(tsym.isPrimitiveClass());
1391                 }
1392             }
1393             return flavor == Flavor.L_TypeOf_Q;
1394         }
1395 
1396         @Override
1397         public Type valueProjection() {
1398             if (!isReferenceProjection())
1399                 return null;
1400 
1401             if (projection !=  null)
1402                 return projection;
1403 
1404             projection = new ClassType(outer_field, typarams_field, tsym, getMetadata(), Flavor.Q_TypeOf_Q);
1405             projection.allparams_field = allparams_field;
1406             projection.supertype_field = supertype_field;
1407 
1408             projection.interfaces_field = interfaces_field;
1409             projection.all_interfaces_field = all_interfaces_field;
1410             projection.projection = this;
1411             return projection;
1412         }
1413 
1414         // return the reference projection type preserving parameterizations
1415         @Override
1416         public ClassType referenceProjection() {
1417 
1418             if (!isPrimitiveClass())
1419                 return null;
1420 
1421             if (projection != null)
1422                 return projection;
1423 
1424             projection = new ClassType(outer_field, typarams_field, tsym, getMetadata(), Flavor.L_TypeOf_Q);
1425             projection.allparams_field = allparams_field;
1426             projection.supertype_field = supertype_field;
1427 
1428             projection.interfaces_field = interfaces_field;
1429             projection.all_interfaces_field = all_interfaces_field;
1430             projection.projection = this;
1431             return projection;
1432         }
1433 
1434         @Override
1435         public boolean isNullOrReference() {
1436             return true;
1437         }
1438 
1439         /** A cache for the rank. */
1440         int rank_field = -1;
1441 
1442         /** A class type is raw if it misses some
1443          *  of its type parameter sections.
1444          *  After validation, this is equivalent to:
1445          *  {@code allparams.isEmpty() && tsym.type.allparams.nonEmpty(); }
1446          */
1447         public boolean isRaw() {
1448             return
1449                 this != tsym.type && // necessary, but not sufficient condition
1450                 tsym.type.allparams().nonEmpty() &&
1451                 allparams().isEmpty();
1452         }
1453 

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

2619         @Override
2620         public boolean isNullOrReference() {
2621             return true;
2622         }
2623 
2624     }
2625 
2626     public static class ErrorType extends ClassType
2627             implements javax.lang.model.type.ErrorType {
2628 
2629         private Type originalType = null;
2630 
2631         public ErrorType(ClassSymbol c, Type originalType) {
2632             this(originalType, c);
2633             c.type = this;
2634             c.kind = ERR;
2635             c.members_field = new Scope.ErrorScope(c);
2636         }
2637 
2638         public ErrorType(Type originalType, TypeSymbol tsym) {
2639             super(noType, List.nil(), tsym, TypeMetadata.EMPTY, Flavor.E_Typeof_X);

2640             this.originalType = (originalType == null ? noType : originalType);
2641         }
2642 
2643         private ErrorType(Type originalType, TypeSymbol tsym,
2644                           TypeMetadata metadata, Flavor flavor) {
2645             super(noType, List.nil(), null, metadata, flavor);
2646             this.tsym = tsym;
2647             this.originalType = (originalType == null ? noType : originalType);
2648         }
2649 
2650         @Override
2651         public ErrorType cloneWithMetadata(TypeMetadata md) {
2652             return new ErrorType(originalType, tsym, md, getFlavor()) {
2653                 @Override
2654                 public Type baseType() { return ErrorType.this.baseType(); }
2655             };
2656         }
2657 
2658         @Override
2659         public TypeTag getTag() {
2660             return ERROR;
2661         }
2662 
2663         @Override
2664         public boolean isPartial() {
2665             return true;
2666         }
2667 
2668         @Override
2669         public boolean isReference() {
2670             return true;
2671         }
2672 
< prev index next >