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: