Skip to content

Instantly share code, notes, and snippets.

@jasononeil
Forked from Simn/Builder.hx
Last active December 11, 2015 08:08
Show Gist options
  • Save jasononeil/4570788 to your computer and use it in GitHub Desktop.
Save jasononeil/4570788 to your computer and use it in GitHub Desktop.
import haxe.macro.Context;
import haxe.macro.Expr;
class Builder {
// Build macros are called using @:build() or @:autoBuild() metadata
// They must return an array containing all of the fields of the new type
macro static function build():Array<Field> {
// Create expression representing the test() function
var funcExpr = macro function():String {
return "test";
}
// Create expression representing the new() constructor function
var ctorExpr = macro function(foo) {
trace("I was created with " +foo);
}
// Return an array of the fields we want in our class - the test() and new() methods
return [makeFunc("test", funcExpr), makeFunc("new", ctorExpr)];
}
// This takes the expression representing a function (e) and the name and turns it into
// a Field declaration. Access and meta are optional, defaulting to "public" and empty
// metadata, respectively.
static function makeFunc(name:String, e:Expr, ?access, ?meta) {
return {
name: name,
doc: null,
access: access != null ? access : [APublic],
pos: e.pos,
meta: meta != null ? meta : [],
// Make sure the expression given is in fact a function, and then declare that
// our field is a function (FFun) defined inside our given expression.
kind: switch(e.expr) {
case EFunction(_, func): FFun(func);
case _: Context.error("Argument to makeFunc must be a function expression", e.pos);
}
}
}
}
class Main {
private static function main() {
// Create a new BuildMe object, which though it is empty, will have new() and test() created by the build macro
trace(new BuildMe("Argument").test());
}
}
@:build(Builder.build())
class BuildMe { }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment