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
|