Java tutorial
/* * Copyright (C) 2011 Saarland University * * This file is part of Javalanche. * * Javalanche is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Javalanche 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 Lesser Public License for more details. * * You should have received a copy of the GNU Lesser Public License * along with Javalanche. If not, see <http://www.gnu.org/licenses/>. */ package de.unisb.cs.st.javalanche.mutation.bytecodeMutations.negateJumps; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import de.unisb.cs.st.javalanche.mutation.bytecodeMutations.BytecodeTasks; import de.unisb.cs.st.javalanche.mutation.bytecodeMutations.MutationCode; import de.unisb.cs.st.javalanche.mutation.results.Mutation; import de.unisb.cs.st.javalanche.mutation.results.Mutation.MutationType; import de.unisb.cs.st.javalanche.mutation.results.persistence.MutationManager; import de.unisb.cs.st.javalanche.mutation.results.persistence.QueryManager; public class NegateJumpsMethodAdapter extends AbstractNegateJumpsAdapter { private static Logger logger = Logger.getLogger(NegateJumpsMethodAdapter.class); private final MutationManager mutationManager; public NegateJumpsMethodAdapter(MethodVisitor mv, String className, String methodName, Map<Integer, Integer> possibilities, MutationManager mutationManager, String desc) { super(mv, className, methodName, possibilities, desc); this.mutationManager = mutationManager; } @Override protected void handleMutation(Mutation mutation, final Label label, final int opcode) { logger.debug("Applying mutation for line: " + getLineNumber()); MutationCode unMutated = new MutationCode(null) { @Override public void insertCodeBlock(MethodVisitor mv) { mv.visitJumpInsn(opcode, label); } }; List<Mutation> mutations = QueryManager.getMutations(mutation.getClassName(), mutation.getMethodName(), mutation.getLineNumber(), mutation.getMutationForLine(), MutationType.NEGATE_JUMP); List<MutationCode> mutationCode = new ArrayList<MutationCode>(); for (final Mutation m : mutations) { if (mutationManager.shouldApplyMutation(m)) { MutationCode mutated = new MutationCode(m) { @Override public void insertCodeBlock(MethodVisitor mv) { int insertOpcode = Integer.parseInt(m.getOperatorAddInfo()); if (insertOpcode == POP_ONCE_TRUE) { mv.visitInsn(Opcodes.POP); mv.visitJumpInsn(Opcodes.GOTO, label); } else if (insertOpcode == POP_ONCE_FALSE) { mv.visitInsn(Opcodes.POP); } else if (insertOpcode == POP_TWICE_TRUE) { mv.visitInsn(Opcodes.POP2); mv.visitJumpInsn(Opcodes.GOTO, label); } else if (insertOpcode == POP_TWICE_FALSE) { mv.visitInsn(Opcodes.POP2); } else { mv.visitJumpInsn(insertOpcode, label); } } }; mutationCode.add(mutated); } } if (mutationCode.size() > 0) { BytecodeTasks.insertIfElse(mv, unMutated, mutationCode.toArray(new MutationCode[0])); } else { mv.visitJumpInsn(opcode, label); } } }