Use HaXe Macro with OpenFL?

So how can I use HaXe Macro with OpenFL? I tried the simple code with openfl 2.2.7, lime 2.1.2, but it doesn’t compile:

package;
import haxe.macro.Expr;
import openfl.display.Sprite;
import openfl.Lib;

class Main extends Sprite
{

    public function new() 
    {
        super();
        // Assets:
        // openfl.Assets.getBitmapData("img/assetname.jpg");
        init();
    }
    function init()
    {
        var x = 0;
        var b = add(x++);
        trace(x); // 2
    }
    
    macro static function add(e:Expr) {
    return macro $e + $e;
    }
}

I also tried to add “” in my project.xml, but seems not working. The output:

    Running process: D:\Program Files\FlashDevelop\Tools\fdbuild\fdbuild.exe "F:\New Project\New Project.hxproj" -ipc 986f9ca7-41c6-4ab9-b386-a92de70fa223 -version "3.1.3" -compiler "D:\HaxeToolkit\haxe" -notrace -library "D:\Program Files\FlashDevelop\Library" -target "flash"
    Building New Project
    Running Pre-Build Command Line...
    cmd: "D:\HaxeToolkit\haxe/haxelib" run lime build "project.xml" flash -release -Dfdb
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/utils/ByteArray.hx:108: characters 13-24 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/utils/ByteArray.hx:1153: characters 39-50 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/utils/ByteArray.hx:1152: characters 39-50 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/utils/ByteArray.hx:1151: characters 48-59 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/utils/ByteArray.hx:1150: characters 53-64 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2200: characters 45-56 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2201: characters 44-55 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2202: characters 51-62 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2203: characters 42-53 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2204: characters 47-58 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2205: characters 48-59 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2206: characters 43-54 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2207: characters 42-53 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2208: characters 45-56 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2209: characters 54-65 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2210: characters 41-52 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2211: characters 50-61 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2212: characters 42-53 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2213: characters 46-57 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2214: characters 55-66 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2215: characters 36-47 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2216: characters 42-53 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2217: characters 42-53 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2218: characters 44-55 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2219: characters 41-52 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2220: characters 45-56 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2221: characters 54-65 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2222: characters 58-69 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2223: characters 48-59 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2224: characters 52-63 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2225: characters 44-55 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2226: characters 49-60 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2227: characters 45-56 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2228: characters 51-62 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2229: characters 44-55 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2230: characters 45-56 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2231: characters 40-51 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2232: characters 44-55 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2233: characters 49-60 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2234: characters 45-56 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2235: characters 51-62 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2236: characters 44-55 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2237: characters 45-56 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2238: characters 41-52 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2239: characters 41-52 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2240: characters 42-53 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2241: characters 44-55 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2242: characters 38-49 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2243: characters 58-69 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2244: characters 42-53 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2245: characters 44-55 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2246: characters 37-48 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2247: characters 57-68 : Class<lime.system.System> has no field load
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/graphics/opengl/GL.hx:2248: characters 37-48 : Class<lime.system.System> has no field load
.....
   Class<openfl.Lib> has no field notImplemented
    D:/HaxeToolkit/haxe/lib/openfl/2,2,7/openfl/display/Graphics.hx:750: characters 2-27 : Class<openfl.Lib> has no field notImplemented
    D:/HaxeToolkit/haxe/lib/openfl/2,2,7/openfl/display/Loader.hx:193: characters 2-27 : Class<openfl.Lib> has no field notImplemented
    D:/HaxeToolkit/haxe/lib/openfl/2,2,7/openfl/display/Loader.hx:581: characters 2-27 : Class<openfl.Lib> has no field notImplemented
    D:/HaxeToolkit/haxe/lib/openfl/2,2,7/openfl/display/InteractiveObject.hx:1157: characters 2-27 : Class<openfl.Lib> has no field notImplemented
    D:/HaxeToolkit/haxe/lib/openfl/2,2,7/openfl/display/DisplayObject.hx:1452: characters 10-21 : Class<openfl.Lib> has no field current
    D:/HaxeToolkit/haxe/lib/lime/2,1,2/lime/utils/ByteArray.hx:108: characters 13-60 : Invalid call
    Aborted
    Build halted with errors.
    Done(1)

Looks like there’s some sort of problem with your installation. If you commented all the macro stuff and compiled again; you’d probably see exactly the same errors. Did you remember to run haxelib run openfl setup?

Once you get that working, you’ll find yourself getting another error: “You cannot access the flash package while in a macro.” This can be solved by moving your macro into a dedicated class:

class Macros {
    public static macro function add(e:Expr):Expr {
        return macro $e + $e;
    }
}

This class is allowed to import haxe.* classes, but not flash.* or openfl.*.

3 Likes

Thanks, that should solve my problem for now! Not sure whether this is an installation problem since I can compile old projects successfully. I can see the error: “You cannot access the flash package while in a macro.” when using an old version of openfl. By the way, is it possible to mix haxe Macro and openfl?

You mean like this?

public static macro function makeOpenFLSprite():Expr {
    return macro new openfl.display.Sprite();
}

You aren’t allowed to have “import openfl.display.Sprite;” at the top of the file, but you can get around that by typing out the full class name when you need it.

That’s exactly what I mean. Thanks!

You also might have to be careful with #if macro or #if !macro statements, we use this to mix macro and non-macro statements in the same file, but it does require care

This really helped me—thanks Joseph!