1 30 package com.tc.asm.util; 31 32 import java.io.FileInputStream ; 33 import java.io.PrintWriter ; 34 35 import com.tc.asm.AnnotationVisitor; 36 import com.tc.asm.Attribute; 37 import com.tc.asm.ClassReader; 38 import com.tc.asm.ClassVisitor; 39 import com.tc.asm.MethodVisitor; 40 import com.tc.asm.Opcodes; 41 import com.tc.asm.FieldVisitor; 42 import com.tc.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 return; 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 if (name != null) { 278 buf.append(' ').append(name).append(' '); 279 } else { 280 buf.append(' '); 281 } 282 appendDescriptor(METHOD_DESCRIPTOR, desc); 283 buf.append('\n'); 284 text.add(buf.toString()); 285 286 if (cv != null) { 287 cv.visitOuterClass(owner, name, desc); 288 } 289 } 290 291 public AnnotationVisitor visitAnnotation( 292 final String desc, 293 final boolean visible) 294 { 295 text.add("\n"); 296 AnnotationVisitor tav = super.visitAnnotation(desc, visible); 297 if (cv != null) { 298 ((TraceAnnotationVisitor) tav).av = cv.visitAnnotation(desc, 299 visible); 300 } 301 return tav; 302 } 303 304 public void visitAttribute(final Attribute attr) { 305 text.add("\n"); 306 super.visitAttribute(attr); 307 308 if (cv != null) { 309 cv.visitAttribute(attr); 310 } 311 } 312 313 public void visitInnerClass( 314 final String name, 315 final String outerName, 316 final String innerName, 317 final int access) 318 { 319 buf.setLength(0); 320 buf.append(tab).append("// access flags ").append(access 321 & ~Opcodes.ACC_SUPER).append('\n'); 322 buf.append(tab); 323 appendAccess(access); 324 buf.append("INNERCLASS "); 325 if ((access & Opcodes.ACC_ENUM) != 0) { 326 buf.append("enum "); 327 } 328 appendDescriptor(INTERNAL_NAME, name); 329 buf.append(' '); 330 appendDescriptor(INTERNAL_NAME, outerName); 331 buf.append(' '); 332 appendDescriptor(INTERNAL_NAME, innerName); 333 buf.append('\n'); 334 text.add(buf.toString()); 335 336 if (cv != null) { 337 cv.visitInnerClass(name, outerName, innerName, access); 338 } 339 } 340 341 public FieldVisitor visitField( 342 final int access, 343 final String name, 344 final String desc, 345 final String signature, 346 final Object value) 347 { 348 buf.setLength(0); 349 buf.append('\n'); 350 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 351 buf.append(tab).append("// DEPRECATED\n"); 352 } 353 buf.append(tab).append("// access flags ").append(access).append('\n'); 354 if (signature != null) { 355 buf.append(tab); 356 appendDescriptor(FIELD_SIGNATURE, signature); 357 358 TraceSignatureVisitor sv = new TraceSignatureVisitor(0); 359 SignatureReader r = new SignatureReader(signature); 360 r.acceptType(sv); 361 buf.append(tab) 362 .append("// declaration: ") 363 .append(sv.getDeclaration()) 364 .append('\n'); 365 } 366 367 buf.append(tab); 368 appendAccess(access); 369 if ((access & Opcodes.ACC_ENUM) != 0) { 370 buf.append("enum "); 371 } 372 373 appendDescriptor(FIELD_DESCRIPTOR, desc); 374 buf.append(' ').append(name); 375 if (value != null) { 376 buf.append(" = "); 377 if (value instanceof String ) { 378 buf.append("\"").append(value).append("\""); 379 } else { 380 buf.append(value); 381 } 382 } 383 384 buf.append('\n'); 385 text.add(buf.toString()); 386 387 TraceFieldVisitor tav = createTraceFieldVisitor(); 388 text.add(tav.getText()); 389 390 if (cv != null) { 391 tav.fv = cv.visitField(access, name, desc, signature, value); 392 } 393 394 return tav; 395 } 396 397 public MethodVisitor visitMethod( 398 final int access, 399 final String name, 400 final String desc, 401 final String signature, 402 final String [] exceptions) 403 { 404 buf.setLength(0); 405 buf.append('\n'); 406 if ((access & Opcodes.ACC_DEPRECATED) != 0) { 407 buf.append(tab).append("// DEPRECATED\n"); 408 } 409 buf.append(tab).append("// access flags ").append(access).append('\n'); 410 buf.append(tab); 411 appendDescriptor(METHOD_SIGNATURE, signature); 412 413 if (signature != null) { 414 TraceSignatureVisitor v = new TraceSignatureVisitor(0); 415 SignatureReader r = new SignatureReader(signature); 416 r.accept(v); 417 String genericDecl = v.getDeclaration(); 418 String genericReturn = v.getReturnType(); 419 String genericExceptions = v.getExceptions(); 420 421 buf.append(tab) 422 .append("// declaration: ") 423 .append(genericReturn) 424 .append(' ') 425 .append(name) 426 .append(genericDecl); 427 if (genericExceptions != null) { 428 buf.append(" throws ").append(genericExceptions); 429 } 430 buf.append('\n'); 431 } 432 433 appendAccess(access); 434 if ((access & Opcodes.ACC_NATIVE) != 0) { 435 buf.append("native "); 436 } 437 if ((access & Opcodes.ACC_VARARGS) != 0) { 438 buf.append("varargs "); 439 } 440 if ((access & Opcodes.ACC_BRIDGE) != 0) { 441 buf.append("bridge "); 442 } 443 444 buf.append(name); 445 appendDescriptor(METHOD_DESCRIPTOR, desc); 446 if (exceptions != null && exceptions.length > 0) { 447 buf.append(" throws "); 448 for (int i = 0; i < exceptions.length; ++i) { 449 appendDescriptor(INTERNAL_NAME, exceptions[i]); 450 buf.append(' '); 451 } 452 } 453 454 buf.append('\n'); 455 text.add(buf.toString()); 456 457 TraceMethodVisitor tcv = createTraceMethodVisitor(); 458 text.add(tcv.getText()); 459 460 if (cv != null) { 461 tcv.mv = cv.visitMethod(access, name, desc, signature, exceptions); 462 } 463 464 return tcv; 465 } 466 467 public void visitEnd() { 468 text.add("}\n"); 469 470 printList(pw, text); 471 pw.flush(); 472 473 if (cv != null) { 474 cv.visitEnd(); 475 } 476 } 477 478 482 protected TraceFieldVisitor createTraceFieldVisitor() { 483 return new TraceFieldVisitor(); 484 } 485 486 protected TraceMethodVisitor createTraceMethodVisitor() { 487 return new TraceMethodVisitor(); 488 } 489 490 496 private void appendAccess(final int access) { 497 if ((access & Opcodes.ACC_PUBLIC) != 0) { 498 buf.append("public "); 499 } 500 if ((access & Opcodes.ACC_PRIVATE) != 0) { 501 buf.append("private "); 502 } 503 if ((access & Opcodes.ACC_PROTECTED) != 0) { 504 buf.append("protected "); 505 } 506 if ((access & Opcodes.ACC_FINAL) != 0) { 507 buf.append("final "); 508 } 509 if ((access & Opcodes.ACC_STATIC) != 0) { 510 buf.append("static "); 511 } 512 if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) { 513 buf.append("synchronized "); 514 } 515 if ((access & Opcodes.ACC_VOLATILE) != 0) { 516 buf.append("volatile "); 517 } 518 if ((access & Opcodes.ACC_TRANSIENT) != 0) { 519 buf.append("transient "); 520 } 521 if ((access & Opcodes.ACC_ABSTRACT) != 0) { 525 buf.append("abstract "); 526 } 527 if ((access & Opcodes.ACC_STRICT) != 0) { 528 buf.append("strictfp "); 529 } 530 if ((access & Opcodes.ACC_SYNTHETIC) != 0) { 531 buf.append("synthetic "); 532 } 533 } 534 } 535 | Popular Tags |