package org.pitest.mutationtest.engine.gregor.mutators.experimental;
import java.util.ArrayList;
import java.util.List;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.pitest.mutationtest.engine.MutationIdentifier;
import org.pitest.mutationtest.engine.gregor.MethodInfo;
import org.pitest.mutationtest.engine.gregor.MethodMutatorFactory;
import org.pitest.mutationtest.engine.gregor.MutationContext;
/**
* Remove switch statements. We get an array of labels to jump to, plus a
* default label. We change each label to the default label, thus removing it
*/
public class RemoveSwitchMutator implements MethodMutatorFactory {
// EXPERIMENTAL_REMOVE_SWITCH_MUTATOR;
private final int key;
public RemoveSwitchMutator(final int i) {
this.key = i;
}
public static Iterable<MethodMutatorFactory> makeMutators() {
List<MethodMutatorFactory> variations = new ArrayList<MethodMutatorFactory>();
for (int i = 0; i != 100; i++) {
variations.add(new RemoveSwitchMutator(i));
}
return variations;
}
@Override
public MethodVisitor create(final MutationContext context,
final MethodInfo methodInfo, final MethodVisitor methodVisitor) {
return new RemoveSwitchMethodVisitor(context, methodVisitor);
}
@Override
public String getGloballyUniqueId() {
return this.getClass().getName() + "_" + this.key;
}
@Override
public String getName() {
return toString();
}
@Override
public String toString() {
return "EXPERIMENTAL_REMOVE_SWITCH_MUTATOR_" + this.key;
}
private final class RemoveSwitchMethodVisitor extends MethodVisitor {
private final MutationContext context;
RemoveSwitchMethodVisitor(final MutationContext context,
final MethodVisitor methodVisitor) {
super(Opcodes.ASM5, methodVisitor);
this.context = context;
}
@Override
public void visitTableSwitchInsn(final int i, final int i1,
final Label defaultLabel, final Label... labels) {
if ((labels.length > RemoveSwitchMutator.this.key) && shouldMutate()) {
Label[] newLabels = labels.clone();
newLabels[RemoveSwitchMutator.this.key] = defaultLabel;
super.visitTableSwitchInsn(i, i1, defaultLabel, newLabels);
} else {
super.visitTableSwitchInsn(i, i1, defaultLabel, labels);
}
}
@Override
public void visitLookupSwitchInsn(final Label defaultLabel,
final int[] ints, final Label[] labels) {
if ((labels.length > RemoveSwitchMutator.this.key) && shouldMutate()) {
Label[] newLabels = labels.clone();
newLabels[RemoveSwitchMutator.this.key] = defaultLabel;
super.visitLookupSwitchInsn(defaultLabel, ints, newLabels);
} else {
super.visitLookupSwitchInsn(defaultLabel, ints, labels);
}
}
private boolean shouldMutate() {
final MutationIdentifier mutationId = this.context.registerMutation(
RemoveSwitchMutator.this, "RemoveSwitch "
+ RemoveSwitchMutator.this.key + " mutation");
return this.context.shouldMutate(mutationId);
}
}
}