KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > asm > FieldWriter


1 /***
2  * ASM: a very small and fast Java bytecode manipulation framework
3  * Copyright (c) 2000-2005 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */

30 package com.tc.asm;
31
32 /**
33  * An {@link FieldVisitor} that generates Java fields in bytecode form.
34  *
35  * @author Eric Bruneton
36  */

37 final class FieldWriter implements FieldVisitor {
38
39     /**
40      * Next field writer (see {@link ClassWriter#firstField firstField}).
41      */

42     FieldWriter next;
43
44     /**
45      * The class writer to which this field must be added.
46      */

47     private ClassWriter cw;
48
49     /**
50      * Access flags of this field.
51      */

52     private int access;
53
54     /**
55      * The index of the constant pool item that contains the name of this
56      * method.
57      */

58     private int name;
59
60     /**
61      * The index of the constant pool item that contains the descriptor of this
62      * field.
63      */

64     private int desc;
65
66     /**
67      * The index of the constant pool item that contains the signature of this
68      * field.
69      */

70     private int signature;
71
72     /**
73      * The index of the constant pool item that contains the constant value of
74      * this field.
75      */

76     private int value;
77
78     /**
79      * The runtime visible annotations of this field. May be <tt>null</tt>.
80      */

81     private AnnotationWriter anns;
82
83     /**
84      * The runtime invisible annotations of this field. May be <tt>null</tt>.
85      */

86     private AnnotationWriter ianns;
87
88     /**
89      * The non standard attributes of this field. May be <tt>null</tt>.
90      */

91     private Attribute attrs;
92
93     // ------------------------------------------------------------------------
94
// Constructor
95
// ------------------------------------------------------------------------
96

97     /**
98      * Constructs a new {@link FieldWriter}.
99      *
100      * @param cw the class writer to which this field must be added.
101      * @param access the field's access flags (see {@link Opcodes}).
102      * @param name the field's name.
103      * @param desc the field's descriptor (see {@link Type}).
104      * @param signature the field's signature. May be <tt>null</tt>.
105      * @param value the field's constant value. May be <tt>null</tt>.
106      */

107     protected FieldWriter(
108         final ClassWriter cw,
109         final int access,
110         final String JavaDoc name,
111         final String JavaDoc desc,
112         final String JavaDoc signature,
113         final Object JavaDoc value)
114     {
115         if (cw.firstField == null) {
116             cw.firstField = this;
117         } else {
118             cw.lastField.next = this;
119         }
120         cw.lastField = this;
121         this.cw = cw;
122         this.access = access;
123         this.name = cw.newUTF8(name);
124         this.desc = cw.newUTF8(desc);
125         if (signature != null) {
126             this.signature = cw.newUTF8(signature);
127         }
128         if (value != null) {
129             this.value = cw.newConstItem(value).index;
130         }
131     }
132
133     // ------------------------------------------------------------------------
134
// Implementation of the FieldVisitor interface
135
// ------------------------------------------------------------------------
136

137     public AnnotationVisitor visitAnnotation(
138         final String JavaDoc desc,
139         final boolean visible)
140     {
141         ByteVector bv = new ByteVector();
142         // write type, and reserve space for values count
143
bv.putShort(cw.newUTF8(desc)).putShort(0);
144         AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2);
145         if (visible) {
146             aw.next = anns;
147             anns = aw;
148         } else {
149             aw.next = ianns;
150             ianns = aw;
151         }
152         return aw;
153     }
154
155     public void visitAttribute(final Attribute attr) {
156         attr.next = attrs;
157         attrs = attr;
158     }
159
160     public void visitEnd() {
161     }
162
163     // ------------------------------------------------------------------------
164
// Utility methods
165
// ------------------------------------------------------------------------
166

167     /**
168      * Returns the size of this field.
169      *
170      * @return the size of this field.
171      */

172     int getSize() {
173         int size = 8;
174         if (value != 0) {
175             cw.newUTF8("ConstantValue");
176             size += 8;
177         }
178         if ((access & Opcodes.ACC_SYNTHETIC) != 0
179                 && (cw.version & 0xffff) < Opcodes.V1_5)
180         {
181             cw.newUTF8("Synthetic");
182             size += 6;
183         }
184         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
185             cw.newUTF8("Deprecated");
186             size += 6;
187         }
188         if (cw.version == Opcodes.V1_4 && (access & Opcodes.ACC_ENUM) != 0) {
189             cw.newUTF8("Enum");
190             size += 6;
191         }
192         if (signature != 0) {
193             cw.newUTF8("Signature");
194             size += 8;
195         }
196         if (anns != null) {
197             cw.newUTF8("RuntimeVisibleAnnotations");
198             size += 8 + anns.getSize();
199         }
200         if (ianns != null) {
201             cw.newUTF8("RuntimeInvisibleAnnotations");
202             size += 8 + ianns.getSize();
203         }
204         if (attrs != null) {
205             size += attrs.getSize(cw, null, 0, -1, -1);
206         }
207         return size;
208     }
209
210     /**
211      * Puts the content of this field into the given byte vector.
212      *
213      * @param out where the content of this field must be put.
214      */

215     void put(final ByteVector out) {
216         out.putShort(access).putShort(name).putShort(desc);
217         int attributeCount = 0;
218         if (value != 0) {
219             ++attributeCount;
220         }
221         if ((access & Opcodes.ACC_SYNTHETIC) != 0
222                 && (cw.version & 0xffff) < Opcodes.V1_5)
223         {
224             ++attributeCount;
225         }
226         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
227             ++attributeCount;
228         }
229         if (cw.version == Opcodes.V1_4 && (access & Opcodes.ACC_ENUM) != 0) {
230             ++attributeCount;
231         }
232         if (signature != 0) {
233             ++attributeCount;
234         }
235         if (anns != null) {
236             ++attributeCount;
237         }
238         if (ianns != null) {
239             ++attributeCount;
240         }
241         if (attrs != null) {
242             attributeCount += attrs.getCount();
243         }
244         out.putShort(attributeCount);
245         if (value != 0) {
246             out.putShort(cw.newUTF8("ConstantValue"));
247             out.putInt(2).putShort(value);
248         }
249         if ((access & Opcodes.ACC_SYNTHETIC) != 0
250                 && (cw.version & 0xffff) < Opcodes.V1_5)
251         {
252             out.putShort(cw.newUTF8("Synthetic")).putInt(0);
253         }
254         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
255             out.putShort(cw.newUTF8("Deprecated")).putInt(0);
256         }
257         if (cw.version == Opcodes.V1_4 && (access & Opcodes.ACC_ENUM) != 0) {
258             out.putShort(cw.newUTF8("Enum")).putInt(0);
259         }
260         if (signature != 0) {
261             out.putShort(cw.newUTF8("Signature"));
262             out.putInt(2).putShort(signature);
263         }
264         if (anns != null) {
265             out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
266             anns.put(out);
267         }
268         if (ianns != null) {
269             out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
270             ianns.put(out);
271         }
272         if (attrs != null) {
273             attrs.put(cw, null, 0, -1, -1, out);
274         }
275     }
276 }
277
Popular Tags