So of course I know I can accomplish this by running a pre-build script or something like that. But I want to see if there’s a way I can read in some text from somewhere (let’s say, after processing a file) and effectively paste the code at a given position using the macro system.
While you can’t exactly paste code you have haxe.macro.Context.parse to go from a string to code.
You can do this in an initialization macro, in which case you can generate a class with your code using haxe.macro.Context.defineType.
Or adding it to an existing class using a build macro and @:build
.
EDIT: see @bendmorris’ answer bellow for how to actually include code at a specific position (forgot about those macros)
Sure you can. A macro function returns an expression of Haxe code (which can also be a block); calls to that function are replaced with the resulting expression at compile time:
import haxe.macro.Context;
class Test {
macro static function insertCode() {
return Context.parse("{var a = 1, b = 2; trace(a + b);}", Context.currentPos());
}
static function main() {
trace("start");
insertCode();
trace("end");
}
}
Result:
Test.hx:9: start
Test.hx:10: 3
Test.hx:11: end
While that works with something simple like that, I haven’t been able to let the code actually define classes and use the class outside:
This doesn’t work:
class Main
{
private static macro function generateClass()
{
var text = "class TextAdventureTest
{
public function run():Bool
{
trace('Hello big, adventurous world!');
return true;
}
}";
return Context.parse(text, Context.currentPos());
}
static function main()
{
generateClass();
var adventure = new TextAdventureTest();
adventure.run();
}
}
I get Type not found : TextAdventureTest
This won’t work because a class declaration isn’t valid at the place you’re calling the macro (inside a function.) For this you can use an initialization macro, as @ibilon described.
Okay. So the thing I want to do isn’t possible. Macros probably aren’t the right approach anyway. Thanks all for your help!