1 34 35 package org.logicalcobwebs.asm.util; 36 37 import org.logicalcobwebs.asm.ClassVisitor; 38 import org.logicalcobwebs.asm.CodeVisitor; 39 import org.logicalcobwebs.asm.Constants; 40 import org.logicalcobwebs.asm.ClassReader; 41 import org.logicalcobwebs.asm.Attribute; 42 43 import java.io.PrintWriter ; 44 45 90 91 public class TraceClassVisitor extends PrintClassVisitor { 92 93 97 98 protected final ClassVisitor cv; 99 100 110 111 public static void main (final String [] args) throws Exception { 112 if (args.length == 0) { 113 System.err.println("Prints a disassembled view of the given class."); 114 System.err.println("Usage: TraceClassVisitor <fully qualified class name>"); 115 System.exit(-1); 116 } 117 ClassReader cr = new ClassReader(args[0]); 118 cr.accept(new TraceClassVisitor(null, new PrintWriter (System.out)), true); 119 } 120 121 128 129 public TraceClassVisitor (final ClassVisitor cv, final PrintWriter pw) { 130 super(pw); 131 this.cv = cv; 132 } 133 134 public void visit ( 135 final int access, 136 final String name, 137 final String superName, 138 final String [] interfaces, 139 final String sourceFile) 140 { 141 buf.setLength(0); 142 if ((access & Constants.ACC_DEPRECATED) != 0) { 143 buf.append("// DEPRECATED\n"); 144 } 145 if (sourceFile != null) { 146 buf.append("// compiled from ").append(sourceFile).append("\n"); 147 } 148 appendAccess(access & ~Constants.ACC_SUPER); 149 if ((access & Constants.ACC_INTERFACE) != 0) { 150 buf.append("interface "); 151 } else { 152 buf.append("class "); 153 } 154 buf.append(name).append(" "); 155 if (superName != null && !superName.equals("java/lang/Object")) { 156 buf.append("extends ").append(superName).append(" "); 157 } 158 if (interfaces != null && interfaces.length > 0) { 159 buf.append("implements "); 160 for (int i = 0; i < interfaces.length; ++i) { 161 buf.append(interfaces[i]).append(" "); 162 } 163 } 164 buf.append("{\n\n"); 165 text.add(buf.toString()); 166 167 if (cv != null) { 168 cv.visit(access, name, superName, interfaces, sourceFile); 169 } 170 } 171 172 public void visitInnerClass ( 173 final String name, 174 final String outerName, 175 final String innerName, 176 final int access) 177 { 178 buf.setLength(0); 179 buf.append(" INNERCLASS ") 180 .append(name) 181 .append(" ") 182 .append(outerName) 183 .append(" ") 184 .append(innerName) 185 .append(" ") 186 .append(access) 187 .append("\n"); 188 text.add(buf.toString()); 189 190 if (cv != null) { 191 cv.visitInnerClass(name, outerName, innerName, access); 192 } 193 } 194 195 public void visitField ( 196 final int access, 197 final String name, 198 final String desc, 199 final Object value, 200 final Attribute attrs) 201 { 202 buf.setLength(0); 203 if ((access & Constants.ACC_DEPRECATED) != 0) { 204 buf.append(" // DEPRECATED\n"); 205 } 206 buf.append(" "); 207 appendAccess(access); 208 buf.append(desc) 209 .append(" ") 210 .append(name); 211 if (value != null) { 212 buf.append(" = "); 213 if (value instanceof String ) { 214 buf.append("\"").append(value).append("\""); 215 } else { 216 buf.append(value); 217 } 218 } 219 Attribute attr = attrs; 220 while (attr != null) { 221 buf.append(" , FIELD ATTRIBUTE ").append(attr.type); 222 attr = attr.next; 223 } 224 buf.append("\n\n"); 225 text.add(buf.toString()); 226 227 if (cv != null) { 228 cv.visitField(access, name, desc, value, attrs); 229 } 230 } 231 232 public CodeVisitor visitMethod ( 233 final int access, 234 final String name, 235 final String desc, 236 final String [] exceptions, 237 final Attribute attrs) 238 { 239 buf.setLength(0); 240 if ((access & Constants.ACC_DEPRECATED) != 0) { 241 buf.append(" // DEPRECATED\n"); 242 } 243 buf.append(" "); 244 appendAccess(access); 245 buf.append(name). 246 append(" "). 247 append(desc); 248 if (exceptions != null && exceptions.length > 0) { 249 buf.append(" throws "); 250 for (int i = 0; i < exceptions.length; ++i) { 251 buf.append(exceptions[i]).append(" "); 252 } 253 } 254 buf.append("\n"); 255 text.add(buf.toString()); 256 Attribute attr = attrs; 257 while (attr != null) { 258 buf.setLength(0); 259 buf.append(" METHOD ATTRIBUTE ") 260 .append(attr.type) 261 .append("\n"); 262 text.add(buf.toString()); 263 attr = attr.next; 264 } 265 266 CodeVisitor cv; 267 if (this.cv != null) { 268 cv = this.cv.visitMethod(access, name, desc, exceptions, attrs); 269 } else { 270 cv = null; 271 } 272 PrintCodeVisitor pcv = new TraceCodeVisitor(cv); 273 text.add(pcv.getText()); 274 return pcv; 275 } 276 277 public void visitAttribute (final Attribute attr) { 278 buf.setLength(0); 279 buf.append(" CLASS ATTRIBUTE ") 280 .append(attr.type) 281 .append("\n"); 282 text.add(buf.toString()); 283 284 if (cv != null) { 285 cv.visitAttribute(attr); 286 } 287 } 288 289 public void visitEnd () { 290 text.add("}\n"); 291 292 if (cv != null) { 293 cv.visitEnd(); 294 } 295 296 super.visitEnd(); 297 } 298 299 305 306 private void appendAccess (final int access) { 307 if ((access & Constants.ACC_PUBLIC) != 0) { 308 buf.append("public "); 309 } 310 if ((access & Constants.ACC_PRIVATE) != 0) { 311 buf.append("private "); 312 } 313 if ((access & Constants.ACC_PROTECTED) != 0) { 314 buf.append("protected "); 315 } 316 if ((access & Constants.ACC_FINAL) != 0) { 317 buf.append("final "); 318 } 319 if ((access & Constants.ACC_STATIC) != 0) { 320 buf.append("static "); 321 } 322 if ((access & Constants.ACC_SYNCHRONIZED) != 0) { 323 buf.append("synchronized "); 324 } 325 if ((access & Constants.ACC_VOLATILE) != 0) { 326 buf.append("volatile "); 327 } 328 if ((access & Constants.ACC_TRANSIENT) != 0) { 329 buf.append("transient "); 330 } 331 if ((access & Constants.ACC_NATIVE) != 0) { 332 buf.append("native "); 333 } 334 if ((access & Constants.ACC_ABSTRACT) != 0) { 335 buf.append("abstract "); 336 } 337 if ((access & Constants.ACC_STRICT) != 0) { 338 buf.append("strictfp "); 339 } 340 } 341 } 342 | Popular Tags |