1 30 package org.objectweb.asm.util; 31 32 import java.io.FileInputStream ; 33 import java.io.PrintWriter ; 34 35 import org.objectweb.asm.AnnotationVisitor; 36 import org.objectweb.asm.Attribute; 37 import org.objectweb.asm.ClassReader; 38 import org.objectweb.asm.ClassVisitor; 39 import org.objectweb.asm.MethodVisitor; 40 import org.objectweb.asm.Opcodes; 41 import org.objectweb.asm.FieldVisitor; 42 import org.objectweb.asm.signature.SignatureReader; 43 44 94 public class TraceClassVisitor extends TraceAbstractVisitor implements 95 ClassVisitor 96 { 97 98 102 protected final ClassVisitor cv; 103 104 107 protected final PrintWriter pw; 108 109 119 public static void main(final String [] args) throws Exception { 120 int i = 0; 121 boolean skipDebug = true; 122 123 boolean ok = true; 124 if (args.length < 1 || args.length > 2) { 125 ok = false; 126 } 127 if (ok && args[0].equals("-debug")) { 128 i = 1; 129 skipDebug = false; 130 if (args.length != 2) { 131 ok = false; 132 } 133 } 134 if (!ok) { 135 System.err.println("Prints a disassembled view of the given class."); 136 System.err.println("Usage: TraceClassVisitor [-debug] " 137 + "<fully qualified class name or class file name>"); 138 System.exit(-1); 139 } 140 ClassReader cr; 141 if (args[i].endsWith(".class") || args[i].indexOf('\\') > -1 142 || args[i].indexOf('/') > -1) 143 { 144 cr = new ClassReader(new FileInputStream (args[i])); 145 } else { 146 cr = new ClassReader(args[i]); 147 } 148 cr.accept(new TraceClassVisitor(new PrintWriter (System.out)), 149 getDefaultAttributes(), 150 skipDebug); 151 } 152 153 158 public TraceClassVisitor(final PrintWriter pw) { 159 this(null, pw); 160 } 161 162 169 public TraceClassVisitor(final ClassVisitor cv, final PrintWriter pw) { 170 this.cv = cv; 171 this.pw = pw; 172 } 173 174 178 public void visit( 179 final int version, 180 final int access, 181 final String name, 182 final String signature, 183 final String superName, 184 final String [] interfaces) 185 { 186 int major = version & 0xFFFF; 187 int minor = version >>> 16; 188 buf.setLength(0); 189 buf.append("// class version ") 190 .append(major) 191 .append('.') 192 .append(minor) 193 .append(" (") 194 .append(version) 195 .append(")\n"); 196 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 197 buf.append("// DEPRECATED\n"); 198 } 199 buf.append("// access flags ").append(access).append('\n'); 200 201 appendDescriptor(CLASS_SIGNATURE, signature); 202 if (signature != null) { 203 TraceSignatureVisitor sv = new TraceSignatureVisitor(access); 204 SignatureReader r = new SignatureReader(signature); 205 r.accept(sv); 206 buf.append("// declaration: ") 207 .append(name) 208 .append(sv.getDeclaration()) 209 .append('\n'); 210 } 211 212 appendAccess(access & ~Opcodes.ACC_SUPER); 213 if ((access & Opcodes.ACC_ANNOTATION) != 0) { 214 buf.append("@interface "); 215 } else if ((access & Opcodes.ACC_INTERFACE) != 0) { 216 buf.append("interface "); 217 } else if ((access & Opcodes.ACC_ENUM) != 0) { 218 buf.append("enum "); 219 } else { 220 buf.append("class "); 221 } 222 appendDescriptor(INTERNAL_NAME, name); 223 224 if (superName != null && !superName.equals("java/lang/Object")) { 225 buf.append(" extends "); 226 appendDescriptor(INTERNAL_NAME, superName); 227 buf.append(' '); 228 } 229 if (interfaces != null && interfaces.length > 0) { 230 buf.append(" implements "); 231 for (int i = 0; i < interfaces.length; ++i) { 232 appendDescriptor(INTERNAL_NAME, interfaces[i]); 233 buf.append(' '); 234 } 235 } 236 buf.append(" {\n\n"); 237 238 text.add(buf.toString()); 239 240 if (cv != null) { 241 cv.visit(version, access, name, signature, superName, interfaces); 242 } 243 } 244 245 public void visitSource(final String file, final String debug) { 246 buf.setLength(0); 247 if (file != null) { 248 buf.append(tab) 249 .append("// compiled from: ") 250 .append(file) 251 .append('\n'); 252 } 253 if (debug != null) { 254 buf.append(tab) 255 .append("// debug info: ") 256 .append(debug) 257 .append('\n'); 258 } 259 if (buf.length() > 0) { 260 text.add(buf.toString()); 261 } 262 263 if (cv != null) { 264 cv.visitSource(file, debug); 265 } 266 } 267 268 public void visitOuterClass( 269 final String owner, 270 final String name, 271 final String desc) 272 { 273 buf.setLength(0); 274 buf.append(tab).append("OUTERCLASS "); 275 appendDescriptor(INTERNAL_NAME, owner); 276 buf.append(' ').append(name).append(' '); 277 appendDescriptor(METHOD_DESCRIPTOR, desc); 278 buf.append('\n'); 279 text.add(buf.toString()); 280 281 if (cv != null) { 282 cv.visitOuterClass(owner, name, desc); 283 } 284 } 285 286 public AnnotationVisitor visitAnnotation( 287 final String desc, 288 final boolean visible) 289 { 290 text.add("\n"); 291 AnnotationVisitor tav = super.visitAnnotation(desc, visible); 292 if (cv != null) { 293 ((TraceAnnotationVisitor) tav).av = cv.visitAnnotation(desc, 294 visible); 295 } 296 return tav; 297 } 298 299 public void visitAttribute(final Attribute attr) { 300 text.add("\n"); 301 super.visitAttribute(attr); 302 303 if (cv != null) { 304 cv.visitAttribute(attr); 305 } 306 } 307 308 public void visitInnerClass( 309 final String name, 310 final String outerName, 311 final String innerName, 312 final int access) 313 { 314 buf.setLength(0); 315 buf.append(tab).append("INNERCLASS "); 316 appendDescriptor(INTERNAL_NAME, name); 317 buf.append(' '); 318 appendDescriptor(INTERNAL_NAME, outerName); 319 buf.append(' '); 320 appendDescriptor(INTERNAL_NAME, innerName); 321 buf.append(' ').append(access & ~Opcodes.ACC_SUPER); 322 if ((access & Opcodes.ACC_ENUM) != 0) { 323 buf.append("enum "); 324 } 325 buf.append('\n'); 326 text.add(buf.toString()); 327 328 if (cv != null) { 329 cv.visitInnerClass(name, outerName, innerName, access); 330 } 331 } 332 333 public FieldVisitor visitField( 334 final int access, 335 final String name, 336 final String desc, 337 final String signature, 338 final Object value) 339 { 340 buf.setLength(0); 341 buf.append('\n'); 342 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 343 buf.append(tab).append("// DEPRECATED\n"); 344 } 345 buf.append(tab).append("// access flags ").append(access).append('\n'); 346 if (signature != null) { 347 buf.append(tab); 348 appendDescriptor(FIELD_SIGNATURE, signature); 349 350 TraceSignatureVisitor sv = new TraceSignatureVisitor(0); 351 SignatureReader r = new SignatureReader(signature); 352 r.acceptType(sv); 353 buf.append(tab) 354 .append("// declaration: ") 355 .append(sv.getDeclaration()) 356 .append('\n'); 357 } 358 359 buf.append(tab); 360 appendAccess(access); 361 if ((access & Opcodes.ACC_ENUM) != 0) { 362 buf.append("enum "); 363 } 364 365 appendDescriptor(FIELD_DESCRIPTOR, desc); 366 buf.append(' ').append(name); 367 if (value != null) { 368 buf.append(" = "); 369 if (value instanceof String ) { 370 buf.append("\"").append(value).append("\""); 371 } else { 372 buf.append(value); 373 } 374 } 375 376 buf.append('\n'); 377 text.add(buf.toString()); 378 379 TraceFieldVisitor tav = createTraceFieldVisitor(); 380 text.add(tav.getText()); 381 382 if (cv != null) { 383 tav.fv = cv.visitField(access, name, desc, signature, value); 384 } 385 386 return tav; 387 } 388 389 public MethodVisitor visitMethod( 390 final int access, 391 final String name, 392 final String desc, 393 final String signature, 394 final String [] exceptions) 395 { 396 buf.setLength(0); 397 buf.append('\n'); 398 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 399 buf.append(tab).append("// DEPRECATED\n"); 400 } 401 buf.append(tab).append("// access flags ").append(access).append('\n'); 402 buf.append(tab); 403 appendDescriptor(METHOD_SIGNATURE, signature); 404 405 if (signature != null) { 406 TraceSignatureVisitor v = new TraceSignatureVisitor(0); 407 SignatureReader r = new SignatureReader(signature); 408 r.accept(v); 409 String genericDecl = v.getDeclaration(); 410 String genericReturn = v.getReturnType(); 411 String genericExceptions = v.getExceptions(); 412 413 buf.append(tab) 414 .append("// declaration: ") 415 .append(genericReturn) 416 .append(' ') 417 .append(name) 418 .append(genericDecl); 419 if (genericExceptions != null) { 420 buf.append(" throws ").append(genericExceptions); 421 } 422 buf.append('\n'); 423 } 424 425 appendAccess(access); 426 if ((access & Opcodes.ACC_NATIVE) != 0) { 427 buf.append("native "); 428 } 429 if ((access & Opcodes.ACC_VARARGS) != 0) { 430 buf.append("varargs "); 431 } 432 if ((access & Opcodes.ACC_BRIDGE) != 0) { 433 buf.append("bridge "); 434 } 435 436 buf.append(name); 437 appendDescriptor(METHOD_DESCRIPTOR, desc); 438 if (exceptions != null && exceptions.length > 0) { 439 buf.append(" throws "); 440 for (int i = 0; i < exceptions.length; ++i) { 441 appendDescriptor(INTERNAL_NAME, exceptions[i]); 442 buf.append(' '); 443 } 444 } 445 446 buf.append('\n'); 447 text.add(buf.toString()); 448 449 TraceMethodVisitor tcv = createTraceMethodVisitor(); 450 text.add(tcv.getText()); 451 452 if (cv != null) { 453 tcv.mv = cv.visitMethod(access, name, desc, signature, exceptions); 454 } 455 456 return tcv; 457 } 458 459 public void visitEnd() { 460 text.add("}\n"); 461 462 printList(pw, text); 463 pw.flush(); 464 465 if (cv != null) { 466 cv.visitEnd(); 467 } 468 } 469 470 474 protected TraceFieldVisitor createTraceFieldVisitor() { 475 return new TraceFieldVisitor(); 476 } 477 478 protected TraceMethodVisitor createTraceMethodVisitor() { 479 return new TraceMethodVisitor(); 480 } 481 482 488 private void appendAccess(final int access) { 489 if ((access & Opcodes.ACC_PUBLIC) != 0) { 490 buf.append("public "); 491 } 492 if ((access & Opcodes.ACC_PRIVATE) != 0) { 493 buf.append("private "); 494 } 495 if ((access & Opcodes.ACC_PROTECTED) != 0) { 496 buf.append("protected "); 497 } 498 if ((access & Opcodes.ACC_FINAL) != 0) { 499 buf.append("final "); 500 } 501 if ((access & Opcodes.ACC_STATIC) != 0) { 502 buf.append("static "); 503 } 504 if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) { 505 buf.append("synchronized "); 506 } 507 if ((access & Opcodes.ACC_VOLATILE) != 0) { 508 buf.append("volatile "); 509 } 510 if ((access & Opcodes.ACC_TRANSIENT) != 0) { 511 buf.append("transient "); 512 } 513 if ((access & Opcodes.ACC_ABSTRACT) != 0) { 517 buf.append("abstract "); 518 } 519 if ((access & Opcodes.ACC_STRICT) != 0) { 520 buf.append("strictfp "); 521 } 522 } 523 } 524 | Popular Tags |