1 // Copyright (c) 1997, 2000, 2003, 2004, 2006, 2009 Per M.A. Bothner. 2 // This is free software; for terms and warranty disclaimer see ./COPYING. 3 4 package gnu.bytecode; 5 import java.util.*; 6 import gnu.kawa.util.AbstractWeakHashTable; 7 8 /** An abstract type as used by both gnu.bytecode and gnu.expr. */ 9 10 public abstract class Type 11 /* #ifdef JAVA5 */ 12 implements java.lang.reflect.Type 13 /* #endif */ 14 { 15 String signature; 16 String genericSignature; 17 // Fully-qualified name (in external format, i.e. using '.' to separate). 18 String this_name; 19 /** 20 * Nominal unpromoted size in bytes. 21 */ 22 int size; 23 24 ArrayType array_type; 25 Type()26 protected Type () { } 27 28 /** Return Java-level implementation type. 29 * The type used to implement types not natively understood by the JVM 30 * or the Java language. 31 * Usually, the identity function. However, a language might handle 32 * union types or template types or type expressions calculated at 33 * run time. In that case return the type used at the Java level, 34 * and known at compile time. 35 */ getImplementationType()36 public Type getImplementationType() 37 { 38 return this; 39 } 40 41 /** Return JVM-level implementation type. */ getRawType()42 public Type getRawType() { 43 Type t = getImplementationType(); 44 if (t != this && t != null) 45 t = t.getRawType(); 46 return t; 47 } 48 49 /** If this is a type alias, get the aliased type. 50 * This is semi-deprecated. 51 */ getRealType()52 public Type getRealType() { 53 return this; 54 } 55 isInterface()56 public boolean isInterface() { 57 Type raw = getRawType(); 58 return raw != this && raw.isInterface(); 59 } 60 isExisting()61 public boolean isExisting() 62 { 63 // Overridden in ObjectType. 64 return true; 65 } 66 67 static ClassToTypeMap mapClassToType; 68 69 /** Maps Java type name (e.g. "java.lang.String[]") to corresponding Type. */ 70 /* #ifdef JAVA5 */ 71 static java.util.HashMap<String,Type> mapNameToType; 72 /* #else */ 73 // static java.util.Hashtable mapNameToType; 74 /* #endif */ 75 lookupType(String name)76 public static Type lookupType (String name) 77 { 78 /* #ifdef JAVA5 */ 79 java.util.HashMap<String,Type> map = mapNameToType; 80 synchronized (map) { return map.get(name); } 81 /* #else */ 82 // return (Type) mapNameToType.get(name); 83 /* #endif */ 84 } 85 86 /** Find an Type with the given name, or create a new one. 87 * Use this for "library classes", where you need the field/method types, 88 * but not one where you are about to generate code for. 89 * @param name the name of the class (e..g. "java.lang.String"). 90 */ getType(String name)91 public static Type getType (String name) 92 { 93 /* #ifdef JAVA5 */ 94 java.util.HashMap<String,Type> map = mapNameToType; 95 /* #else */ 96 // java.util.Hashtable map = mapNameToType; 97 /* #endif */ 98 synchronized (map) 99 { 100 Type type = (Type) map.get(name); 101 if (type == null) 102 { 103 if (name.endsWith("[]")) 104 type = ArrayType.make(name); 105 else 106 { 107 ClassType cl = new ClassType(name); 108 cl.setExisting(true); 109 type = cl; 110 } 111 map.put(name, type); 112 } 113 return type; 114 } 115 } 116 117 /** Register that the Type for class is type. */ registerTypeForClass(Class clas, Type type)118 public synchronized static void registerTypeForClass(Class clas, Type type) 119 { 120 ClassToTypeMap map = mapClassToType; 121 if (map == null) 122 mapClassToType = map = new ClassToTypeMap(); 123 type.reflectClass = clas; 124 map.put(clas, type); 125 } 126 127 /** Try to map java.lang.reflect.Type to gnu.bytecode.Type. 128 * If we can't handle that, resolve the Class instead. 129 */ make(Class reflectClass, java.lang.reflect.Type type)130 public static Type make(Class reflectClass, java.lang.reflect.Type type) { 131 Type t = make(type); 132 return t != null ? t : make(reflectClass); 133 } 134 135 /** Resolve a java.lang.reflect.Type to gnu.bytecode.Type. 136 * Handles simple parameterized types, but does not handle type variables. 137 * @return a translated Type, or null for unhandled types. 138 */ make(java.lang.reflect.Type type)139 static Type make(java.lang.reflect.Type type) { 140 if (type instanceof Class) 141 return make((Class) type); 142 if (type instanceof java.lang.reflect.GenericArrayType) 143 return null; 144 if (type instanceof java.lang.reflect.ParameterizedType) { 145 java.lang.reflect.ParameterizedType ptype 146 = (java.lang.reflect.ParameterizedType) type; 147 java.lang.reflect.Type typeArguments[] 148 = ptype.getActualTypeArguments(); 149 Type rt = Type.make(ptype.getRawType()); 150 if (rt instanceof ClassType) { 151 ClassType rawType = (ClassType) rt; 152 int nargs = typeArguments.length; 153 Type[] typeArgumentTypes = new Type[nargs]; 154 char[] bounds = new char[nargs]; 155 for (int i = 0; i < nargs; i++) { 156 java.lang.reflect.Type ti = typeArguments[i]; 157 if (ti instanceof java.lang.reflect.WildcardType) { 158 java.lang.reflect.WildcardType wi = 159 (java.lang.reflect.WildcardType) ti; 160 java.lang.reflect.Type[] lower = wi.getLowerBounds(); 161 java.lang.reflect.Type[] upper = wi.getUpperBounds(); 162 if (lower.length + upper.length != 1) 163 return null; 164 else if (lower.length == 1) { 165 bounds[i] = '-'; 166 ti = lower[0]; 167 } 168 else /* if (upper.length == 1) */ { 169 bounds[i] = '+'; 170 ti = upper[0]; 171 } 172 } 173 typeArgumentTypes[i] = Type.make(ti); 174 } 175 ParameterizedType ret = new ParameterizedType(rawType, typeArgumentTypes); 176 ret.setTypeArgumentBounds(bounds); 177 return ret; 178 } 179 } 180 if (type instanceof java.lang.reflect.TypeVariable) { 181 return TypeVariable.make((java.lang.reflect.TypeVariable) type); 182 } 183 return null; 184 } 185 make(Class reflectClass)186 public synchronized static Type make(Class reflectClass) 187 { 188 Type type; 189 190 if (mapClassToType != null) 191 { 192 Type t = mapClassToType.get(reflectClass); 193 if (t != null) 194 return t; 195 } 196 if (reflectClass.isArray()) 197 type = ArrayType.make(Type.make(reflectClass.getComponentType())); 198 else if (reflectClass.isPrimitive()) 199 throw new Error("internal error - primitive type not found"); 200 else 201 { 202 String name = reflectClass.getName(); 203 /* #ifdef JAVA5 */ 204 java.util.HashMap<String,Type> map = mapNameToType; 205 /* #else */ 206 // java.util.Hashtable map = mapNameToType; 207 /* #endif */ 208 synchronized (map) 209 { 210 type = (Type) map.get(name); 211 if (type == null 212 || (type.reflectClass != reflectClass 213 && type.reflectClass != null)) 214 { 215 ClassType cl = new ClassType(name); 216 cl.setExisting(true); 217 type = cl; 218 mapNameToType.put(name, type); 219 } 220 } 221 } 222 registerTypeForClass(reflectClass, type); 223 return type; 224 } 225 getSignature()226 public String getSignature() { return signature; } setSignature(String sig)227 protected void setSignature(String sig) { this.signature = sig; } getGenericSignature()228 public String getGenericSignature() { return genericSignature; } setGenericSignature(String sig)229 protected void setGenericSignature(String sig) { this.genericSignature = sig; } getMaybeGenericSignature()230 public String getMaybeGenericSignature() { 231 String s = getGenericSignature(); 232 return s != null ? s : getSignature(); 233 } 234 Type(String nam, String sig)235 Type (String nam, String sig) { 236 this_name = nam; 237 signature = sig; 238 } 239 Type(Type type)240 public Type (Type type) 241 { 242 this_name = type.this_name; 243 signature = type.signature; 244 size = type.size; 245 reflectClass = type.reflectClass; 246 } 247 promote()248 public Type promote () { 249 return size < 4 ? intType : this; 250 } 251 promoteIfUnsigned()252 public Type promoteIfUnsigned() { 253 if (this instanceof PrimType) { 254 char sig1 = signature.charAt(0); 255 if ((sig1 == 'B' || sig1 == 'S') && ((PrimType) this).isUnsigned()) 256 return intType; 257 } 258 return this; 259 } 260 getSize()261 public final int getSize() { return size; } getSizeInWords()262 public int getSizeInWords () { return size > 4 ? 2 : 1; } 263 isVoid()264 public final boolean isVoid () { return size == 0; } 265 266 /** Returns the primitive type corresponding to a signature character. 267 * @return a primitive type, or null if there is no such type. */ signatureToPrimitive(char sig)268 public static PrimType signatureToPrimitive(char sig) 269 { 270 switch(sig) 271 { 272 case 'B': return Type.byteType; 273 case 'C': return Type.charType; 274 case 'D': return Type.doubleType; 275 case 'F': return Type.floatType; 276 case 'S': return Type.shortType; 277 case 'I': return Type.intType; 278 case 'J': return Type.longType; 279 case 'Z': return Type.booleanType; 280 case 'V': return Type.voidType; 281 } 282 return null; 283 } 284 285 /** Get a Type corresponding to the given signature string. */ signatureToType(String sig, int off, int len)286 public static Type signatureToType(String sig, int off, int len) 287 { 288 if (len == 0) 289 return null; 290 char c = sig.charAt(off); 291 Type type; 292 if (len == 1) 293 { 294 type = signatureToPrimitive(c); 295 if (type != null) 296 return type; 297 } 298 if (c == '[') 299 { 300 type = signatureToType(sig, off+1, len-1); 301 return type == null ? null : ArrayType.make(type); 302 } 303 if (c == 'L' && len > 2 && sig.indexOf(';', off) == len-1+off) 304 return ClassType.make(sig.substring(off+1,len-1+off).replace('/', '.')); 305 return null; 306 } 307 308 /** Get a Type corresponding to the given signature string. */ signatureToType(String sig)309 public static Type signatureToType(String sig) 310 { 311 return signatureToType(sig, 0, sig.length()); 312 } 313 printSignature(String sig, int off, int len, java.io.PrintWriter out)314 public static void printSignature (String sig, int off, int len, 315 java.io.PrintWriter out) 316 { 317 if (len == 0) 318 return; 319 char c = sig.charAt(off); 320 Type type; 321 if (len == 1) 322 { 323 type = signatureToPrimitive(c); 324 if (type != null) 325 out.print(type.getName()); 326 } 327 else if (c == '[') 328 { 329 printSignature(sig, off+1, len-1, out); 330 out.print("[]"); 331 } 332 else if (c == 'L' && len > 2 && sig.indexOf(';', off) == len-1+off) 333 out.print(sig.substring(off+1,len-1+off).replace('/', '.')); 334 else 335 out.append(sig, off, len-off); 336 } 337 338 /** Return the length of the signature starting at a given string position. 339 * Returns -1 for an invalid signature. */ signatureLength(String sig, int pos)340 public static int signatureLength (String sig, int pos) 341 { 342 int len = sig.length(); 343 if (len <= pos) 344 return -1; 345 char c = sig.charAt(pos); 346 int arrays = 0; 347 while (c == '[') 348 { 349 arrays++; 350 pos++; 351 c = sig.charAt(pos); 352 } 353 if (signatureToPrimitive(c) != null) 354 return arrays+1; 355 if (c == 'L') 356 { 357 int end = sig.indexOf(';', pos); 358 if (end > 0) 359 return arrays + end + 1 - pos; 360 } 361 return -1; 362 } 363 signatureLength(String sig)364 public static int signatureLength (String sig) 365 { 366 return signatureLength(sig, 0); 367 } 368 369 /** Returns the Java-level type name from a given signature. 370 * Returns null for an invalid signature. */ signatureToName(String sig)371 public static String signatureToName(String sig) 372 { 373 int len = sig.length(); 374 if (len == 0) 375 return null; 376 char c = sig.charAt(0); 377 Type type; 378 if (len == 1) 379 { 380 type = signatureToPrimitive(c); 381 if (type != null) 382 return type.getName(); 383 } 384 if (c == '[') 385 { 386 int arrays = 1; 387 if (arrays < len && sig.charAt(arrays) == '[') 388 arrays++; 389 sig = signatureToName(sig.substring(arrays)); 390 if (sig == null) 391 return null; 392 StringBuffer buf = new StringBuffer(50); 393 buf.append(sig); 394 while (--arrays >= 0) 395 buf.append("[]"); 396 return buf.toString(); 397 } 398 if (c == 'L' && len > 2 && sig.indexOf(';') == len-1) 399 return sig.substring(1,len-1).replace('/', '.'); 400 return null; 401 } 402 getName()403 public String getName () 404 { 405 return this_name; 406 } 407 setName(String name)408 protected void setName (String name) 409 { 410 this_name = name; 411 } 412 isValidJavaTypeName(String name)413 public static boolean isValidJavaTypeName (String name) 414 { 415 boolean in_name = false; 416 int i; 417 int len = name.length(); 418 while (len > 2 && name.charAt(len-1) == ']' 419 && name.charAt(len-2) == '[') 420 len -= 2; 421 for (i = 0; i < len; i++) 422 { 423 char ch = name.charAt(i); 424 if (ch == '.') 425 { 426 if (in_name) 427 in_name = false; 428 else 429 return false; 430 } 431 else if (in_name ? Character.isJavaIdentifierPart(ch) 432 : Character.isJavaIdentifierStart(ch)) 433 in_name = true; 434 else 435 return false; 436 } 437 return i == len; 438 } 439 isInstance(Object obj)440 public boolean isInstance (Object obj) 441 { 442 return getReflectClass().isInstance(obj); 443 } 444 445 /** Return true if this is a "subtype" of other. */ isSubtype(Type other)446 public final boolean isSubtype (Type other) 447 { 448 int comp = compare(other); 449 return comp == -1 || comp == 0; 450 } 451 452 /** If this is the target type, is a given source type compatible? 453 * @return -1 if not compatible; 0 if need to check at run-time; 454 * 1 if compatible; 2 if compatible and no conversion or cast needed. 455 * We also return 0 for some "narrowing" conversions even if we know 456 * they will always succeed, so as to make such conversions less 457 * preferred when doing method overloading. 458 */ isCompatibleWithValue(Type valueType)459 public int isCompatibleWithValue(Type valueType) { 460 if (Type.isSame(this, valueType)) 461 return 2; 462 if (this == toStringType) 463 return valueType == javalangStringType ? 2 : 0; 464 // Hack for LangPrimType.charType. 465 if (this == charType && valueType.getImplementationType()== this) 466 return 2; 467 return isCompatibleWithValue(this, valueType); 468 } 469 isCompatibleWithValue(Type targetType, Type valueType)470 public static int isCompatibleWithValue(Type targetType, Type valueType) { 471 int comp = targetType.compare(valueType); 472 return comp >= 0 ? 1 : comp == -3 ? -1 : 0; 473 } 474 475 /** 476 * Computes the common supertype 477 * 478 * Interfaces are not taken into account. 479 * This would be difficult, since interfaces allow multiple-inheritance. 480 * This means that there may exists multiple common supertypes 481 * to t1 and t2 that are not comparable. 482 * 483 * @return the lowest type that is both above t1 and t2, 484 * or null if t1 and t2 have no common supertype. 485 */ lowestCommonSuperType(Type t1, Type t2)486 public static Type lowestCommonSuperType(Type t1, Type t2) 487 { 488 if (t1 == neverReturnsType) 489 return t2; 490 if (t2 == neverReturnsType) 491 return t1; 492 if (t1 == null || t2 == null) 493 return null; 494 if (t1 == t2) 495 return t1; 496 if (t1 instanceof PrimType && t2 instanceof PrimType) 497 { 498 t1 = ((PrimType) t1).promotedType(); 499 t2 = ((PrimType) t2).promotedType(); 500 return t1 == t2 ? t1 : null; 501 } 502 return lowestCommonSharedType(t1, t2); 503 } 504 lowestCommonSharedType(Type t1, Type t2)505 public static Type lowestCommonSharedType(Type t1, Type t2) 506 { 507 if (t1.isSubtype(t2)) 508 return t2; 509 else if (t2.isSubtype(t1)) 510 return t1; 511 else 512 { 513 // the only chance left is that t1 and t2 are ClassTypes. 514 if (!(t1 instanceof ClassType && t2 instanceof ClassType)) 515 return Type.objectType; 516 ClassType c1 = (ClassType) t1; 517 ClassType c2 = (ClassType) t2; 518 if (! c1.isInterface() && ! c2.isInterface()) 519 { 520 ClassType s1 = c1.getSuperclass(); 521 ClassType s2 = c2.getSuperclass(); 522 if (s1 != null && s2 != null) 523 return lowestCommonSuperType(s1, s2); 524 } 525 } 526 return Type.objectType; 527 } 528 529 /** Return a numeric code showing "subtype" relationship: 530 * 1: if other is a pure subtype of this; 531 * 0: if has the same values; 532 * -1: if this is a pure subtype of other; 533 * -2: if they have values in common but neither is a subtype of the other; 534 * -3: if the types have no values in common. 535 * "Same values" is rather loose; by "A is a subtype of B" 536 * we mean that all instance of A can be "widened" to B. 537 * More formally, A.compare(B) returns: 538 * 1: all B values can be converted to A without a coercion failure 539 * (i.e. a ClassCastException or overflow or major loss of information), 540 * but not vice versa. 541 * 0: all A values can be converted to B without a coercion failure 542 * and vice versa; 543 * -1: all A values can be converted to B without a coercion failure 544 * but not vice versa; 545 * -2: there are (potentially) some A values that can be converted to B, 546 * and some B values can be converted to A; 547 * -3: there are no A values that can be converted to B, and neither 548 * are there any B values that can be converted to A. 549 */ compare(Type other)550 public abstract int compare(Type other); 551 552 /** Change result from compare to compensate for argument swapping. */ swappedCompareResult(int code)553 protected static int swappedCompareResult(int code) 554 { 555 return code == 1 ? -1 : code == -1 ? 1 : code; 556 } 557 558 /** Return true iff t1[i].isSubtype(t2[i]) for all i. */ isMoreSpecific(Type[] t1, Type[] t2)559 public static boolean isMoreSpecific (Type[] t1, Type[] t2) 560 { 561 if (t1.length != t2.length) 562 return false; 563 for (int i = t1.length; --i >= 0; ) 564 { 565 if (! t1[i].isSubtype(t2[i])) 566 return false; 567 } 568 return true; 569 } 570 isSame(Type t1, Type t2)571 public static boolean isSame(Type t1, Type t2) { 572 return t1 == t2 573 || (t1 != null && t2 != null && t1.equals(t2)); 574 } 575 emitIsInstance(CodeAttr code)576 public void emitIsInstance (CodeAttr code) 577 { 578 code.emitInstanceof(this); 579 } 580 581 /** Convert an object to a value of this Type. 582 * The result is actually of the implementation type, boxed as appropriate, 583 * so it is suitable for standard reflective operations, 584 * like the arguments to Field#set or Method#invoke. 585 * Throw a ClassCastException when this is not possible. 586 */ coerceFromObject(Object obj)587 public abstract Object coerceFromObject (Object obj); 588 589 /** Given a raw JVM value convert it to an object of this type. 590 * I.e. the argument is an object of the type returned by 591 * {@code getRawType()}, boxed as needed. The result may be 592 * a language-specific (boxed) value. Generally a no-op. 593 */ coerceToObject(Object obj)594 public Object coerceToObject(Object obj) { 595 return obj; 596 } 597 598 /** Convert from stackType (usually PrimType) to this type. 599 * However, we might only convert part-way, to some object type. 600 * If converting to this type might fail at run-time, only convert 601 * to Object (as by emitCoerceToObject); a caller can use 602 * {@code stackType.emitConvertFromObject} to convert the rest, 603 * but that might throw an exception. (This is a bit of a kludge.) 604 */ emitConvertFromPrimitive(Type stackType, CodeAttr code)605 public void emitConvertFromPrimitive (Type stackType, CodeAttr code) 606 { 607 stackType.emitCoerceToObject(code); 608 } 609 610 /** Compile code to convert a object of this type on the stack to Object. */ emitCoerceToObject(CodeAttr code)611 public void emitCoerceToObject (CodeAttr code) 612 { 613 } 614 615 /** Compile code to coerce/convert from Object to this type. */ emitCoerceFromObject(CodeAttr code)616 public void emitCoerceFromObject (CodeAttr code) 617 { 618 throw new Error ("unimplemented emitCoerceFromObject for "+this); 619 } 620 621 public static final PrimType byteType 622 = new PrimType ("byte", "B", 1, java.lang.Byte.TYPE); 623 public static final PrimType shortType 624 = new PrimType ("short", "S", 2, java.lang.Short.TYPE); 625 public static final PrimType intType 626 = new PrimType ("int", "I", 4, java.lang.Integer.TYPE); 627 public static final PrimType longType 628 = new PrimType ("long", "J", 8, java.lang.Long.TYPE); 629 public static final PrimType floatType 630 = new PrimType ("float", "F", 4, java.lang.Float.TYPE); 631 public static final PrimType doubleType 632 = new PrimType ("double", "D", 8, java.lang.Double.TYPE); 633 public static final PrimType booleanType 634 = new PrimType ("boolean", "Z", 1, java.lang.Boolean.TYPE); 635 public static final PrimType charType 636 = new PrimType ("char", "C", 2, java.lang.Character.TYPE); 637 public static final PrimType voidType 638 = new PrimType ("void", "V", 0, java.lang.Void.TYPE); 639 640 /* @deprecated */ public static final PrimType byte_type = byteType; 641 /* @deprecated */ public static final PrimType short_type = shortType; 642 /* @deprecated */ public static final PrimType int_type = intType; 643 /* @deprecated */ public static final PrimType long_type = longType; 644 /* @deprecated */ public static final PrimType float_type = floatType; 645 /* @deprecated */ public static final PrimType double_type = doubleType; 646 /* @deprecated */ public static final PrimType boolean_type = booleanType; 647 /* @deprecated */ public static final PrimType char_type = charType; 648 /* @deprecated */ public static final PrimType void_type = voidType; 649 650 static 651 { 652 /* #ifdef JAVA5 */ 653 mapNameToType = new java.util.HashMap<String,Type>(); 654 /* #else */ 655 // mapNameToType = new java.util.Hashtable(); 656 /* #endif */ 657 mapNameToType.put("byte", byteType); 658 mapNameToType.put("short", shortType); 659 mapNameToType.put("int", intType); 660 mapNameToType.put("long", longType); 661 mapNameToType.put("float", floatType); 662 mapNameToType.put("double", doubleType); 663 mapNameToType.put("boolean", booleanType); 664 mapNameToType.put("char", charType); 665 mapNameToType.put("void", voidType); 666 } 667 668 /** The return type of an expression that never returns, such as a throw. */ 669 public static final Type neverReturnsType 670 = ClassType.make("gnu.bytecode.Type$NeverReturns"); 671 672 public static final ClassType javalangObjectType 673 = ClassType.make("java.lang.Object"); 674 public static final ClassType objectType = javalangObjectType; 675 public static final ClassType javalangBooleanType 676 = ClassType.make("java.lang.Boolean"); 677 public static final ClassType javalangCharacterType 678 = ClassType.make("java.lang.Character"); 679 public static final ClassType javalangThrowableType 680 = ClassType.make("java.lang.Throwable"); 681 public static final ClassType javalangannotationAnnotationType 682 = ClassType.make("java.lang.annotation.Annotation"); 683 public static final Type[] typeArray0 = new Type[0]; 684 public static final Method toString_method 685 = objectType.getDeclaredMethod("toString", 0); 686 public static final ClassType javalangNumberType 687 = ClassType.make("java.lang.Number"); 688 public static final Method clone_method 689 = Method.makeCloneMethod(objectType); 690 public static final Method intValue_method 691 = javalangNumberType.addMethod("intValue", typeArray0, 692 intType, Access.PUBLIC); 693 public static final Method longValue_method 694 = javalangNumberType.addMethod("longValue", typeArray0, 695 longType, Access.PUBLIC); 696 public static final Method floatValue_method 697 = javalangNumberType.addMethod("floatValue", typeArray0, 698 floatType, Access.PUBLIC); 699 public static final Method doubleValue_method 700 = javalangNumberType.addMethod("doubleValue", typeArray0, 701 doubleType, Access.PUBLIC); 702 public static final Method booleanValue_method 703 = javalangBooleanType.addMethod("booleanValue", typeArray0, 704 booleanType, Access.PUBLIC); 705 public static final ClassType javalangClassType 706 = ClassType.make("java.lang.Class"); 707 708 public static final ClassType javalanginvokeMethodHandleType 709 = ClassType.make("java.lang.invoke.MethodHandle"); 710 711 /** The magic type of null. */ 712 public static final ObjectType nullType 713 //= new ObjectType("(type of null)"); 714 = new SpecialObjectType("(type of null)", objectType); 715 public static final ObjectType errorType 716 = new SpecialObjectType("<error-type>", javalangObjectType); 717 718 static public ClassType javalangStringType = ClassType.make("java.lang.String"); 719 /* The String type. but coercion is handled by toString. */ 720 public static final ObjectType toStringType 721 = new SpecialObjectType("String", javalangStringType); 722 723 @Deprecated 724 public static final ClassType pointer_type = javalangObjectType; 725 @Deprecated 726 public static final ClassType string_type = javalangStringType; 727 @Deprecated 728 public static final ObjectType tostring_type = toStringType; 729 @Deprecated 730 public static final ClassType java_lang_Class_type = javalangClassType; 731 @Deprecated 732 public static final ClassType boolean_ctype = javalangBooleanType; 733 public static final ClassType throwable_type = javalangThrowableType; 734 @Deprecated 735 public static final ClassType number_type = javalangNumberType; 736 737 protected Class reflectClass; 738 739 /** Get the java.lang.Class object for the representation type. */ getReflectClass()740 public java.lang.Class getReflectClass() 741 { 742 return reflectClass; 743 } 744 setReflectClass(java.lang.Class rclass)745 public void setReflectClass(java.lang.Class rclass) 746 { 747 reflectClass = rclass; 748 } 749 toString()750 public String toString() 751 { 752 return "Type " + getName(); 753 } 754 hashCode()755 public int hashCode() 756 { 757 String name = toString(); 758 return name == null ? 0 : name.hashCode (); 759 } 760 761 /** A marker class, used for {@code Type.neverReturnsType}. */ 762 public static class NeverReturns { NeverReturns()763 private NeverReturns() { } 764 } 765 766 static class ClassToTypeMap extends AbstractWeakHashTable<Class,Type> 767 { getKeyFromValue(Type type)768 protected Class getKeyFromValue (Type type) 769 { 770 return type.reflectClass; 771 } 772 matches(Class oldValue, Class newValue)773 protected boolean matches (Class oldValue, Class newValue) 774 { 775 // Minor optimization. 776 return oldValue == newValue; 777 } 778 } 779 } 780