//create the function name and parameterise it with the return type
//and the argument types
final int paraSize = paramTypes.size() - args.size();
Node typeArgs = GNode.create("TypeArguments");
typeArgs.add(retType);
for (int i = args.size(); i < paramTypes.size(); i++) {
typeArgs.add(paramTypes.get(i));
}
Node functionTypeNode = GNode.create("Type",
GNode.create("InstantiatedType",
GNode.create("TypeInstantiation", "Function", null),
GNode.create("TypeInstantiation", "F" + paraSize,
typeArgs)),
null);
// Populate the formal parameters for the "apply" method
Node formalParameters = GNode.create("FormalParameters", paraSize);
// Names of formal parameters
List<String> formalParams = new ArrayList<String>();
for (int i = args.size(); i < paramTypes.size(); i++) {
String newPara = table.freshJavaId("para");
formalParams.add(newPara);
formalParameters.add(GNode.create("FormalParameter", fmod,
paramTypes.get(i), null, newPara, null));
}
// Create block for apply method
Node block = GNode.create("Block");
// Names of temporary variables
List<String> tempVars = new ArrayList<String>();
for (int i = 0; i < args.size(); i++) {
// Assign to a temporary variable
String tempVar = table.freshJavaId("var");
tempVars.add(tempVar);
block.add(factory.fieldDecl2(paramTypes.get(i),
tempVar, args.getGeneric(i)));
}
// Node of new arguments
Node newArgs = GNode.create("Arguments");
for (String s : tempVars) newArgs.add(toIdentifier(s));
for (String s : formalParams) newArgs.add(toIdentifier(s));
// Create return statement
Node ret = factory.ret(factory.apply(toIdentifier(funcName),
makeArgumentList(newArgs)));
block.add(ret);
// Create body of the class
Node classBody = GNode.create("ClassBody",
GNode.create("MethodDeclaration", pmod, null,
retType, "apply", formalParameters, null, null,
block));
return toNewExpression2(functionTypeNode,null,classBody);