final ClassWriter writerPhase1 = AsmHelper.newClassWriter(true);
final ClassReader readerPhase1 = new ClassReader(bytecode);
ClassVisitor reversedChainPhase1 = writerPhase1;
reversedChainPhase1 = new AddMixinMethodsVisitor(reversedChainPhase1, classInfo, context, addedMethods);
reversedChainPhase1 = new AddInterfaceVisitor(reversedChainPhase1, classInfo, context);
reversedChainPhase1 = new AddSerialVersionUidVisitor(reversedChainPhase1, classInfo, context, true);
readerPhase1.accept(reversedChainPhase1, Attributes.getDefaultAttributes(), false);
final byte[] bytesPhase1 = writerPhase1.toByteArray();
// update the class info
classInfo = AsmClassInfo.newClassInfo(bytesPhase1, loader);
// -- Phase 2 -- advices
final ClassWriter writerPhase2 = AsmHelper.newClassWriter(true);
final ClassReader readerPhase2 = new ClassReader(bytesPhase1);
ClassVisitor reversedChainPhase2 = writerPhase2;
reversedChainPhase2 = new InstanceLevelAspectVisitor(reversedChainPhase2, classInfo, context);
reversedChainPhase2 = new MethodExecutionVisitor(reversedChainPhase2, classInfo, context, addedMethods);
reversedChainPhase2 = new ConstructorBodyVisitor(reversedChainPhase2, classInfo, context, addedMethods);
reversedChainPhase2 = new HandlerVisitor(reversedChainPhase2, loader, classInfo, context, catchLabels);
if (!filterForCall) {
reversedChainPhase2 = new MethodCallVisitor(reversedChainPhase2, loader, classInfo, context);
reversedChainPhase2 = new ConstructorCallVisitor(
reversedChainPhase2, loader, classInfo, context, newInvocationsByCallerMemberHash
);
}
if (!filterForGetSet) {
reversedChainPhase2 = new FieldSetFieldGetVisitor(reversedChainPhase2, loader, classInfo, context);
reversedChainPhase2 = new FieldWrapperVisitor(reversedChainPhase2, classInfo, context, addedMethods);
}
reversedChainPhase2 = new MethodWrapperVisitor(reversedChainPhase2, classInfo, context, addedMethods);
readerPhase2.accept(reversedChainPhase2, Attributes.getDefaultAttributes(), false);
final byte[] bytesPhase2 = writerPhase2.toByteArray();
context.setCurrentBytecode(bytesPhase2);
// -- Phase 3 -- serialUID and JoinPoint initialization
if (context.isAdvised()) {
final ClassWriter writerPhase3 = AsmHelper.newClassWriter(true);
ClassReader readerPhase3 = new ClassReader(bytesPhase2);
ClassVisitor reversedChainPhase3 = writerPhase3;
reversedChainPhase3 = new AddSerialVersionUidVisitor(reversedChainPhase3, classInfo, context, false);
reversedChainPhase3 = new JoinPointInitVisitor(reversedChainPhase3, context);
readerPhase3.accept(reversedChainPhase3, Attributes.getDefaultAttributes(), false);
final byte[] bytesPhase3 = writerPhase3.toByteArray();
context.setCurrentBytecode(bytesPhase3);