001: // Copyright (c) 1997 Per M.A. Bothner.
002: // This is free software; for terms and warranty disclaimer see ./COPYING.
003:
004: package gnu.bytecode;
005:
006: import java.io.*;
007:
008: public class Field extends Location implements AttrContainer {
009: int flags;
010: Field next;
011:
012: Attribute attributes;
013:
014: public final Attribute getAttributes() {
015: return attributes;
016: }
017:
018: public final void setAttributes(Attribute attributes) {
019: this .attributes = attributes;
020: }
021:
022: /** The class that contains this field. */
023: ClassType owner;
024:
025: /** If non-null, the interned source-file (unmangled) name of the field. */
026: String sourceName;
027:
028: /** If non-null, a cached version of the Field for reflectivion. */
029: java.lang.reflect.Field rfield;
030:
031: /** Add a new Field to a ClassType. */
032: public Field(ClassType ctype) {
033: if (ctype.last_field == null)
034: ctype.fields = this ;
035: else
036: ctype.last_field.next = this ;
037: ctype.last_field = this ;
038: ctype.fields_count++;
039: owner = ctype;
040: }
041:
042: public final ClassType getDeclaringClass() {
043: return owner;
044: }
045:
046: public final void setStaticFlag(boolean is_static) {
047: if (is_static)
048: flags |= Access.STATIC;
049: else
050: flags ^= ~Access.STATIC;
051: }
052:
053: public final boolean getStaticFlag() {
054: return (flags & Access.STATIC) != 0;
055: }
056:
057: public final boolean isFinal() {
058: return (flags & Access.FINAL) != 0;
059: }
060:
061: public final boolean isStatic() {
062: return (flags & Access.STATIC) != 0;
063: }
064:
065: public final int getFlags() {
066: return flags;
067: }
068:
069: public final int getModifiers() {
070: return flags;
071: }
072:
073: void write(DataOutputStream dstr, ClassType classfile)
074: throws java.io.IOException {
075: dstr.writeShort(flags);
076: dstr.writeShort(name_index);
077: dstr.writeShort(signature_index);
078:
079: Attribute.writeAll(this , dstr);
080: }
081:
082: void assign_constants(ClassType classfile) {
083: ConstantPool constants = classfile.constants;
084: if (name_index == 0 && name != null)
085: name_index = constants.addUtf8(name).index;
086: if (signature_index == 0 && type != null)
087: signature_index = constants.addUtf8(type.signature).index;
088: Attribute.assignConstants(this , classfile);
089: }
090:
091: public java.lang.reflect.Field getReflectField()
092: throws java.lang.NoSuchFieldException {
093: if (rfield == null)
094: rfield = owner.getReflectClass()
095: .getDeclaredField(getName());
096: return rfield;
097: }
098:
099: public void setSourceName(String name) {
100: sourceName = name;
101: }
102:
103: public String getSourceName() {
104: if (sourceName == null)
105: sourceName = getName().intern();
106: return sourceName;
107: }
108:
109: /** Find a field with the given name.
110: * @param fields list of fields to search
111: * @param name (interned source) name of field to look for
112: */
113: public static Field searchField(Field fields, String name) {
114: for (; fields != null; fields = fields.next) {
115: if (fields.getSourceName() == name)
116: return fields;
117: }
118: return null;
119: }
120:
121: public final Field getNext() {
122: return next;
123: }
124:
125: /** Set the ConstantValue attribute for this field.
126: * @param value the value to use for the ConstantValue attribute
127: * of this field
128: * @param ctype the class that contains this field
129: * This field's type is used to determine the kind of constant.
130: */
131: public final void setConstantValue(Object value, ClassType ctype) {
132: ConstantPool cpool = ctype.getConstants();
133: char sig1 = getType().getSignature().charAt(0);
134: CpoolEntry entry;
135: switch (sig1) {
136: case 'Z':
137: entry = addIfNotDefault(cpool, ((Boolean) value)
138: .booleanValue() ? 1 : 0);
139: break;
140: case 'C':
141: entry = addIfNotDefault(cpool, ((Character) value)
142: .charValue());
143: break;
144: case 'B':
145: case 'S':
146: case 'I':
147: entry = addIfNotDefault(cpool, ((Number) value).intValue());
148: break;
149: case 'J':
150: entry = cpool.addLong(((Number) value).longValue());
151: break;
152: case 'F':
153: entry = cpool.addFloat(((Number) value).floatValue());
154: break;
155: case 'D':
156: entry = cpool.addDouble(((Number) value).doubleValue());
157: break;
158: default:
159: entry = cpool.addString(value.toString());
160: break;
161: }
162: if (entry != null) {
163: ConstantValueAttr attr = new ConstantValueAttr(entry
164: .getIndex());
165: attr.addToFrontOf(this );
166: }
167: }
168:
169: private CpoolEntry addIfNotDefault(ConstantPool cpool, int value) {
170: if (value == 0 && !isFinal())
171: // 0 is the default value, no need to specify it.
172: return null;
173: else
174: return cpool.addInt(value);
175: }
176:
177: public String toString() {
178: return owner.getName() + "." + getSourceName();
179: }
180: }
|