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 org.objectweb.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 //jaime 89 private TypeAnnotationWriter xanns; 90 private TypeAnnotationWriter ixanns; 91 //end jaime 92 93 /** 94 * The non standard attributes of this field. May be <tt>null</tt>. 95 */ 96 private Attribute attrs; 97 98 // ------------------------------------------------------------------------ 99 // Constructor 100 // ------------------------------------------------------------------------ 101 102 /** 103 * Constructs a new {@link FieldWriter}. 104 * 105 * @param cw the class writer to which this field must be added. 106 * @param access the field's access flags (see {@link Opcodes}). 107 * @param name the field's name. 108 * @param desc the field's descriptor (see {@link Type}). 109 * @param signature the field's signature. May be <tt>null</tt>. 110 * @param value the field's constant value. May be <tt>null</tt>. 111 */ 112 protected FieldWriter( 113 final ClassWriter cw, 114 final int access, 115 final String name, 116 final String desc, 117 final String signature, 118 final Object value) 119 { 120 if (cw.firstField == null) { 121 cw.firstField = this; 122 } else { 123 cw.lastField.next = this; 124 } 125 cw.lastField = this; 126 this.cw = cw; 127 this.access = access; 128 this.name = cw.newUTF8(name); 129 this.desc = cw.newUTF8(desc); 130 if (signature != null) { 131 this.signature = cw.newUTF8(signature); 132 } 133 if (value != null) { 134 this.value = cw.newConstItem(value).index; 135 } 136 } 137 138 // ------------------------------------------------------------------------ 139 // Implementation of the FieldVisitor interface 140 // ------------------------------------------------------------------------ 141 142 public AnnotationVisitor visitAnnotation( 143 final String desc, 144 final boolean visible) 145 { 146 ByteVector bv = new ByteVector(); 147 // write type, and reserve space for values count 148 bv.putShort(cw.newUTF8(desc)).putShort(0); 149 AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2); 150 if (visible) { 151 aw.next = anns; 152 anns = aw; 153 } else { 154 aw.next = ianns; 155 ianns = aw; 156 } 157 return aw; 158 } 159 160 //jaime 161 public TypeAnnotationVisitor visitTypeAnnotation( 162 final String desc, 163 final boolean visible, 164 final boolean inCode) 165 { 166 ByteVector bv = new ByteVector(); 167 TypeAnnotationWriter xaw = 168 new TypeAnnotationWriter(cw, true, bv, bv, desc); 169 if(visible) { 170 xaw.next = xanns; 171 xanns = xaw; 172 } else { 173 xaw.next = ixanns; 174 ixanns = xaw; 175 } 176 return xaw; 177 } 178 // end jaime 179 180 public void visitAttribute(final Attribute attr) { 181 attr.next = attrs; 182 attrs = attr; 183 } 184 185 public void visitEnd() { 186 } 187 188 // ------------------------------------------------------------------------ 189 // Utility methods 190 // ------------------------------------------------------------------------ 191 192 /** 193 * Returns the size of this field. 194 * 195 * @return the size of this field. 196 */ 197 int getSize() { 198 int size = 8; 199 if (value != 0) { 200 cw.newUTF8("ConstantValue"); 201 size += 8; 202 } 203 if ((access & Opcodes.ACC_SYNTHETIC) != 0 204 && (cw.version & 0xffff) < Opcodes.V1_5) 205 { 206 cw.newUTF8("Synthetic"); 207 size += 6; 208 } 209 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 210 cw.newUTF8("Deprecated"); 211 size += 6; 212 } 213 if (cw.version == Opcodes.V1_4 && (access & Opcodes.ACC_ENUM) != 0) { 214 cw.newUTF8("Enum"); 215 size += 6; 216 } 217 if (signature != 0) { 218 cw.newUTF8("Signature"); 219 size += 8; 220 } 221 if (anns != null) { 222 cw.newUTF8("RuntimeVisibleAnnotations"); 223 size += 8 + anns.getSize(); 224 } 225 if (ianns != null) { 226 cw.newUTF8("RuntimeInvisibleAnnotations"); 227 size += 8 + ianns.getSize(); 228 } 229 //jaime 230 if (xanns != null) { 231 cw.newUTF8("RuntimeVisibleTypeAnnotations"); 232 size += 8 + xanns.getSize(); 233 } 234 if (ixanns != null) { 235 cw.newUTF8("RuntimeInvisibleTypeAnnotations"); 236 size += 8 + ixanns.getSize(); 237 } 238 // end jaime 239 if (attrs != null) { 240 size += attrs.getSize(cw, null, 0, -1, -1); 241 } 242 return size; 243 } 244 245 /** 246 * Puts the content of this field into the given byte vector. 247 * 248 * @param out where the content of this field must be put. 249 */ 250 void put(final ByteVector out) { 251 out.putShort(access).putShort(name).putShort(desc); 252 int attributeCount = 0; 253 if (value != 0) { 254 ++attributeCount; 255 } 256 if ((access & Opcodes.ACC_SYNTHETIC) != 0 257 && (cw.version & 0xffff) < Opcodes.V1_5) 258 { 259 ++attributeCount; 260 } 261 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 262 ++attributeCount; 263 } 264 if (cw.version == Opcodes.V1_4 && (access & Opcodes.ACC_ENUM) != 0) { 265 ++attributeCount; 266 } 267 if (signature != 0) { 268 ++attributeCount; 269 } 270 if (anns != null) { 271 ++attributeCount; 272 } 273 if (ianns != null) { 274 ++attributeCount; 275 } 276 //jaime 277 if (xanns != null) { 278 ++attributeCount; 279 } 280 if (ixanns != null) { 281 ++attributeCount; 282 } 283 // end jaime 284 285 if (attrs != null) { 286 attributeCount += attrs.getCount(); 287 } 288 out.putShort(attributeCount); 289 if (value != 0) { 290 out.putShort(cw.newUTF8("ConstantValue")); 291 out.putInt(2).putShort(value); 292 } 293 if ((access & Opcodes.ACC_SYNTHETIC) != 0 294 && (cw.version & 0xffff) < Opcodes.V1_5) 295 { 296 out.putShort(cw.newUTF8("Synthetic")).putInt(0); 297 } 298 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 299 out.putShort(cw.newUTF8("Deprecated")).putInt(0); 300 } 301 if (cw.version == Opcodes.V1_4 && (access & Opcodes.ACC_ENUM) != 0) { 302 out.putShort(cw.newUTF8("Enum")).putInt(0); 303 } 304 if (signature != 0) { 305 out.putShort(cw.newUTF8("Signature")); 306 out.putInt(2).putShort(signature); 307 } 308 if (anns != null) { 309 out.putShort(cw.newUTF8("RuntimeVisibleAnnotations")); 310 anns.put(out); 311 } 312 if (ianns != null) { 313 out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations")); 314 ianns.put(out); 315 } 316 317 //jaime 318 if (xanns != null) { 319 out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations")); 320 xanns.put(out); 321 } 322 if (ixanns != null) { 323 out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations")); 324 ixanns.put(out); 325 } 326 // end jaime 327 328 if (attrs != null) { 329 attrs.put(cw, null, 0, -1, -1, out); 330 } 331 } 332 } 333