1 21 22 package net.sourceforge.cobertura.instrument; 23 24 import java.util.Collection ; 25 26 import net.sourceforge.cobertura.coveragedata.ClassData; 27 import net.sourceforge.cobertura.coveragedata.ProjectData; 28 29 import org.apache.log4j.Logger; 30 import org.objectweb.asm.ClassAdapter; 31 import org.objectweb.asm.ClassVisitor; 32 import org.objectweb.asm.MethodVisitor; 33 import org.objectweb.asm.Opcodes; 34 35 class ClassInstrumenter extends ClassAdapter 36 { 37 38 private static final Logger logger = Logger 39 .getLogger(ClassInstrumenter.class); 40 41 private final static String hasBeenInstrumented = "net/sourceforge/cobertura/coveragedata/HasBeenInstrumented"; 42 43 private Collection ignoreRegexs; 44 45 private ProjectData projectData; 46 47 private ClassData classData; 48 49 private String myName; 50 51 private boolean instrument = false; 52 53 public String getClassName() 54 { 55 return this.myName; 56 } 57 58 public boolean isInstrumented() 59 { 60 return instrument; 61 } 62 63 public ClassInstrumenter(ProjectData projectData, final ClassVisitor cv, 64 final Collection ignoreRegexs) 65 { 66 super(cv); 67 this.projectData = projectData; 68 this.ignoreRegexs = ignoreRegexs; 69 } 70 71 private boolean arrayContains(Object [] array, Object key) 72 { 73 for (int i = 0; i < array.length; i++) 74 { 75 if (array[i].equals(key)) 76 return true; 77 } 78 79 return false; 80 } 81 82 86 public void visit(int version, int access, String name, String signature, 87 String superName, String [] interfaces) 88 { 89 this.myName = name.replace('/', '.'); 90 this.classData = this.projectData.getOrCreateClassData(this.myName); 91 this.classData.setContainsInstrumentationInfo(); 92 93 if (((access & Opcodes.ACC_INTERFACE) != 0) 96 || arrayContains(interfaces, hasBeenInstrumented)) 97 { 98 super.visit(version, access, name, signature, superName, 99 interfaces); 100 } 101 else 102 { 103 instrument = true; 104 105 String [] newInterfaces = new String [interfaces.length + 1]; 107 System.arraycopy(interfaces, 0, newInterfaces, 0, 108 interfaces.length); 109 newInterfaces[newInterfaces.length - 1] = hasBeenInstrumented; 110 111 super.visit(version, access, name, signature, superName, 112 newInterfaces); 113 } 114 } 115 116 119 public void visitSource(String source, String debug) 120 { 121 super.visitSource(source, debug); 122 classData.setSourceFileName(source); 123 } 124 125 public MethodVisitor visitMethod(final int access, final String name, 126 final String desc, final String signature, 127 final String [] exceptions) 128 { 129 MethodVisitor mv = cv.visitMethod(access, name, desc, signature, 130 exceptions); 131 132 if (!instrument) 133 return mv; 134 135 return mv == null ? null : new MethodInstrumenter(classData, mv, 136 this.myName, name, desc, ignoreRegexs); 137 } 138 139 public void visitEnd() 140 { 141 if (instrument && classData.getNumberOfValidLines() == 0) 142 logger.warn("No line number information found for class " 143 + this.myName 144 + ". Perhaps you need to compile with debug=true?"); 145 } 146 147 } 148 | Popular Tags |