Created
July 31, 2018 23:30
-
-
Save jcward/0158d08773752a4ac5822b180e143501 to your computer and use it in GitHub Desktop.
TypedefMacro.hx - Haxe macro to get typedef fields at macro-time
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
# 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 |
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
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 | |
} |
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.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