在构建宏中访问Context.getLocalClass()的Class <t>

时间:2016-04-18 11:26:28

标签: macros haxe

我想创建一个向我的类添加字段的宏,字段值应该是它们所在类的Class<T>。这是我的最小示例,并且它不会使用此错误进行编译:

  

src / Base.hx:3:字符2-11:未知标识符:foo.Foo

但是如果我将Foo从包foo移到root包,那么它就可以编译并运行。

Main.hx

import foo.Foo;
class Main 
{
    static function main() 
    {
        trace(Foo.data);
    }
}

Build.hx

import haxe.macro.Context;
import haxe.macro.Type;
import haxe.macro.Expr;

class Build
{
    macro static public function build(DataClass):Array<Field> 
    {
        var cls = Context.getLocalClass().get();
        var pack = cls.pack.concat([cls.name]);
        var name = pack.join(".");
        trace(name);

        var expr = {
            expr: ExprDef.EConst(Constant.CIdent(name)),
            pos: Context.currentPos()
        }

        var newFieldCls = macro class {

            public static var data:Class<Dynamic> = $expr; 

        }

        var fields = Context.getBuildFields();
        return fields.concat(newFieldCls.fields);


    }
}

Base.hx

package;

@:autoBuild(Build.build(Main.Data))
class Base
{
    public function new()
    {
    }
}

富/ Foo.hx

package foo;

class Foo extends Base
{
}

1 个答案:

答案 0 :(得分:5)

@staticmethod def deleteProjects(): #projects = os.listdir(os.path.join(ENGINE_DIR, r"scv\Projects")) ENGINE_DIR = r"C:\AutoTest\engine" projects = os.listdir(os.path.join(ENGINE_DIR, r"scv\Projects")) for project in projects: logging.error("Project %s not deleted" % project) path = os.path.join(os.path.join(ENGINE_DIR, r"scv\Projects"), project) print "*** path ***" print path shutil.rmtree(path) 无法使用,因为这非常类似于您可以在其中指定包含EConst(CIdent("foo.Bar"))个句点的名称。相反,您需要执行.,因为这是编译器本身解析EField({ expr: EConst(CIdent("foo")) }, "Bar")的内容(尝试foo.Bar来自宏的表达式。)

所以正确的代码是

trace

处理import haxe.macro.Context; import haxe.macro.Expr; class Build { public static macro function build():Array<Field> { var self = Context.getLocalClass().get(); var cpos = Context.currentPos(); var out:Expr = null; inline function add(name:String) { if (out == null) { out = { expr: EConst(CIdent(name)), pos: cpos }; } else out = { expr: EField(out, name), pos: cpos }; } for (name in self.pack) add(name); add(self.name); return Context.getBuildFields().concat((macro class { public static var data:Class<Dynamic> = $out; }).fields); } } 表达式的创建,然后将其包装在EConst(CIdent)层中,用于尾随包,最后是类名。