I’ve seen several questions about overloaded functions for Haxe, but I haven’t seen one yet for writing an overloaded function in the target language.
Say I have a function like this, which is in a library that is intended to be compiled to Java and used by other applications:
public static function myfunc(arg1:String, ?arg2:String, ?arg3:String):Array<String> { ... }
This is nice if I’m writing code in Haxe, but in Java I end up having to pass null’s for the optional arguments quite a bit. If I were writing this in Java directly, I’d do it like this to make it a little nicer to call:
public static String[] myfunc(String arg1, String arg2, String arg3) { ... }
public static String[] myfunc(String arg1, String arg2) { return myfunc(arg1, arg2, null); }
public static String[] myfunc(String arg1) { return myfunc(arg1, null, null); }
My thinking was that I could use a macro to generate the overloaded calls in Java - and I can, I have a macro that does just that. The issue that I’m having is that I can’t generate the overloaded functions with the same name as the original function, as that gives me a “duplicate class field declaration” error (which makes sense).
Is there a way that - knowing my target language is Java and it supports overloaded functions - I can generate the overloaded functions with the same name as the original function?
For completeness here’s the (very rough) macro function that I’m using to generate the overloaded functions.
/**
* @param field Original field object, from Context.getBuildFields().
* @param func The function represented by the field object.
* @param pos The position.
* @return Any overloaded functions that should be added to the macro return.
*/
private static function handleFunction(field:Field, func:Function, pos:Position):Array<Field>
{
var hasOptArgsAtEnd = false;
var args = new Array<FunctionArg>();
for(arg in func.args)
{
hasOptArgsAtEnd = arg.opt;
args.push(arg);
}
if(!hasOptArgsAtEnd)
{
return null;
}
var rtrn = new Array<Field>();
args.pop();
while(args.length > 0)
{
var nArgs = new Array<Expr>();
for(arg in args)
{
nArgs.push(macro $i{arg.name});
}
for(idx in args.length...func.args.length)
{
nArgs.push(macro $v{null});
}
var myFunc:Function = {
expr: macro return $i{field.name}($a{nArgs}),
ret: func.ret,
args: args.copy()
};
var f:Field = {
name: field.name + Std.string(args.length),
access: field.access,
kind: FieldType.FFun(myFunc),
pos: pos
};
rtrn.push(f);
if(!args.pop().opt)
{
break;
}
}
return rtrn;
}