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.tree; 31 32 import java.util.ArrayList; 33 import java.util.Arrays; 34 import java.util.List; 35 36 import org.objectweb.asm.AnnotationVisitor; 37 import org.objectweb.asm.Attribute; 38 import org.objectweb.asm.ClassVisitor; 39 import org.objectweb.asm.Handle; 40 import org.objectweb.asm.TypeAnnotationVisitor; 41 import org.objectweb.asm.Label; 42 import org.objectweb.asm.MethodVisitor; 43 import org.objectweb.asm.Opcodes; 44 import org.objectweb.asm.Type; 45 import org.objectweb.asm.TypePath; 46 47 /** 48 * A node that represents a method. 49 * 50 * @author Eric Bruneton 51 */ 52 public class MethodNode extends MemberNode implements MethodVisitor { 53 54 // jaime visitTypeAnnotation(String desc, boolean visible, boolean inCode)55 public TypeAnnotationVisitor visitTypeAnnotation(String desc, 56 boolean visible, 57 boolean inCode) 58 { 59 return null; 60 } 61 //end jaime 62 63 /** 64 * The method's access flags (see {@link Opcodes}). This field also 65 * indicates if the method is synthetic and/or deprecated. 66 */ 67 public int access; 68 69 /** 70 * The method's name. 71 */ 72 public String name; 73 74 /** 75 * The method's descriptor (see {@link Type}). 76 */ 77 public String desc; 78 79 /** 80 * The method's signature. May be <tt>null</tt>. 81 */ 82 public String signature; 83 84 /** 85 * The internal names of the method's exception classes (see 86 * {@link Type#getInternalName() getInternalName}). This list is a list of 87 * {@link String} objects. 88 */ 89 public List exceptions; 90 91 /** 92 * The default value of this annotation interface method. This field must be 93 * a {@link Byte}, {@link Boolean}, {@link Character}, {@link Short}, 94 * {@link Integer}, {@link Long}, {@link Float}, {@link Double}, 95 * {@link String} or {@link Type}, or an two elements String array (for 96 * enumeration values), a {@link AnnotationNode}, or a {@link List} of 97 * values of one of the preceding types. May be <tt>null</tt>. 98 */ 99 public Object annotationDefault; 100 101 /** 102 * The runtime visible parameter annotations of this method. These lists are 103 * lists of {@link AnnotationNode} objects. May be <tt>null</tt>. 104 * 105 * @associates org.objectweb.asm.tree.AnnotationNode 106 * @label invisible parameters 107 */ 108 public List[] visibleParameterAnnotations; 109 110 /** 111 * The runtime invisible parameter annotations of this method. These lists 112 * are lists of {@link AnnotationNode} objects. May be <tt>null</tt>. 113 * 114 * @associates org.objectweb.asm.tree.AnnotationNode 115 * @label visible parameters 116 */ 117 public List[] invisibleParameterAnnotations; 118 119 /** 120 * The instructions of this method. This list is a list of 121 * {@link AbstractInsnNode} objects. 122 * 123 * @associates org.objectweb.asm.tree.AbstractInsnNode 124 * @label instructions 125 */ 126 public List instructions; 127 128 /** 129 * The try catch blocks of this method. This list is a list of 130 * {@link TryCatchBlockNode} objects. 131 * 132 * @associates org.objectweb.asm.tree.TryCatchBlockNode 133 */ 134 public List tryCatchBlocks; 135 136 /** 137 * The maximum stack size of this method. 138 */ 139 public int maxStack; 140 141 /** 142 * The maximum number of local variables of this method. 143 */ 144 public int maxLocals; 145 146 /** 147 * The local variables of this method. This list is a list of 148 * {@link LocalVariableNode} objects. May be <tt>null</tt> 149 * 150 * @associates org.objectweb.asm.tree.LocalVariableNode 151 */ 152 public List localVariables; 153 154 /** 155 * The line numbers of this method. This list is a list of 156 * {@link LineNumberNode} objects. May be <tt>null</tt> 157 * 158 * @associates org.objectweb.asm.tree.LineNumberNode 159 */ 160 public List lineNumbers; 161 162 /** 163 * Constructs a new {@link MethodNode}. 164 * 165 * @param access the method's access flags (see {@link Opcodes}). This 166 * parameter also indicates if the method is synthetic and/or 167 * deprecated. 168 * @param name the method's name. 169 * @param desc the method's descriptor (see {@link Type}). 170 * @param signature the method's signature. May be <tt>null</tt>. 171 * @param exceptions the internal names of the method's exception classes 172 * (see {@link Type#getInternalName() getInternalName}). May be 173 * <tt>null</tt>. 174 */ MethodNode( final int access, final String name, final String desc, final String signature, final String[] exceptions)175 public MethodNode( 176 final int access, 177 final String name, 178 final String desc, 179 final String signature, 180 final String[] exceptions) 181 { 182 this.access = access; 183 this.name = name; 184 this.desc = desc; 185 this.signature = signature; 186 this.exceptions = new ArrayList(exceptions == null 187 ? 0 188 : exceptions.length); 189 boolean isAbstract = (access & Opcodes.ACC_ABSTRACT) != 0; 190 this.instructions = new ArrayList(isAbstract ? 0 : 24); 191 if (!isAbstract) { 192 this.localVariables = new ArrayList(5); 193 this.lineNumbers = new ArrayList(5); 194 } 195 this.tryCatchBlocks = new ArrayList(); 196 if (exceptions != null) { 197 this.exceptions.addAll(Arrays.asList(exceptions)); 198 } 199 } 200 201 // ------------------------------------------------------------------------ 202 // Implementation of the MethodVisitor interface 203 // ------------------------------------------------------------------------ 204 visitAnnotationDefault()205 public AnnotationVisitor visitAnnotationDefault() { 206 return new AnnotationNode(new ArrayList(0) { 207 public boolean add(Object o) { 208 annotationDefault = o; 209 return super.add(o); 210 } 211 }); 212 } 213 214 public AnnotationVisitor visitParameterAnnotation( 215 final int parameter, 216 final String desc, 217 final boolean visible) 218 { 219 AnnotationNode an = new AnnotationNode(desc); 220 if (visible) { 221 if (visibleParameterAnnotations == null) { 222 int params = Type.getArgumentTypes(this.desc).length; 223 visibleParameterAnnotations = new List[params]; 224 } 225 if (visibleParameterAnnotations[parameter] == null) { 226 visibleParameterAnnotations[parameter] = new ArrayList(1); 227 } 228 visibleParameterAnnotations[parameter].add(an); 229 } else { 230 if (invisibleParameterAnnotations == null) { 231 int params = Type.getArgumentTypes(this.desc).length; 232 invisibleParameterAnnotations = new List[params]; 233 } 234 if (invisibleParameterAnnotations[parameter] == null) { 235 invisibleParameterAnnotations[parameter] = new ArrayList(1); 236 } 237 invisibleParameterAnnotations[parameter].add(an); 238 } 239 return an; 240 } 241 242 public void visitCode() { 243 } 244 245 public void visitInsn(final int opcode) { 246 instructions.add(new InsnNode(opcode)); 247 } 248 249 public void visitIntInsn(final int opcode, final int operand) { 250 instructions.add(new IntInsnNode(opcode, operand)); 251 } 252 253 public void visitVarInsn(final int opcode, final int var) { 254 instructions.add(new VarInsnNode(opcode, var)); 255 } 256 257 public void visitTypeInsn(final int opcode, final String desc) { 258 instructions.add(new TypeInsnNode(opcode, desc)); 259 } 260 261 public void visitFieldInsn( 262 final int opcode, 263 final String owner, 264 final String name, 265 final String desc) 266 { 267 instructions.add(new FieldInsnNode(opcode, owner, name, desc)); 268 } 269 270 public void visitMethodInsn( 271 final int opcode, 272 final String owner, 273 final String name, 274 final String desc) 275 { 276 instructions.add(new MethodInsnNode(opcode, owner, name, desc)); 277 } 278 279 @Override 280 public void visitInvokeDynamicInsn( 281 String name, 282 String desc, 283 Handle bsm, 284 Object... bsmArgs) 285 { 286 instructions.add(new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs)); 287 } 288 289 public void visitJumpInsn(final int opcode, final Label label) { 290 instructions.add(new JumpInsnNode(opcode, label)); 291 } 292 293 public void visitLabel(final Label label) { 294 instructions.add(new LabelNode(label)); 295 } 296 297 public void visitLdcInsn(final Object cst) { 298 instructions.add(new LdcInsnNode(cst)); 299 } 300 301 public void visitIincInsn(final int var, final int increment) { 302 instructions.add(new IincInsnNode(var, increment)); 303 } 304 305 public void visitTableSwitchInsn( 306 final int min, 307 final int max, 308 final Label dflt, 309 final Label[] labels) 310 { 311 instructions.add(new TableSwitchInsnNode(min, max, dflt, labels)); 312 } 313 314 public void visitLookupSwitchInsn( 315 final Label dflt, 316 final int[] keys, 317 final Label[] labels) 318 { 319 instructions.add(new LookupSwitchInsnNode(dflt, keys, labels)); 320 } 321 322 public void visitMultiANewArrayInsn(final String desc, final int dims) { 323 instructions.add(new MultiANewArrayInsnNode(desc, dims)); 324 } 325 326 public void visitTryCatchBlock( 327 final Label start, 328 final Label end, 329 final Label handler, 330 final String type) 331 { 332 tryCatchBlocks.add(new TryCatchBlockNode(start, end, handler, type)); 333 } 334 335 public void visitLocalVariable( 336 final String name, 337 final String desc, 338 final String signature, 339 final Label start, 340 final Label end, 341 final int index) 342 { 343 localVariables.add(new LocalVariableNode(name, 344 desc, 345 signature, 346 start, 347 end, 348 index)); 349 } 350 351 public void visitLineNumber(final int line, final Label start) { 352 lineNumbers.add(new LineNumberNode(line, start)); 353 } 354 355 public void visitMaxs(final int maxStack, final int maxLocals) { 356 this.maxStack = maxStack; 357 this.maxLocals = maxLocals; 358 } 359 360 // ------------------------------------------------------------------------ 361 // Accept method 362 // ------------------------------------------------------------------------ 363 364 /** 365 * Makes the given class visitor visit this method. 366 * 367 * @param cv a class visitor. 368 */ 369 public void accept(final ClassVisitor cv) { 370 String[] exceptions = new String[this.exceptions.size()]; 371 this.exceptions.toArray(exceptions); 372 MethodVisitor mv = cv.visitMethod(access, 373 name, 374 desc, 375 signature, 376 exceptions); 377 if (mv != null) { 378 accept(mv); 379 } 380 } 381 382 /** 383 * Makes the given method visitor visit this method. 384 * 385 * @param mv a method visitor. 386 */ 387 public void accept(final MethodVisitor mv) { 388 // visits the method attributes 389 int i, j, n; 390 if (annotationDefault != null) { 391 AnnotationVisitor av = mv.visitAnnotationDefault(); 392 AnnotationNode.accept(av, null, annotationDefault); 393 av.visitEnd(); 394 } 395 n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); 396 for (i = 0; i < n; ++i) { 397 AnnotationNode an = (AnnotationNode) visibleAnnotations.get(i); 398 an.accept(mv.visitAnnotation(an.desc, true)); 399 } 400 n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); 401 for (i = 0; i < n; ++i) { 402 AnnotationNode an = (AnnotationNode) invisibleAnnotations.get(i); 403 an.accept(mv.visitAnnotation(an.desc, false)); 404 } 405 n = visibleParameterAnnotations == null 406 ? 0 407 : visibleParameterAnnotations.length; 408 for (i = 0; i < n; ++i) { 409 List l = visibleParameterAnnotations[i]; 410 if (l == null) { 411 continue; 412 } 413 for (j = 0; j < l.size(); ++j) { 414 AnnotationNode an = (AnnotationNode) l.get(j); 415 an.accept(mv.visitParameterAnnotation(i, an.desc, true)); 416 } 417 } 418 n = invisibleParameterAnnotations == null 419 ? 0 420 : invisibleParameterAnnotations.length; 421 for (i = 0; i < n; ++i) { 422 List l = invisibleParameterAnnotations[i]; 423 if (l == null) { 424 continue; 425 } 426 for (j = 0; j < l.size(); ++j) { 427 AnnotationNode an = (AnnotationNode) l.get(j); 428 an.accept(mv.visitParameterAnnotation(i, an.desc, false)); 429 } 430 } 431 n = attrs == null ? 0 : attrs.size(); 432 for (i = 0; i < n; ++i) { 433 mv.visitAttribute((Attribute) attrs.get(i)); 434 } 435 // visits the method's code 436 if (instructions.size() > 0) { 437 mv.visitCode(); 438 // visits try catch blocks 439 for (i = 0; i < tryCatchBlocks.size(); ++i) { 440 ((TryCatchBlockNode) tryCatchBlocks.get(i)).accept(mv); 441 } 442 // visits instructions 443 for (i = 0; i < instructions.size(); ++i) { 444 ((AbstractInsnNode) instructions.get(i)).accept(mv); 445 } 446 // visits local variables 447 n = localVariables == null ? 0 : localVariables.size(); 448 for (i = 0; i < n; ++i) { 449 ((LocalVariableNode) localVariables.get(i)).accept(mv); 450 } 451 // visits line numbers 452 n = lineNumbers == null ? 0 : lineNumbers.size(); 453 for (i = 0; i < n; ++i) { 454 ((LineNumberNode) lineNumbers.get(i)).accept(mv); 455 } 456 // visits maxs 457 mv.visitMaxs(maxStack, maxLocals); 458 } 459 mv.visitEnd(); 460 } 461 462 @Override 463 public AnnotationVisitor visitInsnAnnotation(int typeRef, 464 TypePath typePath, String desc, boolean visible) { 465 // TODO Auto-generated method stub 466 return null; 467 } 468 } 469