package org.pitest.coverage.analysis;
import java.util.List;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.pitest.mutationtest.engine.gregor.analysis.InstructionCounter;
import sun.pitest.CodeCoverageStore;
/**
* Uses local variables as block probes within methods.
*
* Inserts a finally block the method, posting the probes hits to the code
* coverage store via specialised methods for each number of probes.
*
* The range of methods this approach can be applied to is limited by the
* maximum airty of the overloaded methods on the coverage store.
*/
class LocalVariableCoverageMethodVisitor extends AbstractCoverageStrategy {
private int[] locals;
LocalVariableCoverageMethodVisitor(final List<Block> blocks,
final InstructionCounter counter, final int classId,
final MethodVisitor writer, final int access, final String name,
final String desc, final int probeOffset) {
super(blocks, counter, classId, writer, access, name, desc, probeOffset);
}
@Override
void prepare() {
this.locals = new int[this.blocks.size()];
for (int i = 0; i != this.blocks.size(); i++) {
this.locals[i] = newLocal(Type.getType("Z"));
pushConstant(0);
this.mv.visitVarInsn(ISTORE, this.locals[i]);
}
}
@Override
void insertProbe() {
pushConstant(1);
this.mv.visitVarInsn(ISTORE, this.locals[this.probeCount]);
}
@Override
protected void generateProbeReportCode() {
pushConstant(this.classId);
pushConstant(this.probeOffset);
for (final int i : this.locals) {
this.mv.visitVarInsn(ILOAD, i);
}
this.methodVisitor.visitMethodInsn(Opcodes.INVOKESTATIC,
CodeCoverageStore.CLASS_NAME, CodeCoverageStore.PROBE_METHOD_NAME,
"(II"
+ String.format(String.format("%%0%dd", this.blocks.size()), 0)
.replace("0", "Z") + ")V", false);
}
}