jacoco有對類級别,方法級别,邏輯分支級别以及代碼行級别做了專門的處理封裝。具體的封裝類在internal.analysis.flow
1 IFrame 接口
import org.objectweb.asm.MethodVisitor;
/**
* 目前的 stackmap frame 内容的表示
*/
public interface IFrame {
/**
* 向給定的通路者發出具有目前内容的 frame 事件
*
* @param mv 向該方法發出 frame 事件的method visitor
*/
void accept(MethodVisitor mv);
}
涉及的類分别是ClassprobesAdapter.java(類級别),Instruction.java(指令級别),LabelFlowAnalysis.java(邏輯分支級别)和MethodProbesAdapter.java(方法級别)。
2 ClassprobesAdapter
一個 org.objectweb.asm.ClassVisitor,它為每個方法計算探針.
屬性
private static final MethodProbesVisitor EMPTY_METHOD_PROBES_VISITOR = new MethodProbesVisitor() {
};
// The class visitor to which this visitor must delegate method calls. May be null
// 委托的執行個體,該通路者必須委派方法調用的類通路者。 可能為null
private final ClassProbesVisitor cv;
// 如果為true,跟蹤并提供 stackmap frames
private final boolean trackFrames;
private int counter = 0;
private String name;
visitMethod
publicfinal MethodVisitor visitMethod(intaccess, String name, String desc, String signature, String[] exceptions)
{
MethodProbesVisitor mv =this.cv.visitMethod(access, name, desc, signature, exceptions);
MethodProbesVisitor methodProbes;
final MethodProbesVisitor methodProbes;
if (mv == null) {
methodProbes =EMPTY_METHOD_PROBES_VISITOR;
} else {
methodProbes = mv;
}
new MethodSanitizer(null, access, name,desc, signature, exceptions)
{
public void visitEnd()
{
super.visitEnd();
LabelFlowAnalyzer.markLabels(this);
MethodProbesAdapter probesAdapter = newMethodProbesAdapter(methodProbes, ClassProbesAdapter.this);
if(ClassProbesAdapter.this.trackFrames)
{
AnalyzerAdapter analyzer = new AnalyzerAdapter(ClassProbesAdapter.this.name,this.access, this.name, this.desc, probesAdapter); probesAdapter.setAnalyzer(analyzer);
accept(analyzer);
}
else
{
accept(probesAdapter);
}
}
};
}
可見類覆寫率位元組碼埋入實際上是對類中每一個方法和每一個邏輯分支做埋入,隻要記錄調用類中方法的覆寫代碼行,自然類的覆寫就會被統計到。
3 ClassProbesVisitor 抽象類
具有附加方法的 ClassVisitor,可擷取每種方法的探針插入資訊
/**
* 當通路一個方法時,我們需要一個 MethodProbesVisitor 來處理該方法的探測
*/
@Override
public abstract MethodProbesVisitor visitMethod(int access, String name,
String desc, String signature, String[] exceptions);