Tom Moore - 2007-09-25

Logged In: YES
user_id=812261
Originator: NO

It looks like this is a dupe of bug #1627493.

The problem is that the generated code does not know how to call the superclass constructor. The default is to insert a default no-args constructor, which is why this works in some situations and not others.

I have made a hack/patch that fixes this behavior. It basically inserts a method that looks like a constructor and calls super with the argument types specified in the allocator. This is as localized and non-intrusive as I could think to make it. It seems to work.

Patch is as follows.
<pre>
*** Copy of BeanShell-2.0b5\src\bsh\BSHAllocationExpression.java Sat Jun 11 23:16:42 2005
--- BeanShell-2.0b5\src\bsh\BSHAllocationExpression.java Tue Sep 25 12:50:16 2007
***************
*** 34,39 ****
--- 34,40 ----

package bsh;

+ import java.io.StringReader;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;

***************
*** 179,188 ****
{
//throw new InterpreterError("constructWithClassBody unimplemented");

! String name = callstack.top().getName() + "$" + (++innerClassCount);
Modifiers modifiers = new Modifiers();
modifiers.addModifier( Modifiers.CLASS, "public" );
Class clas;
try {
clas = ClassGenerator.getClassGenerator() .generateClass(
name, modifiers, null/*interfaces*/, type/*superClass*/,
--- 180,212 ----
{
//throw new InterpreterError("constructWithClassBody unimplemented");

! String inner = "anon" + (++innerClassCount);
! String name = callstack.top().getName() + "$" + inner;
Modifiers modifiers = new Modifiers();
modifiers.addModifier( Modifiers.CLASS, "public" );
Class clas;
+
+ // If the class was created with arguments then add a constructor that simple invokes super
+ if (args.length > 0) {
+ String formal = "";
+ String argnames = "";
+ for (int i=0; i<args.length; i++) {
+ if (i>0) {
+ formal += ", ";
+ argnames += ", ";
+ }
+ String argname = String.valueOf((char) (97+i));
+ argnames += argname;
+ formal += args[i].getClass().getName()+" "+argname;
+ }
+ String command = inner+"("+formal+") {super("+argnames+");}";
+ Parser p = new Parser(new StringReader(command));
+ p.Line();
+ BSHMethodDeclaration node = (BSHMethodDeclaration) p.popNode();
+ node.eval(new CallStack(), new Interpreter());
+ block.jjtAddChild(node, block.jjtGetNumChildren());
+ }
+
try {
clas = ClassGenerator.getClassGenerator() .generateClass(
name, modifiers, null/*interfaces*/, type/*superClass*/,

</pre>