Skip to content

Instantly share code, notes, and snippets.

@profelis
Last active December 24, 2015 09:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save profelis/6778162 to your computer and use it in GitHub Desktop.
Save profelis/6778162 to your computer and use it in GitHub Desktop.
ElvisReflect.hx
using haxe.macro.ExprTools;
import haxe.macro.Context;
import haxe.macro.Expr;
class ElvisReflect {
@:noUsing macro static public function fast(args:Array<Expr>) {
if (args.length == 0) return macro {};
function map(e:Expr):Expr {
return switch (e.expr) {
case EBinop(OpAssign, {expr:EField(e1, _)}, e2):
macro $e1 != null ? $e : $e2;
case EField(e1, _):
macro $e1 != null ? $e : null;
case _: e.map(map);
}
}
var res = [];
for (e in args) res.push(e.map(map));
return res.length == 1 ? res[0] : macro $b{res};
}
@:noUsing macro static public function setField(expr:Expr, value:Expr):Expr {
return switch (expr.expr) {
case EField(e1, _):
macro $e1 != null ? $expr = $value : $value;
case _: Context.error("first arg must be field call", expr.pos);
}
}
@:noUsing macro static public function field(expr:Expr):Expr {
return switch (expr.expr) {
case EField(e1, _):
macro $e1 != null ? $expr : null;
case _: Context.error("first arg must be field call", expr.pos);
}
}
}
class Main{
static main(method) : Void -> Void
= function() = {
var b = null;
var a = {t : 1};
if ((a != null))a.t = 10 else 10);
if ((b != null))b.t = 10 else 10);
haxe.Log.trace(if ((a != null))a.t else null),{fileName : "Main.hx",lineNumber : 8,className : "Main",methodName : "main"});
haxe.Log.trace(if ((b != null))b.t else null),{fileName : "Main.hx",lineNumber : 9,className : "Main",methodName : "main"});
{
if ((a != null))a.t = 1 else 1);
if ((b != null))b.t = 2 else 2);
haxe.Log.trace(if ((a != null))a.t else null),{fileName : "Main.hx",lineNumber : 14,className : "Main",methodName : "main"});
haxe.Log.trace(if ((b != null))b.t else null),{fileName : "Main.hx",lineNumber : 15,className : "Main",methodName : "main"});
};
};
}
class Main {
static function main() {
var b:{t:Int} = null;
var a = {t:1};
ElvisReflect.setField(a.t, 10);
ElvisReflect.setField(b.t, 10);
trace(ElvisReflect.field(a.t));
trace(ElvisReflect.field(b.t));
ElvisReflect.fast({
a.t = 1;
b.t = 2;
trace(a.t);
trace(b.t);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment