use of org.evosuite.instrumentation.mutation.MutationOperator in project evosuite by EvoSuite.
the class MutationInstrumentation method analyze.
/* (non-Javadoc)
* @see org.evosuite.cfg.instrumentation.MethodInstrumentation#analyze(org.objectweb.asm.tree.MethodNode, java.lang.String, java.lang.String, int)
*/
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public void analyze(ClassLoader classLoader, MethodNode mn, String className, String methodName, int access) {
if (methodName.startsWith("<clinit>"))
return;
if (methodName.startsWith(ClassResetter.STATIC_RESET))
return;
RawControlFlowGraph graph = GraphPool.getInstance(classLoader).getRawCFG(className, methodName);
Iterator<AbstractInsnNode> j = mn.instructions.iterator();
getFrames(mn, className);
boolean constructorInvoked = false;
if (!methodName.startsWith("<init>"))
constructorInvoked = true;
logger.info("Applying mutation operators ");
int frameIndex = 0;
int numMutants = 0;
if (frames.length != mn.instructions.size()) {
logger.error("Number of frames does not match number number of bytecode instructions: " + frames.length + "/" + mn.instructions.size());
logger.error("Skipping mutation of method " + className + "." + methodName);
return;
}
// + " vs " + mn.instructions.size();
while (j.hasNext()) {
Frame currentFrame = frames[frameIndex++];
AbstractInsnNode in = j.next();
if (!constructorInvoked) {
if (in.getOpcode() == Opcodes.INVOKESPECIAL) {
if (className.matches(".*\\$\\d+$")) {
// so best not mutate the constructor
continue;
}
MethodInsnNode cn = (MethodInsnNode) in;
Set<String> superClasses = new HashSet<String>();
if (DependencyAnalysis.getInheritanceTree() != null && DependencyAnalysis.getInheritanceTree().hasClass(className))
superClasses.addAll(DependencyAnalysis.getInheritanceTree().getSuperclasses(className));
superClasses.add(className);
String classNameWithDots = ResourceList.getClassNameFromResourcePath(cn.owner);
if (superClasses.contains(classNameWithDots)) {
constructorInvoked = true;
}
} else {
continue;
}
}
boolean inInstrumentation = false;
for (BytecodeInstruction v : graph.vertexSet()) {
// If the bytecode is instrumented by EvoSuite, then don't mutate
if (v.isLabel()) {
LabelNode labelNode = (LabelNode) v.getASMNode();
if (labelNode.getLabel() instanceof AnnotatedLabel) {
AnnotatedLabel aLabel = (AnnotatedLabel) labelNode.getLabel();
if (aLabel.isStartTag()) {
inInstrumentation = true;
} else {
inInstrumentation = false;
}
}
}
if (inInstrumentation) {
continue;
}
// If this is in the CFG
if (in.equals(v.getASMNode())) {
logger.info(v.toString());
List<Mutation> mutations = new LinkedList<Mutation>();
// TODO: More than one mutation operator might apply to the same instruction
for (MutationOperator mutationOperator : mutationOperators) {
if (numMutants++ > Properties.MAX_MUTANTS_PER_METHOD) {
logger.info("Reached maximum number of mutants per method");
break;
}
// logger.info("Checking mutation operator on instruction " + v);
if (mutationOperator.isApplicable(v)) {
logger.info("Applying mutation operator " + mutationOperator.getClass().getSimpleName());
mutations.addAll(mutationOperator.apply(mn, className, methodName, v, currentFrame));
}
}
if (!mutations.isEmpty()) {
logger.info("Adding instrumentation for mutation");
// InsnList instrumentation = getInstrumentation(in, mutations);
addInstrumentation(mn, in, mutations);
}
}
if (numMutants > Properties.MAX_MUTANTS_PER_METHOD) {
break;
}
}
}
j = mn.instructions.iterator();
logger.info("Result of mutation: ");
while (j.hasNext()) {
AbstractInsnNode in = j.next();
logger.info(new BytecodeInstruction(classLoader, className, methodName, 0, 0, in).toString());
}
logger.info("Done.");
// mn.maxStack += 3;
}
Aggregations