SourceInfo info = ctor.body.getSourceInfo();
currentMethod = ctor;
currentMethodScope = x.scope;
JMethodCall superOrThisCall = null;
ExplicitConstructorCall ctorCall = x.constructorCall;
if (ctorCall != null) {
superOrThisCall = (JMethodCall) dispatch("processExpression",
ctorCall);
}
/*
* Determine if we have an explicit this call. The presence of an
* explicit this call indicates we can skip certain initialization steps
* (as the callee will perform those steps for us). These skippable
* steps are 1) assigning synthetic args to fields and 2) running
* initializers.
*/
boolean hasExplicitThis = (ctorCall != null)
&& !ctorCall.isSuperAccess();
JClassType enclosingType = (JClassType) ctor.getEnclosingType();
// Call clinit; $clinit is always in position 0.
JMethod clinitMethod = (JMethod) enclosingType.methods.get(0);
JMethodCall clinitCall = new JMethodCall(program, info, null,
clinitMethod);
ctor.body.statements.add(clinitCall.makeStatement());
/*
* All synthetic fields must be assigned, unless we have an explicit
* this constructor call, in which case the callee will assign them for
* us.
*/
if (!hasExplicitThis) {
ReferenceBinding declaringClass = x.binding.declaringClass;
if (declaringClass instanceof NestedTypeBinding) {
Iterator/* <JParameter> */paramIt = getSyntheticsIterator(ctor);
NestedTypeBinding nestedBinding = (NestedTypeBinding) declaringClass;
if (nestedBinding.enclosingInstances != null) {
for (int i = 0; i < nestedBinding.enclosingInstances.length; ++i) {
SyntheticArgumentBinding arg = nestedBinding.enclosingInstances[i];
JParameter param = (JParameter) paramIt.next();
if (arg.matchingField != null) {
JField field = (JField) typeMap.get(arg);
ctor.body.statements.add(program.createAssignmentStmt(info,
createVariableRef(info, field), createVariableRef(info,
param)));
}
}
}
if (nestedBinding.outerLocalVariables != null) {
for (int i = 0; i < nestedBinding.outerLocalVariables.length; ++i) {
SyntheticArgumentBinding arg = nestedBinding.outerLocalVariables[i];
JParameter param = (JParameter) paramIt.next();
JField field = (JField) typeMap.get(arg);
ctor.body.statements.add(program.createAssignmentStmt(info,
createVariableRef(info, field), createVariableRef(info,
param)));
}
}
}
}
// optional this or super constructor call
if (superOrThisCall != null) {
ctor.body.statements.add(superOrThisCall.makeStatement());
}
JExpression thisRef = createThisRef(info, enclosingType);
/*
* Call the synthetic instance initializer method, unless we have an
* explicit this constructor call, in which case the callee will.
*/
if (!hasExplicitThis) {
// $init is always in position 1 (clinit is in 0)
JMethod initMethod = (JMethod) enclosingType.methods.get(1);
JMethodCall initCall = new JMethodCall(program, info, thisRef,
initMethod);
ctor.body.statements.add(initCall.makeStatement());
}
// user code (finally!)
if (x.statements != null) {
for (int i = 0, n = x.statements.length; i < n; ++i) {