1 4 package net.sourceforge.pmd.typeresolution.visitors; 5 6 import org.objectweb.asm.AnnotationVisitor; 7 import org.objectweb.asm.Attribute; 8 import org.objectweb.asm.ClassVisitor; 9 import org.objectweb.asm.FieldVisitor; 10 import org.objectweb.asm.Label; 11 import org.objectweb.asm.MethodVisitor; 12 import org.objectweb.asm.Type; 13 import org.objectweb.asm.signature.SignatureReader; 14 import org.objectweb.asm.signature.SignatureVisitor; 15 16 import java.util.ArrayList ; 17 import java.util.HashMap ; 18 import java.util.List ; 19 import java.util.Map ; 20 21 public class PMDASMVisitor implements ClassVisitor { 22 23 private Map packages = new HashMap (); 24 25 private AnnotationVisitor annotationVisitor = new PMDAnnotationVisitor(this); 26 27 private FieldVisitor fieldVisitor = new PMDFieldVisitor(this); 28 29 private SignatureVisitor sigVisitor = new PMDSignatureVisitor(this); 30 31 private MethodVisitor methodVisitor = new PMDMethodVisitor(this); 32 33 public List innerClasses; 34 35 public Map getPackages() { 36 return packages; 37 } 38 39 public List getInnerClasses() { 40 return innerClasses; 41 } 42 43 private String parseClassName(String name) { 44 if (name == null) { 45 return null; 46 } 47 48 String className = name; 49 int n = name.lastIndexOf('/'); 50 if (n > -1) { 51 className = name.substring(n + 1); 52 } 53 name = name.replace('/', '.'); 54 packages.put(className, name); 55 n = className.indexOf('$'); 56 if (n > -1) { 57 packages.put(className.substring(n + 1), name); 59 packages.put(className.replace('$', '.'), name); 60 } 61 62 return name; 63 } 64 65 private void parseClassName(String [] names) { 66 if (names != null) { 67 for (int i = 0; i < names.length; i++) { 68 parseClassName(names[i]); 69 } 70 } 71 } 72 73 private void extractSignature(String sig) { 74 if (sig != null) { 75 new SignatureReader(sig).accept(sigVisitor); 76 } 77 } 78 79 80 81 public void visit(int version, int access, String name, String sig, String superName, String [] interfaces) { 82 parseClassName(name); 83 parseClassName(interfaces); 84 if (sig != null) { 85 extractSignature(sig); 86 } 87 } 88 89 public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 90 addType(Type.getType(desc)); 91 return annotationVisitor; 92 } 93 94 public FieldVisitor visitField(int access, String name, String desc, String sig, Object value) { 95 if (sig != null) { 96 extractSignature(sig); 97 } 98 99 addType(Type.getType(desc)); 100 if (value instanceof Type) { 101 addType((Type) value); 102 } 103 return fieldVisitor; 104 } 105 106 public MethodVisitor visitMethod(int access, String name, String desc, String sig, String [] exceptions) { 107 if (sig != null) { 108 extractSignature(sig); 109 } 110 addMethodDesc(desc); 111 parseClassName(exceptions); 112 return methodVisitor; 113 } 114 115 public void visitSource(String source, String debug) { 116 } 117 118 public void visitInnerClass(String name, String outerName, String innerName, int access) { 119 if (innerClasses == null) { 120 innerClasses = new ArrayList (); 121 } 122 if (!innerClasses.contains(name.replace('/', '.'))) { 123 innerClasses.add(name.replace('/', '.')); 124 } 125 packages.put(innerName, name.replace('/', '.')); 126 } 127 128 public void visitOuterClass(String owner, String name, String desc) { 129 } 130 131 public void visitEnd() { 132 } 133 134 private void addMethodDesc(String desc) { 135 addTypes(desc); 136 addType(Type.getReturnType(desc)); 137 } 138 139 private void addTypes(String desc) { 140 Type[] types = Type.getArgumentTypes(desc); 141 for (int i = 0; i < types.length; i++) { 142 addType(types[i]); 143 } 144 } 145 146 private void addType(Type t) { 147 switch (t.getSort()) { 148 case Type.ARRAY: 149 addType(t.getElementType()); 150 break; 151 case Type.OBJECT: 152 parseClassName(t.getClassName().replace('.', '/')); 153 break; 154 } 155 } 156 157 public void visitAttribute(Attribute attr) { 158 } 159 160 163 164 private static class PMDFieldVisitor implements FieldVisitor { 165 166 private PMDASMVisitor parent; 167 168 public PMDFieldVisitor(PMDASMVisitor visitor) { 169 parent = visitor; 170 } 171 172 public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 173 parent.addType(Type.getType(desc)); 174 return parent.annotationVisitor; 175 } 176 177 public void visitAttribute(Attribute attr) { 178 } 179 180 public void visitEnd() { 181 } 182 } 183 184 private static class PMDAnnotationVisitor implements AnnotationVisitor { 185 private PMDASMVisitor parent; 186 187 public PMDAnnotationVisitor(PMDASMVisitor visitor) { 188 parent = visitor; 189 } 190 191 public AnnotationVisitor visitAnnotation(String name, String desc) { 192 parent.addType(Type.getType(desc)); 193 return this; 194 } 195 196 public void visitEnum(String name, String desc, String value) { 197 parent.addType(Type.getType(desc)); 198 } 199 200 public AnnotationVisitor visitArray(String name) { 201 return this; 202 } 203 204 public void visitEnd() { 205 } 206 207 public void visit(String name, Object value) { 208 if (value instanceof Type) { 209 parent.addType((Type) value); 210 } 211 } 212 } 213 214 private static class PMDSignatureVisitor implements SignatureVisitor { 215 private PMDASMVisitor parent; 216 217 public PMDSignatureVisitor(PMDASMVisitor visitor) { 218 this.parent = visitor; 219 } 220 221 public void visitFormalTypeParameter(String name) { 222 } 223 224 public SignatureVisitor visitClassBound() { 225 return this; 226 } 227 228 public SignatureVisitor visitInterfaceBound() { 229 return this; 230 } 231 232 public SignatureVisitor visitSuperclass() { 233 return this; 234 } 235 236 public SignatureVisitor visitInterface() { 237 return this; 238 } 239 240 public SignatureVisitor visitParameterType() { 241 return this; 242 } 243 244 public SignatureVisitor visitReturnType() { 245 return this; 246 } 247 248 public SignatureVisitor visitExceptionType() { 249 return this; 250 } 251 252 public void visitBaseType(char descriptor) { 253 } 254 255 public void visitTypeVariable(String name) { 256 } 257 258 public SignatureVisitor visitArrayType() { 259 return this; 260 } 261 262 public void visitClassType(String name) { 263 parent.parseClassName(name); 264 } 265 266 public void visitInnerClassType(String name) { 267 parent.parseClassName(name); 268 } 269 270 public void visitTypeArgument() { 271 } 272 273 public SignatureVisitor visitTypeArgument(char wildcard) { 274 return this; 275 } 276 277 public void visitEnd() { 278 } 279 } 280 281 private static class PMDMethodVisitor implements MethodVisitor { 282 private PMDASMVisitor parent; 283 284 public PMDMethodVisitor(PMDASMVisitor visitor) { 285 parent = visitor; 286 } 287 288 public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { 289 parent.addType(Type.getType(desc)); 290 return parent.annotationVisitor; 291 } 292 293 public AnnotationVisitor visitAnnotation(String name, String desc) { 294 parent.addType(Type.getType(desc)); 295 return parent.annotationVisitor; 296 } 297 298 public void visitTypeInsn(int opcode, String desc) { 299 if (desc.charAt(0) == '[') { 300 parent.addType(Type.getType(desc)); 301 } else { 302 parent.parseClassName(desc); 303 } 304 } 305 306 public void visitFieldInsn(int opcode, String owner, String name, String desc) { 307 parent.parseClassName(owner); 308 parent.addType(Type.getType(desc)); 309 } 310 311 public void visitMethodInsn(int opcode, String owner, String name, String desc) { 312 parent.parseClassName(owner); 313 parent.addMethodDesc(desc); 314 } 315 316 323 public void visitLdcInsn(Object cst) { 324 if (cst instanceof Type) { 325 parent.addType((Type) cst); 326 } else if (cst instanceof String ) { 327 parent.parseClassName((String ) cst); 328 } 329 } 330 public void visitMultiANewArrayInsn(String desc, int dims) { 331 parent.addType(Type.getType(desc)); 332 } 333 334 public void visitLocalVariable(String name, String desc, String sig, Label start, Label end, int index) { 335 parent.extractSignature(sig); 336 } 337 338 public void visitCode() { 339 } 340 341 public void visitFrame(int type, int nLocal, Object [] local, int nStack, Object [] stack) { 342 } 343 344 public void visitInsn(int opcode) { 345 } 346 347 public void visitIntInsn(int opcode, int operand) { 348 } 349 350 public void visitVarInsn(int opcode, int var) { 351 } 352 353 public void visitJumpInsn(int opcode, Label label) { 354 } 355 356 public void visitLabel(Label label) { 357 } 358 359 public void visitIincInsn(int var, int increment) { 360 } 361 362 public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { 363 } 364 365 public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { 366 } 367 368 public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { 369 parent.parseClassName(type); 370 } 371 372 public void visitLineNumber(int line, Label start) { 373 } 374 375 public void visitMaxs(int maxStack, int maxLocals) { 376 } 377 378 public AnnotationVisitor visitAnnotationDefault() { 379 return parent.annotationVisitor; 380 } 381 382 public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 383 parent.addType(Type.getType(desc)); 384 return parent.annotationVisitor; 385 } 386 387 public void visitEnd() { 388 } 389 390 public void visitAttribute(Attribute attr) { 391 } 392 393 } 394 } | Popular Tags |