RE: Extract Constructor Code to new method

Felix Dorner <[email protected]> Thu, 2 Jul 2009 16:54:52 +0200
Newsgroups gmane.comp.jakarta.bcel.user
Message-ID <FC95BD382E2CF447BAA1B2AF1F9FFFE602628AD26F@MX034ZED0001.TIFDOM.COM>
Hi Abdullah,

> InstructionList il =3D new InstructionList(); Method
> theOldConstructor =3D cg.containsMethod("<>", "()V"); MethodGen
> theNewConstructor =3D new MethodGen(Constants.ACC_PUBLIC,
> Type.VOID, Type.NO_ARGS, NO_STRINGS, "<init>",
> cg.getClassName(), il, cpg);
> il.append(ifact.createInvoke(cg.getSuperclassName(),
> "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
> il.append(InstructionConstants.RETURN);
> cg.replaceMethod(theOldConstructor,
> theNewConstructor.getMethod()); il.dispose(); cg.setConstantPool(cpg);


Wouldn't this just 'delete' the old constructor, and create a new 'default'=
 one?
What misses is to move the code that's inside the old constructor into an o=
rdinairy method. What I came up with so far was to:

/* look up the default constructor */
Method constructor_method =3D getConstructors().get(0);
ConstantPoolGen cpgen =3D new ConstantPoolGen(jc.getConstantPool());

MethodGen constructor =3D new MethodGen(constructor_method, jc.getClassName=
(), new ConstantPoolGen(jc.getConstantPool()));
InstructionList constructor_code =3D constructor.getInstructionList();

/* a new method. Later I'd need to find a unique name.. I also copy the con=
structor's instruction list*/
MethodGen newmethod =3D new MethodGen(Constants.ACC_PUBLIC, Type.VOID, new =
Type[] {}, new String[] {}, "xaxaxa", jc.getClassName(),  constructor_code.=
copy() , cpgen);

InstructionHandle[] newmethod_instructions =3D newmethod.getInstructionList=
().getInstructionHandles();

/* remove the first two instructions (the one that loads the object variabl=
e this,
And the invocation of the super-constructor... */
try {
        newmethod.getInstructionList().delete(newmethod_instructions[0], ne=
wmethod_instructions[1]);
} catch (TargetLostException e) {
        /* not only the target is lost here.. But me too.. :-)
        e.printStackTrace();
}

... Now I'd probably need to handle
 * local variables
 * exception handlers
..

What I don't really pick up is the instruction target exceptions (which in =
fact get thrown by several LineNumberGen's in my tests..)

Felix