/*
 * 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.
/** * 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)); } }