Skip to content

Instantly share code, notes, and snippets.

@back2dos
Created October 20, 2012 08:35
Show Gist options
  • Select an option

  • Save back2dos/3922689 to your computer and use it in GitHub Desktop.

Select an option

Save back2dos/3922689 to your computer and use it in GitHub Desktop.
Optional interface fields with macros
package ;
import tink.macro.build.Member;
import tink.macro.build.MemberTransformer;
import haxe.macro.Type;
using tink.macro.tools.MacroTools;
using tink.core.types.Outcome;
class Optional {
static public function build() {
return new MemberTransformer().build([process]);
}
static function process(ctx:ClassBuildContext) {
if (ctx.cls.isInterface) return;
for (t in ctx.cls.interfaces) {
for (f in TInst(t.t, t.params).getFields().sure()) {
if (!ctx.has(f.name) && f.meta.has(':optional')) {
switch (f.type) {
case TFun(args, ret):
var fArgs = [];
for (a in args)
fArgs.push(a.name.toArg(a.t.toComplex()));
var m = Member.method(f.name, f.pos, (macro throw 'call to unimplemented optional method').func(fArgs, ret.toComplex()));
ctx.add(m);
m.addMeta(':noComplete', f.pos);
m.addMeta(':optional', f.pos);
default:
f.pos.error('only functions can be optional');
}
}
}
}
}
}
package ;
class Test {
static public function main() {
var f = new MyFoo();
}
}
@:autoBuild(Optional.build())
extern class NSObject {}
interface Foo implements NSObject {
@:optional function foobar():Void;
}
class MyFoo implements Foo {
public function new() {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment