1 cananian 1.41.2.16 // HClass.java, created Fri Jul 31 4:33:28 1998 by cananian 2 cananian 1.30 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.30 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1 package harpoon.ClassFile; 5 cananian 1.1 6 cananian 1.41.2.25 import harpoon.Util.ArrayFactory; 7 cananian 1.47 import net.cscott.jutil.ReferenceUnique; 8 cananian 1.47 import net.cscott.jutil.UniqueVector; 9 cananian 1.34 import harpoon.Util.Util; 10 cananian 1.34 11 cananian 1.5 import java.lang.reflect.Modifier; 12 cananian 1.45 import java.util.ArrayList; 13 cananian 1.45 import java.util.HashMap; 14 cananian 1.45 import java.util.List; 15 cananian 1.45 import java.util.Map; 16 cananian 1.1 17 cananian 1.3 /** 18 cananian 1.3 * Instances of the class <code>HClass</code> represent classes and 19 cananian 1.3 * interfaces of a java program. Every array also belongs to a 20 cananian 1.3 * class that is reflected as a <code>HClass</code> object that is 21 cananian 1.3 * shared by all arrays with the same element type and number of 22 cananian 1.3 * dimensions. Finally, the primitive Java types 23 cananian 1.3 * (<code>boolean</code>, <code>byte</code>, <code>char</code>, 24 cananian 1.3 * <code>short</code>, <code>int</code>, <code>long</code>, 25 cananian 1.3 * <code>float</code>, and <code>double</code>) and the keyword 26 cananian 1.3 * <code>void</code> are also represented as <code>HClass</code> objects. 27 cananian 1.3 * <p> 28 cananian 1.3 * There is no public constructor for the class <code>HClass</code>. 29 cananian 1.3 * <code>HClass</code> objects are created with the <code>forName</code>, 30 cananian 1.46 * <code>forDescriptor</code> and <code>forClass</code> methods of 31 cananian 1.46 * <code>Linker</code>. 32 cananian 1.3 * 33 cananian 1.10 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 34 cananian 1.47 * @version $Id: HClass.java,v 1.47 2004/02/08 01:58:03 cananian Exp $ 35 cananian 1.41.2.7 * @see harpoon.IR.RawClass.ClassFile 36 cananian 1.41.2.24 * @see java.lang.Class 37 cananian 1.3 */ 38 cananian 1.41.2.23 public abstract class HClass extends HPointer 39 cananian 1.46 implements java.lang.Comparable<HClass>, ReferenceUnique, HType { 40 cananian 1.41.2.30 /** The linker responsible for the resolution of this <code>HClass</code> 41 cananian 1.41.2.30 * object. */ 42 cananian 1.41.2.30 private final Linker _linker; 43 cananian 1.41.2.30 boolean hasBeenModified = false; 44 cananian 1.37 45 cananian 1.41.2.17 /** Protected constructor, not for external use. */ 46 cananian 1.41.2.30 HClass(Linker l) { _linker = l; } 47 cananian 1.37 48 cananian 1.2 /** 49 cananian 1.41.2.30 * Returns the linker responsible for the resolution of this 50 cananian 1.41.2.30 * <code>HClass</code> object. 51 cananian 1.41.2.30 */ 52 cananian 1.41.2.30 public final Linker getLinker() { return _linker; } 53 cananian 1.1 54 cananian 1.41.2.30 /** 55 cananian 1.41.2.30 * Returns a mutator for this <code>HClass</code>, or <code>null</code> 56 cananian 1.41.2.30 * if this object is immutable. 57 cananian 1.41.2.30 */ 58 cananian 1.41.2.30 public HClassMutator getMutator() { return null; } 59 cananian 1.1 60 cananian 1.41.2.30 /** 61 cananian 1.41.2.30 * Determines whether any part of this <code>HClass</code> has been 62 cananian 1.41.2.30 * modified from its originally loaded state. 63 cananian 1.41.2.30 */ 64 cananian 1.41.2.30 public boolean hasBeenModified() { return hasBeenModified; } 65 cananian 1.2 66 cananian 1.2 /** 67 cananian 1.2 * If this class represents an array type, returns the <code>HClass</code> 68 cananian 1.2 * object representing the component type of the array; otherwise returns 69 cananian 1.2 * null. 70 cananian 1.2 * @see java.lang.reflect.Array 71 cananian 1.2 */ 72 cananian 1.41.2.30 public abstract HClass getComponentType(); 73 cananian 1.1 74 cananian 1.1 /** 75 cananian 1.1 * Returns the fully-qualified name of the type (class, interface, 76 cananian 1.1 * array, or primitive) represented by this <code>HClass</code> object, 77 cananian 1.1 * as a <code>String</code>. 78 cananian 1.1 * @return the fully qualified name of the class or interface 79 cananian 1.1 * represented by this object. 80 cananian 1.1 */ 81 cananian 1.34 public abstract String getName(); 82 cananian 1.34 83 cananian 1.1 /** 84 cananian 1.6 * Returns the package name of this <code>HClass</code>. If this 85 cananian 1.6 * <code>HClass</code> represents a primitive or array type, 86 cananian 1.6 * then returns null. Returns <code>""</code> (a zero-length string) 87 cananian 1.6 * if this class is not in a package. 88 cananian 1.6 */ 89 cananian 1.41.2.30 public abstract String getPackage(); 90 cananian 1.41.2.30 91 cananian 1.6 /** 92 cananian 1.2 * Returns a ComponentType descriptor for the type represented by this 93 cananian 1.2 * <code>HClass</code> object. 94 cananian 1.2 */ 95 cananian 1.34 public abstract String getDescriptor(); 96 cananian 1.34 97 cananian 1.3 /** 98 cananian 1.3 * Returns a <code>HField</code> object that reflects the specified 99 cananian 1.3 * declared field of the class or interface represented by this 100 cananian 1.3 * <code>HClass</code> object. The <code>name</code> parameter is a 101 cananian 1.3 * <code>String</code> that specifies the simple name of the 102 cananian 1.3 * desired field. 103 cananian 1.20 * @exception NoSuchFieldError 104 cananian 1.3 * if a field with the specified name is not found. 105 cananian 1.3 * @see HField 106 cananian 1.3 */ 107 cananian 1.41.2.30 public abstract HField getDeclaredField(String name) 108 cananian 1.41.2.30 throws NoSuchFieldError; 109 cananian 1.41.2.30 110 cananian 1.3 /** 111 cananian 1.3 * Returns an array of <code>HField</code> objects reflecting all the 112 cananian 1.3 * fields declared by the class or interface represented by this 113 cananian 1.3 * <code>HClass</code> object. This includes <code>public</code>, 114 cananian 1.3 * <code>protected</code>, default (<code>package</code>) access, 115 cananian 1.3 * and <code>private</code> fields, but excludes inherited fields. 116 cananian 1.3 * Returns an array of length 0 if the class or interface declares 117 cananian 1.3 * no fields, or if this <code>HClass</code> object represents a 118 cananian 1.3 * primitive type. 119 cananian 1.41.2.14 * @see "The Java Language Specification, sections 8.2 and 8.3" 120 cananian 1.3 * @see HField 121 cananian 1.3 */ 122 cananian 1.34 public abstract HField[] getDeclaredFields(); 123 cananian 1.34 124 cananian 1.3 /** 125 cananian 1.3 * Returns a <code>HField</code> object that reflects the specified 126 cananian 1.6 * accessible member field of the class or interface represented by this 127 cananian 1.3 * <code>HClass</code> object. The <code>name</code> parameter is 128 cananian 1.3 * a <code>String</code> specifying the simple name of the 129 cananian 1.3 * desired field. <p> 130 cananian 1.3 * The field to be reflected is located by searching all member fields 131 cananian 1.3 * of the class or interface represented by this <code>HClass</code> 132 cananian 1.6 * object (and its superclasses and interfaces) for an accessible 133 cananian 1.6 * field with the specified name. 134 cananian 1.3 * @see "The Java Language Specification, sections 8.2 and 8.3" 135 cananian 1.20 * @exception NoSuchFieldError 136 cananian 1.3 * if a field with the specified name is not found. 137 cananian 1.3 * @see HField 138 cananian 1.5 */ 139 cananian 1.41.2.33 public final HField getField(String name) throws NoSuchFieldError { 140 cananian 1.5 // construct master field list, if we haven't already. 141 cananian 1.41.2.33 HField[] fields=getFields(); 142 cananian 1.5 // look for field name in master field list. 143 cananian 1.5 // look backwards to be sure we find local fields first (scoping) 144 cananian 1.5 for (int i=fields.length-1; i>=0; i--) 145 cananian 1.5 if (fields[i].getName().equals(name)) 146 cananian 1.5 return fields[i]; 147 cananian 1.5 // can't find it. 148 cananian 1.41.2.33 throw new NoSuchFieldError(getName()+"."+name); 149 cananian 1.3 } 150 cananian 1.41.2.30 151 cananian 1.3 /** 152 cananian 1.3 * Returns an array containing <code>HField</code> objects reflecting 153 cananian 1.6 * all the accessible fields of the class or interface represented by this 154 cananian 1.3 * <code>HClass</code> object. Returns an array of length 0 if the 155 cananian 1.6 * class or interface has no accessible fields, or if it represents an 156 cananian 1.6 * array type or a primitive type. <p> 157 cananian 1.3 * Specifically, if this <code>HClass</code> object represents a class, 158 cananian 1.6 * returns the accessible fields of this class and of all its superclasses. 159 cananian 1.5 * If this <code>HClass</code> object represents an interface, returns 160 cananian 1.6 * the accessible fields 161 cananian 1.3 * of this interface and of all its superinterfaces. If this 162 cananian 1.3 * <code>HClass</code> object represents an array type or a primitive 163 cananian 1.3 * type, returns an array of length 0. <p> 164 cananian 1.3 * The implicit length field for array types is not reflected by this 165 cananian 1.3 * method. 166 cananian 1.3 * @see "The Java Language Specification, sections 8.2 and 8.3" 167 cananian 1.3 * @see HField 168 cananian 1.5 */ 169 cananian 1.6 public HField[] getFields() { 170 cananian 1.41.2.33 if (isPrimitive() || isArray()) 171 cananian 1.41.2.33 return new HField[0]; 172 cananian 1.41.2.33 // do the actual work. 173 cananian 1.45 UniqueVector<HField> v = new UniqueVector<HField>(); 174 cananian 1.6 // add fields from interfaces. 175 cananian 1.6 HClass[] in = getInterfaces(); 176 cananian 1.6 for (int i=0; i<in.length; i++) { 177 cananian 1.41.2.33 HField[] inf = in[i].getFields(); 178 cananian 1.6 for (int j=0; j<inf.length; j++) 179 cananian 1.45 v.add(inf[j]); 180 cananian 1.6 } 181 cananian 1.6 // now fields from superclasses, subject to access mode constraints. 182 cananian 1.6 HClass sup = getSuperclass(); 183 cananian 1.41.2.33 HField supf[] = (sup==null)?new HField[0]:sup.getFields(); 184 cananian 1.6 for (int i=0; i<supf.length; i++) { 185 cananian 1.6 int m = supf[i].getModifiers(); 186 cananian 1.6 // private fields of superclasses are invisible. 187 cananian 1.6 if (Modifier.isPrivate(m)) 188 cananian 1.6 continue; // skip this field. 189 cananian 1.6 // default access is invisible if packages not identical. 190 cananian 1.41.2.33 /** DISABLED: see notes in getMethods() [CSA 6-22-99] */ 191 cananian 1.41.2.33 /* 192 cananian 1.6 if (!Modifier.isPublic(m) && !Modifier.isProtected(m)) 193 cananian 1.6 if (!supf[i].getDeclaringClass().getPackage().equals(frmPackage)) 194 cananian 1.6 continue; 195 cananian 1.41.2.33 */ 196 cananian 1.6 // all's good. Add this one. 197 cananian 1.45 v.add(supf[i]); 198 cananian 1.6 } 199 cananian 1.6 // now fields from our local class. 200 cananian 1.6 HField locf[] = getDeclaredFields(); 201 cananian 1.6 for (int i=0; i<locf.length; i++) 202 cananian 1.45 v.add(locf[i]); 203 cananian 1.6 204 cananian 1.6 // Merge into one array. 205 cananian 1.45 return v.toArray(new HField[v.size()]); 206 cananian 1.6 } 207 cananian 1.5 208 cananian 1.5 /** 209 cananian 1.5 * Returns a <code>HMethod</code> object that reflects the specified 210 cananian 1.5 * declared method of the class or interface represented by this 211 cananian 1.5 * <code>HClass</code> object. The <code>name</code> parameter is a 212 cananian 1.5 * <code>String</code> that specifies the simple name of the desired 213 cananian 1.5 * method, and the <code>parameterTypes</code> parameter is an array 214 cananian 1.5 * of <code>HClass</code> objects that identify the method's formal 215 cananian 1.5 * parameter types, in declared order. 216 cananian 1.20 * @exception NoSuchMethodError 217 cananian 1.5 * if a matching method is not found. 218 cananian 1.5 * @see HMethod 219 cananian 1.5 */ 220 cananian 1.41.2.30 public abstract HMethod getDeclaredMethod(String name, 221 cananian 1.41.2.30 HClass parameterTypes[]) 222 cananian 1.41.2.30 throws NoSuchMethodError; 223 cananian 1.41.2.30 224 cananian 1.31 /** 225 cananian 1.31 * Returns a <code>HMethod</code> object that reflects the specified 226 cananian 1.31 * declared method of the class or interface represented by this 227 cananian 1.31 * <code>HClass</code> object. The <code>name</code> parameter is a 228 cananian 1.31 * <code>String</code> that specifies the simple name of the desired 229 cananian 1.31 * method, and <code>descriptor</code> is a string describing 230 cananian 1.31 * the parameter types and return value of the method. 231 cananian 1.31 * @exception NoSuchMethodError 232 cananian 1.31 * if a matching method is not found. 233 cananian 1.31 * @see HMethod#getDescriptor 234 cananian 1.31 */ 235 cananian 1.41.2.30 public abstract HMethod getDeclaredMethod(String name, String descriptor) 236 cananian 1.41.2.30 throws NoSuchMethodError; 237 cananian 1.41.2.30 238 cananian 1.5 /** 239 cananian 1.5 * Returns an array of <code>HMethod</code> objects reflecting all the 240 cananian 1.5 * methods declared by the class or interface represented by this 241 cananian 1.5 * <code>HClass</code> object. This includes <code>public</code>, 242 cananian 1.5 * <code>protected</code>, default (<code>package</code>) access, and 243 cananian 1.5 * <code>private</code> methods, but excludes inherited methods. 244 cananian 1.5 * Returns an array of length 0 if the class or interface declares no 245 cananian 1.5 * methods, or if this <code>HClass</code> object represents a primitive 246 cananian 1.7 * type.<p> 247 cananian 1.7 * Constructors are included. 248 cananian 1.5 * @see "The Java Language Specification, section 8.2" 249 cananian 1.5 * @see HMethod 250 cananian 1.5 */ 251 cananian 1.34 public abstract HMethod[] getDeclaredMethods(); 252 cananian 1.34 253 cananian 1.6 /** 254 cananian 1.20 * Returns an <code>HMethod</code> object that reflects the specified 255 cananian 1.6 * accessible method of the class or interface represented by this 256 cananian 1.6 * <code>HClass</code> object. The <code>name</code> parameter is 257 cananian 1.6 * a string specifying the simple name of the desired method, and 258 cananian 1.6 * the <code>parameterTypes</code> parameter is an array of 259 cananian 1.6 * <code>HClass</code> objects that identify the method's formal 260 cananian 1.6 * parameter types, in declared order. <p> 261 cananian 1.6 * The method to reflect is located by searching all the member methods 262 cananian 1.6 * of the class or interface represented by this <code>HClass</code> 263 cananian 1.6 * object for an accessible method with the specified name and exactly 264 cananian 1.6 * the same formal parameter types. 265 cananian 1.6 * @see "The Java Language Specification, sections 8.2 and 8.4" 266 cananian 1.20 * @exception NoSuchMethodError if a matching method is not found. 267 cananian 1.6 */ 268 cananian 1.41.2.33 public final HMethod getMethod(String name, HClass parameterTypes[]) 269 cananian 1.20 throws NoSuchMethodError { 270 cananian 1.6 // construct master method list, if we haven't already. 271 cananian 1.34 HMethod[] methods=getMethods(); 272 cananian 1.20 // look for method name in master method list. 273 cananian 1.6 // look backwards to be sure we find local methods first (scoping). 274 cananian 1.6 for (int i=methods.length-1; i>=0; i--) 275 cananian 1.6 if (methods[i].getName().equals(name)) { 276 cananian 1.6 HClass[] methodParamTypes = methods[i].getParameterTypes(); 277 cananian 1.6 if (methodParamTypes.length == parameterTypes.length) { 278 cananian 1.6 int j; for (j=0; j<parameterTypes.length; j++) 279 cananian 1.32 if (methodParamTypes[j] != parameterTypes[j]) 280 cananian 1.6 break; // oops, this one doesn't match. 281 cananian 1.6 if (j==parameterTypes.length) // hey, we made it to the end! 282 cananian 1.6 return methods[i]; 283 cananian 1.6 } 284 cananian 1.6 } 285 cananian 1.6 // didn't find a match. Oh, well. 286 cananian 1.41.2.33 throw new NoSuchMethodError(getName()+"."+name); 287 cananian 1.6 } 288 cananian 1.41.2.30 289 cananian 1.6 /** 290 cananian 1.20 * Returns an <code>HMethod</code> object that reflects the specified 291 cananian 1.20 * accessible method of the class or interface represented by this 292 cananian 1.20 * <code>HClass</code> object. The <code>name</code> parameter is 293 cananian 1.20 * a string specifying the simple name of the desired method, and 294 cananian 1.20 * the <code>descriptor</code> is a string describing the 295 cananian 1.20 * parameter types and return value of the method. <p> 296 cananian 1.20 * The method is located by searching all the member methods of 297 cananian 1.20 * the class or interface represented by this <code>HClass</code> 298 cananian 1.20 * object for an accessible method with the specified name and 299 cananian 1.20 * exactly the same descriptor. 300 cananian 1.20 * @see HMethod#getDescriptor 301 cananian 1.20 * @exception NoSuchMethodError if a matching method is not found. 302 cananian 1.20 */ 303 cananian 1.41.2.33 public final HMethod getMethod(String name, String descriptor) 304 cananian 1.20 throws NoSuchMethodError { 305 cananian 1.20 // construct master method list, if we haven't already. 306 cananian 1.34 HMethod[] methods=getMethods(); 307 cananian 1.20 // look for method name in master method list. 308 cananian 1.20 // look backwards to be sure we find local methods first (scoping) 309 cananian 1.20 for (int i=methods.length-1; i>=0; i--) 310 cananian 1.20 if (methods[i].getName().equals(name) && 311 cananian 1.20 methods[i].getDescriptor().equals(descriptor)) 312 cananian 1.20 return methods[i]; 313 cananian 1.20 // didn't find a match. 314 cananian 1.41.2.33 throw new NoSuchMethodError(getName()+"."+name+"/"+descriptor); 315 cananian 1.20 } 316 cananian 1.20 317 cananian 1.20 /** 318 cananian 1.6 * Returns an array containing <code>HMethod</code> object reflecting 319 cananian 1.6 * all accessible member methods of the class or interface represented 320 cananian 1.6 * by this <code>HClass</code> object, including those declared by 321 cananian 1.6 * the class or interface and those inherited from superclasses and 322 cananian 1.6 * superinterfaces. Returns an array of length 0 if the class or 323 cananian 1.6 * interface has no public member methods, or if the <code>HClass</code> 324 cananian 1.7 * corresponds to a primitive type or array type.<p> 325 cananian 1.7 * Constructors are included. 326 cananian 1.6 * @see "The Java Language Specification, sections 8.2 and 8.4" 327 cananian 1.6 */ 328 cananian 1.6 public HMethod[] getMethods() { 329 cananian 1.41.2.33 if (isPrimitive()) 330 cananian 1.41.2.33 return new HMethod[0]; 331 cananian 1.41.2.33 // do the actual work. 332 cananian 1.45 Map<String,HMethod> h = new HashMap<String,HMethod>(); // keep track of overriding 333 cananian 1.45 List<HMethod> v = new ArrayList<HMethod>(); 334 cananian 1.41.2.33 335 cananian 1.41.2.33 // first methods we declare locally. 336 cananian 1.41.2.33 HMethod[] locm = getDeclaredMethods(); 337 cananian 1.41.2.33 for (int i=0; i<locm.length; i++) { 338 cananian 1.41.2.33 h.put(locm[i].getName()+locm[i].getDescriptor(), locm[i]); 339 cananian 1.45 v.add(locm[i]); 340 cananian 1.6 } 341 cananian 1.41.2.33 locm=null; // free memory 342 cananian 1.41.2.33 343 cananian 1.6 // grab fields from superclasses, subject to access mode constraints. 344 cananian 1.41.2.36 // note interfaces have the methods of java.lang.Object, too. 345 cananian 1.6 HClass sup = getSuperclass(); 346 cananian 1.41.2.36 if (isInterface()) sup=_linker.forName("java.lang.Object");//this not prim. 347 cananian 1.41.2.33 HMethod supm[] = (sup==null)?new HMethod[0]:sup.getMethods(); 348 cananian 1.6 for (int i=0; i<supm.length; i++) { 349 cananian 1.6 int m = supm[i].getModifiers(); 350 cananian 1.6 // private methods of superclasses are invisible. 351 cananian 1.6 if (Modifier.isPrivate(m)) 352 cananian 1.6 continue; // skip this method. 353 cananian 1.6 // default access is invisible if packages not identical 354 cananian 1.41.2.33 /** SKIPPING this test, because the interpreter doesn't like it. 355 cananian 1.41.2.33 ** For example, harpoon.IR.Quads.OPER invokes 356 cananian 1.41.2.33 ** OperVisitor.dispatch() in method visit(). But dispatch() has 357 cananian 1.41.2.33 ** package visibility and thus doesn't show up in 358 cananian 1.41.2.33 ** SCCAnalysis...operVisitor, and a virtual dispatch to visit() 359 cananian 1.41.2.33 ** on an object of type SCCAnalysis...operVisitor fails. Current 360 cananian 1.41.2.33 ** solution is to move this check into the interpreter; see 361 cananian 1.41.2.33 ** harpoon.Interpret.Quads.Method. [CSA, 6-22-99] */ 362 cananian 1.41.2.33 /* 363 cananian 1.6 if (!Modifier.isPublic(m) && !Modifier.isProtected(m)) 364 cananian 1.6 if (!supm[i].getDeclaringClass().getPackage().equals(frmPackage)) 365 cananian 1.6 continue; // skip this (inaccessible) method. 366 cananian 1.41.2.33 */ 367 cananian 1.24 // skip superclass constructors. 368 cananian 1.24 if (supm[i] instanceof HConstructor) 369 cananian 1.24 continue; 370 cananian 1.41.2.33 // don't add methods which are overriden by locally declared methods. 371 cananian 1.41.2.33 if (h.containsKey(supm[i].getName()+supm[i].getDescriptor())) 372 cananian 1.41.2.33 continue; 373 cananian 1.6 // all's good. Add this one. 374 cananian 1.41.2.33 h.put(supm[i].getName()+supm[i].getDescriptor(), supm[i]); 375 cananian 1.45 v.add(supm[i]); 376 cananian 1.6 } 377 cananian 1.41.2.33 sup=null; supm=null; // free memory. 378 cananian 1.41.2.33 379 cananian 1.41.2.33 // Lastly, interface methods, if not already declared. 380 cananian 1.41.2.33 // [interface methods will typically be explicitly declared in classes, 381 cananian 1.41.2.33 // even if not implemented (abstract), but superinterface methods aren't 382 cananian 1.41.2.33 // declared explicitly in interfaces.] 383 cananian 1.41.2.33 HClass[] intc = getInterfaces(); 384 cananian 1.41.2.33 for (int i=0; i<intc.length; i++) { 385 cananian 1.41.2.33 HMethod intm[] = intc[i].getMethods(); 386 cananian 1.41.2.33 for (int j=0; j<intm.length; j++) { 387 cananian 1.41.2.33 // don't add methods which are overridden by locally declared methods 388 cananian 1.41.2.33 if (h.containsKey(intm[j].getName()+intm[j].getDescriptor())) 389 cananian 1.41.2.33 continue; 390 cananian 1.45 v.add(intm[j]); 391 cananian 1.41.2.33 } 392 cananian 1.41.2.33 } 393 cananian 1.41.2.33 intc = null; // free memory. 394 cananian 1.6 395 cananian 1.6 // Merge into a single array. 396 cananian 1.45 return v.toArray(new HMethod[v.size()]); 397 cananian 1.3 } 398 cananian 1.34 399 cananian 1.7 /** 400 cananian 1.7 * Returns an <code>HConstructor</code> object that reflects the 401 cananian 1.7 * specified declared constructor of the class or interface represented 402 cananian 1.7 * by this <code>HClass</code> object. The <code>parameterTypes</code> 403 cananian 1.7 * parameter is an array of <code>HClass</code> objects that 404 cananian 1.7 * identify the constructor's formal parameter types, in declared order. 405 cananian 1.20 * @exception NoSuchMethodError if a matching method is not found. 406 cananian 1.7 */ 407 cananian 1.41.2.30 public abstract HConstructor getConstructor(HClass parameterTypes[]) 408 cananian 1.41.2.30 throws NoSuchMethodError; 409 cananian 1.34 410 cananian 1.7 /** 411 cananian 1.7 * Returns an array of <code>HConstructor</code> objects reflecting 412 cananian 1.7 * all the constructors declared by the class represented by the 413 cananian 1.7 * <code>HClass</code> object. These are <code>public</code>, 414 cananian 1.7 * <code>protected</code>, default (package) access, and 415 cananian 1.7 * <code>private</code> constructors. Returns an array of length 0 416 cananian 1.7 * if this <code>HClass</code> object represents an interface or a 417 cananian 1.7 * primitive type. 418 cananian 1.7 * @see "The Java Language Specification, section 8.2" 419 cananian 1.7 */ 420 cananian 1.41.2.30 public abstract HConstructor[] getConstructors(); 421 cananian 1.3 422 cananian 1.8 /** 423 cananian 1.8 * Returns the class initializer method, if there is one; otherwise 424 cananian 1.8 * <code>null</code>. 425 cananian 1.8 * @see "The Java Virtual Machine Specification, section 3.8" 426 cananian 1.8 */ 427 cananian 1.41.2.30 public abstract HInitializer getClassInitializer(); 428 cananian 1.41.2.3 429 cananian 1.2 /** 430 cananian 1.2 * Returns the Java language modifiers for this class or interface, 431 cananian 1.2 * encoded in an integer. The modifiers consist of the Java Virtual 432 cananian 1.2 * Machine's constants for public, protected, private, final, and 433 cananian 1.2 * interface; they should be decoded using the methods of class Modifier. 434 cananian 1.2 * @see "The Java Virtual Machine Specification, table 4.1" 435 cananian 1.2 * @see java.lang.reflect.Modifier 436 cananian 1.2 */ 437 cananian 1.34 public abstract int getModifiers(); 438 cananian 1.2 439 cananian 1.2 /** 440 cananian 1.1 * If this object represents any class other than the class 441 cananian 1.1 * <code>Object</code>, then the object that represents the superclass of 442 cananian 1.1 * that class is returned. 443 cananian 1.1 * <p> If this object is the one that represents the class 444 cananian 1.1 * <code>Object</code> or this object represents an interface, 445 cananian 1.1 * <code>null</code> is returned. 446 cananian 1.41.2.27 * If this object represents an array, then the <code>HClass</code> 447 cananian 1.41.2.27 * representing <code>java.lang.Object</code> is returned. 448 cananian 1.1 * @return the superclass of the class represented by this object. 449 cananian 1.1 */ 450 cananian 1.34 public abstract HClass getSuperclass(); 451 cananian 1.1 452 cananian 1.1 /** 453 cananian 1.1 * Determines the interfaces implemented by the class or interface 454 cananian 1.1 * represented by this object. 455 cananian 1.1 * <p> If this object represents a class, the return value is an 456 cananian 1.1 * array containing objects representing all interfaces implemented by 457 cananian 1.1 * the class. The order of the interface objects in the array corresponds 458 cananian 1.1 * to the order of the interface names in the implements clause of the 459 cananian 1.1 * declaration of the class represented by this object. 460 cananian 1.1 * <p> If the object represents an interface, the array contains objects 461 cananian 1.1 * representing all interfaces extended by the interface. The order of 462 cananian 1.1 * the interface objects in the array corresponds to the order of the 463 cananian 1.1 * interface names in the extends clause of the declaration of the 464 cananian 1.1 * interface represented by this object. 465 cananian 1.1 * <p> If the class or interface implements no interfaces, the method 466 cananian 1.1 * returns an array of length 0. 467 cananian 1.41.2.24 * <p><b>NOTE THAT the array returned does NOT contain interfaces 468 cananian 1.41.2.24 * implemented by superclasses.</b> Thus the interface list may 469 cananian 1.41.2.24 * be incomplete. This is pretty bogus behaviour, but it's what 470 cananian 1.41.2.24 * our prototype, <code>java.lang.Class</code>, does. 471 cananian 1.1 * @return an array of interfaces implemented by this class. 472 cananian 1.1 */ 473 cananian 1.34 public abstract HClass[] getInterfaces(); 474 cananian 1.14 475 cananian 1.14 /** 476 cananian 1.14 * Return the name of the source file for this class, or a 477 cananian 1.14 * zero-length string if the information is not available. 478 cananian 1.41.2.7 * @see harpoon.IR.RawClass.AttributeSourceFile 479 cananian 1.14 */ 480 cananian 1.41.2.30 public abstract String getSourceFile(); 481 cananian 1.2 482 cananian 1.19 /** 483 cananian 1.19 * If this <code>HClass</code> is a primitive type, return the 484 cananian 1.19 * wrapper class for values of this type. For example:<p> 485 cananian 1.19 * <DL><DD><CODE>HClass.forDescriptor("I").getWrapper()</CODE></DL><p> 486 cananian 1.41.2.35 * will return <code>l.forName("java.lang.Integer")</code>. 487 cananian 1.19 * Calling <code>getWrapper</code> with a non-primitive <code>HClass</code> 488 cananian 1.19 * will return the value <code>null</code>. 489 cananian 1.19 */ 490 cananian 1.41.2.35 public final HClass getWrapper(Linker l) { 491 cananian 1.41.2.35 if (this==this.Boolean) return l.forName("java.lang.Boolean"); 492 cananian 1.41.2.35 if (this==this.Byte) return l.forName("java.lang.Byte"); 493 cananian 1.41.2.35 if (this==this.Char) return l.forName("java.lang.Character"); 494 cananian 1.41.2.35 if (this==this.Double) return l.forName("java.lang.Double"); 495 cananian 1.41.2.35 if (this==this.Float) return l.forName("java.lang.Float"); 496 cananian 1.41.2.35 if (this==this.Int) return l.forName("java.lang.Integer"); 497 cananian 1.41.2.35 if (this==this.Long) return l.forName("java.lang.Long"); 498 cananian 1.41.2.35 if (this==this.Short) return l.forName("java.lang.Short"); 499 cananian 1.41.2.35 if (this==this.Void) return l.forName("java.lang.Void"); 500 cananian 1.19 return null; // not a primitive type; 501 cananian 1.19 } 502 cananian 1.19 503 cananian 1.19 /** 504 cananian 1.2 * If this <code>HClass</code> object represents an array type, 505 cananian 1.2 * returns <code>true</code>, otherwise returns <code>false</code>. 506 cananian 1.2 */ 507 cananian 1.41.2.30 public abstract boolean isArray(); 508 cananian 1.34 /** 509 cananian 1.34 * Determines if the specified <code>HClass</code> object represents an 510 cananian 1.34 * interface type. 511 cananian 1.34 * @return <code>true</code> is this object represents an interface; 512 cananian 1.34 * <code>false</code> otherwise. 513 cananian 1.34 */ 514 cananian 1.41.2.30 public abstract boolean isInterface(); 515 cananian 1.34 516 cananian 1.34 /** 517 cananian 1.34 * Determines if the specified <code>HClass</code> object represents a 518 cananian 1.34 * primitive Java type. <p> 519 cananian 1.34 * There are nine predefined <code>HClass</code> objects to represent 520 cananian 1.34 * the eight primitive Java types and void. 521 cananian 1.34 */ 522 cananian 1.41.2.30 public abstract boolean isPrimitive(); 523 cananian 1.2 524 cananian 1.2 /** 525 cananian 1.2 * Determines if the class or interface represented by this 526 cananian 1.2 * <code>HClass</code> object is either the same as, or is a superclass 527 cananian 1.2 * or superinterface of, the class or interface represented by the 528 cananian 1.2 * specified <code>HClass</code> parameter. It returns 529 cananian 1.2 * <code>true</code> if so, <code>false</code> otherwise. If this 530 cananian 1.2 * <code>HClass</code> object represents a primitive type, returns 531 cananian 1.2 * <code>true</code> if the specified <code>HClass</code> parameter is 532 cananian 1.2 * exactly this <code>HClass</code> object, <code>false</code> 533 cananian 1.2 * otherwise. 534 cananian 1.2 * <p> Specifically, this method tests whether the type represented 535 cananian 1.2 * by the specified <code>HClass</code> parameter can be converted 536 cananian 1.2 * to the type represented by this <code>HClass</code> object via an 537 cananian 1.2 * identity conversion or via a widening reference conversion. 538 cananian 1.2 * @see "The Java Language Specification, sections 5.1.1 and 5.1.4" 539 cananian 1.2 * @exception NullPointerException 540 cananian 1.2 * if the specified <code>HClass</code> parameter is null. 541 cananian 1.41.2.29 */ 542 cananian 1.41.2.31 public final boolean isAssignableFrom(HClass cls) { 543 cananian 1.43.2.1 assert _linker == cls._linker || isPrimitive() || cls.isPrimitive(); 544 cananian 1.2 if (cls==null) throw new NullPointerException(); 545 cananian 1.2 // test identity conversion. 546 cananian 1.41.2.31 if (cls==this) return true; 547 cananian 1.41.2.31 // widening reference conversions... 548 cananian 1.41.2.31 if (this.isPrimitive()) return false; 549 cananian 1.41.2.31 // widening reference conversions from the null type: 550 cananian 1.41.2.31 if (cls==HClass.Void) return true; 551 cananian 1.41.2.31 if (cls.isPrimitive()) return false; 552 cananian 1.2 // widening reference conversions from an array: 553 cananian 1.2 if (cls.isArray()) { 554 cananian 1.41.2.31 if (this == _linker.forName("java.lang.Object")) return true; 555 cananian 1.41.2.31 if (this == _linker.forName("java.lang.Cloneable")) return true; 556 cananian 1.41.2.31 // see http://java.sun.com/docs/books/jls/clarify.html 557 cananian 1.41.2.31 if (this == _linker.forName("java.io.Serializable")) return true; 558 cananian 1.41.2.31 if (isArray() && 559 cananian 1.41.2.31 !getComponentType().isPrimitive() && 560 cananian 1.41.2.31 !cls.getComponentType().isPrimitive() && 561 cananian 1.2 getComponentType().isAssignableFrom(cls.getComponentType())) 562 cananian 1.2 return true; 563 cananian 1.2 return false; 564 cananian 1.2 } 565 cananian 1.41.2.31 // widening reference conversions from an interface type. 566 cananian 1.41.2.31 if (cls.isInterface()) { 567 cananian 1.41.2.31 if (this.isInterface() && this.isSuperinterfaceOf(cls)) return true; 568 cananian 1.41.2.31 if (this == _linker.forName("java.lang.Object")) return true; 569 cananian 1.41.2.31 return false; 570 cananian 1.41.2.31 } 571 cananian 1.41.2.31 // widening reference conversions from a class type: 572 cananian 1.41.2.31 if (!this.isInterface() && this.isSuperclassOf(cls)) return true; 573 cananian 1.41.2.31 if (this.isInterface() && this.isSuperinterfaceOf(cls)) return true; 574 cananian 1.2 return false; 575 cananian 1.2 } 576 cananian 1.2 577 cananian 1.2 /** 578 cananian 1.28 * Determines if this <code>HClass</code> is a superclass of a given 579 cananian 1.41.2.5 * <code>HClass</code> <code>hc</code>. 580 cananian 1.41.2.5 * [Does not look at interface information.] 581 cananian 1.28 * @return <code>true</code> if <code>this</code> is a superclass of 582 cananian 1.28 * <code>hc</code>, <code>false</code> otherwise. 583 cananian 1.2 */ 584 cananian 1.41.2.31 public final boolean isSuperclassOf(HClass hc) { 585 cananian 1.43.2.1 assert _linker == hc._linker || isPrimitive() || hc.isPrimitive(); 586 cananian 1.43.2.1 assert !this.isInterface(); 587 cananian 1.41.2.31 for ( ; hc!=null; hc = hc.getSuperclass()) 588 cananian 1.41.2.31 if (this == hc) return true; 589 cananian 1.41.2.31 return false; 590 cananian 1.2 } 591 cananian 1.2 592 cananian 1.2 /** 593 cananian 1.41.2.5 * Determines if this <code>HClass</code> is a superinterface of a given 594 cananian 1.41.2.5 * <code>HClass</code> <code>hc</code>. 595 cananian 1.41.2.5 * [does not look at superclass information] 596 cananian 1.41.2.5 * @return <code>true</code> if <code>this</code> is a superinterface of 597 cananian 1.28 * <code>hc</code>, <code>false</code> otherwise. 598 cananian 1.28 */ 599 cananian 1.41.2.31 public final boolean isSuperinterfaceOf(HClass hc) { 600 cananian 1.43.2.1 assert _linker == hc._linker || isPrimitive() || hc.isPrimitive(); 601 cananian 1.43.2.1 assert this.isInterface(); 602 cananian 1.45 UniqueVector<HClass> uv = 603 cananian 1.45 new UniqueVector<HClass>();//unique in case of circularity 604 cananian 1.28 for ( ; hc!=null; hc = hc.getSuperclass()) 605 cananian 1.45 uv.add(hc); 606 cananian 1.41.2.31 607 cananian 1.41.2.31 for (int i=0; i<uv.size(); i++) 608 cananian 1.45 if (uv.get(i) == this) return true; 609 cananian 1.41.2.31 else { 610 cananian 1.45 HClass in[] = uv.get(i).getInterfaces(); 611 cananian 1.41.2.31 for (int j=0; j<in.length; j++) 612 cananian 1.45 uv.add(in[j]); 613 cananian 1.41.2.31 } 614 cananian 1.41.2.31 // ran out of possibilities. 615 cananian 1.2 return false; 616 cananian 1.2 } 617 cananian 1.2 618 cananian 1.41.2.5 /** 619 cananian 1.41.2.5 * Determines if this <code>HClass</code> is an instance of the given 620 cananian 1.41.2.5 * <code>HClass</code> <code>hc</code>. 621 cananian 1.40 */ 622 cananian 1.41.2.31 public final boolean isInstanceOf(HClass hc) { 623 cananian 1.43.2.1 assert _linker == hc._linker || isPrimitive() || hc.isPrimitive(); 624 cananian 1.41.2.31 if (this.isArray()) { 625 cananian 1.41.2.31 if (!hc.isArray()) 626 cananian 1.41.2.31 // see http://java.sun.com/docs/books/jls/clarify.html 627 cananian 1.41.2.31 return (hc==_linker.forName("java.lang.Cloneable") || 628 cananian 1.41.2.31 hc==_linker.forName("java.io.Serializable") || 629 cananian 1.41.2.31 hc==_linker.forName("java.lang.Object")); 630 cananian 1.41.2.31 HClass SC = this.getComponentType(); 631 cananian 1.41.2.31 HClass TC = hc.getComponentType(); 632 cananian 1.41.2.31 return ((SC.isPrimitive() && TC.isPrimitive() && SC==TC) || 633 cananian 1.41.2.31 (!SC.isPrimitive()&&!TC.isPrimitive() && SC.isInstanceOf(TC))); 634 cananian 1.41.2.31 } else { // not array. 635 cananian 1.41.2.31 if (hc.isInterface()) 636 cananian 1.41.2.31 return hc.isSuperinterfaceOf(this); 637 cananian 1.41.2.31 else // hc is class. 638 cananian 1.41.2.31 if (this.isInterface()) // in recursive eval of array instanceof. 639 cananian 1.41.2.31 return (hc==_linker.forName("java.lang.Object")); 640 cananian 1.41.2.31 else return hc.isSuperclassOf(this); 641 cananian 1.41.2.31 } 642 cananian 1.41.2.31 } 643 cananian 1.40 644 cananian 1.40 public int hashCode() { return getDescriptor().hashCode(); } 645 cananian 1.2 /** 646 cananian 1.2 * Converts the object to a string. The string representation is the 647 cananian 1.2 * string <code>"class"</code> or <code>"interface"</code> followed by 648 cananian 1.2 * a space and then the fully qualified name of the class. If this 649 cananian 1.2 * <code>HClass</code> object represents a primitive type, 650 cananian 1.2 * returns the name of the primitive type. 651 cananian 1.2 * @return a string representation of this class object. 652 cananian 1.2 */ 653 cananian 1.41.2.31 public final String toString() { 654 cananian 1.41.2.31 return (isPrimitive()?"":isInterface()?"interface ":"class ")+getName(); 655 cananian 1.41.2.31 } 656 cananian 1.11 657 cananian 1.13 /** 658 cananian 1.12 * Prints a formatted representation of this class. 659 cananian 1.12 * Output is pseudo-Java source. 660 cananian 1.11 */ 661 cananian 1.41.2.30 public final void print(java.io.PrintWriter pw) { 662 cananian 1.11 int m; 663 cananian 1.11 // package declaration. 664 cananian 1.41.2.30 if (getPackage()!=null && !getPackage().equals("")) 665 cananian 1.41.2.30 pw.println("package " + getPackage() + ";"); 666 cananian 1.11 // class declaration. 667 cananian 1.11 m = getModifiers() & (~32); // unset the ACC_SUPER flag. 668 cananian 1.11 pw.println(((m==0)?"":(Modifier.toString(m) + " ")) + 669 cananian 1.11 (isInterface()?"interface ":"class ") + 670 cananian 1.11 getSimpleTypeName(this)); 671 cananian 1.11 // superclass 672 cananian 1.11 HClass sup = getSuperclass(); 673 cananian 1.41.2.30 if ((sup != null) && (!sup.getName().equals("java.lang.Object"))) 674 cananian 1.11 pw.println(" extends " + getSimpleTypeName(sup)); 675 cananian 1.11 // interfaces 676 cananian 1.11 HClass in[] = getInterfaces(); 677 cananian 1.11 if (in.length > 0) { 678 cananian 1.11 if (isInterface()) 679 cananian 1.11 pw.print(" extends "); 680 cananian 1.11 else 681 cananian 1.11 pw.print(" implements "); 682 cananian 1.11 for (int i=0; i<in.length; i++) { 683 cananian 1.11 pw.print(getSimpleTypeName(in[i])); 684 cananian 1.11 if (i<in.length-1) 685 cananian 1.11 pw.print(", "); 686 cananian 1.11 } 687 cananian 1.11 pw.println(); 688 cananian 1.11 } 689 cananian 1.11 pw.println("{"); 690 cananian 1.11 // declared fields. 691 cananian 1.11 HField hf[] = getDeclaredFields(); 692 cananian 1.11 for (int i=0; i<hf.length; i++) { 693 cananian 1.11 m = hf[i].getModifiers(); 694 cananian 1.11 pw.println(" " + 695 cananian 1.11 ((m==0)?"":(Modifier.toString(m)+" ")) + 696 cananian 1.11 getSimpleTypeName(hf[i].getType()) + " " + 697 cananian 1.11 hf[i].getName() + ";"); 698 cananian 1.11 } 699 cananian 1.11 // declared methods. 700 cananian 1.11 HMethod hm[] = getDeclaredMethods(); 701 cananian 1.11 for (int i=0; i<hm.length; i++) { 702 cananian 1.11 StringBuffer mstr = new StringBuffer(" "); 703 cananian 1.11 m = hm[i].getModifiers(); 704 cananian 1.11 if (m!=0) { 705 cananian 1.11 mstr.append(Modifier.toString(m)); 706 cananian 1.11 mstr.append(' '); 707 cananian 1.18 } 708 cananian 1.41.2.30 if (hm[i] instanceof HInitializer) { 709 cananian 1.18 mstr.append("static {};"); 710 cananian 1.18 pw.println(mstr.toString()); 711 cananian 1.18 continue; 712 cananian 1.11 } 713 cananian 1.11 if (hm[i] instanceof HConstructor) { 714 cananian 1.11 mstr.append(getSimpleTypeName(this)); 715 cananian 1.11 } else { 716 cananian 1.11 mstr.append(getSimpleTypeName(hm[i].getReturnType())); 717 cananian 1.11 mstr.append(' '); 718 cananian 1.11 mstr.append(hm[i].getName()); 719 cananian 1.11 } 720 cananian 1.11 mstr.append('('); 721 cananian 1.11 HClass[] mpt = hm[i].getParameterTypes(); 722 cananian 1.15 String[] mpn = hm[i].getParameterNames(); 723 cananian 1.11 for (int j=0; j<mpt.length; j++) { 724 cananian 1.11 mstr.append(getSimpleTypeName(mpt[j])); 725 cananian 1.11 mstr.append(' '); 726 cananian 1.15 // use appropriate formal parameter name. 727 cananian 1.15 if (mpn[j]!=null) 728 cananian 1.15 mstr.append(mpn[j]); 729 cananian 1.15 else { // don't know it; use generic. 730 cananian 1.15 mstr.append('p'); mstr.append(j); 731 cananian 1.15 } 732 cananian 1.11 if (j<mpt.length-1) 733 cananian 1.11 mstr.append(", "); 734 cananian 1.11 } 735 cananian 1.11 mstr.append(')'); 736 cananian 1.11 HClass[] met = hm[i].getExceptionTypes(); 737 cananian 1.11 if (met.length>0) 738 cananian 1.11 mstr.append(" throws "); 739 cananian 1.11 for (int j=0; j<met.length; j++) { 740 cananian 1.11 mstr.append(getSimpleTypeName(met[j])); 741 cananian 1.11 if (j<met.length-1) 742 cananian 1.11 mstr.append(", "); 743 cananian 1.11 } 744 cananian 1.11 mstr.append(';'); 745 cananian 1.11 pw.println(mstr.toString()); 746 cananian 1.11 } 747 cananian 1.11 // done. 748 cananian 1.11 pw.println("}"); 749 cananian 1.11 } 750 cananian 1.11 private String getSimpleTypeName(HClass cls) { 751 cananian 1.41.2.30 String tn = HClass.getTypeName(cls); 752 cananian 1.11 while (cls.isArray()) cls=cls.getComponentType(); 753 cananian 1.11 if (cls.getPackage()!=null && 754 cananian 1.11 (cls.getPackage().equals(getPackage()) || 755 cananian 1.11 cls.getPackage().equals("java.lang"))) { 756 cananian 1.11 int lastdot = tn.lastIndexOf('.'); 757 cananian 1.11 if (lastdot < 0) return tn; 758 cananian 1.11 else return tn.substring(lastdot+1); 759 cananian 1.11 } 760 cananian 1.11 else return tn; 761 cananian 1.46 } 762 cananian 1.46 763 cananian 1.46 /*****************************************************************/ 764 cananian 1.46 // JSR-14 extensions. 765 cananian 1.46 766 cananian 1.46 /** 767 cananian 1.46 * Returns the <code>HType</code>s representing the interfaces 768 cananian 1.46 * implemented by the class or interface represented by this object. 769 cananian 1.46 * <p> 770 cananian 1.46 * If this object represents a class, the return value is an 771 cananian 1.46 * array containing objects representing all interfaces implemented 772 cananian 1.46 * by the class. The order of the interface objects in the array 773 cananian 1.46 * corresponds to the order of the interface names in the 774 cananian 1.46 * <code>implements</code> clause of the declaration of the class 775 cananian 1.46 * represented by this object. In the case of an array class, the 776 cananian 1.46 * interfaces <code>Cloneable</code> and <code>Serializable</code> are 777 cananian 1.46 * returned in that order. 778 cananian 1.46 * <p> 779 cananian 1.46 * If this object represents an interface, the array contains 780 cananian 1.46 * objects representing all interfaces extended by the interface. The 781 cananian 1.46 * order of the interface objects in the array corresponds to the order 782 cananian 1.46 * of the interface names in the <code>extends</code> clause of the 783 cananian 1.46 * declaration of the interface represented by this object. 784 cananian 1.46 * <p> 785 cananian 1.46 * If this object represents a class or interface that implements no 786 cananian 1.46 * interfaces, the method returns an array of length 0. 787 cananian 1.46 * <p> 788 cananian 1.46 * If this object represents a primitive type or void, the method 789 cananian 1.46 * returns an array of length 0. 790 cananian 1.46 * <p> 791 cananian 1.46 * In particular, if the compile-time type of any superinterface is 792 cananian 1.46 * a parameterized type, than an object of the appropriate type 793 cananian 1.46 * (i.e., <code>HParameterizedType</code>) will be returned. 794 cananian 1.46 * @return an array of interfaces implemented by this class. 795 cananian 1.46 */ 796 cananian 1.46 public HType[] getGenericInterfaces() { 797 cananian 1.46 throw new RuntimeException("Unimplemented"); 798 cananian 1.46 } 799 cananian 1.46 /** 800 cananian 1.46 * Returns the <code>HType</code> representing the superclass of the 801 cananian 1.46 * entity (class, interface, primitive type or void) represented by 802 cananian 1.46 * this <code>HClass</code>. If this <code>HClass</code> represents 803 cananian 1.46 * either the <code>Object</code> class, an interface, a primitive 804 cananian 1.46 * type, or void, then null is returned. If this object represents 805 cananian 1.46 * an array class then the <code>HClass</code> object representing 806 cananian 1.46 * the <code>Object</code> class is returned. 807 cananian 1.46 * <p> 808 cananian 1.46 * In particular, if the compile-time superclass declaration is a 809 cananian 1.46 * parameterized type, than an object of the appropriate type (i.e., 810 cananian 1.46 * <code>HParameterizedType</code>) will be returned. 811 cananian 1.46 * @return the superclass of the class represented by this object. 812 cananian 1.46 */ 813 cananian 1.46 public HType getGenericSuperclass() { 814 cananian 1.46 throw new RuntimeException("Unimplemented"); 815 cananian 1.46 } 816 cananian 1.46 /** 817 cananian 1.46 * Returns an array of <code>HClassTypeVariable</code> objects that 818 cananian 1.46 * represents the type variables declared by the class or interface 819 cananian 1.46 * represented by this <code>HClass</code> object, in declaration 820 cananian 1.46 * order. Returns an array of length 0 if the underlying class or 821 cananian 1.46 * interface declares no type variables. */ 822 cananian 1.46 public HClassTypeVariable[] getTypeParameters() { 823 cananian 1.46 throw new RuntimeException("Unimplemented"); 824 cananian 1.2 } 825 cananian 1.2 826 cananian 1.2 /*****************************************************************/ 827 cananian 1.2 // Special classes for primitive types. 828 cananian 1.41.2.30 // [note that these cannot be re-linked as they are hard-coded here] 829 cananian 1.2 830 cananian 1.2 /** The <code>HClass</code> object representing the primitive type boolean.*/ 831 cananian 1.40 public static final HClass Boolean=new HClassPrimitive("boolean", "Z"); 832 cananian 1.2 /** The <code>HClass</code> object representing the primitive type byte.*/ 833 cananian 1.40 public static final HClass Byte=new HClassPrimitive("byte", "B"); 834 cananian 1.2 /** The <code>HClass</code> object representing the primitive type short.*/ 835 cananian 1.40 public static final HClass Short=new HClassPrimitive("short", "S"); 836 cananian 1.2 /** The <code>HClass</code> object representing the primitive type int.*/ 837 cananian 1.40 public static final HClass Int=new HClassPrimitive("int", "I"); 838 cananian 1.2 /** The <code>HClass</code> object representing the primitive type long.*/ 839 cananian 1.40 public static final HClass Long=new HClassPrimitive("long", "J"); 840 cananian 1.2 /** The <code>HClass</code> object representing the primitive type float.*/ 841 cananian 1.40 public static final HClass Float=new HClassPrimitive("float", "F"); 842 cananian 1.2 /** The <code>HClass</code> object representing the primitive type double.*/ 843 cananian 1.40 public static final HClass Double=new HClassPrimitive("double", "D"); 844 cananian 1.2 /** The <code>HClass</code> object representing the primitive type char.*/ 845 cananian 1.40 public static final HClass Char=new HClassPrimitive("char", "C"); 846 cananian 1.2 /** The <code>HClass</code> object representing the primitive type void.*/ 847 cananian 1.40 public static final HClass Void=new HClassPrimitive("void", "V"); 848 cananian 1.5 849 cananian 1.41.2.30 /** Array factory: returns new <code>HClass[]</code>. */ 850 cananian 1.43.2.2 public static final ArrayFactory<HClass> arrayFactory = Factories.hclassArrayFactory; 851 cananian 1.41.2.30 852 cananian 1.41.2.4 /** HPointer interface. */ 853 cananian 1.41.2.30 final HClass actual() { return this; /* no dereferencing necessary. */ } 854 cananian 1.41.2.18 855 cananian 1.41.2.23 // Comparable interface. 856 cananian 1.41.2.23 /** Compares two <code>HClass</code>es by lexicographic order of their 857 cananian 1.41.2.23 * descriptors. */ 858 cananian 1.45 public final int compareTo(HClass o) { 859 cananian 1.45 return getDescriptor().compareTo(o.getDescriptor()); 860 cananian 1.41.2.18 } 861 cananian 1.34 862 cananian 1.41.2.30 // UTILITY CLASSES (used in toString methods all over the place) 863 cananian 1.41.2.30 static String getTypeName(HPointer hc) { 864 cananian 1.41.2.30 HClass hcc; 865 cananian 1.41.2.30 try { hcc = (HClass) hc; } 866 cananian 1.41.2.33 catch (ClassCastException e) { 867 cananian 1.41.2.33 return (hc.getDescriptor().charAt(0)=='L') ? 868 cananian 1.41.2.33 hc.getName() : getTypeName(hc.actual()); 869 cananian 1.41.2.33 } 870 cananian 1.41.2.30 return getTypeName(hcc); 871 cananian 1.41.2.30 } 872 cananian 1.41.2.30 static String getTypeName(HClass hc) { 873 cananian 1.41.2.30 if (hc.isArray()) { 874 cananian 1.41.2.30 StringBuffer r = new StringBuffer(); 875 cananian 1.41.2.30 HClass sup = hc; 876 cananian 1.41.2.30 int i=0; 877 cananian 1.41.2.30 for (; sup.isArray(); sup = sup.getComponentType()) 878 cananian 1.41.2.30 i++; 879 cananian 1.41.2.30 r.append(sup.getName()); 880 cananian 1.41.2.30 for (int j=0; j<i; j++) 881 cananian 1.41.2.30 r.append("[]"); 882 cananian 1.41.2.30 return r.toString(); 883 cananian 1.41.2.30 } 884 cananian 1.41.2.30 return hc.getName(); 885 cananian 1.34 } 886 cananian 1.34 } 887 cananian 1.34 888 cananian 1.25 // set emacs indentation style. 889 cananian 1.25 // Local Variables: 890 cananian 1.25 // c-basic-offset:2 891 cananian 1.25 // End: