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 }