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
|