Last active
August 2, 2016 11:02
-
-
Save skial/9f6b0f0a53f67d6fce4752a8010b7e2d to your computer and use it in GitHub Desktop.
Experimental code for https://groups.google.com/d/msg/haxelang/6W3gmh_DV-I/JFLiTgBXBwAJ over on the Haxe mailing list, using Haxe 3.3.0 (git build development @ f736708), but should work with Haxe 3.3.0
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
-cp src | |
-main Main | |
-dce full | |
--each | |
-neko bin/test.n | |
--next | |
-js bin/test.js |
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
package ; | |
@:build(MyMacro.build()) | |
class Main { | |
public static function main() { | |
MyMacro.register('c'); | |
foo('bar'); | |
MyMacro.register('a'); | |
foo('baz'); | |
trace( getCollection() ); | |
} | |
public static function foo(v:String) { | |
// Do nothing with `v`. | |
MyMacro.register('foo'); // Only appears once, not for each time foo was called. | |
MyMacro.register('b'); // Only appears once, not for each time foo was called. | |
} | |
} |
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
package ; | |
import haxe.macro.Type; | |
import haxe.macro.Expr; | |
import haxe.macro.Context; | |
using StringTools; | |
using haxe.macro.TypeTools; | |
using haxe.macro.ExprTools; | |
using haxe.macro.MacroStringTools; | |
using haxe.macro.ComplexTypeTools; | |
class MyMacro { | |
// Only accepts constant strings. | |
public static macro function register(value:String):Expr { | |
var type:ClassType = switch (Context.getLocalType()) { | |
case TInst(_.get() => c, _): c; | |
case _: null; | |
} | |
if (type != null) { | |
var storage = []; | |
if (type.meta.has(':storage')) { | |
var data = type.meta.extract(':storage')[0].params[0].toString(); | |
storage = haxe.Unserializer.run(data.replace('"', '')); | |
type.meta.remove(':storage'); | |
} | |
storage.push(value); | |
trace( 'incoming - ' + value ); | |
trace( 'current state of storage', storage ); | |
type.meta.add(':storage', [macro @:pos(type.pos) $v{haxe.Serializer.run(storage)}], type.pos); | |
} | |
return macro $v{value}; | |
} | |
public static macro function build():Array<Field> { | |
var fields = Context.getBuildFields(); | |
trace( 'running build macro' ); | |
var type:ClassType = switch (Context.getLocalType()) { | |
case TInst(_.get() => c, _): c; | |
case _: null; | |
} | |
if (type != null) { | |
// Last chance to add types into current Haxe build. | |
Context.onAfterTyping(function(modules:Array<ModuleType>) { | |
for (module in modules) { | |
switch module { | |
case TClassDecl(_.get() => c) if (c.pack.toDotPath(c.name) == type.pack.toDotPath(type.name)): | |
var storage = []; | |
if (c.meta.has(':storage')) { | |
var data = c.meta.extract(':storage')[0].params[0].toString(); | |
storage = haxe.Unserializer.run(data.replace('"', '')); | |
} | |
trace( 'Complete array of macro collected values', storage ); | |
var td:TypeDefinition = macro class Collection { | |
public static var values:Array<String> = $v{storage}; | |
}; | |
// If `-dce full` is enabled. | |
td.meta.push({name:':keep', params:[], pos:type.pos}); | |
Context.defineType(td); | |
case _: | |
} | |
} | |
}); | |
fields.push( (macro class Temp { | |
// Not happy with `untyped`, but Collection doesnt _exist_ yet. | |
public static inline function getCollection():Array<String> return untyped Collection.values; | |
}).fields[0] ); | |
} | |
return fields; | |
} | |
} |
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
haxe build.hxml && neko bin/test.n | |
src/MyMacro.hx:45: running build macro | |
src/MyMacro.hx:33: incoming - c | |
src/MyMacro.hx:34: current state of storage,[c] | |
src/MyMacro.hx:33: incoming - foo | |
src/MyMacro.hx:34: current state of storage,[c,foo] | |
src/MyMacro.hx:33: incoming - b | |
src/MyMacro.hx:34: current state of storage,[c,foo,b] | |
src/MyMacro.hx:33: incoming - a | |
src/MyMacro.hx:34: current state of storage,[c,foo,b,a] | |
src/MyMacro.hx:67: Complete array of macro collected values,[c,foo,b,a] | |
Main.hx:11: [c,foo,b,a] |
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
// Generated by Haxe 3.3.0 (git build development @ f736708) | |
(function () { "use strict"; | |
var Collection = function() { }; | |
var HxOverrides = function() { }; | |
HxOverrides.iter = function(a) { | |
return { cur : 0, arr : a, hasNext : function() { | |
return this.cur < this.arr.length; | |
}, next : function() { | |
return this.arr[this.cur++]; | |
}}; | |
}; | |
var Main = function() { }; | |
Main.main = function() { | |
Main.foo("bar"); | |
Main.foo("baz"); | |
console.log(Collection.values.toString()); | |
}; | |
Main.foo = function(v) { | |
}; | |
Collection.values = ["c","foo","b","a"]; | |
Main.main(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment