1 cananian 1.1.4.1 // HClassImpl.java, created Fri Jul 31 4:33:28 1998 by cananian 2 cananian 1.1.4.1 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.1.4.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1.4.1 package harpoon.ClassFile; 5 cananian 1.1.4.1 6 cananian 1.1.4.1 import harpoon.Util.ArrayFactory; 7 cananian 1.3 import net.cscott.jutil.ReferenceUnique; 8 cananian 1.3 import net.cscott.jutil.UniqueVector; 9 cananian 1.1.4.1 import harpoon.Util.Util; 10 cananian 1.1.4.1 11 cananian 1.1.4.1 import java.lang.reflect.Modifier; 12 cananian 1.1.4.1 13 cananian 1.1.4.1 /** 14 cananian 1.1.4.1 * <code>HClassImpl</code> is a common parent for implementations of 15 cananian 1.1.4.1 * <code>HClass</code>. Linker proxy classes should instead have 16 cananian 1.1.4.1 * <code>HClassProxy</code> as a parent. 17 cananian 1.1.4.1 * <p> 18 cananian 1.1.4.1 * There is no public constructor for the class <code>HClassImpl</code>. 19 cananian 1.1.4.1 * <code>HClass</code> objects are created with the <code>forName</code>, 20 cananian 1.1.4.1 * <code>forDescriptor</code> and <code>forClass</code> methods of a 21 cananian 1.1.4.1 * <code>Linker</code> object. 22 cananian 1.1.4.1 * 23 cananian 1.1.4.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 24 cananian 1.3 * @version $Id: HClassImpl.java,v 1.3 2004/02/08 01:58:03 cananian Exp $ 25 cananian 1.1.4.1 * @see harpoon.IR.RawClass.ClassFile 26 cananian 1.1.4.1 * @see java.lang.Class 27 cananian 1.1.4.1 */ 28 cananian 1.1.4.1 abstract class HClassImpl extends HClass 29 cananian 1.1.4.1 implements java.io.Serializable { 30 cananian 1.1.4.1 31 cananian 1.1.4.1 /** Protected constructor, not for external use. */ 32 cananian 1.1.4.1 HClassImpl(Linker l) { super(l); } 33 cananian 1.1.4.1 34 cananian 1.1.4.1 /** 35 cananian 1.1.4.1 * If this class represents an array type, returns the <code>HClass</code> 36 cananian 1.1.4.1 * object representing the component type of the array; otherwise returns 37 cananian 1.1.4.1 * null. 38 cananian 1.1.4.1 * @see java.lang.reflect.Array 39 cananian 1.1.4.1 */ 40 cananian 1.1.4.1 public HClass getComponentType() { return null; } 41 cananian 1.1.4.1 42 cananian 1.1.4.1 /** 43 cananian 1.1.4.1 * Returns the fully-qualified name of the type (class, interface, 44 cananian 1.1.4.1 * array, or primitive) represented by this <code>HClass</code> object, 45 cananian 1.1.4.1 * as a <code>String</code>. 46 cananian 1.1.4.1 * @return the fully qualified name of the class or interface 47 cananian 1.1.4.1 * represented by this object. 48 cananian 1.1.4.1 */ 49 cananian 1.1.4.1 public abstract String getName(); 50 cananian 1.1.4.1 51 cananian 1.1.4.1 /** 52 cananian 1.1.4.1 * Returns the package name of this <code>HClass</code>. If this 53 cananian 1.1.4.1 * <code>HClass</code> represents a primitive or array type, 54 cananian 1.1.4.1 * then returns null. Returns <code>""</code> (a zero-length string) 55 cananian 1.1.4.1 * if this class is not in a package. 56 cananian 1.1.4.1 */ 57 cananian 1.1.4.1 public String getPackage() { 58 cananian 1.1.4.1 if (isPrimitive() || isArray()) return null; 59 cananian 1.1.4.1 String fullname = getName(); 60 cananian 1.1.4.1 int lastdot = fullname.lastIndexOf('.'); 61 cananian 1.1.4.1 if (lastdot<0) return ""; // no package. 62 cananian 1.1.4.1 else return fullname.substring(0, lastdot); 63 cananian 1.1.4.1 } 64 cananian 1.1.4.1 /** 65 cananian 1.1.4.1 * Returns a ComponentType descriptor for the type represented by this 66 cananian 1.1.4.1 * <code>HClass</code> object. 67 cananian 1.1.4.1 */ 68 cananian 1.1.4.1 public abstract String getDescriptor(); 69 cananian 1.1.4.1 70 cananian 1.1.4.1 /** 71 cananian 1.1.4.1 * Returns a <code>HField</code> object that reflects the specified 72 cananian 1.1.4.1 * declared field of the class or interface represented by this 73 cananian 1.1.4.1 * <code>HClass</code> object. The <code>name</code> parameter is a 74 cananian 1.1.4.1 * <code>String</code> that specifies the simple name of the 75 cananian 1.1.4.1 * desired field. 76 cananian 1.1.4.1 * @exception NoSuchFieldError 77 cananian 1.1.4.1 * if a field with the specified name is not found. 78 cananian 1.1.4.1 * @see HField 79 cananian 1.1.4.1 */ 80 cananian 1.1.4.1 public HField getDeclaredField(String name) 81 cananian 1.1.4.1 throws NoSuchFieldError { 82 cananian 1.1.4.1 // construct master declaredField list, if we haven't already. 83 cananian 1.1.4.1 HField[] declaredFields=getDeclaredFields(); 84 cananian 1.1.4.1 // look for field name in master list. 85 cananian 1.1.4.1 for (int i=0; i<declaredFields.length; i++) 86 cananian 1.1.4.1 if (declaredFields[i].getName().equals(name)) 87 cananian 1.1.4.1 return declaredFields[i]; 88 cananian 1.1.4.1 // not found. 89 cananian 1.1.4.1 throw new NoSuchFieldError(getName()+"."+name); 90 cananian 1.1.4.1 } 91 cananian 1.1.4.1 /** 92 cananian 1.1.4.1 * Returns an array of <code>HField</code> objects reflecting all the 93 cananian 1.1.4.1 * fields declared by the class or interface represented by this 94 cananian 1.1.4.1 * <code>HClass</code> object. This includes <code>public</code>, 95 cananian 1.1.4.1 * <code>protected</code>, default (<code>package</code>) access, 96 cananian 1.1.4.1 * and <code>private</code> fields, but excludes inherited fields. 97 cananian 1.1.4.1 * Returns an array of length 0 if the class or interface declares 98 cananian 1.1.4.1 * no fields, or if this <code>HClass</code> object represents a 99 cananian 1.1.4.1 * primitive type. 100 cananian 1.1.4.1 * @see "The Java Language Specification, sections 8.2 and 8.3" 101 cananian 1.1.4.1 * @see HField 102 cananian 1.1.4.1 */ 103 cananian 1.1.4.1 public abstract HField[] getDeclaredFields(); 104 cananian 1.1.4.1 105 cananian 1.1.4.1 /** 106 cananian 1.1.4.1 * Returns a <code>HMethod</code> object that reflects the specified 107 cananian 1.1.4.1 * declared method of the class or interface represented by this 108 cananian 1.1.4.1 * <code>HClass</code> object. The <code>name</code> parameter is a 109 cananian 1.1.4.1 * <code>String</code> that specifies the simple name of the desired 110 cananian 1.1.4.1 * method, and the <code>parameterTypes</code> parameter is an array 111 cananian 1.1.4.1 * of <code>HClass</code> objects that identify the method's formal 112 cananian 1.1.4.1 * parameter types, in declared order. 113 cananian 1.1.4.1 * @exception NoSuchMethodError 114 cananian 1.1.4.1 * if a matching method is not found. 115 cananian 1.1.4.1 * @see HMethod 116 cananian 1.1.4.1 */ 117 cananian 1.1.4.1 public HMethod getDeclaredMethod(String name, HClass parameterTypes[]) 118 cananian 1.1.4.1 throws NoSuchMethodError { 119 cananian 1.1.4.1 // construct master declaredMethod list, if we haven't already. 120 cananian 1.1.4.1 HMethod[] declaredMethods=getDeclaredMethods(); 121 cananian 1.1.4.1 // look for method name/type in master list. 122 cananian 1.1.4.1 for (int i=0; i<declaredMethods.length; i++) 123 cananian 1.1.4.1 if (declaredMethods[i].getName().equals(name)) { 124 cananian 1.1.4.1 HClass[] methodParamTypes = declaredMethods[i].getParameterTypes(); 125 cananian 1.1.4.1 if (methodParamTypes.length == parameterTypes.length) { 126 cananian 1.1.4.1 int j; for (j=0; j<parameterTypes.length; j++) 127 cananian 1.1.4.1 if (methodParamTypes[j] != parameterTypes[j]) 128 cananian 1.1.4.1 break; // oops, this one doesn't match. 129 cananian 1.1.4.1 if (j==parameterTypes.length) // hey, we made it to the end! 130 cananian 1.1.4.1 return declaredMethods[i]; 131 cananian 1.1.4.1 } 132 cananian 1.1.4.1 } 133 cananian 1.1.4.1 // didn't find a match. Oh, well. 134 cananian 1.1.4.1 throw new NoSuchMethodError(getName()+"."+name); 135 cananian 1.1.4.1 } 136 cananian 1.1.4.1 /** 137 cananian 1.1.4.1 * Returns a <code>HMethod</code> object that reflects the specified 138 cananian 1.1.4.1 * declared method of the class or interface represented by this 139 cananian 1.1.4.1 * <code>HClass</code> object. The <code>name</code> parameter is a 140 cananian 1.1.4.1 * <code>String</code> that specifies the simple name of the desired 141 cananian 1.1.4.1 * method, and <code>descriptor</code> is a string describing 142 cananian 1.1.4.1 * the parameter types and return value of the method. 143 cananian 1.1.4.1 * @exception NoSuchMethodError 144 cananian 1.1.4.1 * if a matching method is not found. 145 cananian 1.1.4.1 * @see HMethod#getDescriptor 146 cananian 1.1.4.1 */ 147 cananian 1.1.4.1 public HMethod getDeclaredMethod(String name, String descriptor) 148 cananian 1.1.4.1 throws NoSuchMethodError { 149 cananian 1.1.4.1 // construct master declaredMethod list, if we haven't already. 150 cananian 1.1.4.1 HMethod[] declaredMethods=getDeclaredMethods(); 151 cananian 1.1.4.1 // look for method name/type in master list. 152 cananian 1.1.4.1 for (int i=0; i<declaredMethods.length; i++) 153 cananian 1.1.4.1 if (declaredMethods[i].getName().equals(name) && 154 cananian 1.1.4.1 declaredMethods[i].getDescriptor().equals(descriptor)) 155 cananian 1.1.4.1 return declaredMethods[i]; 156 cananian 1.1.4.1 // didn't find a match. Oh, well. 157 cananian 1.1.4.1 throw new NoSuchMethodError(getName()+"."+name+"/"+descriptor); 158 cananian 1.1.4.1 } 159 cananian 1.1.4.1 /** 160 cananian 1.1.4.1 * Returns an array of <code>HMethod</code> objects reflecting all the 161 cananian 1.1.4.1 * methods declared by the class or interface represented by this 162 cananian 1.1.4.1 * <code>HClass</code> object. This includes <code>public</code>, 163 cananian 1.1.4.1 * <code>protected</code>, default (<code>package</code>) access, and 164 cananian 1.1.4.1 * <code>private</code> methods, but excludes inherited methods. 165 cananian 1.1.4.1 * Returns an array of length 0 if the class or interface declares no 166 cananian 1.1.4.1 * methods, or if this <code>HClass</code> object represents a primitive 167 cananian 1.1.4.1 * type.<p> 168 cananian 1.1.4.1 * Constructors are included. 169 cananian 1.1.4.1 * @see "The Java Language Specification, section 8.2" 170 cananian 1.1.4.1 * @see HMethod 171 cananian 1.1.4.1 */ 172 cananian 1.1.4.1 public abstract HMethod[] getDeclaredMethods(); 173 cananian 1.1.4.1 174 cananian 1.1.4.1 /** 175 cananian 1.1.4.1 * Returns an <code>HConstructor</code> object that reflects the 176 cananian 1.1.4.1 * specified declared constructor of the class or interface represented 177 cananian 1.1.4.1 * by this <code>HClass</code> object. The <code>parameterTypes</code> 178 cananian 1.1.4.1 * parameter is an array of <code>HClass</code> objects that 179 cananian 1.1.4.1 * identify the constructor's formal parameter types, in declared order. 180 cananian 1.1.4.1 * @exception NoSuchMethodError if a matching method is not found. 181 cananian 1.1.4.1 */ 182 cananian 1.1.4.1 public HConstructor getConstructor(HClass parameterTypes[]) 183 cananian 1.1.4.1 throws NoSuchMethodError { 184 cananian 1.1.4.1 return (HConstructor) getDeclaredMethod("<init>", parameterTypes); 185 cananian 1.1.4.1 } 186 cananian 1.1.4.1 187 cananian 1.1.4.1 /** 188 cananian 1.1.4.1 * Returns an array of <code>HConstructor</code> objects reflecting 189 cananian 1.1.4.1 * all the constructors declared by the class represented by the 190 cananian 1.1.4.1 * <code>HClass</code> object. These are <code>public</code>, 191 cananian 1.1.4.1 * <code>protected</code>, default (package) access, and 192 cananian 1.1.4.1 * <code>private</code> constructors. Returns an array of length 0 193 cananian 1.1.4.1 * if this <code>HClass</code> object represents an interface or a 194 cananian 1.1.4.1 * primitive type. 195 cananian 1.1.4.1 * @see "The Java Language Specification, section 8.2" 196 cananian 1.1.4.1 */ 197 cananian 1.1.4.1 public HConstructor[] getConstructors() { 198 cananian 1.1.4.1 HConstructor[] constructors; 199 cananian 1.1.4.1 if (isPrimitive() || isArray() || isInterface()) 200 cananian 1.1.4.1 constructors = new HConstructor[0]; 201 cananian 1.1.4.1 else { 202 cananian 1.1.4.1 HMethod[] hm = getMethods(); 203 cananian 1.1.4.1 int n=0; 204 cananian 1.1.4.1 for (int i=0; i<hm.length; i++) 205 cananian 1.1.4.1 if (hm[i] instanceof HConstructor) 206 cananian 1.1.4.1 n++; 207 cananian 1.1.4.1 constructors = new HConstructor[n]; 208 cananian 1.1.4.1 for (int i=0; i<hm.length; i++) 209 cananian 1.1.4.1 if (hm[i] instanceof HConstructor) 210 cananian 1.1.4.1 constructors[--n] = (HConstructor) hm[i]; 211 cananian 1.1.4.1 } 212 cananian 1.1.4.1 return constructors; 213 cananian 1.1.4.1 } 214 cananian 1.1.4.1 215 cananian 1.1.4.1 /** 216 cananian 1.1.4.1 * Returns the class initializer method, if there is one; otherwise 217 cananian 1.1.4.1 * <code>null</code>. 218 cananian 1.1.4.1 * @see "The Java Virtual Machine Specification, section 3.8" 219 cananian 1.1.4.1 */ 220 cananian 1.1.4.1 public HInitializer getClassInitializer() { 221 cananian 1.1.4.1 try { 222 cananian 1.1.4.1 return (HInitializer) getDeclaredMethod("<clinit>", new HClass[0]); 223 cananian 1.1.4.1 } catch (NoSuchMethodError e) { 224 cananian 1.1.4.1 return null; 225 cananian 1.1.4.1 } 226 cananian 1.1.4.1 } 227 cananian 1.1.4.1 228 cananian 1.1.4.1 /** 229 cananian 1.1.4.1 * Returns the Java language modifiers for this class or interface, 230 cananian 1.1.4.1 * encoded in an integer. The modifiers consist of the Java Virtual 231 cananian 1.1.4.1 * Machine's constants for public, protected, private, final, and 232 cananian 1.1.4.1 * interface; they should be decoded using the methods of class Modifier. 233 cananian 1.1.4.1 * @see "The Java Virtual Machine Specification, table 4.1" 234 cananian 1.1.4.1 * @see java.lang.reflect.Modifier 235 cananian 1.1.4.1 */ 236 cananian 1.1.4.1 public abstract int getModifiers(); 237 cananian 1.1.4.1 238 cananian 1.1.4.1 /** 239 cananian 1.1.4.1 * If this object represents any class other than the class 240 cananian 1.1.4.1 * <code>Object</code>, then the object that represents the superclass of 241 cananian 1.1.4.1 * that class is returned. 242 cananian 1.1.4.1 * <p> If this object is the one that represents the class 243 cananian 1.1.4.1 * <code>Object</code> or this object represents an interface, 244 cananian 1.1.4.1 * <code>null</code> is returned. 245 cananian 1.1.4.1 * If this object represents an array, then the <code>HClass</code> 246 cananian 1.1.4.1 * representing <code>java.lang.Object</code> is returned. 247 cananian 1.1.4.1 * @return the superclass of the class represented by this object. 248 cananian 1.1.4.1 */ 249 cananian 1.1.4.1 public abstract HClass getSuperclass(); 250 cananian 1.1.4.1 251 cananian 1.1.4.1 /** 252 cananian 1.1.4.1 * Determines the interfaces implemented by the class or interface 253 cananian 1.1.4.1 * represented by this object. 254 cananian 1.1.4.1 * <p> If this object represents a class, the return value is an 255 cananian 1.1.4.1 * array containing objects representing all interfaces implemented by 256 cananian 1.1.4.1 * the class. The order of the interface objects in the array corresponds 257 cananian 1.1.4.1 * to the order of the interface names in the implements clause of the 258 cananian 1.1.4.1 * declaration of the class represented by this object. 259 cananian 1.1.4.1 * <p> If the object represents an interface, the array contains objects 260 cananian 1.1.4.1 * representing all interfaces extended by the interface. The order of 261 cananian 1.1.4.1 * the interface objects in the array corresponds to the order of the 262 cananian 1.1.4.1 * interface names in the extends clause of the declaration of the 263 cananian 1.1.4.1 * interface represented by this object. 264 cananian 1.1.4.1 * <p> If the class or interface implements no interfaces, the method 265 cananian 1.1.4.1 * returns an array of length 0. 266 cananian 1.1.4.1 * <p><b>NOTE THAT the array returned does NOT contain interfaces 267 cananian 1.1.4.1 * implemented by superclasses.</b> Thus the interface list may 268 cananian 1.1.4.1 * be incomplete. This is pretty bogus behaviour, but it's what 269 cananian 1.1.4.1 * our prototype, <code>java.lang.Class</code>, does. 270 cananian 1.1.4.1 * @return an array of interfaces implemented by this class. 271 cananian 1.1.4.1 */ 272 cananian 1.1.4.1 public abstract HClass[] getInterfaces(); 273 cananian 1.1.4.1 274 cananian 1.1.4.1 /** 275 cananian 1.1.4.1 * Return the name of the source file for this class, or a 276 cananian 1.1.4.1 * zero-length string if the information is not available. 277 cananian 1.1.4.1 * @see harpoon.IR.RawClass.AttributeSourceFile 278 cananian 1.1.4.1 */ 279 cananian 1.1.4.1 public String getSourceFile() { return ""; } 280 cananian 1.1.4.1 281 cananian 1.1.4.1 /** 282 cananian 1.1.4.1 * If this <code>HClass</code> object represents an array type, 283 cananian 1.1.4.1 * returns <code>true</code>, otherwise returns <code>false</code>. 284 cananian 1.1.4.1 */ 285 cananian 1.1.4.1 public boolean isArray() { return false; } 286 cananian 1.1.4.1 /** 287 cananian 1.1.4.1 * Determines if the specified <code>HClass</code> object represents an 288 cananian 1.1.4.1 * interface type. 289 cananian 1.1.4.1 * @return <code>true</code> is this object represents an interface; 290 cananian 1.1.4.1 * <code>false</code> otherwise. 291 cananian 1.1.4.1 */ 292 cananian 1.1.4.1 public boolean isInterface() { return false; } 293 cananian 1.1.4.1 294 cananian 1.1.4.1 /** 295 cananian 1.1.4.1 * Determines if the specified <code>HClass</code> object represents a 296 cananian 1.1.4.1 * primitive Java type. <p> 297 cananian 1.1.4.1 * There are nine predefined <code>HClass</code> objects to represent 298 cananian 1.1.4.1 * the eight primitive Java types and void. 299 cananian 1.1.4.1 */ 300 cananian 1.1.4.1 public boolean isPrimitive() { return false; } 301 cananian 1.1.4.1 302 cananian 1.1.4.1 /** Serializable interface. Override if implementation has information 303 cananian 1.1.4.1 * which the linker cannot reconstruct. */ 304 cananian 1.1.4.1 public Object writeReplace() { 305 cananian 1.1.4.1 if (!hasBeenModified()) return new HClassStub(this); 306 cananian 1.1.4.1 else return this; // cannot reconstruct; write this out instead 307 cananian 1.1.4.1 } 308 cananian 1.1.4.1 private static final class HClassStub implements java.io.Serializable { 309 cananian 1.1.4.1 private final String desc; private final Linker l; 310 cananian 1.1.4.1 HClassStub(HClass c) // store only descriptor and linker for resolution. 311 cananian 1.1.4.1 { this.desc = c.getDescriptor().intern(); this.l = c.getLinker(); } 312 cananian 1.1.4.1 public Object readResolve() { return l.forDescriptor(desc); } 313 cananian 1.1.4.1 } 314 cananian 1.1.4.1 } 315 cananian 1.1.4.1 // set emacs indentation style. 316 cananian 1.1.4.1 // Local Variables: 317 cananian 1.1.4.1 // c-basic-offset:2 318 cananian 1.2 // End: