1 cananian 1.1.4.1 // HField.java, created Fri Jul 31  9:33:47 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.1.4.1 
  8 cananian 1.1.4.1 import java.lang.reflect.Modifier;
  9 cananian 1.1.4.1 
 10 cananian 1.1.4.1 /**
 11 cananian 1.1.4.1  * <code>HFieldImpl</code> is the basic implementation of <code>HField</code>.
 12 cananian 1.1.4.1  *
 13 cananian 1.1.4.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
 14 cananian 1.4      * @version $Id: HFieldImpl.java,v 1.4 2003/03/18 02:27:02 cananian Exp $
 15 cananian 1.1.4.1  * @see HField
 16 cananian 1.1.4.1  */
 17 cananian 1.1.4.1 abstract class HFieldImpl
 18 cananian 1.2.2.1   implements HField, java.io.Serializable, java.lang.Comparable<HMember> {
 19 cananian 1.1.4.1   HClass parent;
 20 cananian 1.1.4.1   HPointer type;
 21 cananian 1.1.4.1   String name;
 22 cananian 1.1.4.1   int modifiers;
 23 cananian 1.1.4.1   Object constValue;
 24 cananian 1.1.4.1   boolean isSynthetic;
 25 cananian 1.1.4.1 
 26 cananian 1.1.4.1   /** 
 27 cananian 1.1.4.1    * Returns the <code>HClass</code> object representing the class or
 28 cananian 1.1.4.1    * interface that declares the field represented by this 
 29 cananian 1.1.4.1    * <code>HField</code> object. 
 30 cananian 1.1.4.1    */
 31 cananian 1.1.4.1   public HClass getDeclaringClass() {
 32 cananian 1.1.4.1     return parent;
 33 cananian 1.1.4.1   }
 34 cananian 1.1.4.1   /**
 35 cananian 1.1.4.1    * Returns the name of the field represented by this 
 36 cananian 1.1.4.1    * <code>HField</code> object.
 37 cananian 1.1.4.1    */
 38 cananian 1.1.4.1   public String getName() {
 39 cananian 1.1.4.1     return name;
 40 cananian 1.1.4.1   }
 41 cananian 1.1.4.1   /**
 42 cananian 1.1.4.1    * Returns the Java language modifiers for the field represented by this
 43 cananian 1.1.4.1    * <code>HField</code> object, as an integer.  The <code>Modifier</code>
 44 cananian 1.1.4.1    * class should be used to decode the modifiers.
 45 cananian 1.1.4.1    * @see java.lang.reflect.Modifier
 46 cananian 1.1.4.1    */
 47 cananian 1.1.4.1   public int getModifiers() {
 48 cananian 1.1.4.1     return modifiers;
 49 cananian 1.1.4.1   }
 50 cananian 1.1.4.1   /**
 51 cananian 1.1.4.1    * Returns an <code>HClass</code> object that identifies the declared
 52 cananian 1.1.4.1    * type for the field represented by this <code>HField</code> object.
 53 cananian 1.1.4.1    */
 54 cananian 1.1.4.1   public HClass getType() {
 55 cananian 1.1.4.1     try {
 56 cananian 1.1.4.1       return (HClass) type;
 57 cananian 1.1.4.1     } catch (ClassCastException e) { // type was ClassPointer.
 58 cananian 1.1.4.1       HClass t = type.actual();
 59 cananian 1.1.4.1       type = t;
 60 cananian 1.1.4.1       return t;
 61 cananian 1.1.4.1     }
 62 cananian 1.1.4.1   }
 63 cananian 1.1.4.1   /**
 64 cananian 1.1.4.1    * Return the type descriptor for this <code>HField</code> object.
 65 cananian 1.1.4.1    */
 66 cananian 1.1.4.1   public String getDescriptor() {
 67 cananian 1.1.4.1     return type.getDescriptor();
 68 cananian 1.1.4.1   }
 69 cananian 1.1.4.1   /**
 70 cananian 1.1.4.1    * Returns the constant value of this <code>HField</code>, if
 71 cananian 1.1.4.1    * it is a constant field.
 72 cananian 1.1.4.1    * @return the wrapped value, or <code>null</code> if 
 73 cananian 1.1.4.1    *         <code>!isConstant()</code>.
 74 cananian 1.1.4.1    */
 75 cananian 1.1.4.1   public Object getConstant() { return constValue; }
 76 cananian 1.1.4.1 
 77 cananian 1.1.4.1   /**
 78 cananian 1.1.4.1    * Determines whether this <code>HField</code> represents a constant
 79 cananian 1.1.4.1    * field.
 80 cananian 1.1.4.1    */
 81 cananian 1.1.4.1   public boolean isConstant() { return (constValue!=null); }
 82 cananian 1.1.4.1 
 83 cananian 1.1.4.1   /**
 84 cananian 1.1.4.1    * Determines whether this <code>HField</code> is synthetic.
 85 cananian 1.1.4.1    */
 86 cananian 1.1.4.1   public boolean isSynthetic() { return isSynthetic; }
 87 cananian 1.1.4.1 
 88 cananian 1.1.4.1   /** Determines whether this is a static field. */
 89 cananian 1.1.4.1   public boolean isStatic() {
 90 cananian 1.1.4.1     return Modifier.isStatic(getModifiers());
 91 cananian 1.4       }
 92 cananian 1.4     
 93 cananian 1.4       public HType getGenericType() {
 94 cananian 1.4         throw new RuntimeException("Unimplemented");
 95 cananian 1.1.4.1   }
 96 cananian 1.1.4.1 
 97 cananian 1.1.4.1   /** Returns a mutator for this <code>HField</code>, or <code>null</code>
 98 cananian 1.1.4.1    *  if the object is immutable. */
 99 cananian 1.1.4.1   public HFieldMutator getMutator() { return null; }
100 cananian 1.1.4.1 
101 cananian 1.1.4.1   /** 
102 cananian 1.1.4.1    * Compares this <code>HField</code> against the specified object.
103 cananian 1.1.4.1    * Returns <code>true</code> if the objects are the same.  Two
104 cananian 1.1.4.1    * <code>HFields</code> are the same if they were declared by the same
105 cananian 1.1.4.1    * class and have the same name and type.
106 cananian 1.1.4.1    */
107 cananian 1.1.4.5   public boolean equals(Object obj) { return equals(this, obj); }
108 cananian 1.1.4.5   // factored out for re-use
109 cananian 1.1.4.5   static boolean equals(HField _this_, Object obj) {
110 cananian 1.1.4.1     HField field;
111 cananian 1.1.4.5     if (obj==null) return false;
112 cananian 1.1.4.5     if (_this_==obj) return true;
113 cananian 1.1.4.5     try { field=(HField)obj; } catch (ClassCastException e) {return false; }
114 cananian 1.1.4.5     if (_this_.getDeclaringClass().getDescriptor().equals
115 cananian 1.1.4.1         (field.getDeclaringClass().getDescriptor()) &&
116 cananian 1.1.4.5         _this_.getName().equals
117 cananian 1.1.4.5         (field.getName()) &&
118 cananian 1.1.4.5         _this_.getType().getDescriptor().equals
119 cananian 1.1.4.5         (field.getType().getDescriptor()))
120 cananian 1.1.4.1       return true;
121 cananian 1.1.4.1     return false;
122 cananian 1.1.4.1   }
123 cananian 1.1.4.4 
124 cananian 1.1.4.5   public int hashCode() { return hashCode(this); }
125 cananian 1.1.4.5   // factored out for re-use
126 cananian 1.1.4.5   static int hashCode(HField hf) {
127 cananian 1.1.4.5     return
128 cananian 1.1.4.5       hf.getDeclaringClass().hashCode() ^
129 cananian 1.1.4.5       hf.getName().hashCode() ^
130 cananian 1.1.4.5       hf.getDescriptor().hashCode();
131 cananian 1.1.4.1   }
132 cananian 1.1.4.1 
133 cananian 1.1.4.1   /**
134 cananian 1.1.4.1    * Return a string describing this <code>HField</code>.  The format
135 cananian 1.1.4.1    * is the access modifiers for the field, if any, followed by the
136 cananian 1.1.4.1    * field type, followed by a space, followed by the fully-qualified
137 cananian 1.1.4.1    * name of the class declaring the field, followed by a period,
138 cananian 1.1.4.1    * followed by the name of the field.  For example:<p>
139 cananian 1.1.4.1    * <DL>
140 cananian 1.1.4.1    * <DD><CODE>public static final int java.lang.Thread.MIN_PRIORITY</CODE>
141 cananian 1.1.4.1    * <DD><CODE>private int java.io.FileDescriptor.fd</CODE>
142 cananian 1.1.4.1    * </DL><p>
143 cananian 1.1.4.1    * The modifiers are placed in canonical order as specified by
144 cananian 1.1.4.1    * "The Java Language Specification."  This is
145 cananian 1.1.4.1    * <code>public</code>, <code>protected</code>, or <code>private</code>
146 cananian 1.1.4.1    * first, and then other modifiers in the following order:
147 cananian 1.1.4.1    * <code>static</code>, <code>final</code>, <code>transient</code>,
148 cananian 1.1.4.1    * <code>volatile</code>.
149 cananian 1.1.4.1    */
150 cananian 1.1.4.5   public String toString() { return toString(this); }
151 cananian 1.1.4.5   /** For re-use by other classes implement HField. */
152 cananian 1.1.4.5   static String toString(HField hf) {
153 cananian 1.1.4.1     StringBuffer r = new StringBuffer();
154 cananian 1.1.4.5     int m = hf.getModifiers();
155 cananian 1.1.4.1     if (m!=0) {
156 cananian 1.1.4.1       r.append(Modifier.toString(m));
157 cananian 1.1.4.1       r.append(' ');
158 cananian 1.1.4.1     }
159 cananian 1.1.4.5     r.append(HClass.getTypeName(hf.getType()));
160 cananian 1.1.4.1     r.append(' ');
161 cananian 1.1.4.5     r.append(HClass.getTypeName(hf.getDeclaringClass()));
162 cananian 1.1.4.1     r.append('.');
163 cananian 1.1.4.5     r.append(hf.getName());
164 cananian 1.1.4.1     return r.toString();
165 cananian 1.1.4.1   }
166 cananian 1.1.4.1 
167 cananian 1.1.4.1   /** Serializable interface. */
168 cananian 1.1.4.1   public Object writeReplace() { return new HFieldStub(this); }
169 cananian 1.1.4.3   static final class HFieldStub implements java.io.Serializable {
170 cananian 1.1.4.1     private HClass parent;
171 cananian 1.1.4.1     private String name;
172 cananian 1.1.4.1     HFieldStub(HField f) {
173 cananian 1.1.4.1       this.parent = f.getDeclaringClass();
174 cananian 1.1.4.1       this.name = f.getName().intern();
175 cananian 1.1.4.1     }
176 cananian 1.1.4.1     public Object readResolve() {
177 cananian 1.1.4.1       return parent.getDeclaredField(name);
178 cananian 1.1.4.1     }
179 cananian 1.1.4.1   }
180 cananian 1.1.4.1   // Comparable interface
181 cananian 1.1.4.1   /** Compares two <code>HField</code>s lexicographically; first by
182 cananian 1.1.4.1    *  declaring class, then by name. */
183 cananian 1.2.2.1   public int compareTo(HMember o) {
184 cananian 1.1.4.2     return memberComparator.compare(this, o);
185 cananian 1.1.4.1   }
186 cananian 1.1.4.1 }
187 cananian 1.1.4.1 // set emacs indentation style.
188 cananian 1.1.4.1 // Local Variables:
189 cananian 1.1.4.1 // c-basic-offset:2
190 cananian 1.2     // End: