1 30 package com.tc.asm.util; 31 32 import com.tc.asm.Opcodes; 33 import com.tc.asm.signature.SignatureVisitor; 34 35 public class TraceSignatureVisitor implements SignatureVisitor { 36 37 private StringBuffer declaration; 38 39 private boolean isInterface; 40 41 private boolean seenFormalParameter; 42 43 private boolean seenInterfaceBound; 44 45 private boolean seenParameter; 46 47 private boolean seenInterface; 48 49 private StringBuffer returnType; 50 51 private StringBuffer exceptions; 52 53 59 private int argumentStack; 60 61 66 private int arrayStack; 67 68 private String separator = ""; 69 70 public TraceSignatureVisitor(int access) { 71 isInterface = (access & Opcodes.ACC_INTERFACE) != 0; 72 this.declaration = new StringBuffer (); 73 } 74 75 private TraceSignatureVisitor(StringBuffer buf) { 76 this.declaration = buf; 77 } 78 79 public void visitFormalTypeParameter(String name) { 80 declaration.append(seenFormalParameter ? ", " : "<").append(name); 81 seenFormalParameter = true; 82 seenInterfaceBound = false; 83 } 84 85 public SignatureVisitor visitClassBound() { 86 separator = " extends "; 87 startType(); 88 return this; 89 } 90 91 public SignatureVisitor visitInterfaceBound() { 92 separator = seenInterfaceBound ? ", " : " extends "; 93 seenInterfaceBound = true; 94 startType(); 95 return this; 96 } 97 98 public SignatureVisitor visitSuperclass() { 99 endFormals(); 100 separator = " extends "; 101 startType(); 102 return this; 103 } 104 105 public SignatureVisitor visitInterface() { 106 separator = seenInterface ? ", " : (isInterface 107 ? " extends " 108 : " implements "); 109 seenInterface = true; 110 startType(); 111 return this; 112 } 113 114 public SignatureVisitor visitParameterType() { 115 endFormals(); 116 if (!seenParameter) { 117 seenParameter = true; 118 declaration.append('('); 119 } else { 120 declaration.append(", "); 121 } 122 startType(); 123 return this; 124 } 125 126 public SignatureVisitor visitReturnType() { 127 endFormals(); 128 if (!seenParameter) { 129 declaration.append('('); 130 } else { 131 seenParameter = false; 132 } 133 declaration.append(')'); 134 returnType = new StringBuffer (); 135 return new TraceSignatureVisitor(returnType); 136 } 137 138 public SignatureVisitor visitExceptionType() { 139 if (exceptions == null) { 140 exceptions = new StringBuffer (); 141 } else { 142 exceptions.append(", "); 143 } 144 return new TraceSignatureVisitor(exceptions); 146 } 147 148 public void visitBaseType(char descriptor) { 149 switch (descriptor) { 150 case 'V': 151 declaration.append("void"); 152 break; 153 case 'B': 154 declaration.append("byte"); 155 break; 156 case 'J': 157 declaration.append("long"); 158 break; 159 case 'Z': 160 declaration.append("boolean"); 161 break; 162 case 'I': 163 declaration.append("int"); 164 break; 165 case 'S': 166 declaration.append("short"); 167 break; 168 case 'C': 169 declaration.append("char"); 170 break; 171 case 'F': 172 declaration.append("float"); 173 break; 174 case 'D': 175 declaration.append("double"); 176 break; 177 default: 178 throw new IllegalArgumentException ("Invalid descriptor " 179 + descriptor); 180 } 181 endType(); 182 } 183 184 public void visitTypeVariable(String name) { 185 declaration.append(name); 186 endType(); 187 } 188 189 public SignatureVisitor visitArrayType() { 190 startType(); 191 arrayStack |= 1; 192 return this; 193 } 194 195 public void visitClassType(String name) { 196 if (!"java/lang/Object".equals(name)) { 197 declaration.append(separator).append(name.replace('/', '.')); 198 } else { 199 boolean needObjectClass = argumentStack % 2 == 1 || seenParameter; 205 if (needObjectClass) { 206 declaration.append(separator).append(name.replace('/', '.')); 207 } 208 } 209 separator = ""; 210 argumentStack *= 2; 211 } 212 213 public void visitInnerClassType(String name) { 214 declaration.append(separator).append(name.replace('/', '.')); 216 separator = ""; 217 argumentStack *= 2; 218 } 219 220 public void visitTypeArgument() { 221 if (argumentStack % 2 == 0) { 222 ++argumentStack; 223 declaration.append("<"); 224 } else { 225 declaration.append(", "); 226 } 227 declaration.append("?"); 228 } 229 230 public SignatureVisitor visitTypeArgument(char tag) { 231 if (argumentStack % 2 == 0) { 232 ++argumentStack; 233 declaration.append("<"); 234 } else { 235 declaration.append(", "); 236 } 237 238 if (tag == SignatureVisitor.EXTENDS) { 239 declaration.append("? extends "); 240 } else if (tag == SignatureVisitor.SUPER) { 241 declaration.append("? super "); 242 } 243 244 startType(); 245 return this; 246 } 247 248 public void visitEnd() { 249 if (argumentStack % 2 == 1) { 250 declaration.append(">"); 251 } 252 argumentStack /= 2; 253 endType(); 254 } 255 256 public String getDeclaration() { 257 return declaration.toString(); 258 } 259 260 public String getReturnType() { 261 return returnType == null ? null : returnType.toString(); 262 } 263 264 public String getExceptions() { 265 return exceptions == null ? null : exceptions.toString(); 266 } 267 268 270 private void endFormals() { 271 if (seenFormalParameter) { 272 declaration.append(">"); 273 seenFormalParameter = false; 274 } 275 } 276 277 private void startType() { 278 arrayStack *= 2; 279 } 280 281 private void endType() { 282 if (arrayStack % 2 == 1) { 283 while (arrayStack % 2 == 1) { 284 arrayStack /= 2; 285 declaration.append("[]"); 286 } 287 } else { 288 arrayStack /= 2; 289 } 290 } 291 } 292 | Popular Tags |