Skip to content

Instantly share code, notes, and snippets.

@jcward
Created July 31, 2018 23:30
Show Gist options
  • Save jcward/0158d08773752a4ac5822b180e143501 to your computer and use it in GitHub Desktop.
Save jcward/0158d08773752a4ac5822b180e143501 to your computer and use it in GitHub Desktop.
TypedefMacro.hx - Haxe macro to get typedef fields at macro-time
# Because at runtime, typedefs are Dynamic (not classes), so there is no RTTI inspection of them.
# Try it here: http://try-haxe.mrcdk.com/#10CE7
Haxe is great!
a,b,opt_greeting
a,b,?opt_greeting
class Test {
static function main() {
trace("Haxe is great!");
var fields = TypedefMacro.fieldNames(Something);
trace(fields);
var fields_with_opt = TypedefMacro.fieldNames(Something, true);
trace(fields_with_opt);
}
}
typedef Something = {
a:Int,
b:String,
?opt_greeting:Void->Void
}
import haxe.macro.Expr;
import haxe.macro.Context;
using haxe.macro.ExprTools;
using haxe.macro.TypeTools;
class TypedefMacro {
public static macro function fieldNames<SomeTypedef>(anon:ExprOf<SomeTypedef>, optional_prefixes:Bool=false):ExprOf<Array<String>>
{
var t = try {
Context.getType(anon.toString()).followWithAbstracts();
} catch (e:Dynamic) {
Context.error('TypedefMacro failed typing: ${ anon }:\n${ e }', anon.pos);
null;
}
var field_names:Array<String> = [];
switch t {
case TAnonymous(a):
for (field in a.get().fields) {
var fn = field.name;
if (optional_prefixes) {
switch field.type {
case TType(n, _): if (n.toString()=='Null') fn ='?'+fn;
default:
}
}
field_names.push(fn);
}
default: throw 'TypedefMacro unexpected $t';
}
return macro $v{ field_names };
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment