/*
* Cobertura - http://cobertura.sourceforge.net/
*
* Copyright (C) 2011 Piotr Tabor
*
* Note: This file is dual licensed under the GPL and the Apache
* Source License (so that it can be used from both the main
* Cobertura classes and the ant tasks).
*
* 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 org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.*;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
/**
* A message adapter that keeps list of last N events.
*
* @author piotr.tabor@gmail.com.
*/
public class HistoryMethodAdapter extends MethodVisitor {
private final LinkedList<AbstractInsnNode> backlog = new LinkedList<AbstractInsnNode>();
private final int eventsToTrace;
public HistoryMethodAdapter(MethodVisitor mv, int eventsToTrace) {
super(Opcodes.ASM4, mv);
this.eventsToTrace = eventsToTrace;
}
public List<AbstractInsnNode> backlog() {
return Collections.unmodifiableList(backlog);
}
private void appendToBacklog(AbstractInsnNode node) {
if (backlog.size() >= eventsToTrace) {
backlog.removeFirst();
}
backlog.addLast(node);
}
@Override
public void visitFieldInsn(int arg0, String arg1, String arg2, String arg3) {
super.visitFieldInsn(arg0, arg1, arg2, arg3);
appendToBacklog(new FieldInsnNode(arg0, arg1, arg2, arg3));
}
@Override
public void visitFrame(int arg0, int arg1, Object[] arg2, int arg3,
Object[] arg4) {
super.visitFrame(arg0, arg1, arg2, arg3, arg4);
appendToBacklog(new FrameNode(arg0, arg1, arg2, arg3, arg4));
}
@Override
public void visitIincInsn(int arg0, int arg1) {
super.visitIincInsn(arg0, arg1);
appendToBacklog(new IincInsnNode(arg0, arg1));
}
@Override
public void visitInsn(int arg0) {
super.visitInsn(arg0);
appendToBacklog(new InsnNode(arg0));
}
@Override
public void visitIntInsn(int arg0, int arg1) {
super.visitIntInsn(arg0, arg1);
appendToBacklog(new IntInsnNode(arg0, arg1));
}
@Override
public void visitJumpInsn(int arg0, Label arg1) {
super.visitJumpInsn(arg0, arg1);
appendToBacklog(new JumpInsnNode(arg0, new LabelNode(arg1)));
}
@Override
public void visitLabel(Label arg0) {
super.visitLabel(arg0);
appendToBacklog(new LabelNode(arg0));
}
@Override
public void visitLdcInsn(Object arg0) {
super.visitLdcInsn(arg0);
appendToBacklog(new LdcInsnNode(arg0));
}
@Override
public void visitLineNumber(int arg0, Label arg1) {
super.visitLineNumber(arg0, arg1);
appendToBacklog(new LineNumberNode(arg0, new LabelNode(arg1)));
}
@Override
public void visitLookupSwitchInsn(Label arg0, int[] arg1, Label[] arg2) {
super.visitLookupSwitchInsn(arg0, arg1, arg2);
LabelNode nodes[] = new LabelNode[arg2.length];
for (int i = 0; i < arg2.length; i++) {
nodes[i] = new LabelNode(arg2[i]);
}
appendToBacklog(new LookupSwitchInsnNode(new LabelNode(arg0), arg1,
nodes));
}
@Override
public void visitMethodInsn(int arg0, String arg1, String arg2, String arg3) {
super.visitMethodInsn(arg0, arg1, arg2, arg3);
appendToBacklog(new MethodInsnNode(arg0, arg1, arg2, arg3));
}
@Override
public void visitMultiANewArrayInsn(String arg0, int arg1) {
super.visitMultiANewArrayInsn(arg0, arg1);
appendToBacklog(new MultiANewArrayInsnNode(arg0, arg1));
}
@Override
public void visitTableSwitchInsn(int arg0, int arg1, Label arg2,
Label[] arg3) {
super.visitTableSwitchInsn(arg0, arg1, arg2, arg3);
LabelNode nodes[] = new LabelNode[arg3.length];
for (int i = 0; i < arg3.length; i++) {
nodes[i] = new LabelNode(arg3[i]);
}
appendToBacklog(new TableSwitchInsnNode(arg0, arg1,
new LabelNode(arg2), nodes));
}
@Override
public void visitTypeInsn(int arg0, String arg1) {
super.visitTypeInsn(arg0, arg1);
appendToBacklog(new TypeInsnNode(arg0, arg1));
}
@Override
public void visitVarInsn(int arg0, int arg1) {
super.visitVarInsn(arg0, arg1);
appendToBacklog(new VarInsnNode(arg0, arg1));
}
}