1 package serp.bytecode; 2 3 import serp.bytecode.lowlevel.*; 4 import serp.bytecode.visitor.*; 5 import serp.util.*; 6 7 /*** 8 * A field of a class. 9 * 10 * @author Abe White 11 */ 12 public class BCField extends BCMember implements VisitAcceptor { 13 BCField(BCClass owner) { 14 super(owner); 15 if (owner.isEnum()) 16 setEnum(true); 17 } 18 19 /*** 20 * Manipulate the field access flags. 21 */ 22 public boolean isVolatile() { 23 return (getAccessFlags() & Constants.ACCESS_VOLATILE) > 0; 24 } 25 26 /*** 27 * Manipulate the field access flags. 28 */ 29 public void setVolatile(boolean on) { 30 if (on) 31 setAccessFlags(getAccessFlags() | Constants.ACCESS_VOLATILE); 32 else 33 setAccessFlags(getAccessFlags() & ~Constants.ACCESS_VOLATILE); 34 } 35 36 /*** 37 * Manipulate the field access flags. 38 */ 39 public boolean isTransient() { 40 return (getAccessFlags() & Constants.ACCESS_TRANSIENT) > 0; 41 } 42 43 /*** 44 * Manipulate the field access flags. 45 */ 46 public void setTransient(boolean on) { 47 if (on) 48 setAccessFlags(getAccessFlags() | Constants.ACCESS_TRANSIENT); 49 else 50 setAccessFlags(getAccessFlags() & ~Constants.ACCESS_TRANSIENT); 51 } 52 53 /*** 54 * Manipulate the field access flags. Defaults to true for fields added 55 * to enum classes. 56 */ 57 public boolean isEnum() { 58 return (getAccessFlags() & Constants.ACCESS_ENUM) > 0; 59 } 60 61 /*** 62 * Manipulate the field access flags. Defaults to true for fields added 63 * to enum classes. 64 */ 65 public void setEnum(boolean on) { 66 if (on) 67 setAccessFlags(getAccessFlags() | Constants.ACCESS_ENUM); 68 else 69 setAccessFlags(getAccessFlags() & ~Constants.ACCESS_ENUM); 70 } 71 72 /*** 73 * Return the name of the type of this field. The name will be given in 74 * a form suitable for a {@link Class#forName} call. 75 * 76 * @see BCMember#getDescriptor 77 */ 78 public String getTypeName() { 79 return getProject().getNameCache().getExternalForm 80 (getDescriptor(), false); 81 } 82 83 /*** 84 * Return the {@link Class} object for the type of this field. 85 */ 86 public Class getType() { 87 return Strings.toClass(getTypeName(), getClassLoader()); 88 } 89 90 /*** 91 * Return the bytecode for the type of this field. 92 */ 93 public BCClass getTypeBC() { 94 return getProject().loadClass(getTypeName(), getClassLoader()); 95 } 96 97 /*** 98 * Set the name of the type of this field. 99 * 100 * @see BCMember#setDescriptor 101 */ 102 public void setType(String type) { 103 setDescriptor(type); 104 } 105 106 /*** 107 * Set the type of this field. 108 * 109 * @see BCMember#setDescriptor 110 */ 111 public void setType(Class type) { 112 setType(type.getName()); 113 } 114 115 /*** 116 * Set the type of this field. 117 * 118 * @see BCMember#setDescriptor 119 */ 120 public void setType(BCClass type) { 121 setType(type.getName()); 122 } 123 124 /*** 125 * Return the constant value information for the field. 126 * Acts internally through the {@link Attributes} interface. 127 * 128 * @param add if true, a new constant value attribute will be added 129 * if not already present 130 * @return the constant value information, or null if none and the 131 * <code>add</code> param is set to false 132 */ 133 public ConstantValue getConstantValue(boolean add) { 134 ConstantValue constant = (ConstantValue) getAttribute 135 (Constants.ATTR_CONST); 136 if (!add || (constant != null)) 137 return constant; 138 if (constant == null) 139 constant = (ConstantValue) addAttribute(Constants.ATTR_CONST); 140 return constant; 141 } 142 143 /*** 144 * Remove the constant value attribute for the field. 145 * Acts internally through the {@link Attributes} interface. 146 * 147 * @return true if there was a value to remove 148 */ 149 public boolean removeConstantValue() { 150 return removeAttribute(Constants.ATTR_CONST); 151 } 152 153 public void acceptVisit(BCVisitor visit) { 154 visit.enterBCField(this); 155 visitAttributes(visit); 156 visit.exitBCField(this); 157 } 158 159 void initialize(String name, String descriptor) { 160 super.initialize(name, descriptor); 161 makePrivate(); 162 } 163 }