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: