// Figure out arg names.
String[] argNames = new String[mf.getArity() + 1];
MethodVariable[] argVars = new MethodVariable[argNames.length];
argNames[0] = "$function";
argVars[0] = new MethodVariable(argNames[0]);
for (int i = 0; i < mf.getArity(); i++) {
argNames[i+1] = "$" + CALToJavaNames.fixupVarName(mf.getParameterNames()[i]);
argVars[i+1] = new MethodVariable(argNames[i+1]);
if (mf.getParameterStrictness()[i] && SCJavaDefn.canTypeBeUnboxed(mf.getParameterTypes()[i])) {
argTypes[i+1] = SCJavaDefn.typeExprToTypeName(mf.getParameterTypes()[i]);
}
}
// Add the constructor to the class.
JavaConstructor javaConstructor =
new JavaConstructor(Modifier.PUBLIC, argNames, argTypes, constructorName);
// Add the body of the constructor
// Check for null argument values via assert.
JavaExpression argCheck = new OperatorExpression.Binary (JavaOperator.NOT_EQUALS_OBJECT, argVars[0], LiteralWrapper.NULL);
for (int i = 1; i < argNames.length; ++i) {
// We only do the null pointer check on arguments of type RTValue.
// It is valid to have an external object (ex. String) which is null.
if (argTypes[i].equals(JavaTypeNames.RTVALUE)) {
JavaExpression compareArg = new OperatorExpression.Binary(JavaOperator.NOT_EQUALS_OBJECT, new MethodVariable(argNames[i]), LiteralWrapper.NULL);
argCheck = new JavaExpression.OperatorExpression.Binary(JavaOperator.CONDITIONAL_AND, argCheck, compareArg);
}
}
javaConstructor.addStatement(
new AssertStatement(
argCheck,
new MethodInvocation.Instance(null, "badConsArgMsg", JavaTypeName.STRING, MethodInvocation.InvocationType.VIRTUAL),
JavaTypeName.STRING));
// Assign the argument values to the class fields.
javaConstructor.addStatement(new ExpressionStatement(new Assignment(functionField, new MethodVariable(argNames[0]))));
for (int i = 1; i < argNames.length; i++) {
JavaField field = functionArgumentMemberFields[i-1];
Assignment memberAssignment = new Assignment(field, new MethodVariable(argNames[i]));
javaConstructor.addStatement(new ExpressionStatement(memberAssignment));
}
return javaConstructor;