View Javadoc
1   /*
2    * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  /*
27   * This file is available under and governed by the GNU General Public
28   * License version 2 only, as published by the Free Software Foundation.
29   * However, the following notice accompanied the original version of this
30   * file:
31   *
32   * ASM: a very small and fast Java bytecode manipulation framework
33   * Copyright (c) 2000-2007 INRIA, France Telecom
34   * All rights reserved.
35   *
36   * Redistribution and use in source and binary forms, with or without
37   * modification, are permitted provided that the following conditions
38   * are met:
39   * 1. Redistributions of source code must retain the above copyright
40   *    notice, this list of conditions and the following disclaimer.
41   * 2. Redistributions in binary form must reproduce the above copyright
42   *    notice, this list of conditions and the following disclaimer in the
43   *    documentation and/or other materials provided with the distribution.
44   * 3. Neither the name of the copyright holders nor the names of its
45   *    contributors may be used to endorse or promote products derived from
46   *    this software without specific prior written permission.
47   *
48   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
49   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
52   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
53   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
54   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
55   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
56   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
57   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
58   * THE POSSIBILITY OF SUCH DAMAGE.
59   */
60  package com.sun.xml.internal.ws.org.objectweb.asm;
61  
62  /**
63   * An {@link FieldVisitor} that generates Java fields in bytecode form.
64   *
65   * @author Eric Bruneton
66   */
67  final class FieldWriter implements FieldVisitor {
68  
69      /**
70       * Next field writer (see {@link ClassWriter#firstField firstField}).
71       */
72      FieldWriter next;
73  
74      /**
75       * The class writer to which this field must be added.
76       */
77      private final ClassWriter cw;
78  
79      /**
80       * Access flags of this field.
81       */
82      private final int access;
83  
84      /**
85       * The index of the constant pool item that contains the name of this
86       * method.
87       */
88      private final int name;
89  
90      /**
91       * The index of the constant pool item that contains the descriptor of this
92       * field.
93       */
94      private final int desc;
95  
96      /**
97       * The index of the constant pool item that contains the signature of this
98       * field.
99       */
100     private int signature;
101 
102     /**
103      * The index of the constant pool item that contains the constant value of
104      * this field.
105      */
106     private int value;
107 
108     /**
109      * The runtime visible annotations of this field. May be <tt>null</tt>.
110      */
111     private AnnotationWriter anns;
112 
113     /**
114      * The runtime invisible annotations of this field. May be <tt>null</tt>.
115      */
116     private AnnotationWriter ianns;
117 
118     /**
119      * The non standard attributes of this field. May be <tt>null</tt>.
120      */
121     private Attribute attrs;
122 
123     // ------------------------------------------------------------------------
124     // Constructor
125     // ------------------------------------------------------------------------
126 
127     /**
128      * Constructs a new {@link FieldWriter}.
129      *
130      * @param cw the class writer to which this field must be added.
131      * @param access the field's access flags (see {@link Opcodes}).
132      * @param name the field's name.
133      * @param desc the field's descriptor (see {@link Type}).
134      * @param signature the field's signature. May be <tt>null</tt>.
135      * @param value the field's constant value. May be <tt>null</tt>.
136      */
137     FieldWriter(
138         final ClassWriter cw,
139         final int access,
140         final String name,
141         final String desc,
142         final String signature,
143         final Object value)
144     {
145         if (cw.firstField == null) {
146             cw.firstField = this;
147         } else {
148             cw.lastField.next = this;
149         }
150         cw.lastField = this;
151         this.cw = cw;
152         this.access = access;
153         this.name = cw.newUTF8(name);
154         this.desc = cw.newUTF8(desc);
155         if (ClassReader.SIGNATURES && signature != null) {
156             this.signature = cw.newUTF8(signature);
157         }
158         if (value != null) {
159             this.value = cw.newConstItem(value).index;
160         }
161     }
162 
163     // ------------------------------------------------------------------------
164     // Implementation of the FieldVisitor interface
165     // ------------------------------------------------------------------------
166 
167     public AnnotationVisitor visitAnnotation(
168         final String desc,
169         final boolean visible)
170     {
171         if (!ClassReader.ANNOTATIONS) {
172             return null;
173         }
174         ByteVector bv = new ByteVector();
175         // write type, and reserve space for values count
176         bv.putShort(cw.newUTF8(desc)).putShort(0);
177         AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2);
178         if (visible) {
179             aw.next = anns;
180             anns = aw;
181         } else {
182             aw.next = ianns;
183             ianns = aw;
184         }
185         return aw;
186     }
187 
188     public void visitAttribute(final Attribute attr) {
189         attr.next = attrs;
190         attrs = attr;
191     }
192 
193     public void visitEnd() {
194     }
195 
196     // ------------------------------------------------------------------------
197     // Utility methods
198     // ------------------------------------------------------------------------
199 
200     /**
201      * Returns the size of this field.
202      *
203      * @return the size of this field.
204      */
205     int getSize() {
206         int size = 8;
207         if (value != 0) {
208             cw.newUTF8("ConstantValue");
209             size += 8;
210         }
211         if ((access & Opcodes.ACC_SYNTHETIC) != 0
212                 && (cw.version & 0xffff) < Opcodes.V1_5)
213         {
214             cw.newUTF8("Synthetic");
215             size += 6;
216         }
217         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
218             cw.newUTF8("Deprecated");
219             size += 6;
220         }
221         if (ClassReader.SIGNATURES && signature != 0) {
222             cw.newUTF8("Signature");
223             size += 8;
224         }
225         if (ClassReader.ANNOTATIONS && anns != null) {
226             cw.newUTF8("RuntimeVisibleAnnotations");
227             size += 8 + anns.getSize();
228         }
229         if (ClassReader.ANNOTATIONS && ianns != null) {
230             cw.newUTF8("RuntimeInvisibleAnnotations");
231             size += 8 + ianns.getSize();
232         }
233         if (attrs != null) {
234             size += attrs.getSize(cw, null, 0, -1, -1);
235         }
236         return size;
237     }
238 
239     /**
240      * Puts the content of this field into the given byte vector.
241      *
242      * @param out where the content of this field must be put.
243      */
244     void put(final ByteVector out) {
245         out.putShort(access).putShort(name).putShort(desc);
246         int attributeCount = 0;
247         if (value != 0) {
248             ++attributeCount;
249         }
250         if ((access & Opcodes.ACC_SYNTHETIC) != 0
251                 && (cw.version & 0xffff) < Opcodes.V1_5)
252         {
253             ++attributeCount;
254         }
255         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
256             ++attributeCount;
257         }
258         if (ClassReader.SIGNATURES && signature != 0) {
259             ++attributeCount;
260         }
261         if (ClassReader.ANNOTATIONS && anns != null) {
262             ++attributeCount;
263         }
264         if (ClassReader.ANNOTATIONS && ianns != null) {
265             ++attributeCount;
266         }
267         if (attrs != null) {
268             attributeCount += attrs.getCount();
269         }
270         out.putShort(attributeCount);
271         if (value != 0) {
272             out.putShort(cw.newUTF8("ConstantValue"));
273             out.putInt(2).putShort(value);
274         }
275         if ((access & Opcodes.ACC_SYNTHETIC) != 0
276                 && (cw.version & 0xffff) < Opcodes.V1_5)
277         {
278             out.putShort(cw.newUTF8("Synthetic")).putInt(0);
279         }
280         if ((access & Opcodes.ACC_DEPRECATED) != 0) {
281             out.putShort(cw.newUTF8("Deprecated")).putInt(0);
282         }
283         if (ClassReader.SIGNATURES && signature != 0) {
284             out.putShort(cw.newUTF8("Signature"));
285             out.putInt(2).putShort(signature);
286         }
287         if (ClassReader.ANNOTATIONS && anns != null) {
288             out.putShort(cw.newUTF8("RuntimeVisibleAnnotations"));
289             anns.put(out);
290         }
291         if (ClassReader.ANNOTATIONS && ianns != null) {
292             out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations"));
293             ianns.put(out);
294         }
295         if (attrs != null) {
296             attrs.put(cw, null, 0, -1, -1, out);
297         }
298     }
299 }