1/* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2 *
3 * This program and the accompanying materials are made available under
4 * the terms of the Common Public License v1.0 which accompanies this distribution,
5 * and is available at http://www.eclipse.org/legal/cpl-v10.html
6 *
7 * $Id: Field_info.java,v 1.1.1.1 2004/05/09 16:57:45 vlad_r Exp $
8 */
9package com.vladium.jcd.cls;
10
11import java.io.IOException;
12
13import com.vladium.jcd.cls.attribute.*;
14import com.vladium.jcd.cls.constant.CONSTANT_Utf8_info;
15import com.vladium.jcd.lib.UDataInputStream;
16import com.vladium.jcd.lib.UDataOutputStream;
17
18// ----------------------------------------------------------------------------
19/**
20 * Each class field is described by a variable-length field_info structure. The
21 * format of this structure is
22 * <PRE>
23 *  field_info {
24 *          u2 access_flags;
25 *          u2 name_index;
26 *          u2 descriptor_index;
27 *          u2 attributes_count;
28 *          attribute_info attributes[attributes_count];
29 *  }
30 * </PRE>
31 *
32 * The value of the access_flags item is a mask of modifiers used to describe
33 * access permission to and properties of a field.<P>
34 *
35 * The value of the name_index item must be a valid index into the constant pool
36 * table. The constant pool entry at that index must be a {@link CONSTANT_Utf8_info}
37 * structure which must represent a valid Java field name stored as a simple (not
38 * fully qualified) name, that is, as a Java identifier.<P>
39 *
40 * The value of the descriptor_index item must be a valid index into the constant
41 * pool table. The constant pool entry at that index must be a
42 * {@link CONSTANT_Utf8_info} structure which must represent a valid Java field
43 * descriptor.<P>
44 *
45 * Each value of the attributes table must be a variable-length attribute structure.
46 * A field can have any number of attributes associated with it. The only attribute
47 * defined for the attributes table of a field_info structure at the moment
48 * is the ConstantValue attribute -- see {@link ConstantValueAttribute_info}.
49 *
50 * @author (C) 2001, Vlad Roubtsov
51 */
52public
53final class Field_info implements Cloneable, IAccessFlags
54{
55    // public: ................................................................
56
57
58    public int m_name_index;
59    public int m_descriptor_index;
60
61
62    public Field_info (final int access_flags,
63                       final int name_index, final int descriptor_index,
64                       final IAttributeCollection attributes)
65    {
66        m_access_flags = access_flags;
67
68        m_name_index = name_index;
69        m_descriptor_index = descriptor_index;
70
71        m_attributes = attributes;
72    }
73
74    public Field_info (final IConstantCollection constants,
75                       final UDataInputStream bytes)
76        throws IOException
77    {
78        m_access_flags = bytes.readU2 ();
79
80        m_name_index = bytes.readU2 ();
81        m_descriptor_index = bytes.readU2 ();
82
83        // TODO: put this logic into AttributeCollection
84        final int attributes_count = bytes.readU2 ();
85        m_attributes = ElementFactory.newAttributeCollection (attributes_count);
86
87        for (int i = 0; i < attributes_count; i++)
88        {
89            final Attribute_info attribute_info = Attribute_info.new_Attribute_info (constants, bytes);
90            if (DEBUG) System.out.println ("\t[" + i + "] attribute: " + attribute_info);
91
92            m_attributes.add (attribute_info);
93        }
94    }
95
96    /**
97     * Returns the field name within the context of 'cls' class definition.
98     *
99     * @param cls class that contains this field
100     * @return field name
101     */
102    public String getName (final ClassDef cls)
103    {
104        return ((CONSTANT_Utf8_info) cls.getConstants ().get (m_name_index)).m_value;
105    }
106
107    /**
108     * Returns the descriptor string for this field within the context of 'cls'
109     * class definition.
110     *
111     * @param cls class that contains this field
112     * @return field typename descriptor
113     */
114    public String getDescriptor (final ClassDef cls)
115    {
116        return ((CONSTANT_Utf8_info) cls.getConstants ().get (m_descriptor_index)).m_value;
117    }
118
119    public boolean isSynthetic ()
120    {
121        return m_attributes.hasSynthetic ();
122    }
123
124    // IAccessFlags:
125
126    public final void setAccessFlags (final int flags)
127    {
128        m_access_flags = flags;
129    }
130
131    public final int getAccessFlags ()
132    {
133        return m_access_flags;
134    }
135
136    public IAttributeCollection getAttributes ()
137    {
138        return m_attributes;
139    }
140
141
142    public String toString ()
143    {
144        return "field_info: [modifiers: 0x" + Integer.toHexString(m_access_flags) + ", name_index = " + m_name_index + ", descriptor_index = " + m_descriptor_index + ']';
145    }
146
147
148    // Cloneable:
149
150    /**
151     * Performs a deep copy.
152     */
153    public Object clone ()
154    {
155        try
156        {
157            final Field_info _clone = (Field_info) super.clone ();
158
159            // do deep copy:
160            _clone.m_attributes = (IAttributeCollection) m_attributes.clone ();
161
162            return _clone;
163        }
164        catch (CloneNotSupportedException e)
165        {
166            throw new InternalError (e.toString ());
167        }
168    }
169
170
171    // IClassFormatOutput:
172
173    public void writeInClassFormat (final UDataOutputStream out) throws IOException
174    {
175        out.writeU2 (m_access_flags);
176
177        out.writeU2 (m_name_index);
178        out.writeU2 (m_descriptor_index);
179
180        m_attributes.writeInClassFormat (out);
181    }
182
183    // protected: .............................................................
184
185    // package: ...............................................................
186
187    // private: ...............................................................
188
189
190    private int m_access_flags;
191    private IAttributeCollection m_attributes; // never null
192
193
194    private static final boolean DEBUG = false;
195
196} // end of class
197// ----------------------------------------------------------------------------
198