< prev index next >

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

Print this page

  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.Optional;
  34 import java.util.function.Function;
  35 import java.util.function.Predicate;
  36 
  37 import javax.lang.model.type.*;
  38 
  39 import com.sun.tools.javac.code.Symbol.*;

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

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





































































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

 966 
 967         @DefinedBy(Api.LANGUAGE_MODEL)
 968         public Type getSuperBound() {
 969             if (kind == SUPER)
 970                 return type;
 971             else
 972                 return null;
 973         }
 974 
 975         @DefinedBy(Api.LANGUAGE_MODEL)
 976         public TypeKind getKind() {
 977             return TypeKind.WILDCARD;
 978         }
 979 
 980         @DefinedBy(Api.LANGUAGE_MODEL)
 981         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
 982             return v.visitWildcard(this, p);
 983         }
 984     }
 985 


































 986     public static class ClassType extends Type implements DeclaredType, LoadableConstant,
 987                                                           javax.lang.model.type.ErrorType {
 988 














































































 989         /** The enclosing type of this type. If this is the type of an inner
 990          *  class, outer_field refers to the type of its enclosing
 991          *  instance class, in all other cases it refers to noType.
 992          */
 993         private Type outer_field;
 994 
 995         /** The type parameters of this type (to be set once class is loaded).
 996          */
 997         public List<Type> typarams_field;
 998 
 999         /** A cache variable for the type parameters of this type,
1000          *  appended to all parameters of its enclosing class.
1001          *  @see #allparams
1002          */
1003         public List<Type> allparams_field;
1004 
1005         /** The supertype of this class (to be set once class is loaded).
1006          */
1007         public Type supertype_field;
1008 
1009         /** The interfaces of this class (to be set once class is loaded).
1010          */
1011         public List<Type> interfaces_field;
1012 
1013         /** All the interfaces of this class, including missing ones.
1014          */
1015         public List<Type> all_interfaces_field;
1016 













1017         public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
1018             this(outer, typarams, tsym, List.nil());




1019         }
1020 
1021         public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym,
1022                          List<TypeMetadata> metadata) {
1023             super(tsym, metadata);
1024             this.outer_field = outer;
1025             this.typarams_field = typarams;
1026             this.allparams_field = null;
1027             this.supertype_field = null;
1028             this.interfaces_field = null;

1029         }
1030 
1031         public int poolTag() {
1032             return ClassFile.CONSTANT_Class;
1033         }
1034 
1035         @Override
1036         protected ClassType cloneWithMetadata(List<TypeMetadata> md) {
1037             return new ClassType(outer_field, typarams_field, tsym, md) {
1038                 @Override
1039                 public Type baseType() { return ClassType.this.baseType(); }
1040             };
1041         }
1042 
1043         @Override
1044         public TypeTag getTag() {
1045             return CLASS;
1046         }
1047 
1048         @Override
1049         public <R,S> R accept(Type.Visitor<R,S> v, S s) {
1050             return v.visitClassType(this, s);
1051         }
1052 
1053         public Type constType(Object constValue) {
1054             return addMetadata(new ConstantValue(constValue));
1055         }
1056 
1057         /** The Java source which this type represents.

1068                 if (isAnnotated()) {
1069                     if (!tsym.packge().isUnnamed()) {
1070                         buf.append(tsym.packge());
1071                         buf.append(".");
1072                     }
1073                     ListBuffer<Name> names = new ListBuffer<>();
1074                     for (Symbol sym = tsym.owner; sym != null && sym.kind == TYP; sym = sym.owner) {
1075                         names.prepend(sym.name);
1076                     }
1077                     for (Name name : names) {
1078                         buf.append(name);
1079                         buf.append(".");
1080                     }
1081                     appendAnnotationsString(buf);
1082                     buf.append(tsym.name);
1083                 } else {
1084                     buf.append(className(tsym, true));
1085                 }
1086             }
1087 











1088             if (getTypeArguments().nonEmpty()) {
1089                 buf.append('<');
1090                 buf.append(getTypeArguments().toString());
1091                 buf.append(">");
1092             }
1093             return buf.toString();
1094         }
1095 //where
1096             private String className(Symbol sym, boolean longform) {
1097                 if (sym.name.isEmpty() && (sym.flags() & COMPOUND) != 0) {
1098                     StringBuilder s = new StringBuilder(supertype_field.toString());
1099                     for (List<Type> is=interfaces_field; is.nonEmpty(); is = is.tail) {
1100                         s.append("&");
1101                         s.append(is.head.toString());
1102                     }
1103                     return s.toString();
1104                 } else if (sym.name.isEmpty()) {
1105                     String s;
1106                     ClassType norm = (ClassType) tsym.type;
1107                     if (norm == null) {
1108                         s = Log.getLocalizedString("anonymous.class", (Object)null);
1109                     } else if (norm.interfaces_field != null && norm.interfaces_field.nonEmpty()) {
1110                         s = Log.getLocalizedString("anonymous.class",
1111                                                    norm.interfaces_field.head);
1112                     } else {
1113                         s = Log.getLocalizedString("anonymous.class",
1114                                                    norm.supertype_field);
1115                     }
1116                     if (moreInfo)
1117                         s += String.valueOf(sym.hashCode());
1118                     return s;
1119                 } else if (longform) {
1120                     return sym.getQualifiedName().toString();
1121                 } else {
1122                     return sym.name.toString();
1123                 }
1124             }
1125 




1126         @DefinedBy(Api.LANGUAGE_MODEL)
1127         public List<Type> getTypeArguments() {
1128             if (typarams_field == null) {
1129                 complete();
1130                 if (typarams_field == null)
1131                     typarams_field = List.nil();
1132             }
1133             return typarams_field;
1134         }
1135 
1136         public boolean hasErasedSupertypes() {
1137             return isRaw();
1138         }
1139 
1140         @DefinedBy(Api.LANGUAGE_MODEL)
1141         public Type getEnclosingType() {



1142             return outer_field;
1143         }
1144 
1145         public void setEnclosingType(Type outer) {
1146             outer_field = outer;
1147         }
1148 
1149         public List<Type> allparams() {
1150             if (allparams_field == null) {
1151                 allparams_field = getTypeArguments().prependList(getEnclosingType().allparams());
1152             }
1153             return allparams_field;
1154         }
1155 
1156         public boolean isErroneous() {
1157             return
1158                 getEnclosingType().isErroneous() ||
1159                 isErroneous(getTypeArguments()) ||
1160                 this != tsym.type && tsym.type.isErroneous();
1161         }
1162 
1163         public boolean isParameterized() {
1164             return allparams().tail != null;
1165             // optimization, was: allparams().nonEmpty();
1166         }
1167 
1168         @Override
1169         public boolean isReference() {
1170             return true;
1171         }
1172 










































































1173         @Override
1174         public boolean isNullOrReference() {
1175             return true;
1176         }
1177 
1178         /** A cache for the rank. */
1179         int rank_field = -1;
1180 
1181         /** A class type is raw if it misses some
1182          *  of its type parameter sections.
1183          *  After validation, this is equivalent to:
1184          *  {@code allparams.isEmpty() && tsym.type.allparams.nonEmpty(); }
1185          */
1186         public boolean isRaw() {
1187             return
1188                 this != tsym.type && // necessary, but not sufficient condition
1189                 tsym.type.allparams().nonEmpty() &&
1190                 allparams().isEmpty();
1191         }
1192 

