001 package serp.bytecode; 002 003 import serp.bytecode.lowlevel.*; 004 import serp.bytecode.visitor.*; 005 import serp.util.*; 006 007 /** 008 * A field of a class. 009 * 010 * @author Abe White 011 */ 012 public class BCField extends BCMember implements VisitAcceptor { 013 BCField(BCClass owner) { 014 super(owner); 015 if (owner.isEnum()) 016 setEnum(true); 017 } 018 019 /** 020 * Manipulate the field access flags. 021 */ 022 public boolean isVolatile() { 023 return (getAccessFlags() & Constants.ACCESS_VOLATILE) > 0; 024 } 025 026 /** 027 * Manipulate the field access flags. 028 */ 029 public void setVolatile(boolean on) { 030 if (on) 031 setAccessFlags(getAccessFlags() | Constants.ACCESS_VOLATILE); 032 else 033 setAccessFlags(getAccessFlags() & ~Constants.ACCESS_VOLATILE); 034 } 035 036 /** 037 * Manipulate the field access flags. 038 */ 039 public boolean isTransient() { 040 return (getAccessFlags() & Constants.ACCESS_TRANSIENT) > 0; 041 } 042 043 /** 044 * Manipulate the field access flags. 045 */ 046 public void setTransient(boolean on) { 047 if (on) 048 setAccessFlags(getAccessFlags() | Constants.ACCESS_TRANSIENT); 049 else 050 setAccessFlags(getAccessFlags() & ~Constants.ACCESS_TRANSIENT); 051 } 052 053 /** 054 * Manipulate the field access flags. Defaults to true for fields added 055 * to enum classes. 056 */ 057 public boolean isEnum() { 058 return (getAccessFlags() & Constants.ACCESS_ENUM) > 0; 059 } 060 061 /** 062 * Manipulate the field access flags. Defaults to true for fields added 063 * to enum classes. 064 */ 065 public void setEnum(boolean on) { 066 if (on) 067 setAccessFlags(getAccessFlags() | Constants.ACCESS_ENUM); 068 else 069 setAccessFlags(getAccessFlags() & ~Constants.ACCESS_ENUM); 070 } 071 072 /** 073 * Return the name of the type of this field. The name will be given in 074 * a form suitable for a {@link Class#forName} call. 075 * 076 * @see BCMember#getDescriptor 077 */ 078 public String getTypeName() { 079 return getProject().getNameCache().getExternalForm 080 (getDescriptor(), false); 081 } 082 083 /** 084 * Return the {@link Class} object for the type of this field. 085 */ 086 public Class getType() { 087 return Strings.toClass(getTypeName(), getClassLoader()); 088 } 089 090 /** 091 * Return the bytecode for the type of this field. 092 */ 093 public BCClass getTypeBC() { 094 return getProject().loadClass(getTypeName(), getClassLoader()); 095 } 096 097 /** 098 * Set the name of the type of this field. 099 * 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 }