exceptionTypeNames[i] = Type.getType(exceptionTypes[i]).getInternalName();
}
int targetModifiers = delegatedMethod.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC);
MethodVisitor mv = cw.visitMethod(targetModifiers, delegatedMethod.getName(), methodDescriptor, null, exceptionTypeNames);
// fill method body
mv.visitCode();
// load the contextual instance Provider
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitFieldInsn(Opcodes.GETFIELD, proxyClassFileName, FIELD_INSTANCE_PROVIDER, Type.getDescriptor(Provider.class));
// invoke the get() method on the Provider
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(Provider.class), "get", "()Ljava/lang/Object;");
// and convert the Object to the target class type
mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(classToProxy));
// now calculate the parameters
int offset = 1;
for (Class<?> aClass : delegatedMethod.getParameterTypes())
{
final Type type = Type.getType(aClass);
mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), offset);
offset += type.getSize();
}
// and finally invoke the target method on the provided Contextual Instance
final Type declaringClass = Type.getType(delegatedMethod.getDeclaringClass());
boolean interfaceMethod = Modifier.isInterface(delegatedMethod.getDeclaringClass().getModifiers());
mv.visitMethodInsn(interfaceMethod ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL,
declaringClass.getInternalName(), delegatedMethod.getName(), methodDescriptor);
generateReturn(mv, delegatedMethod);
mv.visitMaxs(-1, -1);
mv.visitEnd();
}
}