1201 
1202         public void complete() {
1203             tsym.complete();
1204         }
1205 
1206         @DefinedBy(Api.LANGUAGE_MODEL)
1207         public TypeKind getKind() {
1208             tsym.apiComplete();
1209             return tsym.kind == TYP ? TypeKind.DECLARED : TypeKind.ERROR;
1210         }
1211 
1212         @DefinedBy(Api.LANGUAGE_MODEL)
1213         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1214             return v.visitDeclared(this, p);
1215         }
1216     }
1217 
1218     public static class ErasedClassType extends ClassType {
1219         public ErasedClassType(Type outer, TypeSymbol tsym,
1220                                List<TypeMetadata> metadata) {
1221             super(outer, List.nil(), tsym, metadata);
1222         }
1223 
1224         @Override
1225         public boolean hasErasedSupertypes() {
1226             return true;
1227         }
1228     }
1229 
1230     // a clone of a ClassType that knows about the alternatives of a union type.
1231     public static class UnionClassType extends ClassType implements UnionType {
1232         final List<? extends Type> alternatives_field;
1233 
1234         public UnionClassType(ClassType ct, List<? extends Type> alternatives) {
1235             // Presently no way to refer to this type directly, so we
1236             // cannot put annotations directly on it.
1237             super(ct.outer_field, ct.typarams_field, ct.tsym);
1238             allparams_field = ct.allparams_field;
1239             supertype_field = ct.supertype_field;
1240             interfaces_field = ct.interfaces_field;
1241             all_interfaces_field = ct.interfaces_field;

2312         @Override
2313         public boolean isNullOrReference() {
2314             return true;
2315         }
2316 
2317     }
2318 
2319     public static class ErrorType extends ClassType
2320             implements javax.lang.model.type.ErrorType {
2321 
2322         private Type originalType = null;
2323 
2324         public ErrorType(ClassSymbol c, Type originalType) {
2325             this(originalType, c);
2326             c.type = this;
2327             c.kind = ERR;
2328             c.members_field = new Scope.ErrorScope(c);
2329         }
2330 
2331         public ErrorType(Type originalType, TypeSymbol tsym) {
2332             super(noType, List.nil(), null);
2333             this.tsym = tsym;
2334             this.originalType = (originalType == null ? noType : originalType);
2335         }
2336 
2337         private ErrorType(Type originalType, TypeSymbol tsym,
2338                           List<TypeMetadata> metadata) {
2339             super(noType, List.nil(), null, metadata);
2340             this.tsym = tsym;
2341             this.originalType = (originalType == null ? noType : originalType);
2342         }
2343 
2344         @Override
2345         protected ErrorType cloneWithMetadata(List<TypeMetadata> md) {
2346             return new ErrorType(originalType, tsym, md) {
2347                 @Override
2348                 public Type baseType() { return ErrorType.this.baseType(); }
2349             };
2350         }
2351 
2352         @Override
2353         public TypeTag getTag() {
2354             return ERROR;
2355         }
2356 
2357         @Override
2358         public boolean isPartial() {
2359             return true;
2360         }
2361 
2362         @Override
2363         public boolean isReference() {
2364             return true;
2365         }
2366 

  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.Optional;
  34 import java.util.function.Function;
  35 import java.util.function.Predicate;
  36 
  37 import javax.lang.model.type.*;
  38 
  39 import com.sun.tools.javac.code.Symbol.*;
  40 import com.sun.tools.javac.code.Type.ClassType.Flavor;
  41 import com.sun.tools.javac.code.TypeMetadata.Annotations;
  42 import com.sun.tools.javac.code.TypeMetadata.ConstantValue;
  43 import com.sun.tools.javac.code.Types.TypeMapping;
  44 import com.sun.tools.javac.code.Types.UniqueType;
  45 import com.sun.tools.javac.comp.Infer.IncorporationAction;
  46 import com.sun.tools.javac.jvm.ClassFile;
  47 import com.sun.tools.javac.jvm.PoolConstant;
  48 import com.sun.tools.javac.util.*;
  49 import com.sun.tools.javac.util.DefinedBy.Api;
  50 
  51 import static com.sun.tools.javac.code.BoundKind.*;
  52 import static com.sun.tools.javac.code.Flags.*;
  53 import static com.sun.tools.javac.code.Kinds.Kind.*;
  54 import static com.sun.tools.javac.code.TypeTag.*;
  55 
  56 /** This class represents Java types. The class itself defines the behavior of
  57  *  the following types:
  58  *  <pre>
  59  *  base types (tags: BYTE, CHAR, SHORT, INT, LONG, FLOAT, DOUBLE, BOOLEAN),
  60  *  type `void' (tag: VOID),

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

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

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

1493 
1494         public void complete() {
1495             tsym.complete();
1496         }
1497 
1498         @DefinedBy(Api.LANGUAGE_MODEL)
1499         public TypeKind getKind() {
1500             tsym.apiComplete();
1501             return tsym.kind == TYP ? TypeKind.DECLARED : TypeKind.ERROR;
1502         }
1503 
1504         @DefinedBy(Api.LANGUAGE_MODEL)
1505         public <R, P> R accept(TypeVisitor<R, P> v, P p) {
1506             return v.visitDeclared(this, p);
1507         }
1508     }
1509 
1510     public static class ErasedClassType extends ClassType {
1511         public ErasedClassType(Type outer, TypeSymbol tsym,
1512                                List<TypeMetadata> metadata) {
1513             super(outer, List.nil(), tsym, metadata, tsym.type.getFlavor());
1514         }
1515 
1516         @Override
1517         public boolean hasErasedSupertypes() {
1518             return true;
1519         }
1520     }
1521 
1522     // a clone of a ClassType that knows about the alternatives of a union type.
1523     public static class UnionClassType extends ClassType implements UnionType {
1524         final List<? extends Type> alternatives_field;
1525 
1526         public UnionClassType(ClassType ct, List<? extends Type> alternatives) {
1527             // Presently no way to refer to this type directly, so we
1528             // cannot put annotations directly on it.
1529             super(ct.outer_field, ct.typarams_field, ct.tsym);
1530             allparams_field = ct.allparams_field;
1531             supertype_field = ct.supertype_field;
1532             interfaces_field = ct.interfaces_field;
1533             all_interfaces_field = ct.interfaces_field;

2604         @Override
2605         public boolean isNullOrReference() {
2606             return true;
2607         }
2608 
2609     }
2610 
2611     public static class ErrorType extends ClassType
2612             implements javax.lang.model.type.ErrorType {
2613 
2614         private Type originalType = null;
2615 
2616         public ErrorType(ClassSymbol c, Type originalType) {
2617             this(originalType, c);
2618             c.type = this;
2619             c.kind = ERR;
2620             c.members_field = new Scope.ErrorScope(c);
2621         }
2622 
2623         public ErrorType(Type originalType, TypeSymbol tsym) {
2624             super(noType, List.nil(), tsym, List.nil(), Flavor.E_Typeof_X);

2625             this.originalType = (originalType == null ? noType : originalType);
2626         }
2627 
2628         private ErrorType(Type originalType, TypeSymbol tsym,
2629                           List<TypeMetadata> metadata, Flavor flavor) {
2630             super(noType, List.nil(), null, metadata, flavor);
2631             this.tsym = tsym;
2632             this.originalType = (originalType == null ? noType : originalType);
2633         }
2634 
2635         @Override
2636         public ErrorType cloneWithMetadata(List<TypeMetadata> md) {
2637             return new ErrorType(originalType, tsym, md, getFlavor()) {
2638                 @Override
2639                 public Type baseType() { return ErrorType.this.baseType(); }
2640             };
2641         }
2642 
2643         @Override
2644         public TypeTag getTag() {
2645             return ERROR;
2646         }
2647 
2648         @Override
2649         public boolean isPartial() {
2650             return true;
2651         }
2652 
2653         @Override
2654         public boolean isReference() {
2655             return true;
2656         }
2657 
< prev index next >