JNewInstance newInstance = new JNewInstance(
type.getSourceInfo().makeChild(BuildDeclMapVisitor.class,
"new instance"), type);
// (new Foo()).Foo() : Invoke the constructor method on the instance
JMethodCall call = new JMethodCall(type.getSourceInfo().makeChild(
BuildDeclMapVisitor.class, "constructor invocation"), newInstance,
constructor);
/*
* If the type isn't static, make the first parameter a reference to the
* instance of the enclosing class. It's the first instance to allow the
* JSNI qualifier to be moved without affecting evaluation order.
*/
JParameter enclosingInstance = null;
if (!staticClass) {
enclosingInstance = program.createParameter(
synthetic.getSourceInfo().makeChild(BuildDeclMapVisitor.class,
"outer instance"), "this$outer".toCharArray(), enclosingType,
false, false, synthetic);
}
/*
* In one pass, add the parameters to the synthetic constructor and
* arguments to the method call.
*/
for (Iterator<JParameter> i = constructor.getParams().iterator(); i.hasNext();) {
JParameter param = i.next();
/*
* This supports x.new Inner() by passing the enclosing instance
* implicitly as the last argument to the constructor.
*/
if (enclosingInstance != null && !i.hasNext()) {
call.addArg(new JParameterRef(synthetic.getSourceInfo().makeChild(
BuildDeclMapVisitor.class, "enclosing instance"),
enclosingInstance));
} else {
JParameter syntheticParam = program.createParameter(
synthetic.getSourceInfo().makeChild(BuildDeclMapVisitor.class,
"Argument " + param.getName()),
param.getName().toCharArray(), param.getType(), true, false,
synthetic);
call.addArg(new JParameterRef(
syntheticParam.getSourceInfo().makeChild(
BuildDeclMapVisitor.class, "reference"), syntheticParam));
}
}