1 30 31 package oracle.toplink.libraries.asm.util; 32 33 import java.io.FileInputStream ; 34 import java.io.PrintWriter ; 35 36 import oracle.toplink.libraries.asm.Attribute; 37 import oracle.toplink.libraries.asm.ClassReader; 38 import oracle.toplink.libraries.asm.ClassVisitor; 39 import oracle.toplink.libraries.asm.CodeVisitor; 40 import oracle.toplink.libraries.asm.Constants; 41 42 89 90 public class TraceClassVisitor extends PrintClassVisitor { 91 92 96 97 protected final ClassVisitor cv; 98 99 110 111 public static void main (final String [] args) throws Exception { 112 if (args.length < 1 || args.length > 2) { 113 printUsage(); 114 } 115 int i = 0; 116 boolean skipDebug = true; 117 if (args[0].equals("-debug")) { 118 i = 1; 119 skipDebug = false; 120 if (args.length != 2) { 121 printUsage(); 122 } 123 } 124 ClassReader cr; 125 if (args[i].endsWith(".class")) { 126 cr = new ClassReader(new FileInputStream (args[i])); 127 } else { 128 cr = new ClassReader(args[i]); 129 } 130 cr.accept(new TraceClassVisitor( 131 null, new PrintWriter (System.out)), getDefaultAttributes(), skipDebug); 132 } 133 134 private static void printUsage () { 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 141 148 149 public TraceClassVisitor (final ClassVisitor cv, final PrintWriter pw) { 150 super(pw); 151 this.cv = cv; 152 } 153 154 public void visit ( 155 final int version, 156 final int access, 157 final String name, 158 final String superName, 159 final String [] interfaces, 160 final String sourceFile) 161 { 162 int major = version & 0xFFFF; 163 int minor = version >>> 16; 164 buf.setLength(0); 165 buf.append("// class version " + major + "." + minor + " (" + version + ")\n"); 166 if ((access & Constants.ACC_DEPRECATED) != 0) { 167 buf.append("// DEPRECATED\n"); 168 } 169 if (sourceFile != null) { 170 buf.append("// compiled from ").append(sourceFile).append("\n"); 171 } 172 buf.append("// access flags ").append(access).append("\n"); 173 appendAccess(access & ~Constants.ACC_SUPER); 174 if ((access & Constants.ACC_ANNOTATION) != 0) { 175 buf.append("@interface "); 176 } else if ((access & Constants.ACC_INTERFACE) != 0) { 177 buf.append("interface "); 178 } else if ((access & Constants.ACC_ENUM) != 0) { 179 buf.append("enum "); 180 } else { 181 buf.append("class "); 182 } 183 buf.append(name).append(" "); 184 if (superName != null && !superName.equals("java/lang/Object")) { 185 buf.append("extends ").append(superName).append(" "); 186 } 187 if (interfaces != null && interfaces.length > 0) { 188 buf.append("implements "); 189 for (int i = 0; i < interfaces.length; ++i) { 190 buf.append(interfaces[i]).append(" "); 191 } 192 } 193 buf.append("{\n\n"); 194 text.add(buf.toString()); 195 196 if (cv != null) { 197 cv.visit(version, access, name, superName, interfaces, sourceFile); 198 } 199 } 200 201 public void visitInnerClass ( 202 final String name, 203 final String outerName, 204 final String innerName, 205 final int access) 206 { 207 buf.setLength(0); 208 buf.append(" INNERCLASS ") 209 .append(name) 210 .append(" ") 211 .append(outerName) 212 .append(" ") 213 .append(innerName) 214 .append(" "); 215 appendAccess(access & ~Constants.ACC_SUPER); 216 if ((access & Constants.ACC_ENUM) != 0) { 217 buf.append("enum "); 218 } 219 buf.append("\n"); 220 text.add(buf.toString()); 221 222 if (cv != null) { 223 cv.visitInnerClass(name, outerName, innerName, access); 224 } 225 } 226 227 public void visitField ( 228 final int access, 229 final String name, 230 final String desc, 231 final Object value, 232 final Attribute attrs) 233 { 234 buf.setLength(0); 235 if ((access & Constants.ACC_DEPRECATED) != 0) { 236 buf.append(" // DEPRECATED\n"); 237 } 238 buf.append(" // access flags ").append(access).append("\n"); 239 buf.append(" "); 240 appendAccess(access); 241 if ((access & Constants.ACC_ENUM) != 0) { 242 buf.append("enum "); 243 } 244 buf.append(desc) 245 .append(" ") 246 .append(name); 247 if (value != null) { 248 buf.append(" = "); 249 if (value instanceof String ) { 250 buf.append("\"").append(value).append("\""); 251 } else { 252 buf.append(value); 253 } 254 } 255 Attribute attr = attrs; 256 while (attr != null) { 257 buf.append(" FIELD ATTRIBUTE ").append(attr.type).append(" : ") 258 .append(attr.toString()).append("\n"); 259 attr = attr.next; 260 } 261 buf.append("\n"); 262 text.add(buf.toString()); 263 264 if (cv != null) { 265 cv.visitField(access, name, desc, value, attrs); 266 } 267 } 268 269 public CodeVisitor visitMethod ( 270 final int access, 271 final String name, 272 final String desc, 273 final String [] exceptions, 274 final Attribute attrs) 275 { 276 buf.setLength(0); 277 if ((access & Constants.ACC_DEPRECATED) != 0) { 278 buf.append(" // DEPRECATED\n"); 279 } 280 buf.append(" // access flags ").append(access).append("\n"); 281 buf.append(" "); 282 appendAccess(access); 283 if ((access & Constants.ACC_NATIVE) != 0) { 284 buf.append("native "); 285 } 286 if ((access & Constants.ACC_VARARGS) != 0) { 287 buf.append("varargs "); 288 } 289 if ((access & Constants.ACC_BRIDGE) != 0) { 290 buf.append("bridge "); 291 } 292 buf.append(name). 293 append(" "). 294 append(desc); 295 if (exceptions != null && exceptions.length > 0) { 296 buf.append(" throws "); 297 for (int i = 0; i < exceptions.length; ++i) { 298 buf.append(exceptions[i]).append(" "); 299 } 300 } 301 buf.append("\n"); 302 text.add(buf.toString()); 303 Attribute attr = attrs; 304 while (attr != null) { 305 buf.setLength(0); 306 buf.append(" METHOD ATTRIBUTE ").append(attr.type).append(" : ") 307 .append(attr.toString()).append("\n"); 308 text.add(buf.toString()); 309 attr = attr.next; 310 } 311 312 CodeVisitor cv; 313 if (this.cv != null) { 314 cv = this.cv.visitMethod(access, name, desc, exceptions, attrs); 315 } else { 316 cv = null; 317 } 318 PrintCodeVisitor pcv = new TraceCodeVisitor(cv); 319 text.add(pcv.getText()); 320 return pcv; 321 } 322 323 public void visitAttribute (final Attribute attr) { 324 buf.setLength(0); 325 buf.append(" CLASS ATTRIBUTE ").append(attr.type).append(" : ") 326 .append(attr.toString()).append("\n"); 327 text.add(buf.toString()); 328 329 if (cv != null) { 330 cv.visitAttribute(attr); 331 } 332 } 333 334 public void visitEnd () { 335 text.add("}\n"); 336 337 if (cv != null) { 338 cv.visitEnd(); 339 } 340 341 super.visitEnd(); 342 } 343 344 350 351 private void appendAccess (final int access) { 352 if ((access & Constants.ACC_PUBLIC) != 0) { 353 buf.append("public "); 354 } 355 if ((access & Constants.ACC_PRIVATE) != 0) { 356 buf.append("private "); 357 } 358 if ((access & Constants.ACC_PROTECTED) != 0) { 359 buf.append("protected "); 360 } 361 if ((access & Constants.ACC_FINAL) != 0) { 362 buf.append("final "); 363 } 364 if ((access & Constants.ACC_STATIC) != 0) { 365 buf.append("static "); 366 } 367 if ((access & Constants.ACC_SYNCHRONIZED) != 0) { 368 buf.append("synchronized "); 369 } 370 if ((access & Constants.ACC_VOLATILE) != 0) { 371 buf.append("volatile "); 372 } 373 if ((access & Constants.ACC_TRANSIENT) != 0) { 374 buf.append("transient "); 375 } 376 if ((access & Constants.ACC_ABSTRACT) != 0) { 380 buf.append("abstract "); 381 } 382 if ((access & Constants.ACC_STRICT) != 0) { 383 buf.append("strictfp "); 384 } 385 } 386 } 387 | Popular Tags |