package hu.advancedweb.scott.instrumentation.transformation; import org.junit.Rule; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import hu.advancedweb.scott.instrumentation.transformation.param.TransformationParameters; import hu.advancedweb.scott.runtime.ScottReportingRule; /** * Manitpulates the class through the appropriate MethodVisitors. * * @see ConstructorTransformerMethodVisitor * @see ScopeExtractorTestMethodVisitor * @see StateEmitterTestMethodVisitor * @author David Csakvari */ public class StateTrackingTestClassVisitor extends ClassVisitor { private String className; private TransformationParameters transformationParameters; public StateTrackingTestClassVisitor(ClassVisitor cv, TransformationParameters transformationParameters) { super(Opcodes.ASM5, cv); this.transformationParameters = transformationParameters; } @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { this.className = name; super.visit(version, access, name, signature, superName, interfaces); } @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); if (name.equals("<init>")) { if (transformationParameters.isRuleInjectionRequired) { MethodVisitor constructorTransformerMethodVisitor = new ConstructorTransformerMethodVisitor(methodVisitor, access, name, desc, signature, exceptions, className); return constructorTransformerMethodVisitor; } else { return methodVisitor; } } else if (transformationParameters.isMethodTrackingRequired(name, desc, signature)) { StateEmitterTestMethodVisitor variableMutationEventEmitter = new StateEmitterTestMethodVisitor(methodVisitor, className, name, transformationParameters.isClearingTrackedDataInTheBeginningOfThisMethodRequired(name, desc, signature)); MethodVisitor variableExtractor = new ScopeExtractorTestMethodVisitor(variableMutationEventEmitter, access, name, desc, signature, exceptions, className); return variableExtractor; } else { return methodVisitor; } } @Override public void visitEnd() { if (transformationParameters.isRuleInjectionRequired) { FieldVisitor fv = super.visitField(Opcodes.ACC_PUBLIC, "scottReportingRule", Type.getDescriptor(ScottReportingRule.class), null, null); if (fv != null) { fv.visitAnnotation(Type.getDescriptor(Rule.class), true).visitEnd(); } } super.visitEnd(); } }