KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > cobertura > instrument > MethodInstrumenter


1 /*
2  * Cobertura - http://cobertura.sourceforge.net/
3  *
4  * Copyright (C) 2005 Mark Doliner
5  * Copyright (C) 2006 John Lewis
6  *
7  * Cobertura is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published
9  * by the Free Software Foundation; either version 2 of the License,
10  * or (at your option) any later version.
11  *
12  * Cobertura is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Cobertura; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20  * USA
21  */

22
23 package net.sourceforge.cobertura.instrument;
24
25 import java.util.Collection JavaDoc;
26
27 import net.sourceforge.cobertura.coveragedata.ClassData;
28 import net.sourceforge.cobertura.util.RegexUtil;
29
30 import org.objectweb.asm.Label;
31 import org.objectweb.asm.MethodAdapter;
32 import org.objectweb.asm.MethodVisitor;
33 import org.objectweb.asm.Opcodes;
34
35 /*
36  * TODO: If class is abstract then do not count the "public abstract class bleh" line as a SLOC.
37  * TODO: For branches, only count the branch as covered if both paths are accessed?
38  */

39 public class MethodInstrumenter extends MethodAdapter implements Opcodes
40 {
41
42     private final String JavaDoc ownerClass;
43
44     private String JavaDoc myName;
45
46     private String JavaDoc myDescriptor;
47
48     private Collection JavaDoc ignoreRegexs;
49
50     private ClassData classData;
51
52     private int currentLine = 0;
53
54     public MethodInstrumenter(ClassData classData, final MethodVisitor mv,
55             final String JavaDoc owner, final String JavaDoc myName, final String JavaDoc myDescriptor,
56             final Collection JavaDoc ignoreRegexs)
57     {
58         super(mv);
59         this.classData = classData;
60         this.ownerClass = owner;
61         this.myName = myName;
62         this.myDescriptor = myDescriptor;
63         this.ignoreRegexs = ignoreRegexs;
64     }
65
66     public void visitJumpInsn(int opcode, Label label)
67     {
68         super.visitJumpInsn(opcode, label);
69
70         // Ignore any jump instructions in the "class init" method.
71
// When initializing static variables, the JVM first checks
72
// that the variable is null before attempting to set it.
73
// This check contains an IFNONNULL jump instruction which
74
// would confuse people if it showed up in the reports.
75
if ((opcode != GOTO) && (currentLine != 0)
76                 && (!this.myName.equals("<clinit>")))
77             classData.markLineAsBranch(currentLine);
78     }
79
80     public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels)
81     {
82         super.visitLookupSwitchInsn(dflt, keys, labels);
83         if (currentLine != 0)
84             classData.markLineAsBranch(currentLine);
85     }
86
87     public void visitLineNumber(int line, Label start)
88     {
89         // Record initial information about this line of code
90
currentLine = line;
91         classData.addLine(currentLine, myName, myDescriptor);
92
93         // Get an instance of ProjectData:
94
// ProjectData.getGlobalProjectData()
95
mv.visitMethodInsn(INVOKESTATIC,
96                 "net/sourceforge/cobertura/coveragedata/ProjectData",
97                 "getGlobalProjectData",
98                 "()Lnet/sourceforge/cobertura/coveragedata/ProjectData;");
99
100         // Get the ClassData object for this class:
101
// projectData.getClassData("name.of.this.class")
102
mv.visitLdcInsn(ownerClass);
103         mv
104                 .visitMethodInsn(INVOKEVIRTUAL,
105                         "net/sourceforge/cobertura/coveragedata/ProjectData",
106                         "getOrCreateClassData",
107                         "(Ljava/lang/String;)Lnet/sourceforge/cobertura/coveragedata/ClassData;");
108
109         // Mark the current line number as covered:
110
// classData.touch(line)
111
mv.visitIntInsn(SIPUSH, line);
112         mv.visitMethodInsn(INVOKEVIRTUAL,
113                 "net/sourceforge/cobertura/coveragedata/ClassData", "touch",
114                 "(I)V");
115
116         super.visitLineNumber(line, start);
117     }
118
119     public void visitMethodInsn(int opcode, String JavaDoc owner, String JavaDoc name,
120             String JavaDoc desc)
121     {
122         super.visitMethodInsn(opcode, owner, name, desc);
123
124         // If any of the ignore patterns match this line
125
// then remove it from our data
126
if (RegexUtil.matches(ignoreRegexs, owner))
127         {
128             classData.removeLine(currentLine);
129         }
130     }
131
132 }
133
Popular Tags