1 package de.loskutov.bco.asm; 2 3 import java.util.BitSet ; 4 5 import org.objectweb.asm.AnnotationVisitor; 6 import org.objectweb.asm.FieldVisitor; 7 import org.objectweb.asm.Label; 8 import org.objectweb.asm.Type; 9 import org.objectweb.asm.util.TraceAnnotationVisitor; 10 import org.objectweb.asm.util.TraceClassVisitor; 11 import org.objectweb.asm.util.TraceFieldVisitor; 12 import org.objectweb.asm.util.TraceMethodVisitor; 13 14 import de.loskutov.bco.preferences.BCOConstants; 15 16 19 20 public class CommentedClassVisitor extends TraceClassVisitor { 21 22 protected boolean raw; 23 protected BitSet modes; 24 protected boolean showLines; 25 protected boolean showLocals; 26 protected boolean showStackMap; 27 28 public CommentedClassVisitor(final BitSet modes) { 29 super(null); 30 this.modes = modes; 31 raw = !modes.get(BCOConstants.F_SHOW_RAW_BYTECODE); 32 showLines = modes.get(BCOConstants.F_SHOW_LINE_INFO); 33 showLocals = modes.get(BCOConstants.F_SHOW_VARIABLES); 34 showStackMap = modes.get(BCOConstants.F_SHOW_STACKMAP); 35 } 36 37 public void visitEnd() { 38 text.add("}\n"); 39 } 40 41 protected TraceAnnotationVisitor createTraceAnnotationVisitor() { 42 return new CommentedAnnotationVisitor(); 43 } 44 45 protected TraceFieldVisitor createTraceFieldVisitor() { 46 return new CommentedFieldVisitor(); 47 } 48 49 protected TraceMethodVisitor createTraceMethodVisitor() { 50 return new CommentedMethodVisitor(); 51 } 52 53 protected void appendDescriptor(final int type, final String desc) { 54 appendDescriptor(buf, type, desc, raw); 55 } 56 57 protected void appendDescriptor(final StringBuffer buf1, final int type, 58 final String desc, final boolean raw1) { 59 if (desc == null) { 60 return; 61 } 62 if (raw1) { 63 if(type == CLASS_SIGNATURE || type == FIELD_SIGNATURE || type == METHOD_SIGNATURE) { 64 buf1.append( "// signature ").append( desc ).append('\n'); 65 } else { 66 buf1.append(desc); 67 } 68 } else { 69 switch (type) { 70 case INTERNAL_NAME : 71 buf1.append(eatPackageNames(desc, '/')); 72 break; 73 case FIELD_DESCRIPTOR : 74 if ("T".equals(desc)) { 75 buf1.append("top"); 76 } else if ("N".equals(desc)) { 77 buf1.append("null"); 78 } else if ("U".equals(desc)) { 79 buf1.append("uninitialized_this"); 80 } else { 81 buf1.append(getSimpleName(Type.getType(desc))); 82 } 83 break; 84 case METHOD_DESCRIPTOR : 85 Type[] args = Type.getArgumentTypes(desc); 86 Type res = Type.getReturnType(desc); 87 buf1.append('('); 88 for (int i = 0; i < args.length; ++i) { 89 if (i > 0) { 90 buf1.append(','); 91 } 92 buf1.append(getSimpleName(args[i])); 93 } 94 buf1.append(") : "); 95 buf1.append(getSimpleName(res)); 96 break; 97 98 case METHOD_SIGNATURE : 99 case FIELD_SIGNATURE : 100 if(buf.lastIndexOf(tab) == buf.length() - tab.length()){ 102 buf.delete(buf.lastIndexOf(tab), buf.length()); 103 } 104 break; 105 106 case CLASS_SIGNATURE : 107 break; 109 case TYPE_DECLARATION : 110 buf1.append(eatPackageNames(desc, '.')); 111 break; 112 case CLASS_DECLARATION : 113 buf1.append(eatPackageNames(desc, '.')); 114 break; 115 case PARAMETERS_DECLARATION : 116 buf1.append(eatPackageNames(desc, '.')); 117 break; 118 default : 119 buf1.append(desc); 120 } 121 } 122 } 123 124 129 public static String getSimpleName(Type t) { 130 String name = t.getClassName(); 131 return eatPackageNames(name, '.'); 132 } 133 134 140 private static String eatPackageNames(String name, char separator){ 141 int lastPoint = name.lastIndexOf(separator); 142 if(lastPoint < 0){ 143 return name; 144 } 145 StringBuffer sb = new StringBuffer (name); 146 do { 147 int start = getPackageStartIndex(sb, separator, lastPoint); 148 sb.delete(start, lastPoint + 1); 149 lastPoint = lastIndexOf(sb, separator, start); 150 } while (lastPoint > 0); 151 152 return sb.toString(); 153 } 154 private static int lastIndexOf(StringBuffer chars, char c, int lastPoint){ 155 for (int i = lastPoint - 1; i > 0; i--) { 156 if(chars.charAt(i) == c){ 157 return i; 158 } 159 } 160 return -1; 161 } 162 163 private static int getPackageStartIndex(StringBuffer chars, char c, int firstPoint){ 164 for (int i = firstPoint - 1; i >= 0; i--) { 165 char curr = chars.charAt(i); 166 if(curr != c && !Character.isJavaIdentifierPart(curr)){ 167 return i + 1; 168 } 169 } 170 return 0; 171 } 172 173 class CommentedAnnotationVisitor extends TraceAnnotationVisitor { 174 175 public void setAnnotationVisitor(AnnotationVisitor av){ 176 this.av = av; 177 } 178 179 protected TraceAnnotationVisitor createTraceAnnotationVisitor() { 180 return new CommentedAnnotationVisitor(); 181 } 182 183 protected void appendDescriptor(final int type, final String desc) { 184 CommentedClassVisitor.this.appendDescriptor(buf, type, desc, raw); 185 } 186 } 187 188 class CommentedFieldVisitor extends TraceFieldVisitor { 189 public void setFieldVisitor(FieldVisitor fv){ 190 this.fv = fv; 191 } 192 193 protected void appendDescriptor(final int type, final String desc) { 194 CommentedClassVisitor.this.appendDescriptor(buf, type, desc, raw); 195 } 196 197 protected TraceAnnotationVisitor createTraceAnnotationVisitor() { 198 return new CommentedAnnotationVisitor(); 199 } 200 } 201 202 class CommentedMethodVisitor extends TraceMethodVisitor { 203 204 private Index getIndex(Label label){ 205 Index index; 206 for (int i = 0; i < text.size(); i++) { 207 Object o = text.get(i); 208 if(o instanceof Index){ 209 index = (Index)o; 210 if(index.labelNode != null && index.labelNode.getLabel() == label){ 211 return index; 212 } 213 } 214 } 215 return null; 216 } 217 218 public void visitFrame(int type, int nLocal, Object [] local, int nStack, Object [] stack) { 219 if(showStackMap) { 220 super.visitFrame(type, nLocal, local, nStack, stack); 221 } 222 } 223 224 public void visitMethodInsn ( 225 final int opcode, 226 final String owner, 227 final String name, 228 final String desc) 229 { 230 buf.setLength(0); 231 buf.append(tab2).append(OPCODES[opcode]).append(' '); 232 appendDescriptor(INTERNAL_NAME, owner); 233 buf.append('.').append(name); 234 appendDescriptor(METHOD_DESCRIPTOR, desc); 235 buf.append('\n'); 236 text.add(buf.toString()); 237 } 238 239 public void visitVarInsn(final int opcode, final int var) { 240 text.add(tab2 + OPCODES[opcode] + " " + var); 241 if (!raw) { 242 text.add(new Integer (var)); 243 } 244 text.add("\n"); 245 } 246 247 public void visitLabel(Label label) { 248 buf.setLength(0); 249 buf.append(ltab); 250 appendLabel(label); 251 Index index = getIndex(label); 252 if(index != null){ 253 buf.append(" (").append(index.insn).append(")"); 254 } 255 buf.append('\n'); 256 text.add(buf.toString()); 257 } 258 259 public void visitIincInsn(final int var, final int increment) { 260 text.add(tab2 + "IINC " + var); 261 if (!raw) { 262 text.add(new Integer (var)); 263 } 264 text.add(" " + increment + "\n"); 265 } 266 267 public void visitLocalVariable(final String name, final String desc, 268 final String signature, final Label start, final Label end, 269 final int index) { 270 if (showLocals) { 271 super.visitLocalVariable( 272 name, desc, signature, start, end, index); 273 } 274 } 275 276 public void visitLineNumber(final int line, final Label start) { 277 if (showLines) { 278 super.visitLineNumber(line, start); 279 } 280 } 281 282 public void visitMaxs(final int maxStack, final int maxLocals) { 283 if (showLocals) { 284 super.visitMaxs(maxStack, maxLocals); 285 } 286 } 287 288 protected TraceAnnotationVisitor createTraceAnnotationVisitor() { 289 return new CommentedAnnotationVisitor(); 290 } 291 292 protected void appendDescriptor(final int type, final String desc) { 293 CommentedClassVisitor.this.appendDescriptor(buf, type, desc, raw); 294 } 295 } 296 297 298 } 299 | Popular Tags |