-
-
Save Simn/8ae509cc3824099c1567 to your computer and use it in GitHub Desktop.
Generic builder macro
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@:genericBuild(MyMacro.build()) | |
class MyValue<T> { | |
var value:T; | |
public function new() { } | |
public function set(t:T) { | |
value = t; | |
} | |
public function get():T { | |
return value; | |
} | |
} | |
class Main { | |
static public function main() { | |
var x = new MyValue<String>(); | |
x.set("foo"); | |
trace(x.get()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import haxe.macro.Context; | |
import haxe.macro.Expr; | |
import haxe.macro.Type; | |
using haxe.macro.Tools; | |
using Lambda; | |
class MyMacro { | |
public static function build():Type { | |
var t = Context.getLocalType(); | |
switch(t.follow()) { | |
case TInst(cr, tl): | |
var c = cr.get(); | |
var params = c.params; | |
function mapType(t:Type) return switch(t.follow()) { | |
case TInst(cr, []) if(switch(cr.get().kind) { case KTypeParameter(_): true; case _: false; }): | |
t.applyTypeParameters(params, tl); | |
case t: | |
t.map(mapType); | |
} | |
function mapExpr(e:TypedExpr) return e; | |
function mapVar(v:TVar) { | |
return { | |
capture: v.capture, | |
id: v.id, | |
extra: v.extra, | |
name: v.name, | |
t: mapType(v.t) | |
} | |
} | |
function convertField(cf:ClassField):Field { | |
var kind = switch(mapType(cf.type.follow())) { | |
case TFun(args, ret): | |
var e = switch(cf.expr().mapWithType(mapExpr, mapType, mapVar).expr) { | |
case TFunction(tf): Context.getTypedExpr(tf.expr); | |
case _: throw false; | |
} | |
FFun({ | |
args: args.map(function(arg) return { | |
name: arg.name, | |
opt: arg.opt, | |
type: arg.t.toComplexType(), | |
value: null | |
}), | |
ret: cf.name == "new" ? null : mapType(ret).toComplexType(), | |
expr: e, | |
params: [] | |
}); | |
case t: | |
FieldType.FVar(t.toComplexType()); | |
} | |
return { | |
name: cf.name, | |
pos: cf.pos, | |
access: cf.isPublic ? [APublic] : [], | |
kind: kind | |
} | |
} | |
var fields = c.fields.get(); | |
if (c.constructor != null) fields.push(c.constructor.get()); | |
var name = cr.toString() + "_" + tl.map(function(t) return t.follow().toString()).join("_"); | |
Context.defineType({ | |
name: name, | |
pack: [], | |
pos: Context.currentPos(), | |
meta: [], | |
params: [], | |
isExtern: false, | |
kind: TDClass(), | |
fields: fields.map(convertField) | |
}); | |
return Context.getType(name); | |
case _: throw false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment