Home | History | Annotate | Download | only in cls
      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  */
      9 package com.vladium.jcd.cls;
     10 
     11 import java.io.IOException;
     12 
     13 import com.vladium.jcd.cls.attribute.*;
     14 import com.vladium.jcd.cls.constant.CONSTANT_Utf8_info;
     15 import com.vladium.jcd.lib.UDataInputStream;
     16 import 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  */
     52 public
     53 final 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