!include once #1019934 // BCEL sclass MethodMaker { replace Type with org.apache.bcel.generic.Type. ClassGen cg; MethodGen mg; new InstructionList il; ConstantPoolGen cp; InstructionFactory factory; int frameSize; *(ClassGen *cg, S methodName, Class returnType, Class... argumentTypes) { cp = cg.getConstantPool(); factory = new InstructionFactory(cg); Type[] argTypes = wrapTypes(argumentTypes); mg = new MethodGen(Const.ACC_PUBLIC, new ObjectType(returnType), argTypes, null /* argNames */, methodName, cg.getClassName(), il, cp); frameSize = l(argTypes)+1; // assume method is not static } Type[] wrapTypes(Class[] classes) { Type[] types = new[l(classes)]; for i over classes: types[i] = wrapType(classes[i]); } Type wrapType(Class c) { ret c == null ?: new ObjectType(className(c)); } // create local variable and return its index int newLocalVar() { ret ++frameSize; } selfType newObject(Class c, Class... argTypes) { il.append(factory.createNew(className(c))); il.append(InstructionConst.DUP); Constructor ctor = findConstructor_onTypes(c, argTypes); il.append(factory.createInvoke(className(c), "", Type.VOID, wrapTypes(ctor.getParameterTypes()), Const.INVOKESPECIAL)); this; } // store object in local variable selfType astore(int var) { il.append(new ASTORE(var)); this; } selfType aload(int var) { il.append(new ALOAD(var)); this; } selfType stringConstant(S s) { il.append(new PUSH(cp, s)); this; } selfType invokeVirtual(Class c, S methodName, Class returnType, Class... argTypes) { Method m = findMethod_onTypes(argTypes); il.append(factory.createInvoke(className(c), methodName, wrapType(m.getReturnType()), wrapTypes(m.getArgumentTypes()), Const.INVOKEVIRTUAL)); this; } selfType areturn() { il.append(InstructionConst.ARETURN); this; } void done() { mg.stripAttributes(true); mg.setMaxStack(); mg.setMaxLocals(); cg.addMethod(mg.getMethod()); } }