Skip to content

Instantly share code, notes, and snippets.

Created December 10, 2015 23:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/4837c6dd39e56b1ffe28 to your computer and use it in GitHub Desktop.
Save anonymous/4837c6dd39e56b1ffe28 to your computer and use it in GitHub Desktop.
package hxml;
import haxe.macro.Compiler;
import haxe.macro.Context;
import haxe.macro.Type;
import haxe.macro.Expr;
/**
* Adds field overloads for optional arguments on HXCS.
* https://github.com/HaxeFoundation/haxe/issues/4623
* @author YellowAfterlife
*/
class CS {
public static function proc() {
if (!Context.defined("display")) {
Compiler.addGlobalMetadata("", "@:build(hxml.CS.build())", true, true, false);
}
}
public static function build() return switch (Context.getLocalType()) {
case null: null;
case TInst(_.get() => c, _) if (!c.isExtern): {
var fields = Context.getBuildFields().slice(0);
if (!c.isInterface) for (fi in 0 ... fields.length) {
var field = fields[fi];
if (field.name == "new") continue;
var acc = field.access;
if (acc != null && acc.indexOf(ADynamic) >= 0) continue;
switch (field.kind) {
case FFun(_func): {
var f:Function = _func;
var args = f.args;
var argc = args.length;
var n = argc;
var overloaded = false;
while (--n >= 0) {
if (!args[n].opt && args[n].value == null) break;
if (!overloaded) {
overloaded = true;
field.meta.push({
name: ":overload",
pos: field.pos,
});
}
var xargs = [];
var xcode = new StringBuf();
var hasRet = switch (f.ret) {
case TPath({ name: "Null", pack: [], params: null}): false;
default: true;
}
if (hasRet) xcode.add("return ");
xcode.add("untyped __cs__('");
xcode.add(field.name);
xcode.addChar("(".code);
for (i in 0 ... argc) {
if (i > 0) {
xcode.addChar(",".code);
xcode.addChar(" ".code);
}
var arg = args[i];
if (i < n) {
xargs.push({
name: arg.name,
type: arg.type
});
xcode.add(arg.name);
} else xcode.add(haxe.macro.ExprTools.toString(arg.value));
}
xcode.add(")')");
var xcodes = xcode.toString();
var xf:Function = {
args: xargs,
params: f.params,
ret: f.ret,
expr: Context.parse(xcodes, field.pos),
};
var xfield:Field = {
name: field.name,
doc: field.doc,
access: field.access,
kind: FFun(xf),
pos: field.pos,
meta: field.meta.slice(0),
};
fields.push(xfield);
}
};
default:
} // switch
};
fields;
};
default: null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment