Skip to content

Instantly share code, notes, and snippets.

@back2dos
Created November 19, 2014 12:41
Show Gist options
  • Save back2dos/1d8c84e8a7101160a555 to your computer and use it in GitHub Desktop.
Save back2dos/1d8c84e8a7101160a555 to your computer and use it in GitHub Desktop.
Support for untyped new.
-js test.js
-main Usage
--macro UntypedNew.use()
-cmd node test.js
package ;
#if macro
import haxe.macro.Compiler;
import haxe.macro.Context;
import haxe.macro.Expr;
using haxe.macro.Tools;
#end
class UntypedNew {
#if macro
static public function use()
Compiler.addGlobalMetadata('', '@:build(UntypedNew.allow())');
var occurrenceFound:Bool = false;
var fields:Array<Field>;
function new() {
fields = Context.getBuildFields();
for (f in fields)
switch f.kind {
case FVar(t, e): f.kind = FVar(t, fix(e));
case FProp(get, set, t, e): f.kind = FProp(get, set, t, fix(e));
case FFun(f): f.expr = fix(f.expr);
}
if (!occurrenceFound)
fields = null;
}
function seek(e:Expr)
switch e {
case null:
case macro untyped new $p($a{args}):
throw this;
default:
e.iter(seek);
}
function replace(e:Expr)
return
switch e {
case macro untyped new $p($a{args}):
var path = p.pack.concat([p.name]);
if (p.sub != null)
path.push(p.sub);
macro @:pos(e.pos) Type.createInstance(untyped $p{path}, [$a{args}]);
default: e.map(replace);
}
function fix(e:Expr)
return
try {
seek(e);
e;
}
catch (_:UntypedNew) {
occurrenceFound = true;
replace(e);
}
static public function allow():Array<Field>
return new UntypedNew().fields;
#end
}
package ;
class Usage {
static function main() {
function X() { }
untyped X.prototype.foo = 5;
var x:Dynamic = untyped new X();
trace(x.foo);//5 ... yay!
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment