// GENERATE <init>(<type> target, ScriptSource source, Integer lineNumber)
String methodDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE,
new Type[]{superclassType, scriptSourceType, integerType});
MethodVisitor methodVisitor = visitor.visitMethod(Opcodes.ACC_PUBLIC, "<init>", methodDescriptor, null,
new String[0]);
methodVisitor.visitCode();
boolean noArgsConstructor;
try {
type.getConstructor(type);
noArgsConstructor = false;
} catch (NoSuchMethodException e) {
try {
type.getConstructor();
noArgsConstructor = true;
} catch (NoSuchMethodException e1) {
throw new IllegalArgumentException(String.format(
"Cannot create subtype for exception '%s'. It needs a zero-args or copy constructor.",
type.getName()));
}
}
if (noArgsConstructor) {
// GENERATE super()
methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, superclassType.getInternalName(), "<init>",
Type.getMethodDescriptor(Type.VOID_TYPE, new Type[0]));
// END super()
} else {
// GENERATE super(target)
methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
methodVisitor.visitVarInsn(Opcodes.ALOAD, 1);
methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, superclassType.getInternalName(), "<init>",
Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{superclassType}));
// END super(target)
}
// GENERATE helper = new ExceptionHelper(this, target, source, lineNumber)
methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
methodVisitor.visitTypeInsn(Opcodes.NEW, helperType.getInternalName());
methodVisitor.visitInsn(Opcodes.DUP);
methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
methodVisitor.visitVarInsn(Opcodes.ALOAD, 1);
methodVisitor.visitVarInsn(Opcodes.ALOAD, 2);
methodVisitor.visitVarInsn(Opcodes.ALOAD, 3);
methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, helperType.getInternalName(), "<init>",
Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{throwableType, throwableType, scriptSourceType, integerType}));
methodVisitor.visitFieldInsn(Opcodes.PUTFIELD, generatedType.getInternalName(), "helper",
helperType.getDescriptor());
// END helper = new ExceptionHelper(target)
methodVisitor.visitInsn(Opcodes.RETURN);
methodVisitor.visitMaxs(0, 0);
methodVisitor.visitEnd();
// END <init>(<type> target, ScriptSource source, Integer lineNumber)
for (Method method : ExceptionHelper.class.getDeclaredMethods()) {
// GENERATE public <type> <method>() { return helper.<method>(); }
methodDescriptor = Type.getMethodDescriptor(Type.getType(method.getReturnType()), new Type[0]);
methodVisitor = visitor.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), methodDescriptor, null,
new String[0]);
methodVisitor.visitCode();
methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
methodVisitor.visitFieldInsn(Opcodes.GETFIELD, generatedType.getInternalName(), "helper",
helperType.getDescriptor());
methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, helperType.getInternalName(), method.getName(),
methodDescriptor);
methodVisitor.visitInsn(Opcodes.ARETURN);
methodVisitor.visitMaxs(0, 0);
methodVisitor.visitEnd();
// END public <type> <method>() { return helper.<method>(); }
}
visitor.visitEnd();