|
Cobertura example source code file (FirstPassMethodInstrumenter.java)
The Cobertura FirstPassMethodInstrumenter.java source code
/*
* Cobertura - http://cobertura.sourceforge.net/
*
* Copyright (C) 2005 Mark Doliner
* Copyright (C) 2006 Jiri Mares
*
* Cobertura is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* Cobertura is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Cobertura; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
package net.sourceforge.cobertura.instrument;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import net.sourceforge.cobertura.coveragedata.ClassData;
import net.sourceforge.cobertura.util.RegexUtil;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodAdapter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.MethodNode;
public class FirstPassMethodInstrumenter extends MethodAdapter implements Opcodes
{
private final String ownerClass;
private String myName;
private String myDescriptor;
private int myAccess;
private Collection ignoreRegexs;
private Collection ignoreBranchesRegexs;
private ClassData classData;
private int currentLine;
private int currentJump;
private int currentSwitch;
private Map jumpTargetLabels;
private Map switchTargetLabels;
private Map lineLabels;
private MethodVisitor writerMethodVisitor;
private MethodNode methodNode;
public FirstPassMethodInstrumenter(ClassData classData, final MethodVisitor mv,
final String owner, final int access, final String name, final String desc,
final String signature, final String[] exceptions, final Collection ignoreRegexs,
final Collection ignoreBranchesRegexs)
{
super(new MethodNode(access, name, desc, signature, exceptions));
writerMethodVisitor = mv;
this.ownerClass = owner;
this.methodNode = (MethodNode) this.mv;
this.classData = classData;
this.myAccess = access;
this.myName = name;
this.myDescriptor = desc;
this.ignoreRegexs = ignoreRegexs;
this.ignoreBranchesRegexs = ignoreBranchesRegexs;
this.jumpTargetLabels = new HashMap();
this.switchTargetLabels = new HashMap();
this.lineLabels = new HashMap();
this.currentLine = 0;
}
public void visitEnd() {
super.visitEnd();
methodNode.accept(lineLabels.isEmpty() ? writerMethodVisitor : new SecondPassMethodInstrumenter(this)); //when there is no line number info -> no instrumentation
}
public void visitJumpInsn(int opcode, Label label)
{
// Ignore any jump instructions in the "class init" method.
// When initializing static variables, the JVM first checks
// that the variable is null before attempting to set it.
// This check contains an IFNONNULL jump instruction which
// would confuse people if it showed up in the reports.
if ((opcode != GOTO) && (opcode != JSR) && (currentLine != 0)
&& (!this.myName.equals("<clinit>")))
{
classData.addLineJump(currentLine, currentJump);
jumpTargetLabels.put(label, new JumpHolder(currentLine, currentJump++));
}
super.visitJumpInsn(opcode, label);
}
public void visitLineNumber(int line, Label start)
{
// Record initial information about this line of code
currentLine = line;
classData.addLine(currentLine, myName, myDescriptor);
currentJump = 0;
currentSwitch = 0;
lineLabels.put(start, new Integer(line));
//removed because the MethodNode doesn't reproduce visitLineNumber where they are but at the end of the file :-((
//therefore we don't need them
//We can directly instrument the visit line number here, but it is better to leave all instrumentation in the second pass
//therefore we just collects what label is the line ...
//super.visitLineNumber(line, start);
}
public void visitMethodInsn(int opcode, String owner, String name,
String desc)
{
super.visitMethodInsn(opcode, owner, name, desc);
// If any of the ignore patterns match this line
// then remove it from our data
if (RegexUtil.matches(ignoreRegexs, owner))
{
classData.removeLine(currentLine);
}
}
public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels)
{
super.visitLookupSwitchInsn(dflt, keys, labels);
if (currentLine != 0)
{
switchTargetLabels.put(dflt, new SwitchHolder(currentLine, currentSwitch, -1));
for (int i = labels.length -1; i >=0; i--)
switchTargetLabels.put(labels[i], new SwitchHolder(currentLine, currentSwitch, i));
classData.addLineSwitch(currentLine, currentSwitch++, keys);
}
}
public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels)
{
super.visitTableSwitchInsn(min, max, dflt, labels);
if (currentLine != 0)
{
switchTargetLabels.put(dflt, new SwitchHolder(currentLine, currentSwitch, -1));
for (int i = labels.length -1; i >=0; i--)
switchTargetLabels.put(labels[i], new SwitchHolder(currentLine, currentSwitch, i));
classData.addLineSwitch(currentLine, currentSwitch++, min, max);
}
}
protected void removeLine(int lineNumber)
{
classData.removeLine(lineNumber);
}
protected MethodVisitor getWriterMethodVisitor()
{
return writerMethodVisitor;
}
protected Collection getIgnoreRegexs()
{
return ignoreRegexs;
}
protected Map getJumpTargetLabels()
{
return jumpTargetLabels;
}
protected Map getSwitchTargetLabels()
{
return switchTargetLabels;
}
protected int getMyAccess()
{
return myAccess;
}
protected String getMyDescriptor()
{
return myDescriptor;
}
protected String getMyName()
{
return myName;
}
protected String getOwnerClass()
{
return ownerClass;
}
protected Map getLineLabels()
{
return lineLabels;
}
}
Other Cobertura examples (source code examples)Here is a short list of links related to this Cobertura FirstPassMethodInstrumenter.java source code file: |
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.