Created
October 29, 2014 11:35
-
-
Save skial/11928684eb90c8bbbf28 to your computer and use it in GitHub Desktop.
How to collect values across multiple @:autoBuild macro runs. Using Haxe 3.2.0 (git build development @ 3a255a8).
This file contains hidden or 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
| -main Main | |
| -js test.js | |
| --next | |
| -cmd node test.js |
This file contains hidden or 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
| package ; | |
| import haxe.ds.StringMap; | |
| import haxe.macro.Compiler; | |
| import haxe.macro.Printer; | |
| import haxe.macro.Type; | |
| import haxe.macro.Expr; | |
| import haxe.macro.Context; | |
| using StringTools; | |
| using haxe.macro.MacroStringTools; | |
| /** | |
| * ... | |
| * @author Skial Bainn | |
| */ | |
| class Macro { | |
| public static var previous:String = 'Helper'; | |
| public static var parent:ClassType = null; | |
| public static var processed:StringMap<String> = new StringMap(); | |
| public static var values:Array<Expr> = []; | |
| public static function build() { | |
| var cls:ClassType = Context.getLocalClass().get(); | |
| var path = cls.pack.toDotPath( cls.name ); | |
| var fields = Context.getBuildFields(); | |
| parent = cls; | |
| var superCls = cls.superClass; | |
| while (superCls != null) { | |
| var c = superCls.t.get(); | |
| var n = c.pack.toDotPath( c.name ); | |
| parent = c; | |
| if (!processed.exists(n)) { | |
| for (field in c.fields.get()) { | |
| for (meta in field.meta.get()) if (meta.name == 'f' && meta.params != null) { | |
| values = values.concat( meta.params ); | |
| } | |
| } | |
| processed.set(n, ''); | |
| } | |
| superCls = c.superClass; | |
| } | |
| if (!processed.exists( path )) { | |
| for (field in fields) for (meta in field.meta) if (meta.name == 'f' && meta.params != null) { | |
| values = values.concat( meta.params ); | |
| } | |
| processed.set( path, '' ); | |
| } | |
| var helperName = 'H${Math.random()}'.replace('.', '_'); | |
| var helperClass = { | |
| pack:[], name: helperName, pos: cls.pos, | |
| meta: [ { name:':native', params:[macro 'Helper'], pos:cls.pos }, { name:':keep', params:[], pos:cls.pos } ], | |
| kind: TDClass(), fields:[{name:'values', access:[APublic, AStatic], kind:FVar(macro:Array<String>, macro $a{values}), pos:cls.pos}] | |
| } | |
| Context.defineType( helperClass ); | |
| Compiler.exclude( previous ); | |
| previous = helperName; | |
| return fields; | |
| } | |
| } |
This file contains hidden or 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
| package ; | |
| /** | |
| * ... | |
| * @author Skial Bainn | |
| */ | |
| class Main { | |
| public static function main() new Main(); | |
| public function new() { | |
| new A(); | |
| trace( Helper.values ); | |
| } | |
| } | |
| class Helper { | |
| public static var values:Array<String> = []; | |
| } | |
| // Need to use an interface as opposed to putting it | |
| // on `A` so `A` actually gets passed to the build | |
| // macro. | |
| @:autoBuild( Macro.build() ) | |
| interface Builder{} | |
| class A implements Builder { | |
| @f('1') public var a:String = 'a'; | |
| public function new() {} | |
| } | |
| class B extends A { | |
| @f('2') public var b:String = 'b'; | |
| public function new() { super(); } | |
| } | |
| class C extends B { | |
| @f('3') public var c:String = 'c'; | |
| public function new() { super(); } | |
| } | |
| class D extends C { | |
| @f('4') public var d:String = 'd'; | |
| public function new() { super(); } | |
| } |
This file contains hidden or 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
| (function () { "use strict"; | |
| var console = (1,eval)('this').console || {log:function(){}}; | |
| function $extend(from, fields) { | |
| function Inherit() {} Inherit.prototype = from; var proto = new Inherit(); | |
| for (var name in fields) proto[name] = fields[name]; | |
| if( fields.toString !== Object.prototype.toString ) proto.toString = fields.toString; | |
| return proto; | |
| } | |
| var Helper = function() { }; | |
| var Main = function() { | |
| new A(); | |
| console.log(Helper.values); | |
| }; | |
| Main.main = function() { | |
| new Main(); | |
| }; | |
| var Builder = function() { }; | |
| var A = function() { | |
| this.a = "a"; | |
| }; | |
| A.__interfaces__ = [Builder]; | |
| var B = function() { | |
| this.b = "b"; | |
| A.call(this); | |
| }; | |
| B.__super__ = A; | |
| B.prototype = $extend(A.prototype,{ | |
| }); | |
| var C = function() { | |
| this.c = "c"; | |
| B.call(this); | |
| }; | |
| C.__super__ = B; | |
| C.prototype = $extend(B.prototype,{ | |
| }); | |
| var D = function() { | |
| this.d = "d"; | |
| C.call(this); | |
| }; | |
| D.__super__ = C; | |
| D.prototype = $extend(C.prototype,{ | |
| }); | |
| Helper.values = ["1","2","3","4"]; | |
| A.__meta__ = { fields : { a : { f : ["1"]}}}; | |
| B.__meta__ = { fields : { b : { f : ["2"]}}}; | |
| C.__meta__ = { fields : { c : { f : ["3"]}}}; | |
| D.__meta__ = { fields : { d : { f : ["4"]}}}; | |
| Main.main(); | |
| })(); |
This file contains hidden or 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
| >haxe build.hxml | |
| [ '1', '2', '3', '4' ] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment